diff --git a/Makefile b/Makefile index dfc6fd5c0..0e2b361e6 100644 --- a/Makefile +++ b/Makefile @@ -50,7 +50,7 @@ SWIFTEST_MODULES = swiftest_globals.f90 \ whm_classes.f90 \ rmvs_classes.f90 \ helio_classes.f90 \ - util.f90 \ + symba_classes.f90 \ module_nrutil.f90 \ swiftest.f90 @@ -151,6 +151,11 @@ lib: 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 .; \ @@ -196,6 +201,7 @@ clean: 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/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* diff --git a/examples/helio_swifter_comparison/cb.swiftest.in b/examples/helio_swifter_comparison/cb.swiftest.in index 058975b81..e4a010b1e 100644 --- a/examples/helio_swifter_comparison/cb.swiftest.in +++ b/examples/helio_swifter_comparison/cb.swiftest.in @@ -1,3 +1,4 @@ +0 39.476926408897626 0.004650467260962157 4.7535806948127355e-12 diff --git a/examples/helio_swifter_comparison/init_cond.py b/examples/helio_swifter_comparison/init_cond.py old mode 100644 new mode 100755 index 7e45bb4bb..4680d9e0a --- a/examples/helio_swifter_comparison/init_cond.py +++ b/examples/helio_swifter_comparison/init_cond.py @@ -1,9 +1,5 @@ +#!/usr/bin/env python3 import swiftest -import numpy as np -import sys -from astroquery.jplhorizons import Horizons -import astropy.constants as const -from scipy.io import FortranFile sim = swiftest.Simulation() diff --git a/examples/helio_swifter_comparison/pl.swifter.in b/examples/helio_swifter_comparison/pl.swifter.in index aba56d467..e0ef4e881 100644 --- a/examples/helio_swifter_comparison/pl.swifter.in +++ b/examples/helio_swifter_comparison/pl.swifter.in @@ -2,35 +2,35 @@ 0 39.476926408897625196 0.0 0.0 0.0 0.0 0.0 0.0 -1 6.5537098095653139645e-06 0.0014751254963649625977 +1 6.5537098095653139645e-06 0.0014751243077781048702 1.6306381826061645943e-05 -0.359124056979876094 -0.1001978128323056938 -0.041130148620746292965 -0.7664364270424182397 10.3592906410849091145 0.7762248217818495593 -2 9.663313399581537916e-05 0.0067591139064765566703 +0.33206272695596028566 0.07436707001147663254 -0.02438290851908785084 +-4.2340114788918336805 10.486553514018327622 1.2453138107251555947 +2 9.663313399581537916e-05 0.006759104275397271956 4.0453784346544178454e-05 --0.709853246614207567 0.109615461427968005625 0.042466530791895232277 --1.166834223638398553 -7.334297883841826485 -0.033323414543104576783 -3 0.000120026935827952453094 0.010044751446422198828 +-0.7188115337296047125 -0.0118554711069603201795 0.041316403191083782287 +0.07826338813583945357 -7.419533988988633545 -0.10634201014368884618 +3 0.000120026935827952453094 0.010044787321379672528 4.25875607065040958e-05 -0.26014404284638581455 -0.9828537227999029069 4.5807148740206238052e-05 -5.9724418390973225248 1.5843954077771575533 -9.4205748659356694786e-05 -4 1.2739802010675941456e-05 0.0072467561525263839036 +0.35677088372527121507 -0.95189300879814897627 4.4027442504036787155e-05 +5.7819217550992820422 2.18192814489641851 -0.00012230072278352209966 +4 1.2739802010675941456e-05 0.007246743835971885302 2.265740805092889601e-05 --1.4908630412685239808 0.7412277078494349247 0.052104480532706012874 --2.084278892390818102 -4.1405652065758745757 -0.035644761583621103612 -5 0.037692251088985676735 0.35527141892920671874 +-1.5233712071242269115 0.6723825347339112968 0.051459143378398922164 +-1.8728417739956807141 -4.239719661832373223 -0.042909557750301418264 +5 0.037692251088985676735 0.35527126534549128905 0.00046732617030490929307 -4.0233930071159198505 -3.029555621945668964 -0.077433472926114965684 -1.626590141045528945 2.3340622087669935288 -0.046085347207395002237 -6 0.011285899820091272997 0.43765136932522125042 +4.049944927347420176 -2.9910878677758190314 -0.078187280837353656526 +1.6060801375519682711 2.349356876761497338 -0.045690062807172619064 +6 0.011285899820091272997 0.4376527512949726007 0.00038925687730393611812 -6.274810893232299236 -7.7275164380757708216 -0.115372736553069593635 -1.4703000143673246375 1.2821134193800077011 -0.08078666716402813097 -7 0.0017236589478267730203 0.469520070575212966 +6.298929503477405767 -7.706413024510769816 -0.11669919842191249504 +1.4661378456572359413 1.2872251175075805794 -0.08070991686100478242 +7 0.0017236589478267730203 0.4695362423191493196 0.00016953449859497231466 -14.871766666738729157 12.9908875920566391216 -0.14444232402201501175 --0.9541590491729433116 1.0172543087941671172 0.016087073469786578863 -8 0.0020336100526728302319 0.78126715446178621345 +14.856082147529010129 13.007589275314199284 -0.14417795763685259391 +-0.9554310497290159123 1.0161753499437922057 0.016099529164307530124 +8 0.0020336100526728302319 0.7812870996943599397 0.000164587904124493665 -29.554624389819270647 -4.648140925388063671 -0.5854586034520335991 -0.1723572655485145611 1.1421549698170996955 -0.027459964210413734165 +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 index 27814f389..9d49cc3da 100644 --- a/examples/helio_swifter_comparison/pl.swiftest.in +++ b/examples/helio_swifter_comparison/pl.swiftest.in @@ -1,33 +1,33 @@ 8 1 6.5537098095653139645e-06 1.6306381826061645943e-05 -0.359124056979876094 -0.1001978128323056938 -0.041130148620746292965 -0.7664364270424182397 10.3592906410849091145 0.7762248217818495593 +0.33206272695596028566 0.07436707001147663254 -0.02438290851908785084 +-4.2340114788918336805 10.486553514018327622 1.2453138107251555947 2 9.663313399581537916e-05 4.0453784346544178454e-05 --0.709853246614207567 0.109615461427968005625 0.042466530791895232277 --1.166834223638398553 -7.334297883841826485 -0.033323414543104576783 +-0.7188115337296047125 -0.0118554711069603201795 0.041316403191083782287 +0.07826338813583945357 -7.419533988988633545 -0.10634201014368884618 3 0.000120026935827952453094 4.25875607065040958e-05 -0.26014404284638581455 -0.9828537227999029069 4.5807148740206238052e-05 -5.9724418390973225248 1.5843954077771575533 -9.4205748659356694786e-05 +0.35677088372527121507 -0.95189300879814897627 4.4027442504036787155e-05 +5.7819217550992820422 2.18192814489641851 -0.00012230072278352209966 4 1.2739802010675941456e-05 2.265740805092889601e-05 --1.4908630412685239808 0.7412277078494349247 0.052104480532706012874 --2.084278892390818102 -4.1405652065758745757 -0.035644761583621103612 +-1.5233712071242269115 0.6723825347339112968 0.051459143378398922164 +-1.8728417739956807141 -4.239719661832373223 -0.042909557750301418264 5 0.037692251088985676735 0.00046732617030490929307 -4.0233930071159198505 -3.029555621945668964 -0.077433472926114965684 -1.626590141045528945 2.3340622087669935288 -0.046085347207395002237 +4.049944927347420176 -2.9910878677758190314 -0.078187280837353656526 +1.6060801375519682711 2.349356876761497338 -0.045690062807172619064 6 0.011285899820091272997 0.00038925687730393611812 -6.274810893232299236 -7.7275164380757708216 -0.115372736553069593635 -1.4703000143673246375 1.2821134193800077011 -0.08078666716402813097 +6.298929503477405767 -7.706413024510769816 -0.11669919842191249504 +1.4661378456572359413 1.2872251175075805794 -0.08070991686100478242 7 0.0017236589478267730203 0.00016953449859497231466 -14.871766666738729157 12.9908875920566391216 -0.14444232402201501175 --0.9541590491729433116 1.0172543087941671172 0.016087073469786578863 +14.856082147529010129 13.007589275314199284 -0.14417795763685259391 +-0.9554310497290159123 1.0161753499437922057 0.016099529164307530124 8 0.0020336100526728302319 0.000164587904124493665 -29.554624389819270647 -4.648140925388063671 -0.5854586034520335991 -0.1723572655485145611 1.1421549698170996955 -0.027459964210413734165 +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 index 9a487a59c..7f0b1d4b9 100644 --- a/examples/helio_swifter_comparison/swiftest_vs_swifter.ipynb +++ b/examples/helio_swifter_comparison/swiftest_vs_swifter.ipynb @@ -153,7 +153,7 @@ "outputs": [ { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ "
" ] diff --git a/examples/helio_swifter_comparison/tp.swifter.in b/examples/helio_swifter_comparison/tp.swifter.in index 62acd79fc..b37f04011 100644 --- a/examples/helio_swifter_comparison/tp.swifter.in +++ b/examples/helio_swifter_comparison/tp.swifter.in @@ -1,13 +1,13 @@ 4 101 -2.3133253483335658451 1.6360857008750779862 -0.37450983998533471375 --2.2458876465769251093 2.8378699270656317882 0.50346273267874514076 +2.2759060918449769417 1.6823262546111898974 -0.3661544509052930274 +-2.3097811686367798667 2.7916683305060454227 0.51377483806222698173 102 -3.009555158239280992 -1.1130165423439479788 0.51172110509120705135 -0.70453633545041942506 2.5148434686651768256 -1.80152331908826862 +3.0206599411327550442 -1.0715345879373190385 0.4820489106686373093 +0.64736314289225124926 2.5354787229381968757 -1.8109825958052419904 103 --0.5218824163555056961 -3.1396467647675119217 0.7342355813480357929 -3.0582031698647593751 -0.12050283730110719834 -0.096945705299882042706 +-0.47156753362343428737 -3.1411451968218520037 0.73253063903937232215 +3.067486522793096946 -0.061867034122113133084 -0.11064022385054755856 104 --2.075368356279947868 -0.76569201199778380573 0.27541025252901979448 -1.7615515330387480359 -3.9484151677488075983 -0.096278788580453326945 +-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 index 62acd79fc..b37f04011 100644 --- a/examples/helio_swifter_comparison/tp.swiftest.in +++ b/examples/helio_swifter_comparison/tp.swiftest.in @@ -1,13 +1,13 @@ 4 101 -2.3133253483335658451 1.6360857008750779862 -0.37450983998533471375 --2.2458876465769251093 2.8378699270656317882 0.50346273267874514076 +2.2759060918449769417 1.6823262546111898974 -0.3661544509052930274 +-2.3097811686367798667 2.7916683305060454227 0.51377483806222698173 102 -3.009555158239280992 -1.1130165423439479788 0.51172110509120705135 -0.70453633545041942506 2.5148434686651768256 -1.80152331908826862 +3.0206599411327550442 -1.0715345879373190385 0.4820489106686373093 +0.64736314289225124926 2.5354787229381968757 -1.8109825958052419904 103 --0.5218824163555056961 -3.1396467647675119217 0.7342355813480357929 -3.0582031698647593751 -0.12050283730110719834 -0.096945705299882042706 +-0.47156753362343428737 -3.1411451968218520037 0.73253063903937232215 +3.067486522793096946 -0.061867034122113133084 -0.11064022385054755856 104 --2.075368356279947868 -0.76569201199778380573 0.27541025252901979448 -1.7615515330387480359 -3.9484151677488075983 -0.096278788580453326945 +-2.0454358521790818592 -0.83017357434175576003 0.27369621627497042748 +1.8825682786003801814 -3.9015333153827542793 -0.112405737336568095776 diff --git a/examples/rmvs_gr_test/cb.swiftest.in b/examples/rmvs_gr_test/cb.swiftest.in deleted file mode 100644 index 2386b53c8..000000000 Binary files a/examples/rmvs_gr_test/cb.swiftest.in and /dev/null differ diff --git a/examples/rmvs_gr_test/init_cond.py b/examples/rmvs_gr_test/init_cond.py deleted file mode 100644 index 7083997bc..000000000 --- a/examples/rmvs_gr_test/init_cond.py +++ /dev/null @@ -1,316 +0,0 @@ -""" -This script generates initial conditions for the solar using JPL Horizons data. - -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 sys -from astroquery.jplhorizons import Horizons -import astropy.constants as const -import swiftestio as swio -from scipy.io import FortranFile - -from numpy.random import default_rng - -#Values from JPL Horizons -AU2M = np.longdouble(const.au.value) -GMSunSI = np.longdouble(const.GM_sun.value) -Rsun = np.longdouble(const.R_sun.value) -GC = np.longdouble(const.G.value) -JD = 86400 -year = np.longdouble(365.25 * JD) -c = np.longdouble(299792458.0) -MSun_over_Mpl = np.array([6023600.0, - 408523.71, - 328900.56, - 3098708., - 1047.3486, - 3497.898, - 22902.98, - 19412.24, - 1.35e8], dtype=np.longdouble) - -MU2KG = np.longdouble(GMSunSI / GC) #Conversion from mass unit to kg -DU2M = np.longdouble(AU2M) #Conversion from radius unit to centimeters -TU2S = np.longdouble(year) #Conversion from time unit to seconds -GU = np.longdouble(GC / (DU2M**3 / (MU2KG * TU2S**2))) - -GMSun = np.longdouble(GMSunSI / (DU2M**3 / TU2S**2)) - -# Simulation start, stop, and output cadence times -t_0 = 0 # simulation start time -deltaT = 0.25 * JD / TU2S # simulation step size -end_sim = 500 * year / TU2S # simulation end time -t_print = 0.1 * year / TU2S #output interval to print results - -# Solar oblatenes values: From Mecheri et al. (2004), using Corbard (b) 2002 values (Table II) -J2 = np.longdouble(2.198e-7) * (Rsun / DU2M)**2 -J4 = np.longdouble(-4.805e-9) * (Rsun / DU2M)**4 - -tstart = '2021-01-28' -tend = '2021-01-29' -tstep = '1d' -planetid = { - 'mercury' : '1', - 'venus' : '2', - 'earthmoon' : '3', - 'mars' : '4', - 'jupiter' : '5', - 'saturn' : '6', - 'uranus' : '7', - 'neptune' : '8', - 'plutocharon' : '9' -} -npl = 9 - -#Planet Msun/M ratio -MSun_over_Mpl = { - 'mercury' : np.longdouble(6023600.0), - 'venus' : np.longdouble(408523.71), - 'earthmoon' : 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), - 'plutocharon' : np.longdouble(1.35e8) -} - -#Planet radii in meters -Rpl = { - 'mercury' : np.longdouble(2439.4e3), - 'venus' : np.longdouble(6051.8e3), - 'earthmoon' : np.longdouble(6371.0084e3), # Earth only for radius - 'mars' : np.longdouble(3389.50e3), - 'jupiter' : np.longdouble(69911e3), - 'saturn' : np.longdouble(58232.0e3), - 'uranus' : np.longdouble(25362.e3), - 'neptune' : np.longdouble(24622.e3), - 'plutocharon' : np.longdouble(1188.3e3) -} - -pdata = {} -plvec = {} -Rhill = {} -THIRDLONG = np.longdouble(1.0) / np.longdouble(3.0) - -for key,val in planetid.items(): - pdata[key] = Horizons(id=val, id_type='majorbody',location='@sun', - epochs={'start': tstart, 'stop': tend, - 'step': tstep}) - plvec[key] = np.array([pdata[key].vectors()['x'][0], - pdata[key].vectors()['y'][0], - pdata[key].vectors()['z'][0], - pdata[key].vectors()['vx'][0], - pdata[key].vectors()['vy'][0], - pdata[key].vectors()['vz'][0] - ]) - Rhill[key] = np.longdouble(pdata[key].elements()['a'][0]) * (3 * MSun_over_Mpl[key])**(-THIRDLONG) - -if __name__ == '__main__': - - nclones = 10 - xv_dispersion_factor = 0.01 # randomly alter x and v vectors by this fraction of the original - - # Get tp data from collidor simulation to produce the parent of the clones - inparfile = "param.tpcollider.in" - paramfile = swio.read_swifter_param(inparfile) - swifterdat = swio.swifter2xr(paramfile) - px = swifterdat.isel(time=-1).sel(id=100)['px'].values.item() - py = swifterdat.isel(time=-1).sel(id=100)['py'].values.item() - pz = swifterdat.isel(time=-1).sel(id=100)['pz'].values.item() - - vx = swifterdat.isel(time=-1).sel(id=100)['vx'].values.item() - vy = swifterdat.isel(time=-1).sel(id=100)['vy'].values.item() - vz = swifterdat.isel(time=-1).sel(id=100)['vz'].values.item() - - jangofett = np.array([px, py, pz, -vx, -vy, -vz]) - - # generate random clones - rng = default_rng() - clone_xv = (rng.standard_normal((nclones, 6)) - 0.5) * xv_dispersion_factor + 1.0 - clonetroops = jangofett * clone_xv - clonenames = range(100, 100 + nclones) - tpvec = dict(zip(clonenames,clonetroops)) - - # Convert from AU-day to AU-year just because I find it easier to keep track of the sim progress - for plid in plvec: - plvec[plid][3:] *= year / JD - - for tpid in tpvec: - tpvec[tpid][3:] *= year / JD - - # Names of all output files - 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" - - iout = int(np.ceil(t_print / deltaT)) - rmin = Rsun / DU2M - rmax = 1000.0 - - #Make Swifter files - plfile = open(swifter_pl, 'w') - print(npl+1, f'! Planet input file generated using init_cond.py using JPL Horizons data for the major planets (and Pluto) for epoch {tstart}' ,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) - for i, plid in enumerate(plvec): - print(i + 2,"{:.23g}".format(GMSun * MSun_over_Mpl[plid]**-1),Rhill[plid], file=plfile) - print(Rpl[plid] / DU2M, file=plfile) - print(plvec[plid][0],plvec[plid][1],plvec[plid][2], file=plfile) - print(plvec[plid][3],plvec[plid][4],plvec[plid][5], file=plfile) - plfile.close() - - tpfile = open(swifter_tp, 'w') - print(nclones,file=tpfile) - for tpid, tp in tpvec.items(): - print(tpid, file=tpfile) - print(f'{tp[0]} {tp[1]} {tp[2]}', file=tpfile) - print(f'{tp[3]} {tp[4]} {tp[5]}', 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 EL') - print(f'OUT_STAT NEW') - 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') - - #Now make Swiftest files - cbfile = FortranFile(swiftest_cb, 'w') - Msun = np.double(1.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) - - name = np.empty(npl, dtype=np.int32) - px = np.empty(npl, dtype=np.double) - py = np.empty(npl, dtype=np.double) - pz = np.empty(npl, dtype=np.double) - vx = np.empty(npl, dtype=np.double) - vy = np.empty(npl, dtype=np.double) - vz = np.empty(npl, dtype=np.double) - mass = np.empty(npl, dtype=np.double) - Gmass = np.empty(npl, dtype=np.double) - radius = np.empty(npl, dtype=np.double) - for i, plid in enumerate(plvec): - name[i] = i + 2 - px[i] = plvec[plid][0] - py[i] = plvec[plid][1] - pz[i] = plvec[plid][2] - vx[i] = plvec[plid][3] - vy[i] = plvec[plid][4] - vz[i] = plvec[plid][5] - Gmass[i] = GMSun * MSun_over_Mpl[plid]**-1 - radius[i] = Rpl[plid] / DU2M - plfile.write_record(name.T) - plfile.write_record(px.T) - plfile.write_record(py.T) - plfile.write_record(pz.T) - plfile.write_record(vx.T) - plfile.write_record(vy.T) - plfile.write_record(vz.T) - plfile.write_record(Gmass.T) - plfile.write_record(radius.T) - plfile.close() - tpfile = FortranFile(swiftest_tp, 'w') - ntp = nclones - tpfile.write_record(ntp) - name = np.empty(ntp, dtype=np.int32) - px = np.empty(ntp, dtype=np.double) - py = np.empty(ntp, dtype=np.double) - pz = np.empty(ntp, dtype=np.double) - vx = np.empty(ntp, dtype=np.double) - vy = np.empty(ntp, dtype=np.double) - vz = np.empty(ntp, dtype=np.double) - for i, tpid in enumerate(tpvec): - name[i] = int(tpid) - px[i] = tpvec[tpid][0] - py[i] = tpvec[tpid][1] - pz[i] = tpvec[tpid][2] - vx[i] = tpvec[tpid][3] - vy[i] = tpvec[tpid][4] - vz[i] = tpvec[tpid][5] - tpfile.write_record(name.T) - tpfile.write_record(px.T) - tpfile.write_record(py.T) - tpfile.write_record(pz.T) - tpfile.write_record(vx.T) - tpfile.write_record(vy.T) - tpfile.write_record(vz.T) - - 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 EL') - 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}') - - - sys.stdout = sys.__stdout__ - - - diff --git a/examples/rmvs_gr_test/mercury_collider_init_cond.py b/examples/rmvs_gr_test/mercury_collider_init_cond.py deleted file mode 100755 index 494669bb8..000000000 --- a/examples/rmvs_gr_test/mercury_collider_init_cond.py +++ /dev/null @@ -1,183 +0,0 @@ -""" -This script generates initial conditions for the solar using JPL Horizons data. -Makes a test particle located at Mercury's position, 500 years into the future so that I can model an impact onto Mercury. - -To use the script, modify the variables just after the "if __name__ == '__main__':" line -""" -import numpy as np -import sys -from astroquery.jplhorizons import Horizons -import astropy.constants as const - -#Values from JPL Horizons -AU2M = const.au.value -GMSunSI = const.GM_sun.value -Rsun = const.R_sun.value -GC = const.G.value -JD = 86400 -year = 365.25 * JD -c = 299792458.0 - - - -MU2KG = GMSunSI / GC #Conversion from mass unit (G * Msun) to kg -DU2M = AU2M #Conversion from distance unit (AU) to meters -TU2S = JD #Conversion from time unit (Julian Day) to seconds -GU = GC / (DU2M**3 / (MU2KG * TU2S**2)) - -GMSun = GMSunSI / (DU2M**3 / TU2S**2) - - - -# Solar oblateness values: From Mecheri et al. (2004), using Corbard (b) 2002 values (Table II) -J2 = 2.198e-7 * (Rsun / DU2M)**2 -J4 = -4.805e-9 * (Rsun / DU2M)**4 - -npl = 9 - -tstart = '2421-01-31' -tend = '2421-02-01' -tstep = '1d' - -# All planets except for Mercury -planetid = { - 'venus' : '2', - 'earthmoon' : '3', - 'mars' : '4', - 'jupiter' : '5', - 'saturn' : '6', - 'uranus' : '7', - 'neptune' : '8', - 'plutocharon' : '9' -} - -tpid = {'mercury_impactor' : '1'} - -#Planet Msun/M ratio -MSun_over_Mpl = { - 'mercury' : 6023600.0, - 'venus' : 408523.71, - 'earthmoon' : 328900.56, - 'mars' : 3098708., - 'jupiter' : 1047.3486, - 'saturn' : 3497.898, - 'uranus' : 22902.98, - 'neptune' : 19412.24, - 'plutocharon' : 1.35e8 -} - -#Planet radii in meters -Rpl = { - 'mercury' : 2439.4e3, - 'venus' : 6051.8e3, - 'earthmoon' : 6371.0084e3, # Earth only for radius - 'mars' : 3389.50e3, - 'jupiter' : 69911e3, - 'saturn' : 58232.0e3, - 'uranus' : 25362.e3, - 'neptune' : 24622.e3, - 'plutocharon' : 1188.3e3 -} - -pdata = {} -vec = {} -Rhill = {} - -for key,val in planetid.items(): - pdata[key] = Horizons(id=val, id_type='majorbody',location='@sun', - epochs={'start': tstart, 'stop': tend, - 'step': tstep}) - vec[key] = np.array([pdata[key].vectors()['x'][0], - pdata[key].vectors()['y'][0], - pdata[key].vectors()['z'][0], - pdata[key].vectors()['vx'][0], - pdata[key].vectors()['vy'][0], - pdata[key].vectors()['vz'][0] - ]) - Rhill[key] = pdata[key].elements()['a'][0] * (3 * MSun_over_Mpl[key])**(-1.0 / 3.0) - -# Make a test particle initially at Mercury's position but with 10% higher velocity -vfactor = 1.00 -tpdata = Horizons(id='1', id_type='majorbody',location='@sun', - epochs={'start': tstart, 'stop': tend, - 'step': tstep}) -tpvec = [tpdata.vectors()['x'][0], - tpdata.vectors()['y'][0], - tpdata.vectors()['z'][0], - vfactor * tpdata.vectors()['vx'][0], - vfactor * tpdata.vectors()['vy'][0], - vfactor * tpdata.vectors()['vz'][0] - ] - -if __name__ == '__main__': - # Names of all output files - swifter_input = "param.tpcollider.in" - swifter_pl = "pl.tpcollider.in" - swifter_tp = "tp.tpcollider.in" - swifter_bin = "bin.tpcollider.dat" - swifter_enc = "enc.tpcollider.dat" - - # Simulation start, stop, and output cadence times - t_0 = 0 * year / TU2S # simulation start time - deltaT = 0.1 * JD / TU2S # simulation step size - t_print = 4.e0 * year / TU2S #output interval to print results - end_sim = 400.0 * year / TU2S # simulation end time - - - iout = int(np.ceil(t_print / deltaT)) - rmin = Rsun / DU2M - rmax = 10000.0 - - #Make Swifter files - # Reverse all the velocity signs to fake going backward in time - plfile = open(swifter_pl, 'w') - print(f'{npl} ! Planet input file generated using init_cond.py using JPL Horizons data for the major planets (and Pluto) for epoch {tstart}' ,file=plfile) - print(f'1 {GMSun}',file=plfile) - print(f'0.0 0.0 0.0',file=plfile) - print(f'0.0 0.0 0.0',file=plfile) - for i, key in enumerate(planetid): - print(f'{i + 3} {GMSun / MSun_over_Mpl[key]} {Rhill[key]}', file=plfile) - print(f'{Rpl[key] / DU2M}', file=plfile) - print(f'{vec[key][0]} {vec[key][1]} {vec[key][2]}', file=plfile) - print(f'{-vec[key][3]} {-vec[key][4]} {-vec[key][5]}', file=plfile) - plfile.close() - tpfile = open(swifter_tp, 'w') - print(1,file=tpfile) - print(100,file=tpfile) - print(f'{tpvec[0]} {tpvec[1]} {tpvec[2]}', file=tpfile) - print(f'{-tpvec[3]} {-tpvec[4]} {-tpvec[5]}', 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 NEW') - 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__ - - - diff --git a/examples/rmvs_gr_test/param.swifter.in b/examples/rmvs_gr_test/param.swifter.in deleted file mode 100644 index 5834d2dcc..000000000 --- a/examples/rmvs_gr_test/param.swifter.in +++ /dev/null @@ -1,26 +0,0 @@ -! 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/examples/rmvs_gr_test/param.swiftest.in b/examples/rmvs_gr_test/param.swiftest.in deleted file mode 100644 index 6e623a5dd..000000000 --- a/examples/rmvs_gr_test/param.swiftest.in +++ /dev/null @@ -1,29 +0,0 @@ -! 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/examples/rmvs_gr_test/param.tpcollider.in b/examples/rmvs_gr_test/param.tpcollider.in deleted file mode 100644 index a6066b36c..000000000 --- a/examples/rmvs_gr_test/param.tpcollider.in +++ /dev/null @@ -1,26 +0,0 @@ -! Swifter input file generated using init_cond.py -T0 0.0 -TSTOP 146100.0 -DT 0.1 -PL_IN pl.tpcollider.in -TP_IN tp.tpcollider.in -IN_TYPE ASCII -ISTEP_OUT 14610 -ISTEP_DUMP 14610 -BIN_OUT bin.tpcollider.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 10000.0 -CHK_EJECT 10000.0 -CHK_QMIN 0.004650467260962157 -CHK_QMIN_COORD HELIO -CHK_QMIN_RANGE 0.004650467260962157 10000.0 -ENC_OUT enc.tpcollider.dat -EXTRA_FORCE no -BIG_DISCARD no -RHILL_PRESENT yes diff --git a/examples/rmvs_gr_test/particle_distance.ipynb b/examples/rmvs_gr_test/particle_distance.ipynb deleted file mode 100644 index 5286218d8..000000000 --- a/examples/rmvs_gr_test/particle_distance.ipynb +++ /dev/null @@ -1,1513 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "import swiftestio as swio\n", - "import matplotlib.pyplot as plt" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Reading Swifter file param.swifter.in\n" - ] - } - ], - "source": [ - "inparfile = \"param.swifter.in\"\n", - "paramfile = swio.read_swifter_param(inparfile)\n", - "swifterdat = swio.swifter2xr(paramfile)" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
<xarray.Dataset>\n",
-       "Dimensions:  (id: 19, time: 1462)\n",
-       "Coordinates:\n",
-       "  * id       (id) int64 2 3 4 5 6 7 8 9 10 ... 102 103 104 105 106 107 108 109\n",
-       "  * time     (time) float64 0.0 0.0006845 0.001369 ... 0.9986 0.9993 1.0\n",
-       "Data variables:\n",
-       "    a        (time, id) float64 0.3871 0.7233 1.0 1.524 ... 0.5458 0.537 0.567\n",
-       "    e        (time, id) float64 0.2056 0.006785 0.01673 ... 0.366 0.3625 0.3776\n",
-       "    inc      (time, id) float64 0.1222 0.05925 4.707e-05 ... 0.1256 0.1248\n",
-       "    capom    (time, id) float64 0.8431 1.337 3.081 ... 0.929 0.9151 0.9155\n",
-       "    omega    (time, id) float64 0.5094 0.9622 5.0 5.003 ... 5.833 5.887 5.824\n",
-       "    capm     (time, id) float64 6.205 2.489 0.4222 1.624 ... 2.416 2.764 1.578\n",
-       "    Mass     (time, id) float64 6.554e-06 9.663e-05 0.00012 ... nan nan nan\n",
-       "    Radius   (time, id) float64 1.631e-05 4.045e-05 4.259e-05 ... nan nan nan
" - ], - "text/plain": [ - "\n", - "Dimensions: (id: 19, time: 1462)\n", - "Coordinates:\n", - " * id (id) int64 2 3 4 5 6 7 8 9 10 ... 102 103 104 105 106 107 108 109\n", - " * time (time) float64 0.0 0.0006845 0.001369 ... 0.9986 0.9993 1.0\n", - "Data variables:\n", - " a (time, id) float64 0.3871 0.7233 1.0 1.524 ... 0.5458 0.537 0.567\n", - " e (time, id) float64 0.2056 0.006785 0.01673 ... 0.366 0.3625 0.3776\n", - " inc (time, id) float64 0.1222 0.05925 4.707e-05 ... 0.1256 0.1248\n", - " capom (time, id) float64 0.8431 1.337 3.081 ... 0.929 0.9151 0.9155\n", - " omega (time, id) float64 0.5094 0.9622 5.0 5.003 ... 5.833 5.887 5.824\n", - " capm (time, id) float64 6.205 2.489 0.4222 1.624 ... 2.416 2.764 1.578\n", - " Mass (time, id) float64 6.554e-06 9.663e-05 0.00012 ... nan nan nan\n", - " Radius (time, id) float64 1.631e-05 4.045e-05 4.259e-05 ... nan nan nan" - ] - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "swifterdat" - ] - }, - { - "cell_type": "code", - "execution_count": 37, - "metadata": {}, - "outputs": [], - "source": [ - "swifterdat['r'] = np.sqrt(swifterdat['px']**2 + swifterdat['py']**2 + swifterdat['pz']**2)" - ] - }, - { - "cell_type": "code", - "execution_count": 38, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[]" - ] - }, - "execution_count": 38, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], - "source": [ - "swifterdat['r'].sel(id=100).plot()" - ] - }, - { - "cell_type": "code", - "execution_count": 39, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Reading Swiftest file param.swiftest.in\n" - ] - } - ], - "source": [ - "inparfile = \"param.swiftest.in\"\n", - "paramfile = swio.read_swiftest_config(inparfile)\n", - "swiftestdat = swio.swiftest2xr(paramfile)" - ] - }, - { - "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.Dataset>\n",
-       "Dimensions:  (id: 12, time: 49)\n",
-       "Coordinates:\n",
-       "  * id       (id) int64 0 2 3 4 5 6 7 8 9 10 100 433\n",
-       "  * time     (time) float64 0.0 121.8 243.5 ... 5.6e+03 5.722e+03 5.844e+03\n",
-       "Data variables:\n",
-       "    Mass     (time, id) float64 1.0 1.66e-07 2.448e-06 ... 7.407e-09 nan nan\n",
-       "    Radius   (time, id) float64 0.00465 1.631e-05 4.045e-05 ... nan nan\n",
-       "    J_2      (time, id) float64 4.754e-12 nan nan nan nan ... nan nan nan nan\n",
-       "    J_4      (time, id) float64 -2.247e-18 nan nan nan nan ... nan nan nan nan\n",
-       "    px       (time, id) float64 nan 0.103 0.0611 -0.6062 ... 29.09 nan -0.9879\n",
-       "    py       (time, id) float64 nan 0.2898 -0.7245 0.7761 ... -24.15 nan -1.04\n",
-       "    pz       (time, id) float64 nan 0.01423 -0.01347 ... -5.83 nan -0.2681\n",
-       "    vx       (time, id) float64 nan -0.03214 0.02002 ... 0.002132 nan 0.007837\n",
-       "    vy       (time, id) float64 nan 0.0105 0.001627 ... 0.001664 nan -0.01188\n",
-       "    vz       (time, id) float64 nan 0.003806 -0.001133 ... nan -3.825e-05
" - ], - "text/plain": [ - "\n", - "Dimensions: (id: 12, time: 49)\n", - "Coordinates:\n", - " * id (id) int64 0 2 3 4 5 6 7 8 9 10 100 433\n", - " * time (time) float64 0.0 121.8 243.5 ... 5.6e+03 5.722e+03 5.844e+03\n", - "Data variables:\n", - " Mass (time, id) float64 1.0 1.66e-07 2.448e-06 ... 7.407e-09 nan nan\n", - " Radius (time, id) float64 0.00465 1.631e-05 4.045e-05 ... nan nan\n", - " J_2 (time, id) float64 4.754e-12 nan nan nan nan ... nan nan nan nan\n", - " J_4 (time, id) float64 -2.247e-18 nan nan nan nan ... nan nan nan nan\n", - " px (time, id) float64 nan 0.103 0.0611 -0.6062 ... 29.09 nan -0.9879\n", - " py (time, id) float64 nan 0.2898 -0.7245 0.7761 ... -24.15 nan -1.04\n", - " pz (time, id) float64 nan 0.01423 -0.01347 ... -5.83 nan -0.2681\n", - " vx (time, id) float64 nan -0.03214 0.02002 ... 0.002132 nan 0.007837\n", - " vy (time, id) float64 nan 0.0105 0.001627 ... 0.001664 nan -0.01188\n", - " vz (time, id) float64 nan 0.003806 -0.001133 ... nan -3.825e-05" - ] - }, - "execution_count": 17, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "swiftestdat" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "metadata": {}, - "outputs": [], - "source": [ - "swiftestdat['r'] = np.sqrt(swiftestdat['px']**2 + swiftestdat['py']**2 + swiftestdat['pz']**2)" - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[]" - ] - }, - "execution_count": 19, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], - "source": [ - "p100swiftest = swiftestdat['r'].sel(id=100)\n", - "p100swiftest.plot()" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "metadata": {}, - "outputs": [], - "source": [ - "dr = p100swiftest - p100" - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[]" - ] - }, - "execution_count": 21, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], - "source": [ - "dr.plot()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "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.8.6" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/examples/rmvs_gr_test/pl.swifter.in b/examples/rmvs_gr_test/pl.swifter.in deleted file mode 100644 index d0d4e7ff9..000000000 --- a/examples/rmvs_gr_test/pl.swifter.in +++ /dev/null @@ -1,40 +0,0 @@ -10 ! Planet input file generated using init_cond.py using JPL Horizons data for the major planets (and Pluto) for epoch 2021-01-28 -1 39.47692640889762629 -0.0 0.0 0.0 -0.0 0.0 0.0 -2 6.553709809565313959502e-06 0.0014751229680863789154 -1.6306381826061645943e-05 -0.1030256860922895 0.2897796047098886 0.01422904600374035 --11.74004209950937 3.8343124110162736 1.3902496665973592 -3 9.6633133995815387361564e-05 0.006759127649782299051 -4.0453784346544178454e-05 -0.06110218027254217 -0.7245466901305982 -0.01346904300924688 -7.311995449678243 0.5941125721336201 -0.4137913843379075 -4 0.00012002693582795246295385 0.0100447565675466429165 -4.25875607065040958e-05 --0.6061796342297583 0.7761214554702035 -3.4750047790977e-05 --5.054824314301841 -3.891667468503358 0.00019720338148272726 -5 1.2739802010675942316241e-05 0.0072464490746299085006 -2.265740805092889601e-05 -0.2751944175855944 1.51937688993241 0.02508924593104206 --4.835983593209577 1.344855094041679 0.14681413000004515 -6 0.037692251088985682938581 0.3552852357486060849 -0.00046732617030490929307 -3.200135438345358 -3.953498213518368 -0.05517737289975112 -2.111393749129838 1.8660266890185446 -0.05498941067210089 -7 0.011285899820091272946487 0.43763064566943408597 -0.00038925687730393611812 -5.607382165725712 -8.258649105608766 -0.07958445228024298 -1.5748468603228847 1.1414574661825514 -0.08250331331320372 -8 0.0017236589478267728883093 0.4690969274244374022 -0.00016953449859497231466 -15.28225422201768 12.53905314208462 -0.1514143582550325 --0.9198472198098231 1.0454390993472462 0.01574538863031621 -9 0.0020336100526728304385693 0.7807192056765467829 -0.000164587904124493665 -29.47483071169769 -5.147686530859088 -0.5733441819169969 -0.19191677740340274 1.1385110364087574 -0.027844325148353527 -10 2.9242167710294538257026e-07 0.05383468172776979939 -7.943294877391593783e-06 -14.14000920780611 -31.14141812522779 -0.7565722591093476 -1.073396108697069 0.23003123192799815 -0.33424529561177047 diff --git a/examples/rmvs_gr_test/pl.swiftest.in b/examples/rmvs_gr_test/pl.swiftest.in deleted file mode 100644 index 7bdc4a619..000000000 Binary files a/examples/rmvs_gr_test/pl.swiftest.in and /dev/null differ diff --git a/examples/rmvs_gr_test/pl.tpcollider.in b/examples/rmvs_gr_test/pl.tpcollider.in deleted file mode 100644 index 95f1a048c..000000000 --- a/examples/rmvs_gr_test/pl.tpcollider.in +++ /dev/null @@ -1,36 +0,0 @@ -9 ! Planet input file generated using init_cond.py using JPL Horizons data for the major planets (and Pluto) for epoch 2421-01-31 -1 0.0002959122081920778 -0.0 0.0 0.0 -0.0 0.0 0.0 -3 7.243452483873648e-10 0.006759130149202631 -4.0453784346544176e-05 -0.7019627011222136 -0.1852496375751218 -0.04300948405789237 --0.005060711738168192 -0.01946939433513342 1.612614183356907e-06 -4 8.99701138216602e-10 0.010044559796067993 -4.25875607065041e-05 --0.5697193205332233 0.8029811715067949 -0.0007045655351608364 -0.01430660935370767 0.01002546009563165 -1.100857588556753e-05 -5 9.549535102761467e-11 0.00724618889821577 -2.2657408050928896e-05 -0.7993560103471902 -1.148987408482768 -0.04313430212910231 --0.01198004310618487 -0.009212920234676632 8.927002293279674e-05 -6 2.825345908631355e-07 0.3551533878488701 -0.0004673261703049093 --4.634097296304171 -2.863163670218678 0.1152887094960275 --0.003870142070986203 0.006066584891983585 5.910227945707925e-05 -7 8.459715183006417e-08 0.4376906786688663 -0.00038925687730393614 --8.865265590469349 2.837147222179521 0.3099061219991513 -0.001998614714254602 0.005352670386838502 -0.0001703654134002045 -8 1.2920249163736676e-08 0.46813372268314535 -0.00016953449859497232 -15.47151038891844 -12.61881964551067 -0.2448817967119467 --0.002462937202468351 -0.002853377332777701 2.133002929086309e-05 -9 1.5243589003230837e-08 0.7791996556565636 -0.00016458790412449367 --24.87809567256067 17.00453520872124 0.2234899970988031 -0.001786881544518242 0.002576864647985829 -9.421562352086046e-05 -10 2.19194228290428e-12 0.05348153138291406 -7.943294877391593e-06 --9.921482526550596 41.28101896209601 -1.54188968720156 -0.002154849797934256 0.001120743083473351 -0.0007433230817862677 diff --git a/examples/rmvs_gr_test/rmvs_vs_whm.ipynb b/examples/rmvs_gr_test/rmvs_vs_whm.ipynb deleted file mode 100644 index 4c91f2f4a..000000000 --- a/examples/rmvs_gr_test/rmvs_vs_whm.ipynb +++ /dev/null @@ -1,120 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "import swiftestio as swio\n", - "import matplotlib.pyplot as plt" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Reading Swifter file param.swifter.in\n", - "Reading Swifter file param.swifter.in\n" - ] - } - ], - "source": [ - "inparfile = \"param.swifter.in\"\n", - "rmvsfile = swio.read_swifter_param(inparfile)\n", - "rmvsfile['BIN_OUT'] = 'bin.swifter.rmvs.dat'\n", - "whmfile = swio.read_swifter_param(inparfile)\n", - "whmfile['BIN_OUT'] = 'bin.swifter.whm.dat'\n", - "\n", - "rmvsdat = swio.swifter2xr(rmvsfile)\n", - "whmdat = swio.swifter2xr(whmfile)" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [], - "source": [ - "rmvsdat['r'] = np.sqrt(rmvsdat['px']**2 + rmvsdat['py']**2 + rmvsdat['pz']**2)\n", - "whmdat['r'] = np.sqrt(whmdat['px']**2 + whmdat['py']**2 + whmdat['pz']**2)" - ] - }, - { - "cell_type": "code", - "execution_count": 28, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[,\n", - " ,\n", - " ,\n", - " ,\n", - " ,\n", - " ,\n", - " ,\n", - " ,\n", - " ,\n", - " ]" - ] - }, - "execution_count": 28, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], - "source": [ - "dr = rmvsdat['r'] - whmdat['r']\n", - "dr.sel(id=slice(100,109)).plot.line(x=\"time\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "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.8.6" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/examples/rmvs_gr_test/swifter2swiftest.py b/examples/rmvs_gr_test/swifter2swiftest.py deleted file mode 120000 index 3539718d1..000000000 --- a/examples/rmvs_gr_test/swifter2swiftest.py +++ /dev/null @@ -1 +0,0 @@ -/Users/daminton/git/swiftest/python/swifter2swiftest.py \ No newline at end of file diff --git a/examples/rmvs_gr_test/swiftest_relativity.ipynb b/examples/rmvs_gr_test/swiftest_relativity.ipynb deleted file mode 100644 index 302934bc0..000000000 --- a/examples/rmvs_gr_test/swiftest_relativity.ipynb +++ /dev/null @@ -1,199 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "import matplotlib.pyplot as plt\n", - "import pandas as pd\n", - "import swiftestio as swio\n", - "from astroquery.jplhorizons import Horizons" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Reading Swifter file param.gr.in\n" - ] - } - ], - "source": [ - "inparfile = 'param.gr.in'\n", - "paramgr = swio.read_swifter_param(inparfile)\n", - "swiftergr = swio.swifter2xr(paramgr)" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Reading Swifter file param.nogr.in\n" - ] - } - ], - "source": [ - "inparfile = 'param.nogr.in'\n", - "paramnogr = swio.read_swifter_param(inparfile)\n", - "swifternogr = swio.swifter2xr(paramnogr)" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Reading Swiftest file param.gr.in\n" - ] - } - ], - "source": [ - "param_file_name = 'param.gr.in'\n", - "config = swio.read_swiftest_config(param_file_name)\n", - "swiftestdat = swio.swiftest2xr(config)" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [], - "source": [ - "tsim = swiftergr['time'] / 365.25\n", - "varpigrsim = (swiftergr.sel(id=2)['omega'].data + swiftergr.sel(id=2)['capom'].data) * 180.0 / np.pi\n", - "varpinogrsim = (swifternogr.sel(id=2)['omega'].data + swifternogr.sel(id=2)['capom'].data) * 180.0 / np.pi\n", - "varpiswiftest = (swiftestdat.sel(id=2)['omega'].data + swiftestdat.sel(id=2)['capom'].data) * 180.0 / np.pi" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [], - "source": [ - "obj = Horizons(id='1', id_type='majorbody',location='@sun',\n", - " epochs={'start':'2020-07-13', 'stop':'3024-07-13',\n", - " 'step':'1461d'})\n", - "el = obj.elements()\n", - "t = (el['datetime_jd']-el['datetime_jd'][0]) / 365.25\n", - "varpi = el['w'] + el['Omega']" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [], - "source": [ - "dvarpigrsim = np.diff(varpigrsim) / np.diff(tsim) * 3600 * 100 \n", - "dvarpinogrsim = np.diff(varpinogrsim) / np.diff(tsim) * 3600 * 100 \n", - "dvarpiswiftest = np.diff(varpiswiftest) / np.diff(tsim) * 3600 * 100 \n", - "dvarpi= np.diff(varpi) / np.diff(t) * 3600 * 100 " - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Mean precession rate for Mercury long. peri. (arcsec/100 y)\n", - "JPL Horizons : 570.3933741520308\n", - "Swifter no GR : 527.4373381337329\n", - "Swifter GR : 570.37497883185\n", - "Swiftest GR : 570.3749787753405\n", - "GR - no GR : 42.93764069811709\n", - "Obs - Swifter : -0.018395320180843555\n", - "Obs - Swiftest: -0.018395376690250487\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, label=\"JPL Horizons\")\n", - "ax.plot(tsim, varpinogrsim, label=\"Swifter no GR\")\n", - "ax.plot(tsim, varpigrsim, 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)}')\n", - "print(f'Swifter no GR : {np.mean(dvarpinogrsim)}')\n", - "print(f'Swifter GR : {np.mean(dvarpigrsim)}')\n", - "print(f'Swiftest GR : {np.mean(dvarpiswiftest)}')\n", - "print(f'GR - no GR : {np.mean(dvarpigrsim) - np.mean(dvarpinogrsim)}')\n", - "print(f'Obs - Swifter : {np.mean(dvarpigrsim) - np.mean(dvarpi)}')\n", - "print(f'Obs - Swiftest: {np.mean(dvarpiswiftest) - np.mean(dvarpi)}')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "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.8.6" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/examples/rmvs_gr_test/swifttest_rmvs_vs_swifter_rmvs.ipynb b/examples/rmvs_gr_test/swifttest_rmvs_vs_swifter_rmvs.ipynb deleted file mode 100644 index 4dbc0754d..000000000 --- a/examples/rmvs_gr_test/swifttest_rmvs_vs_swifter_rmvs.ipynb +++ /dev/null @@ -1,156 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "import swiftestio as swio\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" - ] - } - ], - "source": [ - "inparfile = 'param.swifter.in'\n", - "paramgr = swio.read_swifter_param(inparfile)\n", - "swifterdat = swio.swifter2xr(paramgr)" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Reading Swiftest file param.swiftest.in\n" - ] - } - ], - "source": [ - "param_file_name = 'param.swiftest.in'\n", - "config = swio.read_swiftest_config(param_file_name)\n", - "swiftestdat = swio.swiftest2xr(config)" - ] - }, - { - "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 (y)'})\n" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[,\n", - " ,\n", - " ,\n", - " ,\n", - " ,\n", - " ,\n", - " ,\n", - " ,\n", - " ,\n", - " ,\n", - " ,\n", - " ,\n", - " ,\n", - " ,\n", - " ,\n", - " ,\n", - " ,\n", - " ,\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['a'].plot.line(x=\"time (y)\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "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.8.6" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/examples/rmvs_gr_test/test_unit_change.ipynb b/examples/rmvs_gr_test/test_unit_change.ipynb deleted file mode 100644 index 272e8dda0..000000000 --- a/examples/rmvs_gr_test/test_unit_change.ipynb +++ /dev/null @@ -1,169 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "import sys\n", - "from astroquery.jplhorizons import Horizons\n", - "import astropy.constants as const \n", - "import swiftestio as swio" - ] - }, - { - "cell_type": "code", - "execution_count": 27, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "0.01746575523103058" - ] - }, - "execution_count": 27, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "#Values from JPL Horizons\n", - "AU2M = const.au.value\n", - "GMSunSI = const.GM_sun.value\n", - "Rsun = const.R_sun.value\n", - "GC = const.G.value\n", - "JD = 86400\n", - "year = 365.25 * JD\n", - "c = 299792458.0\n", - "\n", - "MU2KG = GMSunSI / GC #Conversion from mass unit (G * Msun) to kg\n", - "DU2M = AU2M #Conversion from distance unit (AU) to meters\n", - "TU2S = year #Conversion from time unit (Julian Day) to seconds\n", - "GU = GC / (DU2M**3 / (MU2KG * TU2S**2))\n", - "\n", - "GMSun = GMSunSI / (DU2M**3 / TU2S**2)\n", - "\n", - "# Solar oblateness values: From Mecheri et al. (2004), using Corbard (b) 2002 values (Table II)\n", - "J2 = 2.198e-7 * (Rsun / DU2M)**2\n", - "J4 = -4.805e-9 * (Rsun / DU2M)**4\n", - "\n", - "npl = 10\n", - "\n", - "tstart = '2021-01-28'\n", - "tend = '2021-01-29'\n", - "tstep = '1d'\n", - "planetid = {\n", - " 'mercury' : '1',\n", - " 'venus' : '2',\n", - " 'earthmoon' : '3',\n", - " 'mars' : '4',\n", - " 'jupiter' : '5',\n", - " 'saturn' : '6',\n", - " 'uranus' : '7',\n", - " 'neptune' : '8',\n", - " 'plutocharon' : '9'\n", - "}\n", - "\n", - "#Planet Msun/M ratio\n", - "MSun_over_Mpl = {\n", - " 'mercury' : 6023600.0,\n", - " 'venus' : 408523.71,\n", - " 'earthmoon' : 328900.56,\n", - " 'mars' : 3098708.,\n", - " 'jupiter' : 1047.3486,\n", - " 'saturn' : 3497.898,\n", - " 'uranus' : 22902.98,\n", - " 'neptune' : 19412.24,\n", - " 'plutocharon' : 1.35e8\n", - "}\n", - "\n", - "#Planet radii in meters\n", - "Rpl = {\n", - " 'mercury' : 2439.4e3,\n", - " 'venus' : 6051.8e3,\n", - " 'earthmoon' : 6371.0084e3, # Earth only for radius\n", - " 'mars' : 3389.50e3,\n", - " 'jupiter' : 69911e3,\n", - " 'saturn' : 58232.0e3,\n", - " 'uranus' : 25362.e3,\n", - " 'neptune' : 24622.e3,\n", - " 'plutocharon' : 1188.3e3\n", - "}\n", - "\n", - "pdata = {}\n", - "plvec = {}\n", - "Rhill = {}\n", - "\n", - "for key,val in planetid.items():\n", - " pdata[key] = Horizons(id=val, id_type='majorbody',location='@sun',\n", - " epochs={'start': tstart, 'stop': tend,\n", - " 'step': tstep})\n", - " plvec[key] = np.array([pdata[key].vectors()['x'][0],\n", - " pdata[key].vectors()['y'][0], \n", - " pdata[key].vectors()['z'][0], \n", - " pdata[key].vectors()['vx'][0], \n", - " pdata[key].vectors()['vy'][0], \n", - " pdata[key].vectors()['vz'][0] \n", - " ])\n", - " Rhill[key] = pdata[key].elements()['a'][0] * (3 * MSun_over_Mpl[key])**(-1.0 / 3.0)\n", - "ver = np.sqrt(plvec['earthmoon'][3]**2 + plvec['earthmoon'][4]**2 + plvec['earthmoon'][5]**2)\n", - "ver" - ] - }, - { - "cell_type": "code", - "execution_count": 28, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "6.37936709813392" - ] - }, - "execution_count": 28, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "\n", - "for plid in plvec:\n", - " plvec[plid][3:] *= year / JD\n", - "ver = np.sqrt(plvec['earthmoon'][3]**2 + plvec['earthmoon'][4]**2 + plvec['earthmoon'][5]**2)\n", - "ver" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "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.8.6" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/examples/rmvs_gr_test/tp.swifter.in b/examples/rmvs_gr_test/tp.swifter.in deleted file mode 100644 index 3e12e22a6..000000000 --- a/examples/rmvs_gr_test/tp.swifter.in +++ /dev/null @@ -1,31 +0,0 @@ -10 -100 -0.3089139948287037 -0.277270436883302 -0.052337497440874486 -4.590828296619012 9.736244632162235 0.28280742360614397 -101 -0.3070354816876597 -0.2845400603406744 -0.05318033091888456 -4.545139601540877 9.883525912822861 0.28793674166112104 -102 -0.31066213352368505 -0.28113935471688967 -0.053108274441649984 -4.617453752609237 9.800810875613966 0.28446343275638736 -103 -0.3088067674199909 -0.2869523372878359 -0.05191462227061065 -4.6363938524337565 9.713660761176554 0.2789015757022737 -104 -0.307074553418099 -0.28073329893098137 -0.0534617731635447 -4.579194784145406 9.574048169595772 0.2861631995442269 -105 -0.30294954170866395 -0.281481925092296 -0.052234290208198066 -4.604562331430815 9.719598701455027 0.282459654106244 -106 -0.30692242784366397 -0.2878888119399549 -0.05247924519789774 -4.633660571617613 9.88377173149324 0.28490916253088794 -107 -0.30868976460301095 -0.27766108923594196 -0.05385210649760836 -4.581218660618022 9.756537560396604 0.2826382827782646 -108 -0.30635827269855037 -0.2829786891311232 -0.05244294704858842 -4.599148326746042 9.647983245028241 0.28233738073637155 -109 -0.313848717338811 -0.28389321799892847 -0.05290541615450685 -4.556080023696361 9.729321212583539 0.29047556209904657 diff --git a/examples/rmvs_gr_test/tp.swiftest.in b/examples/rmvs_gr_test/tp.swiftest.in deleted file mode 100644 index d91e0934e..000000000 Binary files a/examples/rmvs_gr_test/tp.swiftest.in and /dev/null differ diff --git a/examples/rmvs_gr_test/tp.tpcollider.in b/examples/rmvs_gr_test/tp.tpcollider.in deleted file mode 100644 index 0b3169633..000000000 --- a/examples/rmvs_gr_test/tp.tpcollider.in +++ /dev/null @@ -1,4 +0,0 @@ -1 -100 -0.3568867004762329 -0.128562827221147 -0.0429414817481014 --0.004043366894290556 -0.02767355464504326 -0.001909056361553056 diff --git a/examples/rmvs_gr_test/tp_collider_extract_init.ipynb b/examples/rmvs_gr_test/tp_collider_extract_init.ipynb deleted file mode 100644 index 2f651edb5..000000000 --- a/examples/rmvs_gr_test/tp_collider_extract_init.ipynb +++ /dev/null @@ -1,654 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "import swiftestio as swio" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Reading Swifter file param.tpcollider.in\n" - ] - } - ], - "source": [ - "inparfile = \"param.tpcollider.in\"\n", - "paramfile = swio.read_swifter_param(inparfile)\n", - "swifterdat = swio.swifter2xr(paramfile)" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
<xarray.DataArray 'time' ()>\n",
-       "array(14610.)\n",
-       "Coordinates:\n",
-       "    id       int64 100\n",
-       "    time     float64 1.461e+04
" - ], - "text/plain": [ - "\n", - "array(14610.)\n", - "Coordinates:\n", - " id int64 100\n", - " time float64 1.461e+04" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "swifterdat.isel(time=-1).sel(id=100)['time']" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [], - "source": [ - "px = swifterdat.isel(time=-1).sel(id=100)['px'].values.item()\n", - "py = swifterdat.isel(time=-1).sel(id=100)['py'].values.item()\n", - "pz = swifterdat.isel(time=-1).sel(id=100)['pz'].values.item()\n", - "\n", - "vx = swifterdat.isel(time=-1).sel(id=100)['vx'].values.item()\n", - "vy = swifterdat.isel(time=-1).sel(id=100)['vy'].values.item()\n", - "vz = swifterdat.isel(time=-1).sel(id=100)['vz'].values.item()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [ - { - "ename": "NameError", - "evalue": "name 'tpfile' is not defined", - "output_type": "error", - "traceback": [ - "\u001b[0;31m-------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0mpfile\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mopen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"../tp\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'w'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0mfile\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mtpfile\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 3\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m100\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0mfile\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mtpfile\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34mf'{px} {py} {pz}'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mfile\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mtpfile\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34mf'{vx} {vy} {vz}'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mfile\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mtpfile\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;31mNameError\u001b[0m: name 'tpfile' is not defined" - ] - } - ], - "source": [ - "pfile = open(\"../tp\", 'w')\n", - "print(1,file=tpfile)\n", - "print(100,file=tpfile)\n", - "print(f'{px} {py} {pz}', file=tpfile)\n", - "print(f'{vx} {vy} {vz}', file=tpfile)\n", - "tpfile.close()" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [], - "source": [ - "from numpy.random import default_rng" - ] - }, - { - "cell_type": "code", - "execution_count": 22, - "metadata": {}, - "outputs": [], - "source": [ - "nclones = 10\n", - "xv_dispersion_factor = 0.01 \n", - "rng = default_rng()\n", - "clone_xv = (rng.standard_normal((nclones, 6)) - 0.5) * xv_dispersion_factor + 1.0" - ] - }, - { - "cell_type": "code", - "execution_count": 23, - "metadata": {}, - "outputs": [], - "source": [ - "px = 1.0\n", - "py = 2.0\n", - "pz = 3.0\n", - "vx = 4.0\n", - "vy = 5.0\n", - "vz = 6.0\n", - "jangofett = np.array([px, py, pz, -vx, -vy, -vz])" - ] - }, - { - "cell_type": "code", - "execution_count": 24, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "array([ 1., 2., 3., -4., -5., -6.])" - ] - }, - "execution_count": 24, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "jangofett" - ] - }, - { - "cell_type": "code", - "execution_count": 59, - "metadata": {}, - "outputs": [], - "source": [ - "clones = jangofett * clone_xv" - ] - }, - { - "cell_type": "code", - "execution_count": 60, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(10, 6)" - ] - }, - "execution_count": 60, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "clones.shape" - ] - }, - { - "cell_type": "code", - "execution_count": 61, - "metadata": {}, - "outputs": [], - "source": [ - "clonenames = range(100, 100 + nclones)" - ] - }, - { - "cell_type": "code", - "execution_count": 63, - "metadata": {}, - "outputs": [], - "source": [ - "clonedat = dict(zip(clonenames,clones))" - ] - }, - { - "cell_type": "code", - "execution_count": 64, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{100: array([ 1.00930105, 1.9948283 , 2.99208025, -4.05525929, -5.09831281,\n", - " -5.92580054]),\n", - " 101: array([ 0.99941117, 1.97090351, 3.03529928, -3.97161239, -4.96155703,\n", - " -5.94367707]),\n", - " 102: array([ 0.98148793, 1.99203431, 2.9652801 , -4.04205948, -4.96976478,\n", - " -5.90277054]),\n", - " 103: array([ 0.98976919, 2.00294464, 2.97587626, -4.01195673, -5.04441437,\n", - " -5.96164778]),\n", - " 104: array([ 0.99530072, 1.99825316, 3.00016025, -3.95468703, -4.94515931,\n", - " -5.96765703]),\n", - " 105: array([ 1.00614369, 1.98935313, 2.95064276, -4.01105523, -5.00312835,\n", - " -6.06301916]),\n", - " 106: array([ 0.98931165, 1.98780538, 2.95666409, -3.98514127, -4.89578071,\n", - " -5.98396813]),\n", - " 107: array([ 0.99959316, 2.00748056, 3.04892677, -3.97927546, -4.89214677,\n", - " -5.97922326]),\n", - " 108: array([ 0.99488235, 1.99323474, 3.00338001, -3.97767383, -5.04020251,\n", - " -5.9724389 ]),\n", - " 109: array([ 0.99568866, 1.97598485, 3.00296884, -4.0810708 , -4.92477352,\n", - " -5.87353764])}" - ] - }, - "execution_count": 64, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "clonedat" - ] - }, - { - "cell_type": "code", - "execution_count": 42, - "metadata": {}, - "outputs": [ - { - "ename": "KeyError", - "evalue": "101", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mclones\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m101\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", - "\u001b[0;31mKeyError\u001b[0m: 101" - ] - } - ], - "source": [ - "clones[101]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "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.8.6" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/examples/rmvs_swifter_comparison/1pl_1tp_encounter/cb.swiftest.in b/examples/rmvs_swifter_comparison/1pl_1tp_encounter/cb.swiftest.in index 2386b53c8..96c7f920c 100644 Binary files a/examples/rmvs_swifter_comparison/1pl_1tp_encounter/cb.swiftest.in and b/examples/rmvs_swifter_comparison/1pl_1tp_encounter/cb.swiftest.in differ diff --git a/examples/rmvs_swifter_comparison/1pl_1tp_encounter/check_init_cond.ipynb b/examples/rmvs_swifter_comparison/1pl_1tp_encounter/check_init_cond.ipynb deleted file mode 100644 index 33b054177..000000000 --- a/examples/rmvs_swifter_comparison/1pl_1tp_encounter/check_init_cond.ipynb +++ /dev/null @@ -1,930 +0,0 @@ -{ - "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 397 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": [ - { - "data": { - "text/plain": [ - "[,\n", - " ]" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], - "source": [ - "swiftersim.ds.plot.scatter(x='px', y='py', hue='id', hue_style=\"discrete\", marker='.')" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Reading Swiftest file param.swiftest.in\n", - "Reading in time 2.002e-01\n", - "Creating Dataset\n", - "Successfully converted 586 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": 5, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[,\n", - " ,\n", - " ]" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], - "source": [ - "swiftestsim.ds.plot.scatter(x='px', y='py', hue='id', hue_style=\"discrete\", marker='.')" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
<xarray.Dataset>\n",
-       "Dimensions:   (id: 2, time: 397)\n",
-       "Coordinates:\n",
-       "  * id        (id) int64 2 100\n",
-       "    time (y)  (time) float64 0.0 0.0003422 0.0006845 ... 0.1348 0.1352 0.1355\n",
-       "Dimensions without coordinates: time\n",
-       "Data variables:\n",
-       "    Mass      (time, id) float64 0.0 nan 0.0 nan 0.0 nan ... nan 0.0 nan 0.0 nan\n",
-       "    Radius    (time, id) float64 0.0 nan 0.0 nan 0.0 nan ... nan 0.0 nan 0.0 nan\n",
-       "    delta x   (time, id) float64 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 nan\n",
-       "    delta y   (time, id) float64 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 nan\n",
-       "    pz        (time, id) float64 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 nan\n",
-       "    vx        (time, id) float64 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 nan\n",
-       "    vy        (time, id) float64 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 nan\n",
-       "    vz        (time, id) float64 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 nan
" - ], - "text/plain": [ - "\n", - "Dimensions: (id: 2, time: 397)\n", - "Coordinates:\n", - " * id (id) int64 2 100\n", - " time (y) (time) float64 0.0 0.0003422 0.0006845 ... 0.1348 0.1352 0.1355\n", - "Dimensions without coordinates: time\n", - "Data variables:\n", - " Mass (time, id) float64 0.0 nan 0.0 nan 0.0 nan ... nan 0.0 nan 0.0 nan\n", - " Radius (time, id) float64 0.0 nan 0.0 nan 0.0 nan ... nan 0.0 nan 0.0 nan\n", - " delta x (time, id) float64 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 nan\n", - " delta y (time, id) float64 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 nan\n", - " pz (time, id) float64 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 nan\n", - " vx (time, id) float64 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 nan\n", - " vy (time, id) float64 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 nan\n", - " vz (time, id) float64 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 nan" - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "swiftdiff = swiftestsim.ds - swiftersim.ds\n", - "swiftdiff = swiftdiff.rename_vars({'time' : 'time (y)','px' : 'delta x','py' : 'delta y'})\n", - "swiftdiff" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[,\n", - " ]" - ] - }, - "execution_count": 7, - "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.plot.scatter(x='delta x', y='delta y', hue='id', hue_style=\"discrete\", marker='.')" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "plt.savefig('rmvsdiff.png')" - ] - }, - { - "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/init_cond.py b/examples/rmvs_swifter_comparison/1pl_1tp_encounter/init_cond.py index 4c4ecb7da..b292ed42f 100755 --- a/examples/rmvs_swifter_comparison/1pl_1tp_encounter/init_cond.py +++ b/examples/rmvs_swifter_comparison/1pl_1tp_encounter/init_cond.py @@ -4,68 +4,10 @@ To use the script, modify the variables just after the "if __name__ == '__main__':" line """ import numpy as np -from astroquery.jplhorizons import Horizons -import astropy.constants as const -import swiftest.io as swio +import swiftest from scipy.io import FortranFile import sys -#Values from JPL Horizons -AU2M = np.longdouble(const.au.value) -GMSunSI = np.longdouble(const.GM_sun.value) -Rsun = np.longdouble(const.R_sun.value) -GC = np.longdouble(const.G.value) -JD = 86400 -year = np.longdouble(365.25 * JD) -c = np.longdouble(299792458.0) -MSun_over_Mpl = np.array([6023600.0, - 408523.71, - 328900.56, - 3098708., - 1047.3486, - 3497.898, - 22902.98, - 19412.24, - 1.35e8], dtype=np.longdouble) - -MU2KG = np.longdouble(GMSunSI / GC) #Conversion from mass unit to kg -DU2M = np.longdouble(AU2M) #Conversion from radius unit to centimeters -TU2S = np.longdouble(year) #Conversion from time unit to seconds -GU = np.longdouble(GC / (DU2M**3 / (MU2KG * TU2S**2))) -GMSun = np.longdouble(GMSunSI / (DU2M**3 / TU2S**2)) - -# Solar oblatenes values: From Mecheri et al. (2004), using Corbard (b) 2002 values (Table II) -J2 = np.longdouble(2.198e-7) * (Rsun / DU2M)**2 -J4 = np.longdouble(-4.805e-9) * (Rsun / DU2M)**4 - -#Planet Msun/M ratio -MSun_over_Mpl = { - 'mercury' : np.longdouble(6023600.0), - 'venus' : np.longdouble(408523.71), - 'earthmoon' : 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), - 'plutocharon' : np.longdouble(1.35e8) -} - -#Planet radii in meters -Rpl = { - 'mercury' : np.longdouble(2439.4e3), - 'venus' : np.longdouble(6051.8e3), - 'earthmoon' : np.longdouble(6371.0084e3), # Earth only for radius - 'mars' : np.longdouble(3389.50e3), - 'jupiter' : np.longdouble(69911e3), - 'saturn' : np.longdouble(58232.0e3), - 'uranus' : np.longdouble(25362.e3), - 'neptune' : np.longdouble(24622.e3), - 'plutocharon' : np.longdouble(1188.3e3) -} - -THIRDLONG = np.longdouble(1.0) / np.longdouble(3.0) - swifter_input = "param.swifter.in" swifter_pl = "pl.swifter.in" swifter_tp = "tp.swifter.in" @@ -79,23 +21,29 @@ 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 * JD / TU2S # simulation step size -end_sim = year / TU2S #10 * JD / TU2S # simulation end 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 = Rsun / DU2M +rmin = swiftest.RSun / swiftest.AU2M rmax = 1000.0 npl = 1 plid = 2 tpid = 100 -radius = np.double(Rpl['earthmoon'] / DU2M) -mass = np.double(GMSun * MSun_over_Mpl['earthmoon']**-1) +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) @@ -107,7 +55,7 @@ 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 * ((3 * MSun_over_Mpl['earthmoon'])**(-THIRDLONG)) +Rhill = apl * 0.0100447248332378922085 #Make Swifter files plfile = open(swifter_pl, 'w') @@ -142,8 +90,8 @@ 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'J2 {swiftest.J2Sun}') +print(f'J4 {swiftest.J4Sun}') print(f'CHK_CLOSE yes') print(f'CHK_RMIN {rmin}') print(f'CHK_RMAX {rmax}') @@ -160,10 +108,11 @@ #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.write_record(np.double(swiftest.J2Sun)) +cbfile.write_record(np.double(swiftest.J4Sun)) cbfile.close() plfile = FortranFile(swiftest_pl, 'w') diff --git a/examples/rmvs_swifter_comparison/1pl_1tp_encounter/param.swifter.in b/examples/rmvs_swifter_comparison/1pl_1tp_encounter/param.swifter.in index 9174b181a..d1a0c9f27 100644 --- a/examples/rmvs_swifter_comparison/1pl_1tp_encounter/param.swifter.in +++ b/examples/rmvs_swifter_comparison/1pl_1tp_encounter/param.swifter.in @@ -1,6 +1,6 @@ ! Swifter input file generated using init_cond.py T0 0 -TSTOP 1.0 +TSTOP 0.15 DT 0.0006844626967830253 PL_IN pl.swifter.in TP_IN tp.swifter.in @@ -11,8 +11,8 @@ BIN_OUT bin.swifter.dat OUT_TYPE REAL8 OUT_FORM XV OUT_STAT UNKNOWN -J2 4.7535806948127355e-12 -J4 -2.2473967953572827e-18 +J2 2.198e-07 +J4 -4.805e-09 CHK_CLOSE yes CHK_RMIN 0.004650467260962157 CHK_RMAX 1000.0 diff --git a/examples/rmvs_swifter_comparison/1pl_1tp_encounter/param.swiftest.in b/examples/rmvs_swifter_comparison/1pl_1tp_encounter/param.swiftest.in index d43b46d64..36937896f 100644 --- a/examples/rmvs_swifter_comparison/1pl_1tp_encounter/param.swiftest.in +++ b/examples/rmvs_swifter_comparison/1pl_1tp_encounter/param.swiftest.in @@ -1,6 +1,6 @@ ! Swiftest input file generated using init_cond.py T0 0 -TSTOP 1.0 +TSTOP 0.15 DT 0.0006844626967830253 CB_IN cb.swiftest.in PL_IN pl.swiftest.in diff --git a/examples/rmvs_swifter_comparison/1pl_1tp_encounter/pl.swifter.in b/examples/rmvs_swifter_comparison/1pl_1tp_encounter/pl.swifter.in index a964c7824..95513c9fd 100644 --- a/examples/rmvs_swifter_comparison/1pl_1tp_encounter/pl.swifter.in +++ b/examples/rmvs_swifter_comparison/1pl_1tp_encounter/pl.swifter.in @@ -1,8 +1,8 @@ 2 ! Planet input file generated using init_cond.py -1 39.476926408897625193 +1 39.476926408897625196 0.0 0.0 0.0 0.0 0.0 0.0 -2 0.00012002693582795244940133 0.0100447248332378922085 +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/swiftest_vs_swifter.ipynb b/examples/rmvs_swifter_comparison/1pl_1tp_encounter/swiftest_vs_swifter.ipynb index c6d739ace..52568fd84 100644 --- a/examples/rmvs_swifter_comparison/1pl_1tp_encounter/swiftest_vs_swifter.ipynb +++ b/examples/rmvs_swifter_comparison/1pl_1tp_encounter/swiftest_vs_swifter.ipynb @@ -43,9 +43,9 @@ "output_type": "stream", "text": [ "Reading Swiftest file param.swiftest.in\n", - "Reading in time 1.001e+00\n", + "Reading in time 1.506e-01\n", "Creating Dataset\n", - "Successfully converted 1463 output frames.\n", + "Successfully converted 221 output frames.\n", "Swiftest simulation data stored as xarray DataSet .ds\n" ] } @@ -81,8 +81,8 @@ { "data": { "text/plain": [ - "[,\n", - " ]" + "[,\n", + " ]" ] }, "execution_count": 6, diff --git a/examples/rmvs_swifter_comparison/9pl_18tp_encounters/cb.in b/examples/rmvs_swifter_comparison/9pl_18tp_encounters/cb.in index c33aa2b5c..81c636655 100644 --- a/examples/rmvs_swifter_comparison/9pl_18tp_encounters/cb.in +++ b/examples/rmvs_swifter_comparison/9pl_18tp_encounters/cb.in @@ -1,3 +1,4 @@ +0 0.00029591220819207774 0.004650467260962157 4.7535806948127355e-12 diff --git a/examples/rmvs_swifter_comparison/9pl_18tp_encounters/cb.swiftest.in b/examples/rmvs_swifter_comparison/9pl_18tp_encounters/cb.swiftest.in index c33aa2b5c..81c636655 100644 --- a/examples/rmvs_swifter_comparison/9pl_18tp_encounters/cb.swiftest.in +++ b/examples/rmvs_swifter_comparison/9pl_18tp_encounters/cb.swiftest.in @@ -1,3 +1,4 @@ +0 0.00029591220819207774 0.004650467260962157 4.7535806948127355e-12 diff --git a/examples/rmvs_swifter_comparison/9pl_18tp_encounters/init_cond.py b/examples/rmvs_swifter_comparison/9pl_18tp_encounters/init_cond.py index 11e04e0f3..321c79932 100755 --- a/examples/rmvs_swifter_comparison/9pl_18tp_encounters/init_cond.py +++ b/examples/rmvs_swifter_comparison/9pl_18tp_encounters/init_cond.py @@ -24,7 +24,7 @@ sim.param['T0'] = 0.0 sim.param['DT'] = 1.0 -sim.param['TSTOP'] = 365.25 +sim.param['TSTOP'] = 365.25e1 sim.param['ISTEP_OUT'] = 11 sim.param['ISTEP_DUMP'] = 1 sim.param['CHK_QMIN_COORD'] = "HELIO" diff --git a/examples/rmvs_swifter_comparison/9pl_18tp_encounters/param.swifter.in b/examples/rmvs_swifter_comparison/9pl_18tp_encounters/param.swifter.in index ab8bf65ca..aa33eeaa4 100644 --- a/examples/rmvs_swifter_comparison/9pl_18tp_encounters/param.swifter.in +++ b/examples/rmvs_swifter_comparison/9pl_18tp_encounters/param.swifter.in @@ -1,6 +1,6 @@ ! VERSION Swifter parameter file converted from Swiftest T0 0.0 -TSTOP 365.25 +TSTOP 3652.5 DT 1.0 ISTEP_OUT 11 ISTEP_DUMP 1 diff --git a/examples/rmvs_swifter_comparison/9pl_18tp_encounters/param.swiftest.in b/examples/rmvs_swifter_comparison/9pl_18tp_encounters/param.swiftest.in index 385ac46bb..6504c9637 100644 --- a/examples/rmvs_swifter_comparison/9pl_18tp_encounters/param.swiftest.in +++ b/examples/rmvs_swifter_comparison/9pl_18tp_encounters/param.swiftest.in @@ -1,6 +1,6 @@ ! VERSION Swiftest parameter input T0 0.0 -TSTOP 365.25 +TSTOP 3652.5 DT 1.0 ISTEP_OUT 11 ISTEP_DUMP 1 diff --git a/examples/rmvs_swifter_comparison/9pl_18tp_encounters/swiftest_rmvs_vs_swifter_rmvs.ipynb b/examples/rmvs_swifter_comparison/9pl_18tp_encounters/swiftest_rmvs_vs_swifter_rmvs.ipynb index 4c742df8c..c6bb630b2 100644 --- a/examples/rmvs_swifter_comparison/9pl_18tp_encounters/swiftest_rmvs_vs_swifter_rmvs.ipynb +++ b/examples/rmvs_swifter_comparison/9pl_18tp_encounters/swiftest_rmvs_vs_swifter_rmvs.ipynb @@ -6,9 +6,8 @@ "metadata": {}, "outputs": [], "source": [ - "import numpy as np\n", - "import xarray as xr\n", "import swiftest\n", + "import numpy as np\n", "import matplotlib.pyplot as plt" ] }, @@ -22,9 +21,9 @@ "output_type": "stream", "text": [ "Reading Swifter file param.swifter.in\n", - "Reading in time 3.630e+02\n", + "Reading in time 3.652e+03\n", "Creating Dataset\n", - "Successfully converted 34 output frames.\n", + "Successfully converted 333 output frames.\n", "Swifter simulation data stored as xarray DataSet .ds\n" ] } @@ -46,9 +45,9 @@ "output_type": "stream", "text": [ "Reading Swiftest file param.swiftest.in\n", - "Reading in time 3.630e+02\n", + "Reading in time 3.652e+03\n", "Creating Dataset\n", - "Successfully converted 34 output frames.\n", + "Successfully converted 333 output frames.\n", "Swiftest simulation data stored as xarray DataSet .ds\n" ] } @@ -102,6 +101,128 @@ "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": 12, + "metadata": {}, "outputs": [ { "data": { @@ -457,154 +578,147 @@ " stroke: currentColor;\n", " fill: currentColor;\n", "}\n", - "
<xarray.DataArray 'px' (time (d): 34)>\n",
-       "array([0., 0., 0., 0., 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., 0., 0., 0., 0.])\n",
+       "
<xarray.DataArray 'rmag' (time (d): 333)>\n",
+       "array([0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n",
+       "       0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n",
+       "       0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n",
+       "       0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n",
+       "       0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n",
+       "       0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n",
+       "       0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n",
+       "       0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n",
+       "       0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n",
+       "       0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n",
+       "       0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n",
+       "       0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n",
+       "       0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n",
+       "       0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n",
+       "       0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n",
+       "       0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n",
+       "       0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n",
+       "       0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n",
+       "       0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n",
+       "       0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n",
+       "...\n",
+       "       0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n",
+       "       0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n",
+       "       0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n",
+       "       0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n",
+       "       0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n",
+       "       0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n",
+       "       0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n",
+       "       0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n",
+       "       0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n",
+       "       0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 2.13180114e-12,\n",
+       "       6.30252092e-12, 1.12657932e-11, 1.70947866e-11, 2.35410127e-11,\n",
+       "       3.01486367e-11, 3.63634702e-11, 4.16224366e-11, 4.54289913e-11,\n",
+       "       4.74142910e-11, 4.73824194e-11, 4.53327404e-11, 4.14594589e-11,\n",
+       "       3.61300773e-11, 2.98446324e-11, 2.31845539e-11, 1.67548923e-11,\n",
+       "       1.11262399e-11, 6.78147816e-12, 4.07218435e-12, 3.25977426e-12,\n",
+       "       4.52137637e-12, 7.66342713e-12, 1.23344633e-11, 1.81013732e-11,\n",
+       "       2.44264806e-11, 3.07065663e-11, 3.63320360e-11, 4.07478190e-11,\n",
+       "       4.35128453e-11, 4.43475549e-11, 4.31649567e-11, 4.00801554e-11,\n",
+       "       3.53984592e-11, 2.95862328e-11, 2.32329074e-11, 1.70175537e-11,\n",
+       "       1.17040422e-11])\n",
        "Coordinates:\n",
-       "    id        int64 4\n",
-       "  * time (d)  (time (d)) float64 0.0 11.0 22.0 33.0 ... 330.0 341.0 352.0 363.0
" + " id int64 2\n", + " * time (d) (time (d)) float64 0.0 11.0 22.0 ... 3.63e+03 3.641e+03 3.652e+03
" ], "text/plain": [ - "\n", - "array([0., 0., 0., 0., 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., 0., 0., 0., 0.])\n", + "\n", + "array([0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n", + "...\n", + " 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 2.13180114e-12,\n", + " 6.30252092e-12, 1.12657932e-11, 1.70947866e-11, 2.35410127e-11,\n", + " 3.01486367e-11, 3.63634702e-11, 4.16224366e-11, 4.54289913e-11,\n", + " 4.74142910e-11, 4.73824194e-11, 4.53327404e-11, 4.14594589e-11,\n", + " 3.61300773e-11, 2.98446324e-11, 2.31845539e-11, 1.67548923e-11,\n", + " 1.11262399e-11, 6.78147816e-12, 4.07218435e-12, 3.25977426e-12,\n", + " 4.52137637e-12, 7.66342713e-12, 1.23344633e-11, 1.81013732e-11,\n", + " 2.44264806e-11, 3.07065663e-11, 3.63320360e-11, 4.07478190e-11,\n", + " 4.35128453e-11, 4.43475549e-11, 4.31649567e-11, 4.00801554e-11,\n", + " 3.53984592e-11, 2.95862328e-11, 2.32329074e-11, 1.70175537e-11,\n", + " 1.17040422e-11])\n", "Coordinates:\n", - " id int64 4\n", - " * time (d) (time (d)) float64 0.0 11.0 22.0 33.0 ... 330.0 341.0 352.0 363.0" + " id int64 2\n", + " * time (d) (time (d)) float64 0.0 11.0 22.0 ... 3.63e+03 3.641e+03 3.652e+03" ] }, - "execution_count": 8, + "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "swiftdiff['px'].sel(id=4)" - ] - }, - { - "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['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": 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['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": 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['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": 12, - "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)" + "swiftdiff['rmag'].sel(id=2)" ] }, { diff --git a/examples/rmvs_swifter_comparison/mars_ejecta/cb.swiftest.in b/examples/rmvs_swifter_comparison/mars_ejecta/cb.swiftest.in index 2aafc8408..40cf41bad 100644 --- a/examples/rmvs_swifter_comparison/mars_ejecta/cb.swiftest.in +++ b/examples/rmvs_swifter_comparison/mars_ejecta/cb.swiftest.in @@ -1,3 +1,4 @@ +0 0.00029591220828563 0.004650467260962157 0.0 diff --git a/examples/rmvs_swifter_comparison/mars_ejecta/config.swiftest.in b/examples/rmvs_swifter_comparison/mars_ejecta/param.swiftest.in similarity index 80% rename from examples/rmvs_swifter_comparison/mars_ejecta/config.swiftest.in rename to examples/rmvs_swifter_comparison/mars_ejecta/param.swiftest.in index 3f459514f..7df10c4d0 100644 --- a/examples/rmvs_swifter_comparison/mars_ejecta/config.swiftest.in +++ b/examples/rmvs_swifter_comparison/mars_ejecta/param.swiftest.in @@ -1,8 +1,3 @@ -! -! Parameter file for the CHO run of the 4 giant planets and Pluto. -! -!NPLMAX -1 ! not used -!NTPMAX -1 ! not used T0 0.0e0 TSTOP 6000.000 ! simulation length in days DT 1e0 ! stepsize in days @@ -21,8 +16,6 @@ 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 -!CHK_QMIN_COORD HELIO ! commented out here -!CHK_QMIN_RANGE 1.0 1000.0 ! commented out here ENC_OUT enc.swiftest.dat EXTRA_FORCE no ! no extra user-defined forces BIG_DISCARD yes ! output all planets if anything discarded diff --git a/examples/rmvs_swifter_comparison/mars_ejecta/profmaker.sh b/examples/rmvs_swifter_comparison/mars_ejecta/profmaker.sh deleted file mode 100755 index 9b1adcd8c..000000000 --- a/examples/rmvs_swifter_comparison/mars_ejecta/profmaker.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -gprof ./swiftest_driver | /home/daminton/git/gprof2dot/gprof2dot.py | dot -Tpng -o swiftest_profile.png diff --git a/examples/rmvs_swifter_comparison/mars_ejecta/profswifter.sh b/examples/rmvs_swifter_comparison/mars_ejecta/profswifter.sh deleted file mode 100755 index a03493f54..000000000 --- a/examples/rmvs_swifter_comparison/mars_ejecta/profswifter.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -gprof ./swifter_rmvs | /home/daminton/git/gprof2dot/gprof2dot.py | dot -Tpng -o swifter_profile.png diff --git a/examples/rmvs_swifter_comparison/mars_ejecta/start.in b/examples/rmvs_swifter_comparison/mars_ejecta/start.in deleted file mode 100644 index d6d7c3850..000000000 --- a/examples/rmvs_swifter_comparison/mars_ejecta/start.in +++ /dev/null @@ -1 +0,0 @@ -param.in 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 index 2ef9e28a5..c0ae7eec3 100644 --- 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 @@ -6,8 +6,8 @@ "metadata": {}, "outputs": [], "source": [ + "import swiftest\n", "import numpy as np\n", - "import swiftestio as swio\n", "import matplotlib.pyplot as plt" ] }, @@ -20,14 +20,19 @@ "name": "stdout", "output_type": "stream", "text": [ - "Reading Swifter file param.swifter.in\n" + "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", - "param = swio.read_swifter_param(inparfile)\n", - "swifterdat = swio.swifter2xr(param)" + "swiftersim = swiftest.Simulation(param_file=inparfile, codename=\"Swifter\")\n", + "swiftersim.bin2xr()\n", + "swifterdat = swiftersim.ds" ] }, { @@ -39,14 +44,19 @@ "name": "stdout", "output_type": "stream", "text": [ - "Reading Swiftest file param.swiftest.in\n" + "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": [ - "param_file_name = 'param.swiftest.in'\n", - "config = swio.read_swiftest_config(param_file_name)\n", - "swiftestdat = swio.swiftest2xr(config)" + "inparfile = 'param.swiftest.in'\n", + "swiftestsim = swiftest.Simulation(param_file=inparfile)\n", + "swiftestsim.bin2xr()\n", + "swiftestdat = swiftestsim.ds" ] }, { @@ -94,7 +104,7 @@ "outputs": [ { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ "
" ] @@ -120,7 +130,7 @@ "outputs": [ { "data": { - "image/png": "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\n", + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAZQAAAElCAYAAADDUxRwAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8QVMy6AAAACXBIWXMAAAsTAAALEwEAmpwYAAAmwklEQVR4nO3de7xVVb338c83LmKA4QWVq6Ci3FIEEktTtDAwO+Y1UUsNo4t17FHz2quyHpXqScWjZerx7pE6nUwyvIIezUuKAokhiYqyBQRREkHi4u/5Yw5ysVz7ttbcl8X+vl+v9dpzzTnmmL+x9uW3x5hzjqmIwMzMrFIfaekAzMxsy+CEYmZmuXBCMTOzXDihmJlZLpxQzMwsF04oZmaWCycUy52kH0m6LS33lfSupHYtHVddJH1a0vxmPmZI2r3COp6XNDqfiD5Ud63fR0k7SXpE0ipJv1DmRklvS3qqKeKx1s8JxT5E0kJJny1ad4qkPze2roh4LSK6RMTG/CJsnIb84Y6IRyNiz+aKKS8RMSQiHobNE0ATHKf4+zgReBPYJiLOAg4AxgC9I2LfpojBWj8nFGvzJLVv6Riq0C7A3+KDO6N3ARZGxOrGVuTPf8vhhGJlkdRT0v9IWi7pFUn/Xku5fqmH0L5gv6mS3pK0QNLXCsq2k3SBpJfSUMozkvqkbQMlPZD2my/puIL9bpJ0taQ/pf3+Imm3tO2RVGxOGrL5kqTRkmoknStpKXDjpnUFdfaR9PvUvhWSrqrlM3hP0nYF6/aR9KakDun9VyXNS0NB90napZbP6WOSbknHe1XS9yV9pGD711I9qyT9TdLwtH6hpM9KGgtcAHwptXOOpGMlPVN0nLMk/aGWGPpL+t90jAeAHUp9HyXdBJwMnJOO9XXgeuCT6f1FaZ/DJc2WtFLS45L2KqhvYfr8/wqsTvXul8qtTPGPLij/sKSfSHosxXe/pML4DijYd5GkU9L6rST9P0mvSXpD0jWStk7bdpB0d9rnLUmPFn7mVoaI8MuvzV7AQuCzRetOAf6clj8CPAP8AOgI7Aq8DHwubf8RcFta7gcE0D69/1/gl0AnYBiwHPhM2vY94DlgT0DA3sD2QGdgEXAq0B4YTjbcMiTtdxPwFrBv2n47MKUg9gB2L3g/GtgA/BTYCtg6ratJ29sBc4DL07E7AQfU8lnNAL5W8P7nwDVp+YvAAmBQiuv7wOOl4gJuAe4CuqbP7O/AhLTtWOB14BPpc9kd2KX4e1X4uaf3W6XPZVDBulnA0bW05QngsrTfgcCqOr6PNwH/t9TPR3o/HFgGjEqf58kp1q0K4p4N9Emffy9gBXAY2c/XmPS+eyr/MPASsEcq/zAwKW3rm2IdD3Qg+5kZlrZdAUwFtkuf7R+BS9O2S4Fr0j4dgE8Daunfv2p+tXgAfrW+V/plfxdYWfBawwcJZRTwWtE+5wM3puV//WEr/EOU/nhsBLoW7HcpcFNang8cUSKeLwGPFq37NfDDtHwTcH3BtsOAFwrel0oo64BORes2JZRPkiW69g34rE4DZqRlkSW+A9P7e0hJIb3/SPocdymMi+wP7j+BwQVlvw48nJbvA86o43tVMqGkdb8CLk7LQ4C3SX/Ui8r1JUuynQvW/Vep72PBZ15XQvkV8JOiY8wHDiqI+6sF284Fbi0qfx9wclp+GPh+wbZvAfcW/OzdWaJNAlYDuxWs+yTwSlr+MVkS3714X7/Ke7l7Z7X5YkR02/Qi+wXeZBegZxoqWClpJdlwy0711NkTeCsiVhWse5Xsv1PIEs5LJfbbBRhVdLwTgZ0LyiwtWF4DdKknluURsbaWbX2AVyNiQz11APyObKinJ9l/9QE8WhD35IKY3yL7I9erqI4dyHp6rxasa8jn0hA3AydIEvBl4LcR8c8S5XoCb8fm50BeLVGuoXYBzir6nvVJx9lkUVH5Y4vKHwD0KChT2/e4ts+nO/BR4JmCOu9N6yHrTS4A7pf0sqTzGt9MK+STYVaORWT/5Q1o5H6Lge0kdS1IKn3JhnM21bsbMLfE8f43IsaUG3AJdU2zvQjoK6l9fUklIlZKuh84jmxo645I//6mei6OiNvrieVNYD3pRHdaV+pzqc+H2hQRT0paRzacc0J6lbIE2FZS54Kk0rdUnQ20qe0XNzDeRWQ9lK/VVrieY5W6suxN4D2yodHXizemn8GzyBLfEOAhSU9HxPQyYjB8Ut7K8xTwTjqpurWyk+lDJX2irp0iYhHwOHCppE7pJO0EsnMekJ3Y/YmkAcrsJWl74G5gD0lfltQhvT4haVAD432D7DxPY9q3BJgkqXOKdf86yv8X8BXg6LS8yTXA+emP1aYT78cW7xzZpbi/BS6W1FXZifszgU2XAF8PnC1pRPpcdlfpk/tvAP1KnFi+BbgK2BARJS/9johXgZnARZI6SjoA+EIdba7PdcA3JI1KMXeW9HlJXWspfxvwBUmfSz9PnZRdKNG7Ace6HfispOPSyf3tJQ2LiPdTHJdL2hFAUi9Jn0vLh6fPUsA7ZMOxLXZ5+5bACcUaLf0B/ALZSfVXyP4TvB74WAN2H082Hr8YuJPsPMgDadtlZH9Y7yf7Bf9PYOv0n+ShwPFpv6V8cEK9IX4E3JyGPY6rr3BB+3YHXgNqyM7j1GYqMAB4IyLmFNRzZ4pziqR3yHpe42qp4ztk4/0vA38mS0w3pHr+G7g4rVsF/IHsJHOx/05fV0h6tmD9rcDQ9LUuJ5CdH3sL+CFZIipLRMwEvkaWyN4mG1o6pY7yi4AjyIZOl5P1Or5HA/5GRcRrZOfNzkqxzya7oAOyczMLgCfT9+BBsos+IPuePUh2vvAJ4JeR7umx8uiD3rmZbYnSZbLLgOER8WJLx2NbLvdQzLZ83wSedjKxpuaT8mZbMEkLya4s+2LLRmJtgYe8zMwsFx7yMjOzXDihmDWCSszEvKVQ0bxrZo3lhGJWJP1RXa1sosPXJV2mZn6ei3J4VopZc3NCMStt74joAnyG7P6Mcu7gNmtTnFDM6hARL5DNzTW0eJukfSU9kW6YXCLpKkkdC7aHpG9IelHZ9PVXp7uyN20vObW9Sk+53+Cp1iV9StLTkv6Rvn6qYFud08AXlGvU1Pdm4IRiVidJg8nmwZpVYvNG4P+QTe74SbLezLeKyhxONu383mTzfW2a9uOLZHeFH0U2WeGjwB0AEXFg2nfvyJ6S+Buyu8BrUtmd0r4fukRT2bNZ/gRcSTaN+2XAn9IUNpucQPYogB3JJqU8u0TbpgL9i6a3OYn677a3NswJxay0ZyW9Tfb8jOuBG4sLRMQzEfFkRGyIiIVkU+ofVFRsUkSsTNODPEQ2XQ1k09NfGhHz0gSUlwDDapmjC7LJI3uQTX2/PrJHFpe65v/zwIsRcWuK6w7gBTafl+vGiPh7RLxHNtXNsOJK0ozEvyFLIqT5yPqRzatmVpITillpwyNi24jYLSK+nyYa3IykPdIw1NI0T9QlFDzlMKltyvWGTm2/SUOnWu/Jh6edL5wKv66YijV06nszwAnFrBK/Ivvvf0BEbEM2DKW6d/mXRcDXC585ExFbR8TjpQpHxKqIOCsidiXrbZwp6TMlii4mS1aFCqfCb7CIeJLsQWSbpr73cJfVyQnFrHxdyWZFflfSQLI5sxqqvqntN5tyvxFTrU8jm+r/hDSV+5eAwZQ/VFXv1PdmmzihmJXvbLL/3FeRPXfjNw3dsQFT2/+Izafcb9BU6xGxguxCgLPInsl+DnB4RLzZ2MYlDZ363sxzeZlZ7Tz1vTWGeyhmVhdPfW8N5jl7zKwkT31vjeUhLzMzy4WHvMzMLBdteshrhx12iH79+rV0GGZmVeWZZ555MyK6F69v0wmlX79+zJw5s6XDMDOrKpKKZ2MAPORlZmY5cUIxM7NcOKGYmVku2vQ5FDOzlrB+/XpqampYu3ZtS4dSp06dOtG7d286dOjQoPJOKGZmzaympoauXbvSr18/Ch7i2apEBCtWrKCmpob+/fs3aB8PeZmZNbO1a9ey/fbbt9pkAiCJ7bffvlG9KCcUM7MW0JqTySaNjdEJxczMcuGEYmZWpT71qU+VXH/KKafwu9/9rpmjcUIxM6tajz9e8onRLcZXeZmZVakuXbrw7rvvEhF85zvfYcaMGfTv35+WmkXePRQzsyp35513Mn/+fJ577jmuu+66Fuu5OKGYmVW5Rx55hPHjx9OuXTt69uzJIYcc0iJxOKGYmW0BWsNlyE4oZmZV7sADD2TKlCls3LiRJUuW8NBDD7VIHD4pb2ZW5Y488khmzJjBxz/+cfbYYw8OOuigFonDCcXMrEq9++67QDbcddVVV7VwNB7yMjOznDihmJlZLpxQzMwsF04oZmaWCycUMzPLhROKmZnlwgnFzKwNWrRoEQcffDCDBg1iyJAhTJ48ueI6fR+KmVkb1L59e37xi18wfPhwVq1axYgRIxgzZgyDBw8uu85W1UORNFbSfEkLJJ1XYrskXZm2/1XS8KLt7STNknR380VtZlZ9evTowfDh2Z/Qrl27MmjQIF5//fWK6mw1PRRJ7YCrgTFADfC0pKkR8beCYuOAAek1CvhV+rrJGcA8YJtmCdrMrEIX/fF5/rb4nVzrHNxzG374hSENLr9w4UJmzZrFqFGj6i9ch9bUQ9kXWBARL0fEOmAKcERRmSOAWyLzJNBNUg8ASb2BzwPXN2fQZmbV7N133+Xoo4/miiuuYJttKvtfvNX0UIBewKKC9zVs3vuorUwvYAlwBXAO0LWug0iaCEwE6Nu3b0UBm5lVqjE9ibytX7+eo48+mhNPPJGjjjqq4vpaUw+l1GT+xc+xLFlG0uHAsoh4pr6DRMS1ETEyIkZ27969nDjNzKpeRDBhwgQGDRrEmWeemUudrSmh1AB9Ct73BhY3sMz+wL9JWkg2VHaIpNuaLlQzs+r22GOPceuttzJjxgyGDRvGsGHDmDZtWkV1tqYhr6eBAZL6A68DxwMnFJWZCnxb0hSy4bB/RMQS4Pz0QtJo4OyIOKmZ4jYzqzoHHHAAEcWDQJVpNQklIjZI+jZwH9AOuCEinpf0jbT9GmAacBiwAFgDnNpS8ZqZ2eZaTUIBiIhpZEmjcN01BcsBnF5PHQ8DDzdBeGZmVofWdA7FzMyqmBOKmZnlwgnFzMxy4YRiZma5cEIxM2uD1q5dy7777svee+/NkCFD+OEPf1hxna3qKi8zM2seW221FTNmzKBLly6sX7+eAw44gHHjxrHffvuVXad7KGZmbZAkunTpAmRzeq1fvx6p1OxWDeceiplZS7rnPFj6XL517vxxGDep3mIbN25kxIgRLFiwgNNPP32Lmr7ezMyaUbt27Zg9ezY1NTU89dRTzJ07t6L63EMxM2tJDehJNLVu3boxevRo7r33XoYOHVp2Pe6hmJm1QcuXL2flypUAvPfeezz44IMMHDiwojrdQzEza4OWLFnCySefzMaNG3n//fc57rjjOPzwwyuq0wnFzKwN2muvvZg1a1audXrIy8zMcuGEYmZmuXBCMTOzXDihmJlZLpxQzMwsF04oZmaWCycUM7M2bOPGjeyzzz4V34MCTihmZm3a5MmTGTRoUC51OaGYmbVRNTU1/OlPf+K0007LpT7fKW9m1oJ++tRPeeGtF3Ktc+B2Azl333PrLffd736Xn/3sZ6xatSqX47qHYmbWBt19993suOOOjBgxIrc63UMxM2tBDelJNIXHHnuMqVOnMm3aNNauXcs777zDSSedxG233VZ2ne6hmJm1QZdeeik1NTUsXLiQKVOmcMghh1SUTMAJxczMcuIhLzOzNm706NGMHj264nrcQzEzs1w4oZiZWS5aVUKRNFbSfEkLJJ1XYrskXZm2/1XS8LS+j6SHJM2T9LykM5o/ejOztq3VJBRJ7YCrgXHAYGC8pMFFxcYBA9JrIvCrtH4DcFZEDAL2A04vsa+ZmTWhVpNQgH2BBRHxckSsA6YARxSVOQK4JTJPAt0k9YiIJRHxLEBErALmAb2aM3gzs7au3qu8JPVtYF0rI+KdCmLpBSwqeF8DjGpAmV7Akk0rJPUD9gH+UkEsZmbWSA25bPhmIADVUSaAm4BbKoilVP3RmDKSugD/A3y3tuQmaSLZcBl9+zY0V5qZbXn69etH165dadeuHe3bt2fmzJkV1VdvQomIg4vXSdo5IpZWdOQPqwH6FLzvDSxuaBlJHciSye0R8fvaDhIR1wLXAowcObI4YZmZtSkPPfQQO+ywQy51lXsO5Su5HH1zTwMDJPWX1BE4HphaVGYq8JV0tdd+wD8iYokkAf8JzIuIy5ogNjMzq0e5d8ofIWkN8EBEzM8jkIjYIOnbwH1AO+CGiHhe0jfS9muAacBhwAJgDXBq2n1/4MvAc5Jmp3UXRMS0PGIzM2sqSy+5hH/Oy3f6+q0GDWTnCy6ot5wkDj30UCTx9a9/nYkTJ1Z03HITylFkJ76PlLR7ROTydJaUAKYVrbumYDmA00vs92fqPsdjZmZFHnvsMXr27MmyZcsYM2YMAwcO5MADDyy7vrISSkS8AdybXmZmVqaG9CSaSs+ePQHYcccdOfLII3nqqacqSihlnUORdLWkm9LyoWUf3czMWsTq1av/9aTG1atXc//99zN06NCK6ix3yGsd8EZaPgS4v6IozMysWb3xxhsceeSRAGzYsIETTjiBsWPHVlRnuQllDfCxdKmub+YwM6syu+66K3PmzMm1znITylvAe2Rzbz2WXzhmZlatGnUORVI3STcCR6dVtwAjc4/KzMyqTqN6KBGxUtIkoB/wJrAXUOtd6WZm1naUM+Q1AXglIu4Dnsk5HjMzq1LlJJS3gW9I2hOYA8yOiFn5hmVmZtWm0QklIi6VNB34OzAMOBBwQjEza+MafWOjpB+TPehqDPB6REzOPSozM2tyK1eu5JhjjmHgwIEMGjSIJ554oqL6Gp1QIuIHwD/TvkdLuq6iCMzMrEWcccYZjB07lhdeeIE5c+YwaNCgiuord/r6G4BBwPbALyuKwMzMmt0777zDI488woQJEwDo2LEj3bp1q6jOcm9s/Hey6VfaA5PJzqOYmVkjPfrbv/PmondzrXOHPl349HF71Fnm5Zdfpnv37px66qnMmTOHESNGMHnyZDp37lz2ccvtobwEdALuiggnEzOzKrNhwwaeffZZvvnNbzJr1iw6d+7MpEmTKqqz3B7K88AiYIKkn0fEJyqKwsysjaqvJ9FUevfuTe/evRk1ahQAxxxzTMUJpdweym5kyehaPnhqopmZVYmdd96ZPn36MH9+9tDd6dOnM3jw4IrqLLeHsigiZkjqASyrKAIzM2sR//Ef/8GJJ57IunXr2HXXXbnxxhsrqq/chDJW0t/JZht+lewkvZmZVZFhw4Yxc+bM3Oord8irG3AucA7ZPSlmZtbGldtD+TEwMCLmS9qYZ0BmZladGtxDkbT3puWIqImIB9PyeU0RmJmZVZfGDHnNkvRXSedI6tNkEZmZWVVqTEL5BdAZmAS8IukhSV9tmrDMzKzaNDihRMT3ImI3skf+Xk823cq1TRWYmZlVl8acQ9le0mnAJWQ3M4rsbnkzM6sy8+fPZ9iwYf96bbPNNlxxxRUV1dmYq7yWkiWgt4Ebgdsi4s8VHd3MzFrEnnvuyezZswHYuHEjvXr14sgjj6yozsYklDuB24B7ImJ9RUc1M7NWY/r06ey2227ssssuFdXT4IQSEcdVdCQzM/uQh266lmWvvpxrnTvusisHnzKxweWnTJnC+PHjKz5uuXfKm5nZFmDdunVMnTqVY489tuK6Gn2nvKQvRMQfKz6ymZk1qifRFO655x6GDx/OTjvtVHFd5fRQLq74qLWQNFbSfEkLJH3oDnxlrkzb/yppeEP3NTOzD7vjjjtyGe6C8hKKcjlycaVSO7LZi8cBg4Hxkoon5x8HDEivicCvGrGvmZkVWLNmDQ888ABHHXVULvWVMzlk5HLkD9sXWBARLwNImgIcAfytoMwRwC0REcCTkrqlZ7L0a8C+ubnprEt4r2OHpqjazNqAEV/4NMtqlrZoDB3aiW177MSKFStyq7Pc2YabQi82v1GyBhjVgDK9GrgvAJImkvVu6Nu3b1mBvq92vNfekyybWXlC8L6a6n/zBsbwfv7Hb00JpdRQWnGLayvTkH2zlRHXkqaMGTlyZFmf6Ff/37nl7GZmBsC8efPYuVePlg4jd+UklDdyjyJTAxTOYtwbWNzAMh0bsK+ZmTWhRp+Uj4gxTREI8DQwQFJ/SR2B44GpRWWmAl9JV3vtB/wjIpY0cF8zM2tCrWbIKyI2SPo2cB/QDrghIp6X9I20/RpgGnAYsABYQzZJZa37tkAzzMzarFaTUAAiYhpZ0ihcd03BcgCnN3RfMzNrPmVNvSLpzILlPfMLx8zMmsvll1/OkCFDGDp0KOPHj2ft2rUV1deohJLu+7gROFbStyQdAPiudDOzKvP6669z5ZVXMnPmTObOncvGjRuZMmVKRXU2asgrIlYCp0r6HPAmsBfw+4oiMDOzFrFhwwbee+89OnTowJo1a+jZs2dF9ZV7DmV9RDwjaTGwrKIIzMzasJV/fIl1i1fnWmfHnp3p9oXd6izTq1cvzj77bPr27cvWW2/NoYceyqGHHlrRccudvn6spN7ANcDlFUVgZmbN7u233+auu+7ilVdeYfHixaxevZrbbrutojrL7aF0A84FzgFOqygCM7M2rL6eRFN58MEH6d+/P927dwfgqKOO4vHHH+ekk04qu85yeyg/Bv4QEfMBT2plZlZl+vbty5NPPsmaNWuICKZPn86gQYMqqrPchHI+8OW0/FBFEZiZWbMbNWoUxxxzDMOHD+fjH/8477//PhMnVvawr3KHvNbxwZxeB5PdoW5mZlXkoosu4qKLLsqtvnJ7KGuAj0nqAJQ3B7yZmW1Ryk0oPwReIntK4u35hWNmZtWq3CGvf4+Iy8BTr5iZWaZRCUVSN7LnuO8iaS0wh+yy4VPzD83MzKpJo6dekVQDPAL8BdgbT71iZmaUN+S1AvgGsCdZD6Um14jMzKwqlfPExknA14AfAa8An845JjMzawaTJ09m6NChDBkyhCuuuKLi+hrdQ5H0Y7KnIs4GZkfEwxVHYWZmzWru3Llcd911PPXUU3Ts2JGxY8fy+c9/ngEDBpRdZzk9lB8AVwKrgKMlXVf20c3MrEXMmzeP/fbbj49+9KO0b9+egw46iDvvvLOiOsu9bPjrwK8j4t6Kjm5m1sbdc889LF26NNc6d955Z8aNG1dnmaFDh3LhhReyYsUKtt56a6ZNm8bIkSMrOm65CeUG4JuSOgO3R8TsiqIwM7NmNWjQIM4991zGjBlDly5d2HvvvWnfvtyUkCn7xkay+bzakw1/HVhRFGZmbVR9PYmmNGHCBCZMmADABRdcQO/evSuqr9ypV14COgF3RYSTiZlZFVq2LHvg7muvvcbvf/97xo8fX1F95fZQngcWARMk/TwiPlFRFGZm1uyOPvpoVqxYQYcOHbj66qvZdtttK6qv3ISyG/A2cG36amZmVebRRx/Ntb5yE8qiiJghqQewLM+AzMysOpV7DmWspN7ANcDlOcZjZmZVqtyE0g04FzgH+Gdu0ZiZtRER0dIh1KuxMTY4oUjau+Dtj8mu8JoPbGzUEc3M2rhOnTqxYsWKVp1UIoIVK1bQqVOnBu/TmHMosyTNBW4D7oiIB9NBz2tcmGZmbVvv3r2pqalh+fLlLR1KnTp16tSoe1Mak1B+ARwFTAIukfQocGtE3NC4EM3M2rYOHTrQv3//lg4jdw0e8oqI70XEbsBI4Hqyu+OvzSMISdtJekDSi+lryYuhJY2VNF/SAknnFaz/uaQXJP1V0p3pyZJmZtaMGnMOZXtJpwGXkD3yV2Q3N+bhPGB6RAwApqf3xcdvB1wNjAMGA+MlDU6bHwCGRsRewN+B83OKy8zMGqgxV3ktBX5N1kO5ETgwIvLqsx0B3JyWbwa+WKLMvsCCiHg5ItYBU9J+RMT9EbEhlXsSqGxCGjMza7TGnEO5k+yE/D0RsT7nOHaKiCUAEbFE0o4lyvRi8x5RDTCqRLmvAr/JOT4zM6tHvQlFUt+0eHb62kNSqaIrI+KdOup5ENi5xKYL64thUxUl1m12zZ2kC4ENwO11xDERmAjQt2/f2oqZmVkjNaSHcjMf/OEumUnS9puAW2qrJCI+W9s2SW9I6pF6J7VN51ID9Cl43xtYXFDHycDhwGeijou7I+Ja0sUEI0eObL0XgZuZVZl6E0pEHNwMcUwFTia7JPlk4K4SZZ4GBkjqD7wOHA+cANnVX2R37h8UEWuaIV4zMytS7tQreZsEjJH0IjAmvUdST0nTANJJ928D9wHzgN9GxPNp/6uArsADkmZLuqa5G2Bm1tZV9rzHnETECuAzJdYvBg4reD8NmFai3O5NGqCZmdWrtfRQzMysyjmhmJlZLpxQzMwsF04oZmaWCycUMzPLhROKmZnlwgnFzMxy4YRiZma5cEIxM7NcOKGYmVkunFDMzCwXTihmZpYLJxQzM8uFE4qZmeXCCcXMzHLhhGJmZrlwQjEzs1w4oZiZWS6cUMzMLBdOKGZmlgsnFDMzy4UTipmZ5cIJxczMcuGEYmZmuXBCMTOzXDihmJlZLpxQzMwsF04oZmaWCycUMzPLhROKmZnlwgnFzMxy0SoSiqTtJD0g6cX0ddtayo2VNF/SAknnldh+tqSQtEPTR21mZoVaRUIBzgOmR8QAYHp6vxlJ7YCrgXHAYGC8pMEF2/sAY4DXmiViMzPbTGtJKEcAN6flm4EvliizL7AgIl6OiHXAlLTfJpcD5wDRhHGamVktWktC2SkilgCkrzuWKNMLWFTwviatQ9K/Aa9HxJz6DiRpoqSZkmYuX7688sjNzAyA9s11IEkPAjuX2HRhQ6sosS4kfTTVcWhDKomIa4FrAUaOHOnejJlZTpotoUTEZ2vbJukNST0iYomkHsCyEsVqgD4F73sDi4HdgP7AHEmb1j8rad+IWJpbA8zMrE6tZchrKnByWj4ZuKtEmaeBAZL6S+oIHA9MjYjnImLHiOgXEf3IEs9wJxMzs+bVWhLKJGCMpBfJrtSaBCCpp6RpABGxAfg2cB8wD/htRDzfQvGamVmRZhvyqktErAA+U2L9YuCwgvfTgGn11NUv7/jMzKx+raWHYmZmVc4JxczMcuGEYmZmuXBCMTOzXDihmJlZLpxQzMwsF04oZmaWCycUMzPLhROKmZnlwgnFzMxy4YRiZma5cEIxM7NcOKGYmVkunFDMzCwXTihmZpYLJxQzM8uFE4qZmeXCCcXMzHLhhGJmZrlwQjEzs1w4oZiZWS6cUMzMLBdOKGZmlgsnFDMzy4UioqVjaDGSlgOvlrn7DsCbOYbTktyW1mdLaQe4La1VJW3ZJSK6F69s0wmlEpJmRsTIlo4jD25L67OltAPcltaqKdriIS8zM8uFE4qZmeXCCaV817Z0ADlyW1qfLaUd4La0Vrm3xedQzMwsF+6hmJlZLpxQzMwsF04oZZA0VtJ8SQskndfS8RSTdIOkZZLmFqzbTtIDkl5MX7ct2HZ+ast8SZ8rWD9C0nNp25WS1AJt6SPpIUnzJD0v6YxqbI+kTpKekjQnteOiamxHUZvaSZol6e5qboukhSmG2ZJmVnlbukn6naQX0u/MJ5u1LRHhVyNeQDvgJWBXoCMwBxjc0nEVxXggMByYW7DuZ8B5afk84KdpeXBqw1ZA/9S2dmnbU8AnAQH3AONaoC09gOFpuSvw9xRzVbUnHbNLWu4A/AXYr9raUdSmM4H/Au6u8p+xhcAOReuqtS03A6el5Y5At+ZsS7P/EFb7K33I9xW8Px84v6XjKhFnPzZPKPOBHmm5BzC/VPzAfamNPYAXCtaPB37dCtp1FzCmmtsDfBR4FhhVre0AegPTgUP4IKFUa1sW8uGEUnVtAbYBXiFdbNUSbfGQV+P1AhYVvK9J61q7nSJiCUD6umNaX1t7eqXl4vUtRlI/YB+y/+6rrj1piGg2sAx4ICKqsh3JFcA5wPsF66q1LQHcL+kZSRPTumpsy67AcuDGNBR5vaTONGNbnFAar9RYYjVfe11be1pVOyV1Af4H+G5EvFNX0RLrWkV7ImJjRAwj++9+X0lD6yjeatsh6XBgWUQ809BdSqxrFW1J9o+I4cA44HRJB9ZRtjW3pT3ZUPevImIfYDXZEFdtcm+LE0rj1QB9Ct73Bha3UCyN8YakHgDp67K0vrb21KTl4vXNTlIHsmRye0T8Pq2u2vZExErgYWAs1dmO/YF/k7QQmAIcIuk2qrMtRMTi9HUZcCewL9XZlhqgJvV8AX5HlmCarS1OKI33NDBAUn9JHYHjgaktHFNDTAVOTssnk52L2LT+eElbSeoPDACeSl3jVZL2S1d4fKVgn2aTjv2fwLyIuKxgU1W1R1J3Sd3S8tbAZ4EXqq0dABFxfkT0joh+ZD//MyLipGpsi6TOkrpuWgYOBeZShW2JiKXAIkl7plWfAf5Gc7aluU+AbQkv4DCyq41eAi5s6XhKxHcHsARYT/bfxgRge7KTqC+mr9sVlL8wtWU+BVdzACPJfrleAq6i6GRfM7XlALLu9l+B2el1WLW1B9gLmJXaMRf4QVpfVe0o0a7RfHBSvuraQnbeYU56Pb/p97ka25JiGAbMTD9nfwC2bc62eOoVMzPLhYe8zMwsF04oZmaWCycUMzPLhROKmZnlwgnFzMxy4YRiloM0y+u3Ct73lPS7JjrWFyX9oJZt76av3SXd2xTHN6uNE4pZProB/0ooEbE4Io5pomOdA/yyrgIRsRxYImn/JorB7EOcUMzyMQnYLT1T4+eS+ik9j0bSKZL+IOmPkl6R9G1JZ6YJ/J6UtF0qt5uke9MkhY9KGlh8EEl7AP+MiDfT+/6SnpD0tKSfFBX/A3Bik7barIATilk+zgNeiohhEfG9EtuHAieQzRN1MbAmsgn8niCb2gLgWuA7ETECOJvSvZD9yaa+32Qy2WSAnwCWFpWdCXy6zPaYNVr7lg7ArI14KCJWkc2R9A/gj2n9c8BeaTblTwH/XfBwvK1K1NODbIryTfYHjk7LtwI/Ldi2DOiZT/hm9XNCMWse/yxYfr/g/ftkv4cfAVZGNr19Xd4DPla0rrb5kzql8mbNwkNeZvlYRfaI4rJE9oyXVyQdC9ksy5L2LlF0HrB7wfvHyGb8hQ+fL9mDbII/s2bhhGKWg4hYATwmaa6kn5dZzYnABEmbZr49okSZR4B99MG42BlkD4V6mg/3XA4G/lRmLGaN5tmGzaqMpMnAHyPiwXrKPQIcERFvN09k1ta5h2JWfS4BPlpXAUndgcucTKw5uYdiZma5cA/FzMxy4YRiZma5cEIxM7NcOKGYmVkunFDMzCwX/x/UeybrQ0phsQAAAABJRU5ErkJggg==\n", "text/plain": [ "
" ] @@ -141,7 +151,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 10, "metadata": {}, "outputs": [ { @@ -153,7 +163,7 @@ }, { "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYYAAAElCAYAAADgCEWlAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/Il7ecAAAACXBIWXMAAAsTAAALEwEAmpwYAABEaUlEQVR4nO3deXxU9bn48c+Tfd8DCUkgAQIoCAgUwb3u2rrUaq9d7HJpvWj7623torbWWm6328Ve22qtWqvWqvd2s1ata1UQUAFFIUDYAknIvieTbSbz/f1xTsIkmSQzw2SSSZ736zUvZs42z3cS5sk53+95vmKMQSmllOoXMdEBKKWUmlw0MSillBpEE4NSSqlBNDEopZQaRBODUkqpQTQxKKWUGkQTg/JKRO4Ukcfs57NFpENEIic6rtGIyFkiUjrRccDYsYTyMxWR10Tk8/bzT4rIix7rzhCRA3YsV4nITBHZKCLtIvLz8Y5NTU6aGKYoETkiIhcMWfZZEXnD32MZY8qNMUnGmL7gRegfETEiMn+0bYwxm4wxC0MV02iGxjL05zFRn6kx5o/GmIs8Fm0Afm3H8hRwA9AApBhjvhbK2NTkoYlBTQkiEjXRMYSpOUDJkNd7TAB3vurPYOrQxDCNicgsEfmLiNSLSJmIfHmE7Qrtv9ijPPZ7WkSaROSgiHzBY9tIEfmWiByyL0fsEJECe90iEXnJ3q9URD7msd/DInKPiDxr7/eWiMyz1220N3vPvuTxbyJyrohUisgtIlID/L5/mccxC0Tkr3b7GkXk1yO0704R+bOI/K/93u+IyDKP9SfZl2NaRKRERK7wWHeZiOyx9zsmIl+3lw/EIiJ/AGYD/7Dj/6afn+mdIvJ/IvKo/T4lIrJqlJ/rhSKyT0Ra7TaLx7qBs0YROQTM9YjrCeAzwDft1xeISISI3Gr/PBvtODKG/F6sE5Fy4F/28n8Xkb0i0iwiL4jIHI/3NyKy3r581Wz/zD3j+4K9b7v9ua7w+Hy8/q6KyGoR2S4ibSJSKyJ3jfTZKB8ZY/QxBR/AEeCCIcs+C7xhP48AdgB3ADFYXxCHgYvt9XcCj9nPCwEDRNmvXwfuBeKA5UA9cL697hvALmAh1hfSMiATSAQqgM8BUcAKrEsWi+39HgaagNX2+j8CT3rEboD5Hq/PBVzAfwOxQLy9rNJeHwm8B/zCfu844MwRPqs7ASdwDRANfB0os59HAweBb9mf03lAO7DQ3rcaOMt+ng6s8IivcqSfh5+f6Z1AN3CZ3a4fAW+O0JYsoM2jLV+1P6fPD/0dGCGuh4Hve7z+CvAmkG9/zr8FnhjShkftzzgeuMr+vE6yf463A1uG/ByfAdKwkmU9cIm97lrgGPABrN+d+VhnMGP9rm4FrrefJwFrJvr/X7g/JjwAfYzTD9b6D98BtHg8OjmeGE4Dyofscxvwe/v5nXhJDEAB0Acke+z3I+Bh+3kpcKWXeP4N2DRk2W+B79rPHwYe9Fh3GbDP47W3xNALxA1Z1p8Y1tpfOlE+fFZ34vFFa38RVQNn2Y8aIMJj/RPAnfbzcuA/sK7J4y0Wj5+H18Tgw2d6J/Cyx7qTga4R2vLpIW0RoJLAE8Ne7ARlv87FSqJRHm2Y67H+n8C6IZ9lJzDH4+d4psf6/wNutZ+/APynlzaN9bu6EfgekDXR/++mykMvJU1tVxlj0vofwE0e6+YAs+zLIy0i0oL1V/HMMY45C2gyxrR7LDsK5NnPC4BDXvabA5w25P0+CeR4bFPj8bwT66+/0dQbY7pHWFcAHDXGuMY4Rr+K/ifGGDfWl+ks+1FhL+vn2d6PYiWxoyLyuois9fH9PI31mcLwzyZOvF/TnzWkLcbzdQDmAH/z+JntxUpinr8nFUO2v9tj+yas5DRaW/p/zqP97oz2u7oOWADsE5FtIvJhv1upBtHOoumrAigzxhT7uV8VkCEiyR5fZLOxLgH0H3cesNvL+71ujLkw0IC9GK2DtAKYLSJRPiaHgv4nIhKBdemkqn+diER4JIfZwH4AY8w24EoRiQa+hPUX8MCxfIx1rM/UH9VD2iIjxOOrCuDfjTGbh64QkUL7qRmy/Q+MMX8M8L3mjbB8xN9VY8wB4OP2z+1q4M8ikmmMcQQQg0I7n6ezt4E2u/M2XqxO4yUi8oHRdjLGVABbgB+JSJyILMX6i63/i+BB4L9EpFgsS0UkE+u68gIRuV5Eou3HB0TkJB/jrcW6tuxP+6qBH4tIoh3rGaNsv1JErrb/Cv8K0IN1bf0twIHVIRstIucClwNPikiMWPcFpBpjnFjX9kcafjpi/D58pv54Fljs0ZYvM/iszF/3AT/o70AWkWwRuXKM7W8TkcX29qkicq2P7/Ug8HURWWn/7sy333fU31UR+ZSIZNuJu8U+1oQNrZ4KNDFMU8YaP385VkdnGVZH8INAqg+7fxzr+nIV8DesfoKX7HV3Yf3V/CLWF+XvgHj7L+GLgOvs/Wo43nHsizuBR+xLCR8ba2OP9s3H6geoxOrnGMnf7fXNwPXA1cYYpzGmF7gCuBTrM7oX+LQxZp+93/XAERFpA9YDnxrh+D8Cbrfj/7qX9aN9pj4zxjRgdeL+GGgEioFhf+374W7gaeBFEWnHSpanjfL+f8P6uT5pfya7sT47X2L/E/AD4HGsDv6ngAwfflcvAUpEpMOO97pRLjEqH4jdeaPUtCUid2J1bI/0pa7UtKJnDEoppQbRxKCUUmoQvZSklFJqED1jUEopNYgmBqXGkQwpcz3KdgNlzicDsWpXfX+i41ATQxODmjTk+BwF/Q8jIg6P12cFcMxh5ceHrD9XRNz28dvFKu73uQDjH1QYD7yWuVZq0tM7n9WkYYwpx6MMhogYYJkx5uA4v3WVMSbfvkv4Sqw7Z98yxuzx9QAjlKdQKizpGYMKCyISKyI/E5FysUor3yci8fa6LBF5xr55rElENolVLnpYuevR3sNYnsK6ye1kEfmQiLwrVjnnCvt+h/54vJWc7i8P3mK/31oZMjmSiCyW46XHa0XkWyO0d42IbLHb9J59x3X/us+KyGH7DKdMRD45ymf2PyJSZT/+R0Ri7XX9Zcu/JiJ1IlI90pmSiOwWkcs9XkeLSIOILB/t81ThSxODChf/jVUobTnW3cx5WGWYAb6GdWdzNlZhtW9hfc9fj3XX8+XGmqHsJ6O9gZ1MPoJVEnoXVimMT9uvPwTcKCJXDdntHKwS0xcDZ9vL0uz32zrk+MnAy8DzWMXu5gOveIkjD6u0xfeBDKwy4H+xy1EkAr8ELjXGJAOnAztHaNK3gTVYn9kyrJLmt3usz8G6ezgPqwTHPSKS7uU4jzL4ju7LgGpjzEjvq8LclEgMIvKQ/VfP0MJtgR5vtoi8KNaEIXvkeLEwNQHsSzxfAL5qjOmvQvpDrPIaYJWBzsUq7ew01rSa/ozDniVWxc4G4LtYtf1LjTGvGWN2GWPcxpj3scptnzNk3zuNMQ5jTJcP7/NhoMYY83NjTLcxpt0Y85aX7T4FPGeMec5+75eA7VhfyABuYImIxBtjqo0xJV6OAVb12g3GmDpjTD1WaerrPdY77fVOY8xzWGXavU2N+hhwmYik2K+vB/7gQ3tVmJoSiQGrhvwlQTzeo8BPjTEnYf2VVRfEYyv/ZQMJwA45Xnb5eXs5wE+xJod50b7Ecqufx6+yS5NnGGOWG2OeBBCR00TkVbFmDWvFqoWUNWRff0paj1RWeqg5wLUyuMz0mUCuXTH03+xYqsWa8W7RCMeZhVW+u99Re1m/xiGVZ72WOjfGVGHVW/qoiKRh1T4KpMCfChNTIjEYYzZi1X0fICLzROR5saaW3DTKf55BRORkrMldXrKP3WGM6Qx+1MoPDUAX1mxv/fNLpBpjkgDsv7y/ZoyZi1Vs7WYROd/e90Tu4Hwcq4BcgTEmFatyqAzZxozw3JuRykp72+4PnnNpGGMSjTE/BjDGvGCXL88F9gEPjHCcKqwk0282x0uJ++sRrDOZa4GtxphASoKrMDElEsMI7gf+nzFmJdY12nt93G8BVufhX+2Ox5+KSOS4RanGZJdTfgD4hYjMAOs6vIhcbD//sFglmoXjpa/7yy77W67bUzLWBDrdIrIa+MQY29djXeYZ6f2eAXJE5Ct2x3CyiHirVPoYcLmIXCxWiek4u7M4X0RmisgVdl9DD9bln5FKTD+BVdE1W0SysPpkAr1X4ims6Vj/E+uMWk1hUzIxiEgSVqfcn0RkJ9YUkrn2uqvtURZDHy/Yu0dhTef4day5Z+diTYeoJtYtWJeL3hSrnPPLHL8eXmy/7sCa//deY8xr9rqxyl2P5iZgg1jlpu/AKic+IvvM8gfAZvv91gxZ3w5ciHVWUwMcAD7o5TgVWMNmv4WVbCqw5tKOsB9fw/rLvwmrz+OmocewfR+rb+J9rM70d+xlfrP7UP4CFAF/DeQYKnxMmVpJdgfxM8aYJXYnWakxJjeA46wBfmyMOdd+fT3W5OJfDGa8SoUbEbkDWKDlyae+KXnGYIxpA8rEnjlKLMt83H0bkC4i/R2b5wE+3+ik1FQkIhlYQ1rvn+hY1PibEolBRJ7AuoSw0L5pZx3WUL11IvIeUIJ1aj4me7aorwOviMgurM7GkTr3lJryROQLWJez/mkP9FBT3JS5lKSUUio4psQZg1JKqeAJ+8JfWVlZprCwcKLDUEqpsLJjx44GY0y2t3VhnxgKCwvZvn37RIehlFJhRUSOjrROLyUppZQaRBODUkqpQTQxKKWUGkQTg1JKqUE0MSillBpEE4NSSqlBNDEopZQaRBODUkqFSI2jhsf3Pk5rT+tEhzKqsL/BTSmlwoExhi+98iVKm0vZXrudu869a6JDGpGeMSilVAjsadpDaXMpGXEZvHz0Zao7qic6pBFpYlBKqRDYWLkRQfjVeb/CYHi98vWJDmlEmhiUUioEShpKKEot4pSsU8hLyuPN6jcnOqQRaWJQSqlxZoxhd8NulmQtQURYnbOa7bXbmazz4WhiUEqpcdbY3UhjdyOLMhYBsCRrCa09rRzrODbBkXmniUEppcZZeVs5AIUphQAszloMQEljyUSFNCpNDEopNc7K263EMCdlDgDFacVER0Szp3HPRIY1Ik0MSik1zsrbyomUSHKTcgGIiYyhOL1YzxiUUmq6Km8vJy8pj+iI6IFlC9IXcLD54ARGNTJNDEopNc7K28opSCkYtGx+2nwauxtp6W4J6JgHmw+OW2mNkCUGESkQkVdFZK+IlIjIf3rZRkTklyJyUETeF5EVoYpPKaXGS7Wjmvyk/EHL5qfNB+Bgi/9nDcYYrnv2Oh7c9WBQ4hsqlGcMLuBrxpiTgDXAF0Xk5CHbXAoU248bgN+EMD6llAq6nr4eWnpamJEwY9DyeWnzgMASQ1tvGz19PWTFZwUlxqFClhiMMdXGmHfs5+3AXiBvyGZXAo8ay5tAmojkhipGpZQKtrrOOgCy47MHLZ+ZMJPk6OSAEkNDVwPAsGQTLBPSxyAihcCpwFtDVuUBFR6vKxmePBCRG0Rku4hsr6+vH7c4lVLqRPUnhpkJMwctFxHmpc0LKDH0HzPszxj6iUgS8BfgK8aYtqGrvewy7J5xY8z9xphVxphV2dnZXnZRSqnJ4V91RwH4Z8vwr9v56fM51HLI79IY/YkhJyHnxAP0IqSJQUSisZLCH40xf/WySSXg2XWfD1SFIjallAq2ZqeL3x3ZD8CDNX281jT4b+H5afNp6WmhsbvRr+PWOGoAmJEY5peSRESA3wF7jTEjzVDxNPBpe3TSGqDVGDN5i5YrpdQoHqtqxOlsIiYylpy4VH5bMfjSd//IpAPNB/w6bm1nLemx6cRGxgYtVk+hPGM4A7geOE9EdtqPy0RkvYist7d5DjgMHAQeAG4KYXxKKRVU/6hvIVPayEmYyTU5GWxsbqeh1zWwPtAhq7WdteQkjs9lJAjh1J7GmDfw3ofguY0BvhiaiJRSavwc6+7l/fYuTpE2ZsTP4EPZafyqvI7Xmtq4JicDgMz4TDLiMvxPDI5achPHb8Cm3vmslFLj4M2WDgDcriayE7I5JTme1KhIttjL+xWnFftdGqOms4aZiTPH3jBAmhiUUmocvNXqIClCaO1uYGbCTCJFWJuWyObmwYlhfvp8DrQcwG3cPh23y9VFa0/rsOGvwaSJQSmlxsHbrQ5OTTL09PUM3Ii2Ni2Jo9291PU4B7YrTiumy9VFVYdvAzAHhqqOYx+DJgallAqyVqeLfY5uFsZ2AcfvUF6WnADAe+2dA9vOT/dvZFKtoxYYfsNcMGliUEqpINvr6AYgJ9K6bNSfGE5JikeA99q7Brb1d2RSlcM6s9AzBqWUCiP77cQQb1qA44khMSqS4oS4QWcMidGJ5CXl+XzGUNleSYRE6KgkpZQKJ6WObhIjI3A6rTuaPQvoLU2OH5QYwDprONDiW2KoaK8gNzGX6MjosTcOkCYGpZQKsv2d3SxIiKO+s5702HRiImMG1i1Njqeu1zW4Azq9mCOtR3D2Ob0dbpDKjsphczsEmyYGpZQKslJHNwsS46jrrBtWGvukxHgA9tmXm8A6Y3AZF0fajox57Mr2SvKTNTEopVTYaHa6qOt1sTAxjtrO2mGJYVFSHAD7HP53QDucDpq6mzQxKKVUOOnveB7pjCE7JprM6KhBZwxzU+cSFRHF3qa9ox67sr0SgILkglG3O1GaGJRSKohK7S/8efGRNHU3eZ1lbVFiHHs7jieG6MhoFqUvoqShZNRjH22z5nbQxKCUUmFkf2c3CZERxLrbMJgRE0NpZzdujwl6lmQtoaSxhD5334jHPtRyCEEoSi0al9j7aWJQSqkgKnXYI5K6rNIVXhNDUhydfW4qunsHli3JWoLD6Ri1A/pgy0HykvKIj4oPetyeNDEopVQQ7Xd0syAxdsS5nuH4yKRSj36GU7JOAWBXw64Rj32w5eBACY3xpIlBKaWCpMXporbXxcLE+IHE4O2MYWGiNTLJs5+hMLWQxOhEdjfs9nrs3r5eytvKB0YwjSdNDEopFST9I5L6h6pGR0STFps2bLvkqEjyYqPZ6zFkNUIiOCXrFN6te9frsctay3AZlyYGpZQKJ6Wd9lDVhNiBoarWdPfDnZQUP+hSEsBpuaexv3k/jV2Nw7Z/v+F94Pglp/GkiUEppYJkv8MakZQfF+P1HgZPixLjONjZg9N9fGTSaTmnAfB2zdvDtt9Vv4u02LRxH6oKmhiUUipoSh3dFCfEEiHiU2JwGsOhruNnDSdnnkxydDJvVb81bPv3699nafbSEc9AgkkTg1JKBcl+Rw8LE+MwxoyZGE5KsmsmeXRAR0ZEclruaWys3Djofoa6zjoOtR5ixYwV4xe8B00MSikVBK1OFzW9ThYkxNHubKfL1TXqLGvz4mOJFIb1M1xceDH1XfXsqN0xsGzzsc0AnJl35vgEP4QmBqWUApxuJ79855fcs/OeUe8+Hsn+zh7AGpFU5xh5qGq/uMgI5sbHDqqZBHBOwTnER8Xz9KGnB5a9cOQFchNzWZC+wO+4AqGJQSmlgCf2PsEDux7gvvfu47G9j/m9f6nHUNXR7mHwtDAxbtCQVYD4qHiumHcFz5Y9S3VHNUfbjrKlagtXzb8qJP0LoIlBKaUAeLL0SVbOXMma3DU8UvIITvfYk+Z4KnV0ER9hjUiq7awFxk4MJyXGc7SrF0ff4DOUdUvWESVRfGPjN/j2G98mLiqOaxdc61+DToAmBqXUtFfRVkFFewUXF17MdQuvo76rnu012/06xn5HDwsSj49IgrETw6KkOAxwwNEzaHluUi4bztjAnsY9lDSW8N213yU7Idv7QcZBVMjeSSmlJqmt1VsBWJu7lpmJM4mPiufloy+zdtZan49R6ujmrIwkwBpFlBabRmxk7Kj7LEo8PmnP8pSEQesuLbqU02edjtu4SY9L96c5J0wTg1Jq2tvTuIe02DTmpMxBRFibu5bNVZt93r9/RNLCBOuLvtpRTW5i7pj7FcbHEhch7B3SAd0vNTbV5xiCSS8lKaWmvX1N+1iYvnCgc/e03NM41nFsYMa0sfSPSFpgnwFUdVT5lBgiRViQEEdph/fEMFE0MSilpjWX28XBloMszFg4sGx1zmoAttVs8+kYnsXzjDFUOaqYlTTLp30XJsUNG7I60TQxKKWmtfK2cnr6egYlhnlp88iIy+CtmuGlKbwpdXQTHxFBQVwMLT0tdLm6yEvK82nfkxLjqel10ux0BRT/eNDEoJSa1sraygCYmzp3YJmIsDpnNdtrtmM8pt8cyX5HN8X2iKSqjioAn88YjndAT56zBk0MSqlprb8fYWjV0pUzV1LbWcuxjmNjHqO0s3tg8p3+7TUxKKVUmKporyAlJmXYCKCVM1cCDKpZ5E2bq4/qHqtGElgjksD3xJAbG01KVAR7O7rG3jhENDEopaa18rZyr3MczEubR2psKttrR7/Rrb8UxiKPM4bk6GRSYlJ8en8RYXFSPLs1MSil1ORQ0V7hNTFESAQrZ6wc84xhn13raKHnUNWksYeqelqWnEBJR9egSXsmkiYGpdS05XQ7qXZUjzgr2sqZK6lor6DWUTviMUod3STas7YBlLeXMzt5tl9xLE9OoMdtKHVMjrOGkCUGEXlIROpEZPcI688VkVYR2Wk/7ghVbEqp6ammo4Y+0zdyYsgZu59hX0c3CxLiiBDB5XZR0V7BnJQ5fsWxLNkqh/F++zRLDMDDwCVjbLPJGLPcfmwIQUxKqWmsvL0cGD4iqd/C9IUkRieOmhhKO7tZlHT8MpLL7aIwtdCvOArjY0iJimBne6df+42XkCUGY8xGoClU76eUUmPpH6qan5zvdX1URBSnzjh1xMTQ2Ouivtc1UCPpSNsRAApTCv2KQ0RYmpTAe9MtMfhorYi8JyL/FJHFI20kIjeIyHYR2V5fXx/K+JRSU0iVo4qoiKhRy2OvnLmSQ62HaOoe/nftwIgk+4zhSOsRwP/EALAsJYE9Hd30uN1+7xtsYyYGEZnt48O3sVkjeweYY4xZBvwKeGqkDY0x9xtjVhljVmVnh65GuVJqaqnuqCYnIYcIGfmrcNXMVQC8U/vOsHVDRyQdaTtCamwqaXFpfseyLDkBpzHsnQQF9Xwpu/0IYIDR5pQzWH0IjwYaiDGmzeP5cyJyr4hkGWMaAj2mUkqNxpdid4szFxMXGceO2h1cMOeCQetKHd2kRkWSExMNwKGWQwGdLQCssOdj2N7mGDY3Q6iNmRiMMR8cukxEcowxNcEMRERygFpjjBGR1VhnM43BfA+llPJU3VE95mQ80ZHRLMte5vVGt1KHVQpDRDDGsL95Px+a+6GAYsmPiyEvNpo3Wzr4fP7EXgkJtI/h0/7uICJPAFuBhSJSKSLrRGS9iKy3N7kG2C0i7wG/BK4zvlSvUkqpADj7nNR31ftUumLlzJWUNpXS1jtwYQNjzEBiAOuO5w5nx6Aqrf5ak5bEW60Onwr3jadAZ3C7UkQ6gZeMMaW+7GCM+fgY638N/DrAeJRSyi81jhoMxqcJdVbOXInBsLNuJ2fnnw1Aba+LZlffQGIobbK+ChelLwo4ptNSE/lLbTNlXb3MTRh9WtDxFOgZw9XAQeAjIvJgEONRSqmQqHL4Xh57afZSoiKi2F5z/HJSf22jJUnxAOxr3keERDA/fX7AMZ2WZs0Z/WZrR8DHCIaAzhiMMbXA8/ZDKaXCzsC8CYljJ4a4qDhOyTplUD/Dbvueg8V2YthZt5P5afOJj4oPOKYFCbFkREfyZksHn8jNDPg4JyqgMwYRuUdEHrafXxTUiJRSKgSqHdUIQk5ijk/br521lt0Nu6nvtO6d2t3RRWF8DMlRkTjdTt6rf2+gVHegRITT05LY2NQxof0MgV5K6gUO28/PC1IsSikVMlUdVWTHZxMdGe3T9hfNuQiD4aWjLwFWYhi4jNS4jy5XFytmrjjhuM7LTKGm18meCZy4J9DE0Amkikg04F8ZQaWUmgSqHdV+lceelzaPeanzePHoi7S7+jjS1TuQGLZWbwWO3wx3Is7LsO4V/ldj2xhbjp9AE0MTcAi4B9gcvHCUUio0qjqqfOpf8HRJ0SW8U/sOr9bsB2CJXRX1lfJXWJq9lKz4rBOOKyc2msVJcbwSLolBRNJE5PfAR+1FjwInniKVUiqE3MZNTWeN3xPqfLT4o0RGRPKn0icBa0TSkdYj7Gncw/mzzw9afOdnpLCtzUFjrytox/SHX4nBGNMC/Bj4HvAWUAz8NfhhKaXU+KnvrMfldvl9xpCdkM2lhZfyftWzZNHMzJgoHtv7GFERUVwx74qgxXfFjDT6DDxT3xK0Y/ojkEtJ64C5xpgdxpjfG2P+EeyglFJqPFU7qgH8PmMA+NKpX8IYSGz4Dc+VPcef9/+Zq+dfHZTLSP0WJ8VTnBDL32qbg3ZMfwSSGJqB9SLyPyLyORE5NdhBKaXUePLnHoahMhNy6Mj8Al2dpdy66VaKUov48oovBzU+EeEjM9N5s9VBZXdvUI/tC79vcDPG/EhEXgH2A8uBs4F3gxyXUkoNeLulg28fOEZWTBS/WDSbnFjfhpiOxJ+7nocqae+iM+E0vnvO6RRE1LN21toTuqltJNfMTOdnZTU8eqyBb83zP84T4fcZg4hsAK4ELgSOGWPuDnpUSilla+h1cf2uMhqcLt5scbC+5MgJ3/xV3VFNamwqCdH+l7d+x77j+aLchZw3+7xxSQoAs+NjuSQrlT9UNdLZF9rJe/xODMaYO7Cqn7YDHxWRB4IelVJK2X55tJZ2Vx9PLpvHhuJZvNnq4KUTHMpZ2VFJfpL36TzH8m5bJzkx0eTGxpxQDL64oSCbZlcff6gK7bQ0gd7H8B/Au8aYHxtjvhDMgJRSql9Xn5snaxq5amY6CxPj+HhOJnmx0fz+2Il9UVa0V1CQXBDQvu+2dXJqiCbSWZOWxAczkrnrSC1NztANXQ00MTwE3CgiPxWR5UGMRymlBrzQ0Eqby80ncjMAiIoQPpaTwWtN7VQF2CnrdDup6qgKKDE0O10c7uoZmG0tFO6YNwtHXx9f31cRsvpJgSaGL2N1XEdhXVZSSqmge7quhVmx0Zxul6MGuCYnHQM819Aa0DFrOmroM30BJYadbVb/QqjOGABOSorn9rmzeK6hlVv2V9LV58blNjxUWc8eu/R3sAWaGA4BccDfjTFnBzEepZQCwG0MW1s6ODs9mQg5PuX8vIQ4ihNieakhsH6GivYKgIASwzttnQiwLDm0czL/R0E2X5o9g0erGlm6eTdLt+zmWweO8WR107i8X6AzuJUAFcA6EfmpMeYDQYxJKaUodXTT7OpjrcfZQr+LslK5v6KedlcfyVGRfh33RBNDcUKc3+95okSE2+fN4vzMFP5a24zTbbgkK5WLs1LG5f0CTQwLgHrgfqwb3pRSKqg2t1izmK1NSxxYZoxBRLgwM4V7yuvY2NzOh7LT/DpueXs5sZGxZCdk+7VfnzFsa+vgiux0v/YLprVpSV4TZbAFeilpEdZNbV8HbgheOEopZdna0kF+XDSz4625jzdVbuKMJ87g6qevJi+ynYTICDY1+z8FZkV7BflJ+USIf19/+xzdtLncrPFIVFNVoIkhDbgF+CYwcbNJKKWmJGP3L/R3Onc6O/nO5u+QEptCVUcV39l8G6elJPBGc7vfxw50qOpW+wzmtBD8xT7RAk0MG7A6nkuB0N6Sp5Sa8ko7u2lyHu9feLXiVRq7G9lw+gZuXnkzO2p3MNtdwsHOHqp7fB+26nK7ONJ2hKK0Ir9jeqvFQV5sNAVx439j20TzKTGISKSIVIvI5wGMMZXGmJft57eOZ4BKqelni32JqP+M4fkjzzMjYQarclZxdfHV5CTmcLTmKQDe8ONyUnl7OS63i/lp8/2KxxjDm60drJkGZwvgY2IwxvQBu4F54xuOUkrBVvuv89lxMfS5+9hWs41z8s8hQiKIiojiuoXXUVK/nQxTzSY/LicdbrGmqp+X6t9XWVlXL/W9rmnRvwD+XUpKAL4pIttF5Gn78ffxCkwpNT0ZY9jS0sHatCREhIMtB3E4HZw643iF/48Uf4QoiSK/dytvNHf4fEfwwZaDABSl+ncp6c3+/oXU6XHG4M9w1bX2vyvsB0Bo7s9WSk0b+zt7aHS6OD3d+hJ+t86q6u+ZGDLiMjgz/0y21W6kKuYqDnf1MC8hbsxjH245TF5Snt9VVTc2tzMjJorihFi/9gtX/pwxFHl5zB2PoJRS01f/6J/+/oVdDbvIis8iLylv0HZXzLsCR28j0d0lbPSxn+FAywHmpvr3teU2ho3N7ZyTkYx43IE9lfmcGIwxR709xjM4pdT0s6Wlg1mx0cyxR/8cbjnM/LT5w76Uz8k/h+SYZDK6N/s0bLXL1UVZaxmLMhb5Fc+uji6anH2cm57s137hLNDhqkopFXT99y/09y8YYyhrK/PaJxATGcNlRZeBYztvNNbRN0Y/Q2lTKX2mjyVZS/yK6fUmK+mcnaGJQSmlQu5gZw/1va6By0j1XfU4nI4RO4uvnHclbncPPW1b2dU+eqXR3Q27AfxODK81tbMkKZ7smBObTjScBDK15+XjEYhSSm0dqI9kJYbDrdbw0pH6BZZkLWF2ShFxjk1jDlstaSwhOz6bGQkzfI7H4epjW6uDc6bR2QIEdsbwg6BHoZRSWP0LOTHRFMVb/QtlrWXAyMNLRYSPFl9FdM9+XqkpHfXY79a9yylZp/gVz6tN7TiN4YOaGMY0PbrllVIhNVAfKT1poKO5rLWMxOhEsuNHroT64bkfBiLYU/0i3X3eK/RUtldyrOMYq3NX+xXT8w2tpEdFsmaa3L/QL5DEoPcuKKWC7nBXD7W9rkFltstayyhKKRp1mOiMhBksyl5NVMcm3mrxPqvb2zVvA7Amd43P8Tjdhpca27gwK4WoiOn197B2PiulJoWtLQ6AQdN4Hm49zNy0se87+MxJHyOyr4knDj7vdf2myk1kx2f7dQ/Dmy0dtLr6uDQr1ed9pgpNDEqpSWFLSwczYqKYa8+/4HA6qOus86l8xWWF5xMdM4u3jjw5rDyGw+lg07FNXDDnAr9uUPtnQyvxEcI5GeMzS9pkFkhiqA16FEqpac0Yw5Zma/6F/i/vI61HAChKGTsxREgEpxddh6v7MH8t+9egdS8eeZGevh4uKbzE53hcbsPTdS2cl5lCQuT0+/vZ7xYbYy4M5I1E5CERqROR3SOsFxH5pYgcFJH3RWSFt+2UUlPPka5eanqdg6at7B+q6mvBu/+35FpcUbn8YvtP6OnrAaDP3cejex6lOL14UK2lsbze3E6D08U1MyduGs+JFMpU+DAwWsq+FCi2HzcAvwlBTEqpSWDLkPpIYHU8R0qkz7OtLUxKIjV3Ha1dVXx3y3dxup38vuT3HGw5yA1Lb/DrMtJfaptJi4rkvMzpdxkJ/KuuekKMMRtFpHCUTa4EHjXWBcI3RSRNRHKNMdWhiVApNVG2tHSQHRPFfI/qpWWtZRQkFxAd6fsdx5fPOYuH2q/h2cN/ZmPlRtp727lozkVcPOdin4/R4erjn/UtXJuTQWzE9LuMBAEmBhG52Rhzl/18oT3F54nKAyo8Xlfay4YlBhG5AeusgtmzZwfhrZVSE8UYwxvN7Zzh0b8A9lBVP+dNuCw7jV+lXMmn5izH1fE2C9IX8IlFn/DrbOGvtc10uQ3X5mT49d5TiV+JQUTSgF8Ai0SkG3gfWAd8LgixePvJeb1nwhhzP3A/wKpVq/S+CqXC2CH7/oUz0o9fRnK5XRxtP8o5Bef4dazlyfHMT4hlp/tk/n7mlX7HYozh98caWJIUz6oU/+ZsmEr8Ok8yxrQYYz4HfB94CzgL+GuQYqkEPC8m5gNVQTq2UmqS2mzPpXBm2vGyE5XtlbjcLr/PGESEj+Vk8FargyNdPX7H8marg72Obv49L2vazL3gTaAX0M7BGra6BgholJIXTwOftkcnrQFatX9BqanvjWZr/oVCuz4SjF0jaTTXzExHgP+tbvJ73/sr6kmLiuSqaToaqV+giSENuAX4JtDtyw4i8gSwFVgoIpUisk5E1ovIenuT54DDwEHgAeCmAGNTSoUJtz2/8+lD+xfaAk8Ms+JiuCAzhUerGukaoXaSN7vbO/lnQyufz8+elvcueAp0VNIGYJExplREfPrkjTEfH2O9Ab4YYDxKqTBU6uim0enizPTBReoOtxwmMy6TlJjAhoveWDCDq3ce5M+1TVw/K8unfe46UktKVARfyPdt+6ksoLRojKk0xrxsP781uCEppaaLzfb9C2cMmTazrLWMeWnzAj7u2rREliXH8+ujdfS4x/7bdXNzO881tLK+YAap0SEbxT9pBZQYROQeEXnYfn5RUCNSSk0bbzS3MzsuhoK44/0LxhgOtR7yq+DdUCLCbXNzOdrdy4OVDaNu2+t2c+v+SmbHxXBjge+T+ExlgV5I68XqDwA4L0ixKKWmkV63m03NHZw7ZBKcus46HE7HCZ0xAJybkcIFmSn84kjNqCOUNhyq4kBnDz8oziN+mvct9Av0U+gEUkUkGtA7zJRSftvW6sDR5+a8IdVLD7UeAkaeztMfPyzOI1KEG0qO4HD1DVv/WFUjD1Y28Pn8LC6chuW1RxJoYmgCDgH3AJuDF45Sarr4V1M7UYLXjmfAp3kYxjI7PpZfnTSbko4urn3vEGWd1plDZ5+bn5RV8/XSCs7LSOaOebNO+L2mkkDvfF4IPAY8inXns1JK+eXVxjZWpyaRFBU5aPnh1sOkxqaSGZcZlPe5KCuVBxYX8uW95Zz+1l7mJ8RS3eOko8/NtTnp/HRBATHTtCbSSPxKDMaYFhH5MVAINABLCd6dz0qpaaKmx8keRze3z80dtu5Qi9XxHMw7jy/LTuPUlAQeq2pkb0c3a9OS+MjM9EFlvtVxgYzLWgeUGWNeAHYEOR6l1DTwr6Y2gGFlrftHJF0w+4Kgv2dubAzfKBqeiNRwgSSGZmC9iCwE3gN2GmPeDW5YSqmp7F+NbeTERHNSYtyg5dWOalp7Wjk58+QJikxBAInBGPMjEXkF2A8sB84GNDEopXzS3efm1aZ2PjIjfdjlor2NewE4KeOkiQhN2fxODCKyAYgEdmKdLbwW5JiUUlPYpuZ2HH1uLs0ePjx0b9NeIiWS4vTiCYhM9Qtkzuc7gB5734+KyANBj0opNWU939BKUmTEsGGqYCWGotQi4qLivOypQiXQMVoPAScBmcC9wQtHKTWV9RnD8w1tXJCZMmzaTGMMexv36mWkSSDQxPBlrMtQUcDdwQtHKTWVbWt10Oh0cYmXu4yPdRyjvquepdlLJyAy5SnQxHAIiAP+bow5O4jxKKXCVEt3Cze+fCMr/rCC9S+vp8ZRM2ybfza0EiPC+ZnDy2nvqLVGv6+YuWLcY1WjCzQxlAD/AtaJyLYgxqOUClN3bLmDt6rf4op5V7Czbief+ednqO+sH1jvNoZ/1LVwTkYyyUPudgZ4p+4dUmJSmJ82P5RhKy8CTQzzsC4j3Q98LnjhKKXC0a76Xbxa8So3Lb+JO0+/k99d/Duae5q5+bWbcfY5AXizxUFVj5OrvUybaYxhW802Tp1xKhGi5SkmWqA/gQpjzNNY03DuDWI8Sqkw9MS+J0iKTuLji6yJGhdnLmbDGRvYWb+T+96/D4C/1jaTEBnBRVnDLyOVtZVR0V7BGXlnhDRu5V2gUxVdIiL7saqrHsXqjFZKTUPOPievVbzGhXMuJDE6cWD5JYWXsPnYZh7c9SBrZ53FM/WRXJqVSmLk8MtIr1e8DsC5+eeGKGo1mkDPGNKAW4BvYt3ToJSaprbXbqfd2c4HCz44bN0tH7iFnIQcvrHxNlp6O71eRgJ46ehLLMpYRG6S1jKaDAJNDBuwRiSVAsNnv1BKTRtbqrYQHRHNmllrhq1Likni+2d+n4bOSjLbnuDsIXM7A+xv3s+uhl1cMe+KUISrfOBTYhCRSBGpFpHPAxhjKo0xL9vPbx3PAJVSk1tJYwmLMhYRHxXvdX1hxnK6Uz5MRNsrPF/2zLD1j5Q8QkxEDJfPvXy8Q1U+8ikxGGP6gN1Yo5GUUgoAt3Gzp3HPqNVQ/7e6ifbUa1ictYINWzewreb4CPfdDbt55vAzfHzRx0mLSwtBxMoX/nQ+JwDfFJELgSp7mTHGXBn8sJRS4aC8rRyH08HizMVe1xtj+GN1I2vSUrhn7V2se2EdN758I+uXrSc/OZ+fvP0TZibM5AtLvxDiyNVo/EkMa+1/V9gPABPccJRS4+V/q5v4dXktBrhp9gw+kXviU2eWNJYAjHjGsLmlg7KuXm4uzCEzPoOHLnmI72z+Dne/Y1XSyUvK41fn/YrU2OElMtTE8ScxFI1bFEqpcfVgZT23HzjG8uQEIgVu3ldBm7OP9bNnnNBxSxpLiI2MZW7aXK/rHz7WQGpUJB/OTgMgIy6De86/h7LWMlp6WliSuYToyOgTikEF35iJQURm20+9nh14rG8xxrQFKzClVHC8397JHQeOcWlWKg8uKQTghpIjbDhUxQdSE1mZmjj6AUaxp3EPCzMWEh0x/Mv9aFcPz9W3ctPsGcRHDu7OLErVvzMnM1/OGB7BSgqjzcxtgIeBR4MQk1IqSPqM4RulFWTFRHH3SbOJtGdMu3vRbN5p28ct+yt5fuUCoiJG++89wrHdfext3DviMNMHKuuJEFiXn3VCbVChN2ZiMMYMv2tFKRUWnq1v5b32Lu45aTYpHoXrkqIi+d78PG4oOcKTNU18apb//Q1H247S6epkcdbwjucWp4vHq5v4yMx0cmNjTqgNKvS0WpVSU5Qxht+U11EYH8NVXu44vjw7lZUpCdx1pIbuPrffxx+t4/n3xxro7HOzvuDE+jDUxNDEoNQU9Xarg3fbO/mPghkDl5A8iQi3FuVS1ePksepGv4+/p3EPcZFxzE0d3PHc6nRxX0U9F2elsDjJ+01vanLTxKDUFPWbijoyoiP5t5yMEbc5Mz2J09OSuPtoLY4+/6rb7Gncw6KMRURFDL4ifV9FPa2uPr5ZpHWPwpUmBqWmoIOd3bzQ0MZnZmWREDnyf3PrrCGH+l4Xv6ts8Pn4fe4+9jbtHXYZqaHXxQOV9Xw4O1XPFsKYJgalpqD7K+qJiRD+3YcRQavTkrgoM4Vfl9fS7HT5dPyy1jK6XF3DOp5/dLiKbrebW/RsIaxpYlBqimnodfF/NU1cMzOd7Bjfbh67bW4u7S43vzxa69P2e5r2AAwqhfFuWyePVzfx+fxsihPj/A9cTRqaGJSaYh4+1kC32/AffowIOikpnmtz0nnoWAPHunvH3L6koYT4qHgKUwoBcLoNt+yvIDsmiq8V5gQaupokNDEoNYV09bl56Fg9F2amsMDPv9q/UZSLAN85cGzMbUsaSzgp4yQiI6x7I35xtIb327v4YXE+yVHDZ2hT4SWkiUFELhGRUhE5KCLD5nEQkXNFpFVEdtqPO0IZn1Lh7k81TTQ5+1hfkO33vgVxMXy9MIfnGlp5pq5lxO2cbielTaUDHc9bWzq4+2gtH8tJ58Mz0gKMXE0mgc757DcRicSaI/pCoBLYJiJPG2P2DNl0kzHmw6GKS6mpwm0Mv62oZ2lyPKenJQV0jPUFM3i6roVv7q9gaXI8s+Njh21zqOUQ3X3dLMlawtGuHtbtLqMoPpbvF+efaBPUJBHKM4bVwEFjzGFjTC/wJKBzOSgVJC81tnGoq4ebCmYgXm5o80VUhPCbxXNwGcPndpfR4mWU0u6G3QBkJC3kmp2HcBt49JS5g0puqPAWysSQB1R4vK60lw21VkTeE5F/iojX2T9E5AYR2S4i2+vr68cjVqXCzm/K68iLjR4ocR2oeQlx/PbkQvY7evjozoMc7eoZtH53w24SopO5YX8X7a4+nlw2j7kJw88sVPgKZWLw9ifM0FLe7wBzjDHLgF8BT3k7kDHmfmPMKmPMquxs/6+lKjXV7Gh18GargxsKsgOqlDrUBzNT+MPSIo529XLu26V8a38lf6tt5g9VDTxbsYOWyELSoqN4asV8lqckBKEFajIJZWKoBAo8XudzfIpQAIwxbcaYDvv5c0C0iGjNXqXGcG9FHalRkXwyCLOy9Ts3I4XXVi/i0uxU/lDVyI17jvKNvQfp7i5n9YylPL9qAYsS9e7mqSiUiWEbUCwiRSISA1wHPO25gYjkiH1xVERW2/H5X91LqWnkcKc1Ic5n87JICvJ1/vy4GO49eQ77zzqF11Yv5LfznICbLxSfTmKk9ilMVSEblWSMcYnIl4AXgEjgIWNMiYist9ffB1wD3CgiLqALuM4Yo/NKKzWK+yrqiIkQ1uWN38l1fGQEixLjebH0XSIlkpUzV47be6mJF7LEAAOXh54bsuw+j+e/Bn4dypiUCmf1vU7+t6aJj+VkMCN2/OdOfrvmbRZnLiYxOvDpQNXkp3c+KxXGHqpsoNdtArqhzV+dzk5KGkr4QM4Hxv291MTSxKBUmGpz9fHQsQYuzUplXsL4F63bUrUFl3GxdtbacX8vNbE0MSgVpu63J8T5auHMkLzfK+WvkBqbqv0L04AmBqXCUKvTxf2VdVyalcopyeN/H0FvXy+vV77OufnnDpuxTU09mhiUCkP3V9bT5nJzc4jOFl4++jLtve1cWnRpSN5PTSxN/UqFmVanNX1moGcLu+p38bPtP6OksYTs+GwuLbqUzyz+DKmxqV63N8bwxL4nKEgu0P6FaULPGJQKM/dVWGcLXwvgbGFn3U4+98LnqOyo5NoF11KUWsSDux7kiqeu4MUjL3rdZ9OxTeys38n1J19PhOhXxnSgZwxKhZHaHie/raznQ9mpLPHzbKGnr4fbNt1Gdnw2f/zQH8mIywCgtKmUO7bcwdde/xrnl53PratvJSfRmoWtoauBDVs3MCdlDtcUXxP09qjJSRODUmHk50dq6HW7+fbcWX7v+/jex6nsqOTBix4cSAoACzMW8sfL/sgjJY9w33v3ccVTV3BZ0WXMTJzJ3w78jdaeVu4+726iI8f/Bjo1OWhiUCpM7Hd088fqRj4zK8vvMtcut4vH9z3O6pzVnJZ72rD1URFRrDtlHRcXXsy9O+/lubLn6HJ1cXLmyfzsnJ+xONNrBXw1RWliUCpM/PBwFfEREdxcmOP3vpsqN1HjqOHW1cNm1B0kPzmfH571Q75vvk+3q5uEaC2pPR1pT5JSYeDNlg6eb2jj/82eSVaM/3/PvXj0RVJjUzk7/2yfto+QCE0K05gmBqUmOZfbcPuBY8yKjeYLAdREcvY5eb3idT5Y8EGiI7SfQI1NLyUpNck9UtXA7o4u7l9cSEKk/3/LvV3zNu3Odi6cc+E4RKemIj1jUGoSq+918t9l1ZydnsTl2d5vQBvL1qqtREdEszpndZCjU1OVJgalJrEfHKqmq8/wg+J87MkN/fZ2zdssy15GXNT4V2BVU4MmBqUmqW2tDp6saeKGgmyKEwP7Um/taWVf0z49W1B+0cSg1CTU43Zz875y8mKjuXlO4IXydtTuwGB0ch3lF+18VmoS+sWRWg509vD40rkkRkUGfJxtNduIjYxlafbSIEanpjo9Y1Bqktnd3smvymu5Nied8zJTTuhYb9e8zfIZy4mJjAlSdGo60MSg1CTidBu+uq+CjOgoNszPO6FjtXS3sL95v/YvKL/ppSSlJpG7j9ayq6OL3y0pJD36xP577qjdAcCqmauCEZqaRvSMQalJYlurg7uO1HDNzHQ+lJ12wsfbXrud2MhYlmQtOfHg1LSiiUGpSaDd1ccX9xwlPy6GHy3ID8oxd9TuYFn2Mu1fUH7TxKDUJHDb/kqO9fRy78lzSD6BUUj92nrb2Ne0Ty8jqYBoYlBqgj1Z3cifa5v56pwcVqUmBuWY79a+i8GwKkcTg/KfJgalJtD77Z3csr+SM9OS+MoJ3Mg21Pba7URHRHNK1ilBO6aaPjQxKDVBmpwu/n13GVnRUdy3uJCoiMBqIXmzpWqL1kdSAdPEoNQEcLkNN5Ucpa7HxYNLigKafGckNY4a9jfv93lSHqWG0vsYlAoxYwzfOlDJa83t/HxhAaemBHemtDeOvQHAWXlnBfW4avrQMwalQuzX5XU8WtXIl2bP4JOzMoN+/FcrXmVW4izmpc0L+rHV9KCJQakQ+nNNEz84XM1VM9L41tzcoB+/sauRzcc2c0nRJQHP36CUJgalQuSp2ma+vLecM9KS+J9Fs4kYhy/uZw8/S5/p4/K5lwf92Gr60MSgVAj8va6ZL+49yurURB5dWkRcAHM3j8XpdvLY3sdYnr2c+enzg358NX1o57NS4+yBinruOHiM1amJPLZ0LomRJ35nszf/V/p/VDuquX3N7eNyfBUafR0d9B48SF9rK8btJiojg6jsbKJmzkTG6XdnKE0MSo2T7j43dx6q4uFjDVyWlco9J88hfhzOFAD2N+/nl+/8ktNnna6jkcKQu6uL9hdfpPlPf6Jr+w7vG0VFEZ2bS3ReHtH5ecTk55Ow+jQSVpwa9Hg0MSg1DvY5uvjSnnJ2d3RxY0E2t8+bReQ49CkYY3jq4FP8fMfPSYpJ4nunf087ncOEMYbu99+n9e9P0/qPf+Bubyd6zmyybrqJuCWLicrMBBFcTU24autwHjuGs7IS57FjdLz2On0NDWTeuD78E4OIXALcDUQCDxpjfjxkvdjrLwM6gc8aY94JZYxKnYj6Xie/OlrH747VkxoVyaOnFHFRVuq4vNfh1sP819b/YnvtdlbMWMGGMzaQk5gzLu+lAmecTrree4+u3bvpPXoUZ0UlzqoqnFVVmO5uJCaG5IsvJu2aa0hY/QGfE7u7qwvT1zcuMYcsMYhIJHAPcCFQCWwTkaeNMXs8NrsUKLYfpwG/sf9VatJyG8P2VgdP1DTxl5pmnMZw/axMbinKJTOIdzT363Z188CuB3ho90MkRCXwvdO/x1XzryJCdCzJZOHu7aXj9ddpe+ZZHJs24e7sBCAiNZWYggJi588n6eyziV20kOTzzycyOdnv94iIjw922APEGDNuBx/0RiJrgTuNMRfbr28DMMb8yGOb3wKvGWOesF+XAucaY6pHOu6qVavM9u3b/Y7n9nu+x3MLtfKkUip8nVZfym8+fnNA+4rIDmOM1y/BUF5KygMqPF5XMvxswNs2ecCgxCAiNwA3AMyePTugYKJ7neQ4GwLaVymlJoPErp5xOW4oE4O3C2dDT1d82QZjzP3A/WCdMQQSzHe/+v1AdlNKqSkvlBclK4ECj9f5QFUA2yillBpHoUwM24BiESkSkRjgOuDpIds8DXxaLGuA1tH6F5RSSgVfyC4lGWNcIvIl4AWs4aoPGWNKRGS9vf4+4DmsoaoHsYarfi5U8SmllLKE9D4GY8xzWF/+nsvu83hugC+GMiallFKD6cBnpZRSg2hiUEopNYgmBqWUUoNoYlBKKTVIyEpijBcRqQeOBrh7FjBVbn/WtkxOU6UtU6UdoG3pN8cYk+1tRdgnhhMhIttHqhUSbrQtk9NUactUaQdoW3yhl5KUUkoNoolBKaXUINM9Mdw/0QEEkbZlcpoqbZkq7QBty5imdR+DUkqp4ab7GYNSSqkhNDEopZQaZNomBhG5RERKReSgiNw60fF4IyIPiUidiOz2WJYhIi+JyAH733SPdbfZ7SkVkYs9lq8UkV32ul+Kr7ONB68dBSLyqojsFZESEfnPMG5LnIi8LSLv2W35Xri2xY4hUkTeFZFnwrwdR+wYdorI9jBvS5qI/FlE9tn/Z9aGvC3GmGn3wCr7fQiYC8QA7wEnT3RcXuI8G1gB7PZY9hPgVvv5rcB/289PttsRCxTZ7Yu0170NrMWaIe+fwKUhbkcusMJ+ngzst+MNx7YIkGQ/jwbeAtaEY1vsGG4GHgeeCdffLzuGI0DWkGXh2pZHgM/bz2OAtFC3JaQNniwP+8N6weP1bcBtEx3XCLEWMjgxlAK59vNcoNRbG7DmvVhrb7PPY/nHgd9OcJv+DlwY7m0BEoB3sOYuD7u2YM2Q+ApwHscTQ9i1w37fIwxPDGHXFiAFKMMeGDRRbZmul5LygAqP15X2snAw09iz2tn/zrCXj9SmPPv50OUTQkQKgVOx/tIOy7bYl192AnXAS8aYcG3L/wDfBNwey8KxHWDNDf+iiOwQkRvsZeHYlrlAPfB7+xLfgyKSSIjbMl0Tg7drbeE+bnekNk2atopIEvAX4CvGmLbRNvWybNK0xRjTZ4xZjvUX92oRWTLK5pOyLSLyYaDOGLPD1128LJvwdng4wxizArgU+KKInD3KtpO5LVFYl49/Y4w5FXBgXToaybi0ZbomhkqgwON1PlA1QbH4q1ZEcgHsf+vs5SO1qdJ+PnR5SIlINFZS+KMx5q/24rBsSz9jTAvwGnAJ4deWM4ArROQI8CRwnog8Rvi1AwBjTJX9bx3wN2A14dmWSqDSPgsF+DNWoghpW6ZrYtgGFItIkYjEANcBT09wTL56GviM/fwzWNfr+5dfJyKxIlIEFANv26ed7SKyxh6V8GmPfULCft/fAXuNMXd5rArHtmSLSJr9PB64ANhHmLXFGHObMSbfGFOI9fv/L2PMp8KtHQAikigiyf3PgYuA3YRhW4wxNUCFiCy0F50P7CHUbQl1J9FkeQCXYY2OOQR8e6LjGSHGJ4BqwIn1F8A6IBOrw/CA/W+Gx/bftttTiscIBGAV1n+UQ8CvGdKxFYJ2nIl1Gvs+sNN+XBambVkKvGu3ZTdwh7087NriEce5HO98Drt2YF2Xf89+lPT/fw7HttgxLAe2279jTwHpoW6LlsRQSik1yHS9lKSUUmoEmhiUUkoNoolBKaXUIJoYlFJKDaKJQSml1CCaGJTyYFe2vMnj9SwR+fM4vddVInLHCOs67H+zReT58Xh/pUaiiUGpwdKAgcRgjKkyxlwzTu/1TeDe0TYwxtQD1SJyxjjFoNQwmhiUGuzHwDy7rv9PRaRQ7PkwROSzIvKUiPxDRMpE5EsicrNd7OxNEcmwt5snIs/bBd02iciioW8iIguAHmNMg/26SES2isg2EfmvIZs/BXxyXFutlAdNDEoNditwyBiz3BjzDS/rlwCfwKrF8wOg01jFzrZilR0Aa4L2/2eMWQl8He9nBWdglezudzdW4bQPADVDtt0OnBVge5TyW9REB6BUmHnVGNOOVYemFfiHvXwXsNSuIHs68CePCbNivRwnF6u8cr8zgI/az/8A/LfHujpgVnDCV2psmhiU8k+Px3O3x2s31v+nCKDFWGW5R9MFpA5ZNlJ9mjh7e6VCQi8lKTVYO9b0owEx1jwTZSJyLViVZUVkmZdN9wLzPV5vxqpyCsP7ExZgFUNTKiQ0MSjlwRjTCGwWkd0i8tMAD/NJYJ2I9Ff7vNLLNhuBUz0maP9PrAlmtjH8TOKDwLMBxqKU37S6qlITRETuBv5hjHl5jO02AlcaY5pDE5ma7vSMQamJ80MgYbQNRCQbuEuTggolPWNQSik1iJ4xKKWUGkQTg1JKqUE0MSillBpEE4NSSqlBNDEopZQa5P8DTPV73PxQkggAAAAASUVORK5CYII=\n", + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYYAAAElCAYAAADgCEWlAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8QVMy6AAAACXBIWXMAAAsTAAALEwEAmpwYAAAkRElEQVR4nO3de7hcVX3/8feHJMgtJUJShFxIhACiDyAeuRRFvCABL7GiFYpQaTClStWq5WL9YUQtWlurPoKYUkS8QBURoo3EWxGqogkVMAGCgQA5TYDDJRK5J/n+/ljrkD2TmZNzJnP2nD3n83qeec6+7+/aM2e+s9fae21FBGZmZv226XQAZmY2sjgxmJlZDScGMzOr4cRgZmY1nBjMzKyGE4OZmdVwYrCGJM2T9I08PE3SHyWN6XRcA5H0SknLOx0HbDmWMo+ppOsknZaHT5L0o8K8IyT9PsfyFkm7Sbpe0jpJ/zrcsdnI5MTQpSTdI+l1ddPeJel/hrqtiLgvInaKiA3ti3BoJIWkvQdaJiJuiIh9y4ppIPWx1L8fnTqmEfHNiHh9YdJ5wJdyLFcDc4GHgD+JiA+VGZuNHE4M1hUkje10DBW1J7Csbvy2aOHOV78H3cOJYRSTtIek70rqk7RS0vuaLDc9/2IfW1hvgaRHJK2Q9O7CsmMkfUTSXbk64iZJU/O8/ST9OK+3XNJfFNa7VNIFkv4rr/drSXvledfnxW7JVR7vkHSUpF5JZ0m6H/hq/7TCNqdKuiqX72FJX2pSvnmSrpT0n3nf/yvpwML8F+XqmLWSlkl6c2HecZJuy+v9n6QP5+nPxSLp68A04Ps5/jOHeEznSfq2pMvyfpZJ6hngfT1a0h2S/pDLrMK8584aJd0FvLAQ1+XAXwFn5vHXSdpG0tn5/Xw4x7FL3edijqT7gJ/l6X8t6XZJj0paJGnPwv5D0um5+urR/J4X43t3XnddPq4HF45Pw8+qpEMkLZH0mKQHJH2u2bGxQYoIv7rwBdwDvK5u2ruA/8nD2wA3AecC25K+IO4Gjsnz5wHfyMPTgQDG5vGfAxcC2wEHAX3Aa/O8fwB+B+xL+kI6ENgV2BFYBZwKjAUOJlVZvDivdynwCHBInv9N4IpC7AHsXRg/ClgPfAZ4HrB9ntab548BbgH+Le97O+AVTY7VPOBZ4G3AOODDwMo8PA5YAXwkH6fXAOuAffO6a4BX5uHnAwcX4utt9n4M8ZjOA54CjsvlOh+4sUlZJgKPFcry9/k4nVb/GWgS16XAJwvjHwBuBKbk4/wV4PK6MlyWj/H2wFvy8XpRfh8/Cvyy7n38ATCBlCz7gFl53tuB/wNeTvrs7E06g9nSZ/VXwMl5eCfgsE7//1X91fEA/BqmNzb9w/8RWFt4PcGmxHAocF/dOucAX83D82iQGICpwAZgfGG984FL8/ByYHaDeN4B3FA37SvAx/LwpcDFhXnHAXcUxhslhmeA7eqm9SeGw/OXzthBHKt5FL5o8xfRGuCV+XU/sE1h/uXAvDx8H/A3pDp5GsVSeD8aJoZBHNN5wE8K8/YHnmxSllPqyiKgl9YTw+3kBJXHdycl0bGFMrywMP+HwJy6Y/kEsGfhfXxFYf63gbPz8CLg/Q3KtKXP6vXAx4GJnf6/65aXq5K621siYkL/C3hPYd6ewB65emStpLWkX8W7bWGbewCPRMS6wrR7gcl5eCpwV4P19gQOrdvfScALCsvcXxh+gvTrbyB9EfFUk3lTgXsjYv0WttFvVf9ARGwkfZnukV+r8rR+xfIeT0pi90r6uaTDB7m/oi0dU9j82GynxnX6e9SVJYrjLdgT+F7hPbudlMSKn5NVdct/obD8I6TkNFBZ+t/ngT47A31W5wD7AHdIWizpjUMupdVwY9HotQpYGREzh7jeamAXSeMLX2TTSFUA/dvdC1jaYH8/j4ijWw24gYEaSFcB0ySNHWRymNo/IGkbUtXJ6v55krYpJIdpwJ0AEbEYmC1pHHAG6Rfwc9saZKxbOqZDsaauLGoSz2CtAv46In5RP0PS9DwYdct/KiK+2eK+9moyvelnNSJ+D5yY37e3AldK2jUiHm8hBsONz6PZb4DHcuPt9kqNxi+R9PKBVoqIVcAvgfMlbSfpANIvtv4vgouBT0iaqeQASbuS6pX3kXSypHH59XJJLxpkvA+Q6paHUr41wKcl7ZhjPWKA5V8m6a35V/gHgKdJdeu/Bh4nNciOk3QU8CbgCknbKt0XsHNEPEuq2292+WnT+AdxTIfiv4AXF8ryPmrPyobqIuBT/Q3IkiZJmr2F5c+R9OK8/M6S3j7IfV0MfFjSy/JnZ++83wE/q5LeKWlSTtxr87Y6dml1N3BiGKUiXT//JlJD50pSQ/DFwM6DWP1EUv3yauB7pHaCH+d5nyP9av4R6YvyP4Dt8y/h1wMn5PXuZ1PD8WDMA76WqxL+YksLF8q3N6kdoJfUztHMNXn+o8DJwFsj4tmIeAZ4M3As6RhdCJwSEXfk9U4G7pH0GHA68M4m2z8f+GiO/8MN5g90TActIh4iNeJ+GngYmAls9mt/CL4ALAB+JGkdKVkeOsD+v0d6X6/Ix2Qp6dgNJvbvAJ8CvkVq4L8a2GUQn9VZwDJJf8zxnjBAFaMNgnLjjdmoJWkeqWG72Ze62ajiMwYzM6vhxGBmZjVclWRmZjV8xmBmZjWcGMyGkeq6uR5guee6OR8JlPqu+mSn47DOcGKwEUObnlHQ/wpJjxfGX9nCNjfrfrxu/lGSNubtr1Pq3O/UFuOv6RgPGnZzbTbi+c5nGzEi4j4K3WBICuDAiFgxzLteHRFT8l3Cs0l3zv46Im4b7AaadE9hVkk+Y7BKkPQ8Sf8i6T6lrpUvkrR9njdR0g/yzWOPSLpBqbvozbq7HmgfkVxNusltf0lvkPRbpe6cV+X7HfrjadTldH/34Gvz/g5X3cORJL1Ym7oef0DSR5qU9zBJv8xluiXfcd0/712S7s5nOCslnTTAMfu8pNX59XlJz8vz+rst/5CkByWtaXamJGmppDcVxsdJekjSQQMdT6suJwaris+QOko7iHQ382RSN8wAHyLd2TyJ1LHaR0jf8yeT7np+U6QnlP3zQDvIyeTPSV1C/47UFcYpefwNwN9Kekvdaq8idTF9DHBknjYh7+9XddsfD/wEuJbU2d3ewE8bxDGZ1LXFJ4FdSN2Afzd3R7Ej8EXg2IgYD/wZcHOTIv0jcBjpmB1I6tL8o4X5LyDdPTyZ1AXHBZKe32A7l1F7R/dxwJqIaLZfq7iuSAySLsm/euo7bmt1e5/Jv5KWShqoGwUrQa7ieTfw9xHR3wvpP5G614DUDfTupK6dn430WM2hXIe9h1KPnQ8BHyP17b88Iq6LiN9FxMaIuJXU3far6tadFxGPR8STg9jPG4H7I+JfI+KpiFgXEb9usNw7gYURsTDv+8fAEtIXMsBG4CWSto+INRGxrME2IPVee15EPBgRfaSuqU8uzH82z382IhaSumlv9GjUbwDHSfqTPH4y8PVBlNcqqisSA6kP+Vnt2JCkN5AeInMQqU+Yfyj8Q1hnTAJ2AG7Spm6Xr83TAT5LejjMj3IVy9lD3P7q3DX5LhFxUERcASDpUEn/rfTUsD+Q+kKaWLfuULq0btatdL09gbertpvpVwC75x5D35FjWaP0xLv9mmxnD1L33f3uzdP6PVzX82zDrs4jYjWpv6XjJU0g9X3USgd/VhFdkRgi4npSv+/PkbSXpGuVHi15wwD/PPX2J3UPvT7/E95Cm5KOtewh4EnS0976ny+xc0TsBJB/eX8oIl5I6mztg5Jem9fdmjs4v0XqQG5qROxM6jlUdctEk+FGmnUr3Wi5rxefpRERO0bEpwEiYlHuvnx34A7g35tsZzUpyfSbxqauxIfqa6QzmbcDv4qIVroEt4roisTQxHzg7yLiZaQ62gsHud4twLGSdpA0EXg1W9efvW2l3J3yvwP/JulPIdXDSzomD79RqYtmsanr6/5ul4faXXfReNIDdJ6SdAjwl1tYvo9UzdNsfz8AXiDpA7lheLykRj2VfgN4k6RjlLqY3i43Fk+RtJukN+e2hqdJ1T/Nupi+nNSj66T8WT43b7sVV5POpN9PanOwLtaViUHSTqRGue9Iupn0CMnd87y3FtoPiq9FABHxI2AhqX/8y0nPkx3sU8Bs+JxFqi66Uak755+wqT58Zh7/I+n9ujAirsvzttTd9UDeA5yn1N30uaTuxJuKiCdI3Ub/Iu/vsLr564CjSWc19wO/J/3wqN/OKtJlsx8hJZtVpGdpb5NfHyL98n+E1ObxnvptZJ8ktU3cSmpM/988bchyG8p3gRnAVa1sw6qja/pKUnqa1A8i4iW5TWB5ROzehu1+i/Ts44Vbuy2zKpN0LrCPuyfvfl15xhARjwErlZ8cpeTAwaybT913zcMHAAeQHjpjNmpJ2oV0Sev8Tsdiw68rEoOk/iqfffNNO3NIl+rNkXQLsIx0aj4Y44AbJN1G+id45yCfGWzWlSS9m1Sd9cN8oYd1ua6pSjIzs/boijMGMzNrn8p3/DVx4sSYPn16p8MwM6uUm2666aGImNRoXmmJQdIlpC4BHoyIlzSYfxLpkkRIlx3+bUTcsqXtTp8+nSVLlrQ1VjOzbifp3mbzyqxKupSB7yBeCbwqIg4APoGvfjAz64jSzhgi4vp8r0Gz+b8sjN4ITBn2oMzMbDMjtfF5DvDDZjMlzZW0RNKSvr6+EsMyM+t+Iy4xSHo1KTGc1WyZiJgfET0R0TNpUsO2EzMza9GIuiop32l8MekhJA93Oh4zs9FoxJwxSJpG6pzr5Ii4s9PxmJmNVmVerno5cBQwUVIv6UlZ4wAi4iJS75W7Ahem3pNZHxE9ZcVnZmZJmVclnbiF+acBp5UUjllbbIjgP+9/hL/YbRfGblP/DB+zahoxVUlmVfSN1Q/zwTtWcXGvr46z7uHEYLYVHn02dbz76PpmD1Ezqx4nBjMzq+HEYGZmNZwYzMyshhODmZnVcGIwawM/CdG6iROD2VYQvnfBuo8Tg5mZ1XBiMDOzGk4MZmZWw4nBrA3c9GzdxInBbCvIbc/WhZwYzMyshhODmZnVcGIw2wq+r826kRODWRu4qcG6iRODWRv4xMG6iROD2VbwVUnWjZwYzMyshhODmZnVcGIwM7MaTgxmZlbDicGsDXxVknUTJwazreCLkqwblZYYJF0i6UFJS5vMl6QvSloh6VZJB5cVm5mZbVLmGcOlwKwB5h8LzMyvucCXS4jJzMzqlJYYIuJ64JEBFpkNXBbJjcAESbuXE52ZmfUbSW0Mk4FVhfHePG0zkuZKWiJpSV9fXynBmZmNFiMpMTRqx2t4sUdEzI+InojomTRp0jCHZbZlvirJuslISgy9wNTC+BRgdYdiMTMbtUZSYlgAnJKvTjoM+ENErOl0UGaD4ctWrZuMLWtHki4HjgImSuoFPgaMA4iIi4CFwHHACuAJ4NSyYjMzs01KSwwRceIW5gfw3pLCMTOzJkZSVZJZZbnx2bqJE4OZmdVwYjAzsxpODGZmVsOJwczMajgxmJlZDScGszYIX5ZkXcSJwWwr+I5n60ZODGZmVsOJwczMajgxmJlZDScGs63gNmfrRk4MZmZWw4nBbCv4qiTrRk4MZmZWw4nBzMxqODGYmVkNJwYzM6vhxGDWBuELV62LODGYbQXJ1yVZ93FiMDOzGk4MZmZWw4nBzMxqODGYtYGbnq2bODGYbQU3PVu92LCBDevWdTqMrVJqYpA0S9JySSsknd1g/s6Svi/pFknLJJ1aZnxmZlvr/nnzuPPlhxDr13c6lJaVlhgkjQEuAI4F9gdOlLR/3WLvBW6LiAOBo4B/lbRtWTGaDZWrkKzeH66+BkhnDlU1dksLSJo2yG2tjYjHBph/CLAiIu7O270CmA3cVlgmgPFKF4fvBDwCVDftmtno039vS1T3Z8MWEwPwNdIX9kDVqQFcClw2wDKTgVWF8V7g0LplvgQsAFYD44F3RMTG+g1JmgvMBZg2bbB5y2z4uK3BnjMaEkNEvLp+mqQXRMT9Q9xXo/+d+iN3DHAz8BpgL+DHkm6oPxOJiPnAfICenp7qHn3rGv4Q2nO6IDG02sZwSgvr9AJTC+NTSGcGRacCV0WyAlgJ7NdaiGbDz2cKtpku6Cal1cQwW9IZkvYdwjqLgZmSZuQG5RNI1UZF9wGvBZC0G7AvcHeLMZqZdc4oPGN4K7AC+HNJFw9mhYhYD5wBLAJuB74dEcsknS7p9LzYJ4A/k/Q74KfAWRHxUIsxmpmVL58xVDgvDKrxeTMR8QBwbX4NZb2FwMK6aRcVhlcDr28lJjOzkUD0tzlVNzO0dMYg6QJJl+Zhf5GbmfUbxY3Pz7Cp7v81bYrFrLKq+xVgbTeKE8MTwM6SxgG+kcBGrf5//Qp/B1i7jeKrkh4B7iJ1cfGL9oVjVi33Pfk0AFc+8EiHI7ERp8K/FoaUGCRNkPRV4Pg86TKgp+1RmVVE/235Y7vgV6K1yWirSoqItcCngY8DvwZmAle1Pyyzalif//mdGKzfhLe9DYBtxo/vcCSta+Vy1TnAyohYBNzU5njMKqU/MYxxYrBsmx12yAPVfdxNK5E/Cpwu6fOSTpX00nYHZVYVr3p++lV42pSJHY7ERowKVyH1G/IZQ0ScL+mnwJ3AQcCRwG/bHJdZJey27TgADhi/Q4cjsZFGFT6LHHJikHQeMIbUC+rNEXFdm2Myq5zqfgWYba6VM4Zzcwd3LwWOl7RXRLy7/aGZmVkntNRXEvA3wFciYkh9JZmZ2cjXamK4BPhbSTsC34yIm9sXkplZhXVB43Or11O9j5RUxgJfbF84ZmbWaa0mhruA7YBrIuLINsZjZmYd1mpiWAb8DJgjaXEb4zEzsw5rtY1hH6APmE+64c3MzLpEq2cM+5FuavswMLd94ZiZWae1mhgmAGcBZwJPtS0aM7PKq/5VSa1WJZ0H7BcRyyVt3OLSZmajSYW7w4BBnjFIGiNpjaTTACKiNyJ+kofPHs4AzcysXINKDBGxAVgK7DW84ZiZWacNpSppB+BMSUcDq/O0iIjZ7Q/LzMw6ZSiJ4fD89+D8gm5oZTHbCv4HsHrRBV1iDCUxzBi2KMwqrtpNjdZ2o6HxGSAi7m30GsrOJM2StFzSCkkNG60lHSXpZknLJP18KNs3M7Ot1+rlqkMmaQxwAXA00AsslrQgIm4rLDMBuBCYFRH3SfrTsuIzM7OkzKdVHwKsiIi7I+IZ4AqgvuH6L4GrIuI+gIh4sMT4zMyMFhKDpDe1uK/JwKrCeG+eVrQP8HxJ10m6SdIpTWKYK2mJpCV9fX0thmNmNgy6oPG5lTOGT7W4r0atMfVHcCzwMuANwDHA/5O0z2YrRcyPiJ6I6Jk0aVKL4ZiZDZOKNz630sbQaol7gamF8Slsuh+iuMxDEfE48Lik64EDgTtb3KeZmQ1RK2cMrZ4nLQZmSpohaVvgBGBB3TLXAK+UNFbSDsChwO0t7s/MzFpQ2lVJEbFe0hnAImAMcElELJN0ep5/UUTcLula4FZgI3BxRCwtK0YzMysxMQBExEJgYd20i+rGPwt8tsy4zMzapvptzy1VJT3Q9ijMzGzEGHJiiIijhyMQM7OuUfGrksq8wc3MzCrAicHMzGq0lBgkfbAwvG/7wjGrlrLbGVetW8VBlx3E3WvvLnnPNpoMKTFImiDpq8DbJb1H0isAP9rTRr2yapQX3bOIDbGBa+66pqQ92pB1QZcYQ7pcNSLWAqdKegNwP/B64KphiMvMBhDdcE1kNxuljc+vIl22ehipG20zK4H6z02cF2wYtZoYJgBnAWcCT7UtGjMbkPIvUZ8x2HBq9c7n84D9ImK5pI3tDMjMmus/Y+iG5wrbyNVSYoiIXlJPqESEG5/NSvJcYvAZw8jVBUm71ctVL5B0aR5+fVsjMrOmVPFGzdGi6u9Sq20MzwD9F1K/pk2xmNkg+YzBhlOrieEJYGdJ44BpbYzHzAbBbQw2nFptfH4EeBK4APhF+8Ixs4Go8pUUVgWt3vl8fJ50GdDT9qjMrKFtlP5lXZU0klX/vRnync+SPg1MBx4CDsB3PpuVpr/xeWP4KnEbPq1UJc0BVkbEIuCmNsdjZlZ9Fb96rJXE8Chweu5V9Rbg5oj4bXvDMjOzThlyYoiI8yX9FLgTOAg4EnBisFGpU3X9boS24TTkxCDpPGAMcDPpbOG6NsdkVjll33jmxmcbTq088/lc4Om87vGS/r3tUZmZVVUX3GPS6g1ulwAvAnYFLmxfOGZmXaDijc+tJob3kaqhxgJfaF84ZmbWaa0mhruA7YBrIuLINsZjZoPgLjFsOLWaGJYBPwPmSFo82JUkzZK0XNIKSU2765b0ckkbJL2txfjMzKxFrfaVtBfpfob5+e8WSRpD6lvpaNKzHBZLWhARtzVY7jPAohZjM+t67n575OqGs7lWzxhWRcQCYAVw+yDXOQRYERF3R8QzwBXA7AbL/R3wXeDBFmMz63rd8OXT1SqeuFtNDLMkTQEuAv5tkOtMBlYVxnvztOdImgz8ed5uU5LmSloiaUlfX9/gozarON/YZmVoNTFMAM4CziTd0zAYjT7R9T97Pg+cFREbBtpQRMyPiJ6I6Jk0adIgd29mZoPRahvDecB+EbFc0oBf4gW9wNTC+BRgdd0yPcAVuf50InCcpPURcXWLcZqZ2RAN6oxB0hhJaySdBhARvRHxkzzc9OqiOouBmZJmSNoWOAFYUFwgImZExPSImA5cCbzHScFsc+4SYwTrgrdmUGcMEbFB0lLS1UgtiYj1ks4gXW00BrgkIpZJOj3PH7BdwczMyjGUqqQdgDMlHc2mKqCIiEZXFjUUEQuBhXXTGiaEiHjXEGIzG1XcCD3CVfyqpKEkhsPz34PzC7ripMmsdZ26atRVSTachpIYZgxbFGY2KL6xzcqwxcQgaVoebPgTpTB/bUQ81q7AzKrEX9f2nC64+XAwZwxfIyWFgT77AVwKXNaGmMzMrIO2mBgi4tVlBGJm1jUqXuXX6p3PZmbWpZwYzMyshhODmZnVcGIwM2unLrgqyYnBrEJ8x3M1VP1dcmIwM7MaTgxmFeQnuNlwcmIwq5D+PpKe3fhshyOxbubEYFYhjz71KADfW/G9DkdiTXXB2ZwTg1mFuFdVK4MTg9lW8Ne0NeQuMcysLG50tjI4MZi1Qdm/D30/gw0nJwazCnEbQxVU/z1yYjCrkP6qJD/JzYaTE4NZBbkqaYSreOJ2YjCrICcGG05ODGZmVsOJwaxC3PhsZXBiMKuQ5+5jcE3SiNUN95qUmhgkzZK0XNIKSWc3mH+SpFvz65eSDiwzPrORrv+MwW0MI5wbnwdH0hjgAuBYYH/gREn71y22EnhVRBwAfAKYX1Z8ZlXixGDDqcwzhkOAFRFxd0Q8A1wBzC4uEBG/jIhH8+iNwJQS4zMb8dzGYGUoMzFMBlYVxnvztGbmAD9sNEPSXElLJC3p6+trY4hmI1x/E0PFqypsZCszMTT6JDf8+SPp1aTEcFaj+RExPyJ6IqJn0qRJbQzRbGQbu81YAHYct2OHI7GmuuCkrszE0AtMLYxPAVbXLyTpAOBiYHZEPFxSbGYtKfs7oGe3HgDmHT6v5D3bkFT8jK7MxLAYmClphqRtgROABcUFJE0DrgJOjog7S4zNrBry982E7SZ0NAzrbmPL2lFErJd0BrAIGANcEhHLJJ2e518EnAvsClyY61DXR0RPWTGataravw/NapWWGAAiYiGwsG7aRYXh04DTyozJrFK6oP7aRj7f+WxWQb6PYQTznc9mZtZtnBjMzNrNVyWZmVk3cWIwM7MaTgxmZu3kxmczK5M70bMyODGYmbVZtZuenRjMzKyOE4OZmdVwYjAzsxpODGZm7eSrksxGt+p/Bdiw8J3PZlbWZSi+XNXK4MRgVkF+5rMNJycGMzOr4cRgZtZW1a/uc2IwM7MaTgxmZu1W8TYgJwYzM6vhxGBWIdEFN0/ZyOfEYFZBqnz/nd2rG5K3E4OZmdVwYjAzazc3PpuZWTcpNTFImiVpuaQVks5uMF+Svpjn3yrp4DLjMzOzEhODpDHABcCxwP7AiZL2r1vsWGBmfs0FvlxWfGZmlqisFnRJhwPzIuKYPH4OQEScX1jmK8B1EXF5Hl8OHBURa5ptt6enJ5YsWTLkeD56wcdZuG/PkNczMxspDu1bzpdP/GBL60q6KSIafgmO3aqohmYysKow3gscOohlJgM1iUHSXNIZBdOmTWspmHHPPMsLnn2opXXNzEaCHZ98eli2W2ZiaNRMX3+6MphliIj5wHxIZwytBPOxv/9kK6uZmXW9Mhufe4GphfEpwOoWljEzs2FUZmJYDMyUNEPStsAJwIK6ZRYAp+Srkw4D/jBQ+4KZmbVfaVVJEbFe0hnAImAMcElELJN0ep5/EbAQOA5YATwBnFpWfGZmlpTZxkBELCR9+RenXVQYDuC9ZcZkZma1fOezmZnVcGIwM7MaTgxmZlbDicHMzGqU1iXGcJHUB9zb4uoTgW65/dllGZm6pSzdUg5wWfrtGRGTGs2ofGLYGpKWNOsrpGpclpGpW8rSLeUAl2UwXJVkZmY1nBjMzKzGaE8M8zsdQBu5LCNTt5SlW8oBLssWjeo2BjMz29xoP2MwM7M6TgxmZlZj1CYGSbMkLZe0QtLZnY6nEUmXSHpQ0tLCtF0k/VjS7/Pf5xfmnZPLs1zSMYXpL5P0uzzvi5IaPRBpOMsxVdJ/S7pd0jJJ769wWbaT9BtJt+SyfLyqZckxjJH0W0k/qHg57skx3CxpScXLMkHSlZLuyP8zh5delogYdS9St993AS8EtgVuAfbvdFwN4jwSOBhYWpj2z8DZefhs4DN5eP9cjucBM3L5xuR5vwEOJz0h74fAsSWXY3fg4Dw8Hrgzx1vFsgjYKQ+PA34NHFbFsuQYPgh8C/hBVT9fOYZ7gIl106palq8Bp+XhbYEJZZel1AKPlFc+WIsK4+cA53Q6riaxTqc2MSwHds/DuwPLG5WB9NyLw/MydxSmnwh8pcNlugY4uuplAXYA/pf07PLKlYX0hMSfAq9hU2KoXDnyfu9h88RQubIAfwKsJF8Y1KmyjNaqpMnAqsJ4b55WBbtFfqpd/vuneXqzMk3Ow/XTO0LSdOClpF/alSxLrn65GXgQ+HFEVLUsnwfOBDYWplWxHJCeDf8jSTdJmpunVbEsLwT6gK/mKr6LJe1IyWUZrYmhUV1b1a/bbVamEVNWSTsB3wU+EBGPDbRog2kjpiwRsSEiDiL94j5E0ksGWHxElkXSG4EHI+Kmwa7SYFrHy1FwREQcDBwLvFfSkQMsO5LLMpZUffzliHgp8Dip6qiZYSnLaE0MvcDUwvgUYHWHYhmqByTtDpD/PpinNytTbx6un14qSeNISeGbEXFVnlzJsvSLiLXAdcAsqleWI4A3S7oHuAJ4jaRvUL1yABARq/PfB4HvAYdQzbL0Ar35LBTgSlKiKLUsozUxLAZmSpohaVvgBGBBh2MarAXAX+XhvyLV1/dPP0HS8yTNAGYCv8mnneskHZavSjilsE4p8n7/A7g9Ij5XmFXFskySNCEPbw+8DriDipUlIs6JiCkRMZ30+f9ZRLyzauUAkLSjpPH9w8DrgaVUsCwRcT+wStK+edJrgdsouyxlNxKNlBdwHOnqmLuAf+x0PE1ivBxYAzxL+gUwB9iV1GD4+/x3l8Ly/5jLs5zCFQhAD+kf5S7gS9Q1bJVQjleQTmNvBW7Or+MqWpYDgN/msiwFzs3TK1eWQhxHsanxuXLlINXL35Jfy/r/n6tYlhzDQcCS/Bm7Gnh+2WVxlxhmZlZjtFYlmZlZE04MZmZWw4nBzMxqODGYmVkNJwYzM6vhxGBWkHu2fE9hfA9JVw7Tvt4i6dwm8/6Y/06SdO1w7N+sGScGs1oTgOcSQ0Ssjoi3DdO+zgQuHGiBiOgD1kg6YphiMNuME4NZrU8De+V+/T8rabry8zAkvUvS1ZK+L2mlpDMkfTB3dnajpF3ycntJujZ36HaDpP3qdyJpH+DpiHgoj8+Q9CtJiyV9om7xq4GThrXUZgVODGa1zgbuioiDIuIfGsx/CfCXpL54PgU8Eamzs1+Ruh2A9ID2v4uIlwEfpvFZwRGkLrv7fYHUcdrLgfvrll0CvLLF8pgN2dhOB2BWMf8dEetI/dD8Afh+nv474IDcg+yfAd8pPDDreQ22szupe+V+RwDH5+GvA58pzHsQ2KM94ZttmROD2dA8XRjeWBjfSPp/2gZYG6lb7oE8CexcN61Z/zTb5eXNSuGqJLNa60iPH21JpOdMrJT0dkg9y0o6sMGitwN7F8Z/QerlFDZvT9iH1BmaWSmcGMwKIuJh4BeSlkr6bIubOQmYI6m/t8/ZDZa5Hnhp4QHt7yc9YGYxm59JvBr4rxZjMRsy965q1iGSvgB8PyJ+soXlrgdmR8Sj5URmo53PGMw655+AHQZaQNIk4HNOClYmnzGYmVkNnzGYmVkNJwYzM6vhxGBmZjWcGMzMrIYTg5mZ1fj/dC7Cvm5A4wEAAAAASUVORK5CYII=\n", "text/plain": [ "
" ] @@ -176,7 +186,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 11, "metadata": {}, "outputs": [ { @@ -188,7 +198,7 @@ }, { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ "
" ] @@ -219,9 +229,9 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3", + "display_name": "swiftestOOF", "language": "python", - "name": "python3" + "name": "swiftestoof" }, "language_info": { "codemirror_mode": { @@ -233,7 +243,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.8.6" + "version": "3.7.10" } }, "nbformat": 4, diff --git a/examples/whm_gr_test/cb.swiftest.in b/examples/whm_gr_test/cb.swiftest.in index 46a8d0257..e4a010b1e 100644 --- a/examples/whm_gr_test/cb.swiftest.in +++ b/examples/whm_gr_test/cb.swiftest.in @@ -1,4 +1,5 @@ -1.0 +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 old mode 100644 new mode 100755 index 7904eb100..57b0fb534 --- a/examples/whm_gr_test/init_cond.py +++ b/examples/whm_gr_test/init_cond.py @@ -1,226 +1,51 @@ -import numpy as np -import sys -from astroquery.jplhorizons import Horizons -import astropy.constants as const - -#Values from JPL Horizons -AU2M = const.au.value -GMSunSI = const.GM_sun.value -Rsun = const.R_sun.value -GC = const.G.value -JD = 86400 -year = 365.25 * JD -c = 299792458.0 -MSun_over_Mpl = [6023600.0, - 408523.71, - 328900.56, - 3098708., - 1047.3486, - 3497.898, - 22902.98, - 19412.24, - 1.35e8] - -MU2KG = GMSunSI / GC #Conversion from mass unit to kg -DU2M = AU2M #Conversion from radius unit to centimeters -TU2S = year #Conversion from time unit to seconds -GU = GC / (DU2M**3 / (MU2KG * TU2S**2)) - -GMSun = GMSunSI / (DU2M**3 / TU2S**2) - -t_print = 10.e0 * year / TU2S #output interval to print results -deltaT = 0.25 * JD / TU2S #timestep simulation -end_sim = 1.0e3 * year / TU2S + t_print #end time - -# Solar oblatenes values: From Mecheri et al. (2004), using Corbard (b) 2002 values (Table II) -J2 = 2.198e-7 * (Rsun / DU2M)**2 -J4 = -4.805e-9 * (Rsun / DU2M)**4 - -tstart = '2021-01-28' -tend = '2021-01-29' -tstep = '1d' -planetid = { - 'mercury' : '1', - 'venus' : '2', - 'earthmoon' : '3', - 'mars' : '4', - 'jupiter' : '5', - 'saturn' : '6', - 'uranus' : '7', - 'neptune' : '8', - 'plutocharon' : '9' +#!/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'] = 100.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, } -npl = 9 - -#Planet Msun/M ratio -MSun_over_Mpl = { - 'mercury' : 6023600.0, - 'venus' : 408523.71, - 'earthmoon' : 328900.56, - 'mars' : 3098708., - 'jupiter' : 1047.3486, - 'saturn' : 3497.898, - 'uranus' : 22902.98, - 'neptune' : 19412.24, - 'plutocharon' : 1.35e8 -} - -#Planet radii in meters -Rpl = { - 'mercury' : 2439.4e3, - 'venus' : 6051.8e3, - 'earthmoon' : 6371.0084e3, # Earth only for radius - 'mars' : 3389.50e3, - 'jupiter' : 69911e3, - 'saturn' : 58232.0e3, - 'uranus' : 25362.e3, - 'neptune' : 24622.e3, - 'plutocharon' : 1188.3e3 -} - -pdata = {} -plvec = {} -Rhill = {} - -for key,val in planetid.items(): - pdata[key] = Horizons(id=val, id_type='majorbody',location='@sun', - epochs={'start': tstart, 'stop': tend, - 'step': tstep}) - plvec[key] = np.array([pdata[key].vectors()['x'][0], - pdata[key].vectors()['y'][0], - pdata[key].vectors()['z'][0], - pdata[key].vectors()['vx'][0], - pdata[key].vectors()['vy'][0], - pdata[key].vectors()['vz'][0] - ]) - Rhill[key] = pdata[key].elements()['a'][0] * (3 * MSun_over_Mpl[key])**(-1.0 / 3.0) - - -if __name__ == '__main__': - # Convert from AU-day to AU-year just because I find it easier to keep track of the sim progress - for plid in plvec: - plvec[plid][3:] *= year / JD - - # Names of all output files - 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" - - # Simulation start, stop, and output cadence times - t_0 = 0 # simulation start time - end_sim = 1000.0e0 * year / TU2S # simulation end time - deltaT = 0.25 * JD / TU2S # simulation step size - t_print = 1.0 * year / TU2S #output interval to print results - - iout = int(np.ceil(t_print / deltaT)) - rmin = Rsun / DU2M - rmax = 1000.0 - - #Make Swifter files - plfile = open(swifter_pl, 'w') - print(f'{npl+1} ! Planet input file generated using init_cond.py using JPL Horizons data for the major planets (and Pluto) for epoch {tstart}' ,file=plfile) - print(f'1 {GMSun}',file=plfile) - print(f'0.0 0.0 0.0',file=plfile) - print(f'0.0 0.0 0.0',file=plfile) - for i, plid in enumerate(plvec): - print(f'{i + 2} {GMSun / MSun_over_Mpl[plid]} {Rhill[plid]}', file=plfile) - print(f'{Rpl[plid] / DU2M}', file=plfile) - print(f'{plvec[plid][0]} {plvec[plid][1]} {plvec[plid][2]}', file=plfile) - print(f'{plvec[plid][3]} {plvec[plid][4]} {plvec[plid][5]}', 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 EL') - print(f'OUT_STAT NEW') - 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') - print(f'C {c / (DU2M / TU2S)}') - - #Now make Swiftest files - cbfile = open(swiftest_cb, 'w') - print(f'{1.0}',file=cbfile) - print(f'{rmin}',file=cbfile) - print(f'{J2}',file=cbfile) - print(f'{J4}',file=cbfile) - - plfile = open(swiftest_pl, 'w') - print(npl,file=plfile) - - for i, plid in enumerate(plvec): - print(f'{i + 2} {1.0 / MSun_over_Mpl[plid]}', file=plfile) - print(f'{Rpl[plid] / DU2M}', file=plfile) - print(f'{plvec[plid][0]} {plvec[plid][1]} {plvec[plid][2]}', file=plfile) - print(f'{plvec[plid][3]} {plvec[plid][4]} {plvec[plid][5]}', file=plfile) - plfile.close() - tpfile = open(swiftest_tp, 'w') - print(0,file=tpfile) - 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 ASCII') - 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 EL') - 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 yes') - print(f'MU2KG {MU2KG}') - print(f'DU2M {DU2M}') - print(f'TU2S {TU2S}') +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") - sys.stdout = sys.__stdout__ diff --git a/examples/whm_gr_test/param.swifter.in b/examples/whm_gr_test/param.swifter.in index 0582bd1f7..6addd694c 100644 --- a/examples/whm_gr_test/param.swifter.in +++ b/examples/whm_gr_test/param.swifter.in @@ -1,27 +1,27 @@ -! Swifter input file generated using init_cond.py -T0 0 -TSTOP 1000.0 -DT 0.0006844626967830253 -PL_IN pl.swifter.in -TP_IN tp.swifter.in -IN_TYPE ASCII -ISTEP_OUT 1461 -ISTEP_DUMP 1461 -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 -C 63241.07708426628 +! VERSION Swifter parameter file converted from Swiftest +T0 0.0 +TSTOP 100.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 index b0d8ac31c..c9b7462f0 100644 --- a/examples/whm_gr_test/param.swiftest.in +++ b/examples/whm_gr_test/param.swiftest.in @@ -1,29 +1,35 @@ -! Swiftest input file generated using init_cond.py -T0 0 -TSTOP 1000.0 -DT 0.0006844626967830253 -CB_IN cb.swiftest.in -PL_IN pl.swiftest.in -TP_IN tp.swiftest.in -IN_TYPE ASCII -ISTEP_OUT 1461 -ISTEP_DUMP 1461 -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 yes -MU2KG 1.988409870698051e+30 -DU2M 149597870700.0 -TU2S 31557600.0 +! VERSION Swiftest parameter input +T0 0.0 +TSTOP 100.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 index 60d090453..e0ef4e881 100644 --- a/examples/whm_gr_test/pl.swifter.in +++ b/examples/whm_gr_test/pl.swifter.in @@ -1,40 +1,36 @@ -10 ! Planet input file generated using init_cond.py using JPL Horizons data for the major planets (and Pluto) for epoch 2021-01-28 -1 39.476926408897626 +9 +0 39.476926408897625196 0.0 0.0 0.0 0.0 0.0 0.0 -2 6.553709809565314e-06 0.001475122968086379 -1.6306381826061646e-05 -0.1030256860922895 0.2897796047098886 0.01422904600374035 --11.74004209950937 3.8343124110162736 1.3902496665973592 -3 9.663313399581537e-05 0.006759127649782299 -4.0453784346544176e-05 -0.06110218027254217 -0.7245466901305982 -0.01346904300924688 -7.311995449678243 0.5941125721336201 -0.4137913843379075 -4 0.00012002693582795245 0.010044756567546644 -4.25875607065041e-05 --0.6061796342297583 0.7761214554702035 -3.4750047790977e-05 --5.054824314301841 -3.891667468503358 0.00019720338148272726 -5 1.2739802010675942e-05 0.0072464490746299084 -2.2657408050928896e-05 -0.2751944175855944 1.51937688993241 0.02508924593104206 --4.835983593209577 1.344855094041679 0.14681413000004515 -6 0.037692251088985676 0.3552852357486061 -0.0004673261703049093 -3.200135438345358 -3.953498213518368 -0.05517737289975112 -2.111393749129838 1.8660266890185446 -0.05498941067210089 -7 0.011285899820091273 0.4376306456694341 -0.00038925687730393614 -5.607382165725712 -8.258649105608766 -0.07958445228024298 -1.5748468603228847 1.1414574661825514 -0.08250331331320372 -8 0.001723658947826773 0.4690969274244374 -0.00016953449859497232 -15.28225422201768 12.53905314208462 -0.1514143582550325 --0.9198472198098231 1.0454390993472462 0.01574538863031621 -9 0.0020336100526728304 0.7807192056765467 -0.00016458790412449367 -29.47483071169769 -5.147686530859088 -0.5733441819169969 -0.19191677740340274 1.1385110364087574 -0.027844325148353527 -10 2.924216771029454e-07 0.0538346817277698 -7.943294877391593e-06 -14.14000920780611 -31.14141812522779 -0.7565722591093476 -1.073396108697069 0.23003123192799815 -0.33424529561177047 +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/whm_gr_test/pl.swiftest.in b/examples/whm_gr_test/pl.swiftest.in index 032262e70..9d49cc3da 100644 --- a/examples/whm_gr_test/pl.swiftest.in +++ b/examples/whm_gr_test/pl.swiftest.in @@ -1,37 +1,33 @@ -9 -2 1.6601367952719304e-07 -1.6306381826061646e-05 -0.1030256860922895 0.2897796047098886 0.01422904600374035 --11.74004209950937 3.8343124110162736 1.3902496665973592 -3 2.4478383396645447e-06 -4.0453784346544176e-05 -0.06110218027254217 -0.7245466901305982 -0.01346904300924688 -7.311995449678243 0.5941125721336201 -0.4137913843379075 -4 3.0404326462685257e-06 -4.25875607065041e-05 --0.6061796342297583 0.7761214554702035 -3.4750047790977e-05 --5.054824314301841 -3.891667468503358 0.00019720338148272726 -5 3.2271514450538743e-07 -2.2657408050928896e-05 -0.2751944175855944 1.51937688993241 0.02508924593104206 --4.835983593209577 1.344855094041679 0.14681413000004515 -6 0.0009547919384243222 -0.0004673261703049093 -3.200135438345358 -3.953498213518368 -0.05517737289975112 -2.111393749129838 1.8660266890185446 -0.05498941067210089 -7 0.0002858859806661029 -0.00038925687730393614 -5.607382165725712 -8.258649105608766 -0.07958445228024298 -1.5748468603228847 1.1414574661825514 -0.08250331331320372 -8 4.3662440433515637e-05 -0.00016953449859497232 -15.28225422201768 12.53905314208462 -0.1514143582550325 --0.9198472198098231 1.0454390993472462 0.01574538863031621 -9 5.151389020535497e-05 -0.00016458790412449367 -29.47483071169769 -5.147686530859088 -0.5733441819169969 -0.19191677740340274 1.1385110364087574 -0.027844325148353527 -10 7.407407407407407e-09 -7.943294877391593e-06 -14.14000920780611 -31.14141812522779 -0.7565722591093476 -1.073396108697069 0.23003123192799815 -0.33424529561177047 +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/whm_gr_test/swiftest_relativity.ipynb b/examples/whm_gr_test/swiftest_relativity.ipynb index 0f753993c..0d8111fea 100644 --- a/examples/whm_gr_test/swiftest_relativity.ipynb +++ b/examples/whm_gr_test/swiftest_relativity.ipynb @@ -8,52 +8,59 @@ "source": [ "import numpy as np\n", "import matplotlib.pyplot as plt\n", - "import pandas as pd\n", - "import swiftestio as swio\n", + "import swiftest\n", "from astroquery.jplhorizons import Horizons" ] }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Reading Swifter file param.swifter.in\n" + "Reading Swifter file param.swifter.in\n", + "Reading in time 1.000e+02\n", + "Creating Dataset\n", + "Successfully converted 101 output frames.\n", + "Swifter simulation data stored as xarray DataSet .ds\n" ] } ], "source": [ - "inparfile = 'param.swifter.in'\n", - "paramgr = swio.read_swifter_param(inparfile)\n", - "swifterdat = swio.swifter2xr(paramgr)" + "swiftersim = swiftest.Simulation(param_file=\"param.swifter.in\", codename=\"Swifter\")\n", + "swiftersim.bin2xr()\n", + "swifterdat = swiftersim.ds" ] }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Reading Swiftest file param.swiftest.in\n" + "Reading Swiftest file param.swiftest.in\n", + "Reading in time 1.000e+02\n", + "Creating Dataset\n", + "Successfully converted 101 output frames.\n", + "Swiftest simulation data stored as xarray DataSet .ds\n" ] } ], "source": [ - "param_file_name = 'param.swiftest.in'\n", - "config = swio.read_swiftest_config(param_file_name)\n", - "swiftestdat = swio.swiftest2xr(config)" + "swiftestsim = swiftest.Simulation(param_file=\"param.swiftest.in\")\n", + "swiftestsim.bin2xr()\n", + "swiftestdat = swiftestsim.ds" ] }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 4, "metadata": {}, "outputs": [], "source": [ @@ -63,12 +70,12 @@ }, { "cell_type": "code", - "execution_count": 32, + "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", + " epochs={'start':'2021-01-28', 'stop':'2121-02-05',\n", " 'step':'1y'})\n", "el = obj.elements()\n", "t = (el['datetime_jd']-el['datetime_jd'][0]) / 365.25\n", @@ -77,29 +84,29 @@ }, { "cell_type": "code", - "execution_count": 33, + "execution_count": 6, "metadata": {}, "outputs": [], "source": [ - "varpiswiftest = swiftestdat['varpi'].sel(id=2) * 180.0 / np.pi\n", - "varpiswifter = swifterdat['varpi'].sel(id=2) * 180.0 / np.pi\n", + "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": 39, + "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) / np.diff(t) * 3600 * 100 " + "dvarpi_obs = np.diff(varpi_obs) / np.diff(t) * 3600 * 100 " ] }, { "cell_type": "code", - "execution_count": 40, + "execution_count": 8, "metadata": {}, "outputs": [ { @@ -107,17 +114,17 @@ "output_type": "stream", "text": [ "Mean precession rate for Mercury long. peri. (arcsec/100 y)\n", - "JPL Horizons : 571.3219335838123\n", - "Swifter GR : 571.1981012667945\n", - "Swiftest GR : 571.1981012549461\n", - "Obs - Swifter : 0.12383231701787104\n", - "Obs - Swiftest : 0.12383232886631326\n", - "Swiftest - Swifter: -1.1848442227346823e-08\n" + "JPL Horizons : 573.8351991142854\n", + "Swifter GR : 579.5897815748845\n", + "Swiftest GR : 579.5897815748845\n", + "Obs - Swifter : -5.754582460598964\n", + "Obs - Swiftest : -5.754582460598964\n", + "Swiftest - Swifter: 0.0\n" ] }, { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ "
" ] @@ -146,13 +153,6 @@ "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, @@ -163,9 +163,9 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3", + "display_name": "swiftestOOF", "language": "python", - "name": "python3" + "name": "swiftestoof" }, "language_info": { "codemirror_mode": { @@ -177,7 +177,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.8.6" + "version": "3.7.10" } }, "nbformat": 4, diff --git a/python/swiftest/swiftest/io.py b/python/swiftest/swiftest/io.py index a2eef84fd..ceab9a74f 100644 --- a/python/swiftest/swiftest/io.py +++ b/python/swiftest/swiftest/io.py @@ -466,6 +466,7 @@ def swiftest_stream(f, param): npl = f.read_ints() ntp = f.read_ints() iout_form = f.read_reals('c') + cbid = f.read_ints() Mcb = f.read_reals(np.float64) Rcb = f.read_reals(np.float64) J2cb = f.read_reals(np.float64) @@ -508,7 +509,6 @@ def swiftest_stream(f, param): t4 = f.read_reals(np.float64) t5 = f.read_reals(np.float64) t6 = f.read_reals(np.float64) - cbid = np.array([0]) clab, plab, tlab = make_swiftest_labels(param) @@ -654,10 +654,12 @@ def swiftest_xr2infile(ds, param, framenum=-1): 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) @@ -686,6 +688,7 @@ def swiftest_xr2infile(ds, param, framenum=-1): elif param['IN_TYPE'] == 'REAL8': # Now make Swiftest files cbfile = FortranFile(param['CB_IN'], 'w') + cbfile.write_record(cbid) MSun = np.double(1.0) cbfile.write_record(np.double(GMSun)) cbfile.write_record(np.double(rmin)) diff --git a/src/discard/discard.f90 b/src/discard/discard.f90 index 6609ed802..f82826fac 100644 --- a/src/discard/discard.f90 +++ b/src/discard/discard.f90 @@ -88,11 +88,11 @@ subroutine discard_sun_tp(tp, system, param) 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%name(i), " too far from sun at t = ", t + write(*, *) "Particle ", tp%id(i), " too far from sun at t = ", t tp%ldiscard(i) = .true. else if ((param%rmin >= 0.0_DP) .and. (rh2 < rmin2)) then tp%status(i) = DISCARDED_RMIN - write(*, *) "Particle ", tp%name(i), " too close to sun at t = ", t + write(*, *) "Particle ", tp%id(i), " too close to sun at t = ", t tp%ldiscard(i) = .true. else if (param%rmaxu >= 0.0_DP) then rb2 = dot_product(tp%xb(:, i), tp%xb(:, i)) @@ -100,7 +100,7 @@ subroutine discard_sun_tp(tp, system, param) energy = 0.5_DP * vb2 - msys / sqrt(rb2) if ((energy > 0.0_DP) .and. (rb2 > rmaxu2)) then tp%status(i) = DISCARDED_RMAXU - write(*, *) "Particle ", tp%name(i), " is unbound and too far from barycenter at t = ", t + write(*, *) "Particle ", tp%id(i), " is unbound and too far from barycenter at t = ", t tp%ldiscard(i) = .true. end if end if @@ -129,35 +129,29 @@ subroutine discard_peri_tp(tp, system, param) real(DP) :: r2 real(DP), dimension(NDIM) :: dx - associate(cb => system%cb, ntp => tp%nbody, pl => system%pl, npl => system%pl%nbody, qmin_coord => param%qmin_coord, t => param%t, msys => system%msys) - if (lfirst) then - call util_hills(npl, pl) - call util_peri(lfirst, ntp, tp, cb%Gmass, msys, param%qmin_coord) - lfirst = .false. - else - call util_peri(lfirst, ntp, tp, cb%Gmass, msys, param%qmin_coord) - 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%name(i), " perihelion distance too small at t = ", t - tp%ldiscard(i) = .true. - end if + 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 do - end if + end if + end do end associate return @@ -191,7 +185,7 @@ subroutine discard_pl_tp(tp, system, param) if (isp /= 0) then tp%status(i) = DISCARDED_PLR pl%ldiscard(j) = .true. - write(*, *) "Particle ", tp%name(i), " too close to massive body ", pl%name(j), " at t = ", t + write(*, *) "Particle ", tp%id(i), " too close to massive body ", pl%id(j), " at t = ", t tp%ldiscard(i) = .true. exit end if diff --git a/src/gr/gr.f90 b/src/gr/gr.f90 index a778e3db2..8831a93d5 100644 --- a/src/gr/gr.f90 +++ b/src/gr/gr.f90 @@ -1,43 +1,39 @@ submodule(swiftest_classes) s_gr use swiftest contains - subroutine gr_getaccb_ns_body(self, cb, param, agr, agr0) - + module pure subroutine gr_getaccb_ns_body(self, system, param) !! author: David A. Minton !! - !! Add relativistic correction acceleration for non-symplectic integrators - !! Based on Quinn, Tremaine, & Duncan 1998 + !! 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_getaccb_ns.f90 implicit none ! Arguments - class(swiftest_body), intent(inout) :: self - class(swiftest_cb), intent(inout) :: cb - class(swiftest_parameters), intent(in) :: param - real(DP), dimension(:, :), intent(inout) :: agr - real(DP), dimension(NDIM), intent(out) :: agr0 + 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), dimension(NDIM) :: xh, vh real(DP) :: rmag, rdotv, vmag2 integer(I4B) :: i - associate(n => self%nbody, msun => cb%Gmass, vbsun => cb%vb, xbsun => cb%xb, mu => self%mu, c2 => param%inv_c2, & - xb => self%xb, vb => self%vb) + associate(n => self%nbody, cb => system%cb, inv_c2 => param%inv_c2) if (n == 0) return do i = 1, n - xh(:) = xb(:, i) - xbsun(:) - vh(:) = vb(:, i) - vbsun(:) - rmag = norm2(xh(:)) - vmag2 = dot_product(vh(:), vh(:)) - rdotv = dot_product(xh(:), vh(:)) - agr(:, i) = mu * c2 / rmag**3 * ((4 * mu(i) / rmag - vmag2) * xh(:) + 4 * rdotv * vh(:)) + 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 - agr0 = 0.0_DP select type(self) class is (swiftest_pl) do i = 1, NDIM - agr0(i) = -sum(self%Gmass(1:n) * agr(1:n, i) / msun) + cb%agr(i) = -sum(self%Gmass(1:n) * self%agr(1:n, i) / cb%Gmass) end do end select @@ -45,6 +41,187 @@ subroutine gr_getaccb_ns_body(self, cb, param, agr, agr0) return - end subroutine gr_getaccb_ns_body + end subroutine gr_getaccb_ns_body + + 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 of on 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 of on 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_drift.f90 b/src/helio/helio_drift.f90 index ce55797bf..40da379ee 100644 --- a/src/helio/helio_drift.f90 +++ b/src/helio/helio_drift.f90 @@ -47,7 +47,7 @@ module subroutine helio_drift_pl(self, system, param, dt) dtp(1:npl), iflag(1:npl)) if (any(iflag(1:npl) /= 0)) then do i = 1, npl - write(*, *) " Planet ", pl%name(i), " is lost!!!!!!!!!!" + write(*, *) " Planet ", pl%id(i), " is lost!!!!!!!!!!" write(*, *) pl%xh(:,i) write(*, *) pl%vb(:,i) write(*, *) " stopping " @@ -136,7 +136,7 @@ module subroutine helio_drift_tp(self, system, param, dt) if (any(iflag(1:ntp) /= 0)) then tp%status = DISCARDED_DRIFTERR do i = 1, ntp - if (iflag(i) /= 0) write(*, *) "Particle ", tp%name(i), " lost due to error in Danby drift" + if (iflag(i) /= 0) write(*, *) "Particle ", tp%id(i), " lost due to error in Danby drift" end do end if end associate diff --git a/src/io/io.f90 b/src/io/io.f90 index 55789417b..2bb46ae0e 100644 --- a/src/io/io.f90 +++ b/src/io/io.f90 @@ -14,12 +14,12 @@ module subroutine io_param_reader(self, unit, iotype, v_list, iostat, iomsg) 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. + 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 + 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? @@ -29,10 +29,9 @@ module subroutine io_param_reader(self, unit, iotype, v_list, iostat, iomsg) 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 - integer(I4B) :: integrator !! Symbolic name of integrator being used - integrator = v_list(1) ! Parse the file line by line, extracting tokens then matching them up with known parameters if possible + do read(unit = unit, fmt = linefmt, iostat = iostat, end = 1) line line_trim = trim(adjustl(line)) @@ -42,14 +41,10 @@ module subroutine io_param_reader(self, unit, iotype, v_list, iostat, iomsg) ! 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 util_toupper(param_name) + call io_toupper(param_name) ifirst = ilast + 1 param_value = io_get_token(line_trim, ifirst, ilast, iostat) select case (param_name) - case ("NPLMAX") - read(param_value, *) self%nplmax - case ("NTPMAX") - read(param_value, *) self%ntpmax case ("T0") read(param_value, *) self%t0 t0_set = .true. @@ -66,25 +61,25 @@ module subroutine io_param_reader(self, unit, iotype, v_list, iostat, iomsg) case ("TP_IN") self%intpfile = param_value case ("IN_TYPE") - call util_toupper(param_value) + call io_toupper(param_value) self%in_type = param_value case ("ISTEP_OUT") read(param_value, *) self%istep_out case ("BIN_OUT") self%outfile = param_value case ("OUT_TYPE") - call util_toupper(param_value) + call io_toupper(param_value) self%out_type = param_value case ("OUT_FORM") - call util_toupper(param_value) + call io_toupper(param_value) self%out_form = param_value case ("OUT_STAT") - call util_toupper(param_value) + call io_toupper(param_value) self%out_stat = param_value case ("ISTEP_DUMP") read(param_value, *) self%istep_dump case ("CHK_CLOSE") - call util_toupper(param_value) + call io_toupper(param_value) if (param_value == "YES" .or. param_value == 'T') self%lclose = .true. case ("CHK_RMIN") read(param_value, *) self%rmin @@ -95,7 +90,7 @@ module subroutine io_param_reader(self, unit, iotype, v_list, iostat, iomsg) case ("CHK_QMIN") read(param_value, *) self%qmin case ("CHK_QMIN_COORD") - call util_toupper(param_value) + call io_toupper(param_value) self%qmin_coord = param_value case ("CHK_QMIN_RANGE") read(param_value, *) self%qmin_alo @@ -105,41 +100,33 @@ module subroutine io_param_reader(self, unit, iotype, v_list, iostat, iomsg) case ("ENC_OUT") self%encounter_file = param_value case ("EXTRA_FORCE") - call util_toupper(param_value) + call io_toupper(param_value) if (param_value == "YES" .or. param_value == 'T') self%lextra_force = .true. case ("BIG_DISCARD") - call util_toupper(param_value) + call io_toupper(param_value) if (param_value == "YES" .or. param_value == 'T' ) self%lbig_discard = .true. - case ("FRAGMENTATION") - call util_toupper(param_value) - if (param_value == "YES" .or. param_value == "T") self%lfragmentation = .true. + case ("RHILL_PRESENT") + call io_toupper(param_value) + if (param_value == "YES" .or. param_value == 'T' ) self%lrhill_present = .true. case ("MU2KG") read(param_value, *) self%MU2KG case ("TU2S") read(param_value, *) self%TU2S case ("DU2M") read(param_value, *) self%DU2M - case ("MTINY") - read(param_value, *) self%mtiny - mtiny_set = .true. case ("ENERGY") - call util_toupper(param_value) + call io_toupper(param_value) if (param_value == "YES" .or. param_value == 'T') self%lenergy = .true. + case ("GR") + call io_toupper(param_value) + if (param_value == "YES" .or. param_value == 'T') self%lgr = .true. case ("ROTATION") - call util_toupper(param_value) + call io_toupper(param_value) if (param_value == "YES" .or. param_value == 'T') self%lrotation = .true. case ("TIDES") - call util_toupper(param_value) + call io_toupper(param_value) if (param_value == "YES" .or. param_value == 'T') self%ltides = .true. - case ("GR") - call util_toupper(param_value) - if (param_value == "YES" .or. param_value == 'T') self%lgr = .true. - case ("YARKOVSKY") - call util_toupper(param_value) - if (param_value == "YES" .or. param_value == 'T') self%lyarkovsky = .true. - case ("YORP") - call util_toupper(param_value) - if (param_value == "YES" .or. param_value == 'T') self%lyorp = .true. + 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 @@ -211,9 +198,12 @@ module subroutine io_param_reader(self, unit, iotype, v_list, iostat, iomsg) return end if end if + if (self%ltides .and. .not. self%lrotation) then + write(iomsg,*) 'Tides require rotation to be turned on' + iostat = -1 + return + end if - write(*,*) "NPLMAX = ",self%nplmax - write(*,*) "NTPMAX = ",self%ntpmax write(*,*) "T0 = ",self%t0 write(*,*) "TSTOP = ",self%tstop write(*,*) "DT = ",self%dt @@ -237,7 +227,10 @@ module subroutine io_param_reader(self, unit, iotype, v_list, iostat, iomsg) write(*,*) "ENC_OUT = ",trim(adjustl(self%encounter_file)) write(*,*) "EXTRA_FORCE = ",self%lextra_force write(*,*) "BIG_DISCARD = ",self%lbig_discard - if (self%lenergy) write(*,*) "ENERGY = ",self%lenergy + write(*,*) "RHILL_PRESENT = ",self%lrhill_present + write(*,*) "ROTATION = ", self%lrotation + write(*,*) "TIDES = ", self%ltides + write(*,*) "ENERGY = ",self%lenergy write(*,*) "MU2KG = ",self%MU2KG write(*,*) "TU2S = ",self%TU2S write(*,*) "DU2M = ",self%DU2M @@ -252,51 +245,26 @@ module subroutine io_param_reader(self, unit, iotype, v_list, iostat, iomsg) self%GU = GC / (self%DU2M**3 / (self%MU2KG * self%TU2S**2)) ! Calculate the inverse speed of light in the system units - self%inv_c2 = einstinC * self%TU2S / self%DU2M + self%inv_c2 = einsteinC * self%TU2S / self%DU2M self%inv_c2 = (self%inv_c2)**(-2) - ! The fragmentation model requires the user to set the unit system explicitly. - if ((integrator == SYMBA) .or. (integrator == RINGMOONS)) then - write(*,*) "FRAGMENTATION = ",self%lfragmentation - if (.not.mtiny_set) then - write(iomsg,*) 'SyMBA requres an MTINY value' - iostat = -1 - end if - else - if (self%lfragmentation) then - write(iomsg,*) 'This integrator does not support fragmentation. This parameter will be ignored.' - end if - if (mtiny_set) then - write(iomsg,*) 'This integrator does not support MTINY. This parameter will be ignored.' - return - end if - end if - - if ((integrator == SYMBA) .or. (integrator == RINGMOONS) .or. (integrator == RMVS)) then - if (.not.self%lclose) then - write(iomsg,*) 'This integrator requires CHK_CLOSE to be enabled.' - iostat = -1 - return - end if - end if - - if (mtiny_set) then - if (self%mtiny < 0.0_DP) then - write(iomsg,*) "Invalid MTINY: ", self%mtiny - iostat = -1 - return - else - write(*,*) "MTINY = ", self%mtiny + associate(integrator => v_list(1)) + if (integrator == RMVS) then + if (.not.self%lclose) then + write(iomsg,*) 'This integrator requires CHK_CLOSE to be enabled.' + iostat = -1 + return + end if end if - end if - - ! Determine if the GR flag is set correctly for this integrator - select case(integrator) - case(WHM, RMVS) - write(*,*) "GR = ", self%lgr - case default - write(iomsg, *) 'GR is implemented compatible with this integrator. This parameter will be ignored.' - end select + + ! Determine if the GR flag is set correctly for this integrator + select case(integrator) + case(WHM, RMVS) + write(*,*) "GR = ", self%lgr + case default + write(iomsg, *) 'GR is not yet implemented for this integrator. This parameter will be ignored.' + end select + end associate iostat = 0 @@ -313,83 +281,68 @@ module subroutine io_param_writer(self, unit, iotype, v_list, iostat, iomsg) 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. + 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 + 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 - !! In user-defined derived-type output, we need newline characters at the end of each format statement - !character(*),parameter :: Ifmt = '(A20,1X,I0/)' !! Format label for integer values - !character(*),parameter :: Rfmt = '(A20,1X,ES25.17/)' !! Format label for real values - !character(*),parameter :: R2fmt = '(A20,2(1X,ES25.17)/)' !! Format label for 2x real values - !character(*),parameter :: Sfmt = '(A20,1X,A/)' !! Format label for string values - !character(*),parameter :: Lfmt = '(A20,1X,L1/)' !! Format label for logical values - !character(*),parameter :: Pfmt = '(A20/)' !! Format label for single parameter string - character(*),parameter :: Ifmt = '(A20,1X,I0)' !! Format label for integer values - character(*),parameter :: Rfmt = '(A20,1X,ES25.17)' !! Format label for real values - character(*),parameter :: R2fmt = '(A20,2(1X,ES25.17))' !! Format label for 2x real values - character(*),parameter :: Sfmt = '(A20,1X,A)' !! Format label for string values - character(*),parameter :: Lfmt = '(A20,1X,L1)' !! Format label for logical values - character(*),parameter :: Pfmt = '(A20)' !! Format label for single parameter string - - write(unit, Ifmt) "NPLMAX", self%nplmax - write(unit, Ifmt) "NTPMAX", self%ntpmax - write(unit, Rfmt) "T0", self%t0 - write(unit, Rfmt) "TSTOP", self%tstop - write(unit, Rfmt) "DT", self%dt - write(unit, Sfmt) "CB_IN", trim(adjustl(self%incbfile)) - write(unit, Sfmt) "PL_IN", trim(adjustl(self%inplfile)) - write(unit, Sfmt) "TP_IN", trim(adjustl(self%intpfile)) - write(unit, Sfmt) "IN_TYPE", trim(adjustl(self%out_type)) - if (self%istep_out > 0) then - write(unit, Ifmt) "ISTEP_OUT", self%istep_out - write(unit, Sfmt) "BIN_OUT", trim(adjustl(self%outfile)) - write(unit, Sfmt) "OUT_TYPE", trim(adjustl(self%out_type)) - write(unit, Sfmt) "OUT_FORM", trim(adjustl(self%out_form)) - write(unit, Sfmt) "OUT_STAT", "APPEND" - else - write(unit, Pfmt) "!ISTEP_OUT " - write(unit, Pfmt) "!BIN_OUT" - write(unit, Pfmt) "!OUT_TYPE" - write(unit, Pfmt) "!OUT_FORM" - write(unit, Pfmt) "!OUT_STAT" - end if - write(unit, Sfmt) "ENC_OUT", trim(adjustl(self%encounter_file)) - if (self%istep_dump > 0) then - write(unit, Ifmt) "ISTEP_DUMP", self%istep_dump - else - write(unit, Pfmt) "!ISTEP_DUMP" - end if - write(unit, Rfmt) "CHK_RMIN", self%rmin - write(unit, Rfmt) "CHK_RMAX", self%rmax - write(unit, Rfmt) "CHK_EJECT", self%rmaxu - write(unit, Rfmt) "CHK_QMIN", self%qmin - if (self%qmin >= 0.0_DP) then - write(unit, Sfmt) "CHK_QMIN_COORD", trim(adjustl(self%qmin_coord)) - write(unit, R2fmt) "CHK_QMIN_RANGE", self%qmin_alo, self%qmin_ahi - else - write(unit, Pfmt) "!CHK_QMIN_COORD" - write(unit, Pfmt) "!CHK_QMIN_RANGE" - end if - if (self%lmtiny) write(unit, Rfmt) "MTINY", self%mtiny - write(unit, Rfmt) "MU2KG", self%MU2KG - write(unit, Rfmt) "TU2S", self%TU2S - write(unit, Rfmt) "DU2M", self%DU2M - - write(unit, Lfmt) "EXTRA_FORCE", self%lextra_force - write(unit, Lfmt) "BIG_DISCARD", self%lbig_discard - write(unit, Lfmt) "CHK_CLOSE", self%lclose - write(unit, Lfmt) "FRAGMENTATION", self%lfragmentation - write(unit, Lfmt) "ROTATION", self%lrotation - write(unit, Lfmt) "TIDES", self%ltides - write(unit, Lfmt) "GR", self%lgr - write(unit, Lfmt) "ENERGY", self%lenergy - !write(unit, Lfmt) "YARKOVSKY", self%lyarkovsky - !write(unit, Lfmt) "YORP", self%lyorp - iostat = 0 - iomsg = "UDIO not implemented" + 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%encounter_file)); 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) + iostat = 0 + iomsg = "UDIO not implemented" + end associate return end subroutine io_param_writer @@ -532,7 +485,7 @@ module function io_get_args(integrator, param_file_name) result(ierr) call get_command_argument(2, arg2, status = ierr_arg2) if ((ierr_arg1 == 0) .and. (ierr_arg2 == 0)) then ierr = 0 - call util_toupper(arg1) + call io_toupper(arg1) select case(arg1) case('BS') integrator = BS @@ -570,7 +523,7 @@ module function io_get_args(integrator, param_file_name) result(ierr) if (ierr /= 0) call util_exit(USAGE) end function io_get_args - function io_get_token(buffer, ifirst, ilast, ierr) result(token) + 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 @@ -658,11 +611,16 @@ module subroutine io_read_body_in(self, param) do i = 1, nbody select type(self) class is (swiftest_pl) - read(iu, *, iostat = ierr) self%name(i), val - self%mass(i) = real(val / param%GU, kind=DP) + read(iu, *, iostat = ierr) self%id(i), val self%Gmass(i) = real(val, kind=DP) + self%mass(i) = real(val / param%GU, kind=DP) + if (param%lclose) then - read(iu, *, iostat = ierr) self%radius(i) + if (param%lrhill_present) then + read(iu, *, iostat = ierr) self%radius(i), self%rhill(i) + else + read(iu, *, iostat = ierr) self%radius(i) + end if if (ierr /= 0 ) exit else self%radius(i) = 0.0_DP @@ -676,7 +634,7 @@ module subroutine io_read_body_in(self, param) read(iu, iostat = ierr) self%Q(i) end if class is (swiftest_tp) - read(iu, *, iostat = ierr) self%name(i) + read(iu, *, iostat = ierr) self%id(i) end select if (ierr /= 0 ) exit read(iu, *, iostat = ierr) self%xh(1, i), self%xh(2, i), self%xh(3, i) @@ -698,6 +656,7 @@ module subroutine io_read_body_in(self, param) ierr = -1 end select close(iu) + if (ierr /= 0 ) then write(*,*) 'Error reading in initial conditions from ',trim(adjustl(infile)) call util_exit(FAILURE) @@ -729,21 +688,13 @@ module subroutine io_read_cb_in(self, param) 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 - if (param%lrotation) then - read(iu, *, iostat = ierr) self%Ip(:) - read(iu, *, iostat = ierr) self%rot(:) - end if - if (param%ltides) then - read(iu, *, iostat = ierr) self%k2 - read(iu, *, iostat = ierr) self%Q - end if - else open(unit = iu, file = param%incbfile, status = 'old', form = 'UNFORMATTED', iostat = ierr) call self%read_frame(iu, param, XV, ierr) @@ -767,8 +718,8 @@ module subroutine io_read_param_in(self, param_file_name) !! Adapted from Martin Duncan's Swift routine io_init_param.f implicit none ! Arguments - class(swiftest_parameters),intent(out) :: self !! Current run configuration parameters - character(len=*), intent(in) :: param_file_name !! Parameter input file name (i.e. param.in) + 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 @@ -852,21 +803,21 @@ 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 to the binary output file - !! Note: If outputting to orbital elements, but sure that the conversion is done prior to calling this method + !! 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_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 + 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) self%name(1:n) + read(iu, iostat = ierr) self%id(1:n) + !read(iu, iostat = ierr) self%name(1:n) select case (form) case (EL) read(iu, iostat = ierr) self%a(1:n) @@ -883,22 +834,22 @@ module subroutine io_read_frame_body(self, iu, param, form, ierr) read(iu, iostat = ierr) self%vh(2, 1:n) read(iu, iostat = ierr) self%vh(3, 1:n) end select - select type(self) + select type(pl => self) class is (swiftest_pl) ! Additional output if the passed polymorphic object is a massive body - read(iu, iostat = ierr) self%Gmass(1:n) - self%mass(1:n) = self%Gmass / param%GU - read(iu, iostat = ierr) self%radius(1:n) + read(iu, iostat = ierr) pl%Gmass(1:n) + pl%mass(1:n) = pl%Gmass / param%GU + read(iu, iostat = ierr) pl%radius(1:n) if (param%lrotation) then - read(iu, iostat = ierr) self%Ip(1, 1:n) - read(iu, iostat = ierr) self%Ip(2, 1:n) - read(iu, iostat = ierr) self%Ip(3, 1:n) - read(iu, iostat = ierr) self%rot(1, 1:n) - read(iu, iostat = ierr) self%rot(2, 1:n) - read(iu, iostat = ierr) self%rot(3, 1:n) + read(iu, iostat = ierr) pl%rot(1, 1:n) + read(iu, iostat = ierr) pl%rot(2, 1:n) + read(iu, iostat = ierr) pl%rot(3, 1:n) + read(iu, iostat = ierr) pl%Ip(1, 1:n) + read(iu, iostat = ierr) pl%Ip(2, 1:n) + read(iu, iostat = ierr) pl%Ip(3, 1:n) end if if (param%ltides) then - read(iu, iostat = ierr) self%k2(1:n) - read(iu, iostat = ierr) self%Q(1:n) + read(iu, iostat = ierr) pl%k2(1:n) + read(iu, iostat = ierr) pl%Q(1:n) end if end select end associate @@ -926,6 +877,8 @@ module subroutine io_read_frame_cb(self, iu, param, form, ierr) character(*), intent(in) :: form !! Input format code ("XV" or "EL") integer(I4B), intent(out) :: ierr !! Error cod + read(iu, iostat = ierr) self%id + !read(iu, iostat = ierr) self%name read(iu, iostat = ierr) self%Gmass self%mass = self%Gmass / param%GU read(iu, iostat = ierr) self%radius @@ -1034,6 +987,7 @@ module subroutine io_read_initialize_system(self, param) call self%cb%initialize(param) call self%pl%initialize(param) + if (.not.param%lrhill_present) call self%pl%set_rhill(self%cb) call self%tp%initialize(param) call self%set_msys() call self%pl%set_mu(self%cb) @@ -1041,6 +995,31 @@ module subroutine io_read_initialize_system(self, param) end subroutine io_read_initialize_system + 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 !! @@ -1065,7 +1044,7 @@ module subroutine io_write_discard(self, param) class(swiftest_body), allocatable :: pltemp associate(t => param%t, discards => self%tp_discards, nsp => self%tp_discards%nbody, dxh => self%tp_discards%xh, dvh => self%tp_discards%vh, & - dname => self%tp_discards%name, dstatus => self%tp_discards%status) + dname => self%tp_discards%id, dstatus => self%tp_discards%status) select case(param%out_stat) case('APPEND') @@ -1077,12 +1056,8 @@ module subroutine io_write_discard(self, param) call util_exit(FAILURE) end select lfirst = .false. - if (param%lgr) then - select type(discards) - class is (whm_tp) - call discards%pv2vh(param) - end select - end if + if (param%lgr) call discards%pv2v(param) + write(LUN, HDRFMT) t, nsp, param%lbig_discard do i = 1, nsp write(LUN, NAMEFMT) sub, dname(i), dstatus(i) @@ -1091,15 +1066,12 @@ module subroutine io_write_discard(self, param) end do if (param%lbig_discard) then associate(npl => self%pl%nbody, pl => self%pl, GMpl => self%pl%Gmass, & - Rpl => self%pl%radius, name => self%pl%name, xh => self%pl%xh) + Rpl => self%pl%radius, name => self%pl%id, xh => self%pl%xh) if (param%lgr) then allocate(pltemp, source = pl) - select type(pltemp) - class is (whm_pl) - call pltemp%pv2vh(param) - allocate(vh, source = pltemp%vh) - end select + call pltemp%pv2v(param) + allocate(vh, source = pltemp%vh) deallocate(pltemp) else allocate(vh, source = pl%vh) @@ -1109,7 +1081,6 @@ module subroutine io_write_discard(self, param) do i = 1, npl write(LUN, PLNAMEFMT) name(i), GMpl(i), Rpl(i) write(LUN, VECFMT) xh(1, i), xh(2, i), xh(3, i) - write(LUN, VECFMT) vh(1, i), vh(2, i), vh(3, i) end do deallocate(vh) @@ -1187,7 +1158,8 @@ module subroutine io_write_frame_body(self, iu, param) associate(n => self%nbody) if (n == 0) return - write(iu) self%name(1:n) + 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) @@ -1204,21 +1176,21 @@ module subroutine io_write_frame_body(self, iu, param) write(iu) self%vh(2, 1:n) write(iu) self%vh(3, 1:n) end select - select type(self) + select type(pl => self) class is (swiftest_pl) ! Additional output if the passed polymorphic object is a massive body - write(iu) self%Gmass(1:n) - write(iu) self%radius(1:n) + write(iu) pl%Gmass(1:n) + write(iu) pl%radius(1:n) if (param%lrotation) then - write(iu) self%Ip(1, 1:n) - write(iu) self%Ip(2, 1:n) - write(iu) self%Ip(3, 1:n) - write(iu) self%rot(1, 1:n) - write(iu) self%rot(2, 1:n) - write(iu) self%rot(3, 1:n) + 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) self%k2(1:n) - write(iu) self%Q(1:n) + write(iu) pl%k2(1:n) + write(iu) pl%Q(1:n) end if end select end associate @@ -1239,23 +1211,26 @@ module subroutine io_write_frame_cb(self, iu, param) 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 - write(iu) self%Gmass - write(iu) self%radius - write(iu) self%j2rp2 - write(iu) self%j4rp4 - if (param%lrotation) then - write(iu) self%Ip(1) - write(iu) self%Ip(2) - write(iu) self%Ip(3) - write(iu) self%rot(1) - write(iu) self%rot(2) - write(iu) self%rot(3) - end if - if (param%ltides) then - write(iu) self%k2 - write(iu) self%Q - end if - + 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 @@ -1313,16 +1288,8 @@ module subroutine io_write_frame_system(self, iu, param) call io_write_hdr(iu, param%t, pl%nbody, tp%nbody, param%out_form, param%out_type) if (param%lgr) then - associate(vh => pl%vh, vht => tp%vh) - select type(pl) - class is (whm_pl) - call pl%pv2vh(param) - end select - select type(tp) - class is (whm_tp) - call tp%pv2vh(param) - end select - end associate + 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 diff --git a/src/modules/helio_classes.f90 b/src/modules/helio_classes.f90 index 7dd260dc5..b7bdf826c 100644 --- a/src/modules/helio_classes.f90 +++ b/src/modules/helio_classes.f90 @@ -32,7 +32,6 @@ module helio_classes !! Helio massive body particle class type, public, extends(swiftest_pl) :: helio_pl - real(DP), dimension(:,:), allocatable :: ahi !! heliocentric acceleration due to interactions contains procedure, public :: vh2vb => helio_coord_vh2vb_pl !! Convert massive bodies from heliocentric to barycentric coordinates (velocity only) procedure, public :: vb2vh => helio_coord_vb2vh_pl !! Convert massive bodies from barycentric to heliocentric coordinates (velocity only) @@ -172,7 +171,7 @@ module subroutine helio_step_pl(self, system, param, t, dt) end subroutine helio_step_pl module subroutine helio_step_tp(self, system, param, t, dt) - use swiftest_classes, only : swiftest_cb, swiftest_parameters + 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 diff --git a/src/modules/rmvs_classes.f90 b/src/modules/rmvs_classes.f90 index d6d0fc3a8..7ea5ad2c2 100644 --- a/src/modules/rmvs_classes.f90 +++ b/src/modules/rmvs_classes.f90 @@ -8,12 +8,12 @@ module rmvs_classes implicit none public - 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 + 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 @@ -66,6 +66,7 @@ module rmvs_classes 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 + private procedure, public :: discard => rmvs_discard_tp !! Check to see if test particles should be discarded based on pericenter passage distances with respect to planets encountered procedure, public :: encounter_check => rmvs_encounter_check_tp !! Checks if any test particles are undergoing a close encounter with a massive body procedure, public :: fill => rmvs_fill_tp !! "Fills" bodies from one object into another depending on the results of a mask (uses the MERGE intrinsic) @@ -89,6 +90,7 @@ module rmvs_classes class(rmvs_nbody_system), dimension(:), allocatable :: planetocentric logical :: lplanetocentric = .false. !! Flag that indicates that the object is a planetocentric set of masive bodies used for close encounter calculations contains + private procedure, public :: fill => rmvs_fill_pl !! "Fills" bodies from one object into another depending on the results of a mask (uses the MERGE intrinsic) procedure, public :: setup => rmvs_setup_pl !! Constructor method - Allocates space for number of particles procedure, public :: spill => rmvs_spill_pl !! "Spills" bodies from one object to another depending on the results of a mask (uses the PACK intrinsic) diff --git a/src/modules/swiftest.f90 b/src/modules/swiftest.f90 index 951f2c010..fd8ffaf1b 100644 --- a/src/modules/swiftest.f90 +++ b/src/modules/swiftest.f90 @@ -9,14 +9,10 @@ module swiftest use whm_classes use rmvs_classes use helio_classes - !use symba_classes - use util + use symba_classes use module_nrutil !use advisor_annotate !$ use omp_lib - - - implicit none public diff --git a/src/modules/swiftest_classes.f90 b/src/modules/swiftest_classes.f90 index 3d1cba23d..8efe47fe9 100644 --- a/src/modules/swiftest_classes.f90 +++ b/src/modules/swiftest_classes.f90 @@ -9,18 +9,18 @@ module swiftest_classes public :: discard_pl, discard_system, discard_tp public :: drift_one public :: eucl_dist_index_plpl, eucl_dist_index_pltp, eucl_irij3_plpl - public :: io_dump_param, io_dump_swiftest, io_dump_system, io_get_args, io_param_reader, io_param_writer, io_read_body_in, & + public :: gr_getaccb_ns_body, gr_p4_pos_kick, gr_pseudovel2vel, gr_vel2pseudovel + public :: io_dump_param, io_dump_swiftest, io_dump_system, io_get_args, io_get_token, io_param_reader, io_param_writer, io_read_body_in, & io_read_cb_in, io_read_param_in, io_read_frame_body, io_read_frame_cb, io_read_frame_system, io_read_initialize_system, & - io_write_discard, io_write_encounter, io_write_frame_body, io_write_frame_cb, io_write_frame_system + io_toupper, io_write_discard, io_write_encounter, io_write_frame_body, io_write_frame_cb, io_write_frame_system public :: kickvh_body public :: obl_acc_body, obl_acc_pl, obl_acc_tp public :: orbel_el2xv_vec, orbel_xv2el_vec, orbel_scget, orbel_xv2aeq, orbel_xv2aqt public :: setup_body, setup_construct_system, setup_pl, setup_tp public :: user_getacch_body - public :: util_coord_b2h_pl, util_coord_b2h_tp, util_coord_h2b_pl, util_coord_h2b_tp, util_copy_body, util_copy_cb, util_copy_pl, & - util_copy_tp, util_copy_system, util_fill_body, util_fill_pl, util_fill_tp, util_reverse_status, util_set_beg_end_cb, & - util_set_beg_end_pl, util_set_ir3h, util_set_msys, util_set_mu_pl, util_set_mu_tp, util_set_rhill, & - util_spill_body, util_spill_pl, util_spill_tp + public :: util_coord_b2h_pl, util_coord_b2h_tp, util_coord_h2b_pl, util_coord_h2b_tp, util_exit, util_fill_body, util_fill_pl, util_fill_tp, & + util_index, util_peri_tp, util_reverse_status, util_set_beg_end_cb, util_set_beg_end_pl, util_set_ir3h, util_set_msys, util_set_mu_pl, & + util_set_mu_tp, util_set_rhill, util_sort, util_spill_body, util_spill_pl, util_spill_tp, util_valid, util_version !******************************************************************************************************************************** ! swiftest_parameters class definitions @@ -54,7 +54,6 @@ module swiftest_classes 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) :: encounter_file = ENC_OUTFILE !! Name of output file for encounters - real(DP) :: MTINY = -1.0_DP !! Smallest mass that is fully gravitating 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 @@ -62,15 +61,14 @@ module swiftest_classes real(DP) :: inv_c2 = -1.0_DP !! Inverse speed of light squared in the system units !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 :: lfragmentation = .false. !! Do fragmentation modeling instead of simple merger. - logical :: lmtiny = .false. !! Use the MTINY variable (Automatically set if running SyMBA) - logical :: lrotation = .false. !! Include rotation states of big bodies - logical :: ltides = .false. !! Include tidal dissipation 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 ! Future features not implemented or in development logical :: lgr = .false. !! Turn on GR @@ -82,9 +80,6 @@ module swiftest_classes procedure, public :: writer => io_param_writer procedure, public :: dump => io_dump_param procedure, public :: read_from_file => io_read_param_in - !TODO: Figure out if user-defined derived-type io can be made to work properly - !generic :: read(FORMATTED) => param_reader - !generic :: write(FORMATTED) => param_writer end type swiftest_parameters !******************************************************************************************************************************** @@ -96,11 +91,10 @@ module swiftest_classes contains !! The minimal methods that all systems must have private - procedure :: dump => io_dump_swiftest + procedure :: dump => io_dump_swiftest procedure(abstract_initialize), public, deferred :: initialize - procedure(abstract_write_frame), public, deferred :: write_frame procedure(abstract_read_frame), public, deferred :: read_frame - procedure(abstract_copy), public, deferred :: copy + procedure(abstract_write_frame), public, deferred :: write_frame end type swiftest_base !******************************************************************************************************************************** @@ -108,6 +102,8 @@ module swiftest_classes !******************************************************************************************************************************** !> A concrete lass for the central body in a Swiftest simulation type, abstract, public, 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) @@ -119,16 +115,18 @@ module swiftest_classes real(DP), dimension(NDIM) :: aoblend = 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), 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 private procedure, public :: initialize => io_read_cb_in !! I/O routine for reading in central body data procedure, public :: write_frame => io_write_frame_cb !! I/O routine for writing out a single frame of time-series data for the central body procedure, public :: read_frame => io_read_frame_cb !! I/O routine for reading out a single frame of time-series data for the central body - procedure, public :: copy => util_copy_cb !! Copies elements of one object to another. procedure, public :: set_beg_end => util_set_beg_end_cb !! Sets the beginning and ending oblateness acceleration term end type swiftest_cb @@ -138,25 +136,29 @@ module swiftest_classes !> An abstract class for a generic collection of Swiftest bodies type, abstract, public, 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 - integer(I4B), dimension(:), allocatable :: name !! External identifier - integer(I4B), dimension(:), allocatable :: status !! An integrator-specific status indicator - logical, dimension(:), allocatable :: ldiscard !! Body should be discarded - 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 :: 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 - real(DP), dimension(:), allocatable :: mu !! G * (Mcb + [m]) + 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 + 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 :: 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 + real(DP), dimension(:), allocatable :: mu !! G * (Mcb + [m]) + integer(I4B), dimension(:,:), allocatable :: k_eucl !! Index array used to convert flattened the body-body comparison upper triangular matrix + integer(I8B) :: num_comparisons !! 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_body and util_spill contains @@ -166,6 +168,8 @@ module swiftest_classes procedure(abstract_step_body), public, deferred :: step procedure(abstract_accel), public, deferred :: accel ! These are concrete because the implementation is the same for all types of particles + procedure, public :: v2pv => gr_vh2pv_body !! Converts from velocity to psudeovelocity for GR calculations using symplectic integrators + procedure, public :: pv2v => gr_pv2vh_body !! Converts from psudeovelocity to velocity for GR calculations using symplectic integrators procedure, public :: initialize => io_read_body_in !! Read in body initial conditions from a file procedure, public :: read_frame => io_read_frame_body !! I/O routine for writing out a single frame of time-series data for the central body procedure, public :: write_frame => io_write_frame_body !! I/O routine for writing out a single frame of time-series data for the central body @@ -173,10 +177,9 @@ module swiftest_classes procedure, public :: accel_obl => obl_acc_body !! Compute the barycentric accelerations of bodies due to the oblateness of the central body procedure, public :: el2xv => orbel_el2xv_vec !! Convert orbital elements to position and velocity vectors procedure, public :: xv2el => orbel_xv2el_vec !! Convert position and velocity vectors to orbital elements - procedure, public :: set_ir3 => util_set_ir3h !! Sets the inverse heliocentric radius term (1/rh**3) + procedure, public :: set_ir3 => util_set_ir3h !! Sets the inverse heliocentric radius term (1/rh**3) procedure, public :: setup => setup_body !! A constructor that sets the number of bodies and allocates all allocatable arrays procedure, public :: accel_user => user_getacch_body !! Add user-supplied heliocentric accelerations to planets - procedure, public :: copy => util_copy_body !! Copies elements of one object to another. procedure, public :: fill => util_fill_body !! "Fills" bodies from one object into another depending on the results of a mask (uses the MERGE intrinsic) procedure, public :: spill => util_spill_body !! "Spills" bodies from one object to another depending on the results of a mask (uses the PACK intrinsic) procedure, public :: reverse_status => util_reverse_status !! Reverses the active/inactive status of all particles in a structure @@ -188,23 +191,19 @@ module swiftest_classes !> An abstract class for a generic collection of Swiftest massive bodies type, abstract, public, 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 :: 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 - integer(I4B) :: num_comparisons !! Number of pl-pl Euclidean distance comparisons - integer(I4B), dimension(:,:), allocatable :: k_eucl !! Index array that converts i, j array indices into k index for use in - !! the Euclidean distance matrix - real(DP), dimension(:), allocatable :: irij3 !! 1.0_DP / (rji2 * sqrt(rji2)) where rji2 is the square of the Euclidean distance - 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 :: 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 :: irij3 !! 1.0_DP / (rji2 * sqrt(rji2)) where rji2 is the square of the Euclidean distance + 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 !! 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 @@ -216,11 +215,10 @@ module swiftest_classes procedure, public :: eucl_irij3 => eucl_irij3_plpl !! Parallelized single loop blocking for Euclidean distance matrix calcualtion procedure, public :: accel_obl => obl_acc_pl !! Compute the barycentric accelerations of bodies due to the oblateness of the central body procedure, public :: setup => setup_pl !! A base constructor that sets the number of bodies and allocates and initializes all arrays - procedure, public :: set_mu => util_set_mu_pl !! Method used to construct the vectorized form of the central body mass - procedure, public :: set_rhill => util_set_rhill !! Calculates the Hill's radii for each body + procedure, public :: set_mu => util_set_mu_pl !! Method used to construct the vectorized form of the central body mass + procedure, public :: set_rhill => util_set_rhill !! Calculates the Hill's radii for each body procedure, public :: h2b => util_coord_h2b_pl !! Convert massive bodies from heliocentric to barycentric coordinates (position and velocity) procedure, public :: b2h => util_coord_b2h_pl !! Convert massive bodies from barycentric to heliocentric coordinates (position and velocity) - procedure, public :: copy => util_copy_pl !! Copies elements of one object to another. procedure, public :: fill => util_fill_pl !! "Fills" bodies from one object into another depending on the results of a mask (uses the MERGE intrinsic) procedure, public :: set_beg_end => util_set_beg_end_pl !! Sets the beginning and ending positions and velocities of planets. procedure, public :: spill => util_spill_pl !! "Spills" bodies from one object to another depending on the results of a mask (uses the PACK intrinsic) @@ -232,10 +230,10 @@ module swiftest_classes !> An abstract class for a generic collection of Swiftest test particles type, abstract, public, 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 - real(DP), dimension(:, :), allocatable :: irij3 !! 1.0_DP / (rji2 * sqrt(rji2)) where rji2 is the square of the Euclidean distance betwen each pl-tp + 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 + real(DP), dimension(:, :), allocatable :: irij3 !! 1.0_DP / (rji2 * sqrt(rji2)) where rji2 is the square of the Euclidean distance betwen each pl-tp !! 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 @@ -244,13 +242,13 @@ module swiftest_classes ! These are concrete because they are the same implemenation for all integrators procedure, public :: discard => discard_tp !! Check to see if test particles should be discarded based on their positions relative to the massive bodies procedure, public :: eucl_index => eucl_dist_index_pltp !! Sets up the (i, j) -> k indexing used for the single-loop blocking Euclidean distance matrix - procedure, public :: accel_obl => obl_acc_tp !! Compute the barycentric accelerations of bodies due to the oblateness of the central body + procedure, public :: accel_obl => obl_acc_tp !! Compute the barycentric accelerations of bodies due to the oblateness of the central body procedure, public :: setup => setup_tp !! A base constructor that sets the number of bodies and - procedure, public :: set_mu => util_set_mu_tp !! Method used to construct the vectorized form of the central body mass + procedure, public :: set_mu => util_set_mu_tp !! Method used to construct the vectorized form of the central body mass procedure, public :: h2b => util_coord_h2b_tp !! Convert test particles from heliocentric to barycentric coordinates (position and velocity) procedure, public :: b2h => util_coord_b2h_tp !! Convert test particles from barycentric to heliocentric coordinates (position and velocity) - procedure, public :: copy => util_copy_tp !! Copies elements of one object to another. procedure, public :: fill => util_fill_tp !! "Fills" bodies from one object into another depending on the results of a mask (uses the MERGE intrinsic) + procedure, public :: get_peri => util_peri_tp !! Determine system pericenter passages for test particles procedure, public :: 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 @@ -260,42 +258,38 @@ module swiftest_classes !> An abstract class for a basic Swiftest nbody system type, abstract, public, 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) :: msys = 0.0_DP !! Total system mass - used for barycentric coordinate conversion - real(DP) :: ke = 0.0_DP !! System kinetic energy - real(DP) :: pe = 0.0_DP !! System potential energy - real(DP) :: te = 0.0_DP !! System total energy - real(DP), dimension(NDIM) :: htot = 0.0_DP !! System angular momentum vector - 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 + 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) :: msys = 0.0_DP !! Total system mass - used for barycentric coordinate conversion + real(DP) :: ke = 0.0_DP !! System kinetic energy + real(DP) :: pe = 0.0_DP !! System potential energy + real(DP) :: te = 0.0_DP !! System total energy + 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 :: 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 contains private !> Each integrator will have its own version of the step procedure(abstract_step_system), public, deferred :: step ! Concrete classes that are common to the basic integrator (only test particles considered for discard) - procedure, public :: discard => discard_system !! Perform a discard step on the system - procedure, public :: dump => io_dump_system !! Dump the state of the system to a file - procedure, public :: initialize => io_read_initialize_system !! Initialize the system from an input file - procedure, public :: read_frame => io_read_frame_system !! Append a frame of output data to file - procedure, public :: set_msys => util_set_msys !! Sets the value of msys from the masses of system bodies. - procedure, public :: write_discard => io_write_discard !! Append a frame of output data to file - procedure, public :: write_frame => io_write_frame_system !! Append a frame of output data to file - procedure, public :: copy => util_copy_system !! Copies elements of one object to another. + procedure, public :: discard => discard_system !! Perform a discard step on the system + procedure, public :: dump => io_dump_system !! Dump the state of the system to a file + procedure, public :: initialize => io_read_initialize_system !! Initialize the system from an input file + procedure, public :: read_frame => io_read_frame_system !! Append a frame of output data to file + procedure, public :: set_msys => util_set_msys !! Sets the value of msys from the masses of system bodies. + procedure, public :: write_discard => io_write_discard !! Append a frame of output data to file + procedure, public :: write_frame => io_write_frame_system !! Append a frame of output data to file end type swiftest_nbody_system abstract interface - subroutine abstract_copy(self, src, mask) - import swiftest_base - class(swiftest_base), intent(inout) :: self - class(swiftest_base), intent(in) :: src - logical, dimension(:), intent(in) :: mask - end subroutine abstract_copy - subroutine abstract_discard_body(self, system, param) import swiftest_body, swiftest_nbody_system, swiftest_parameters class(swiftest_body), intent(inout) :: self !! Swiftest body object @@ -346,17 +340,17 @@ 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 + 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 + 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 @@ -370,8 +364,8 @@ 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(in) :: param !! Current run configuration parameters + class(swiftest_nbody_system), intent(inout) :: self !! Swiftest system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters end subroutine discard_system module subroutine discard_tp(self, system, param) @@ -383,10 +377,10 @@ end subroutine discard_tp 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) + 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) @@ -396,26 +390,71 @@ module subroutine eucl_dist_index_plpl(self) module subroutine eucl_dist_index_pltp(self, pl) implicit none - class(swiftest_tp), intent(inout) :: self !! Swiftest test particle object - class(swiftest_pl), intent(inout) :: pl !! Swiftest massive body object + class(swiftest_tp), intent(inout) :: self !! Swiftest test particle object + class(swiftest_pl), intent(inout) :: pl !! Swiftest massive body object end subroutine module subroutine eucl_irij3_plpl(self) implicit none - class(swiftest_pl), intent(inout) :: self !! Swiftest massive body object + class(swiftest_pl), intent(inout) :: self !! Swiftest massive body object end subroutine eucl_irij3_plpl + module pure subroutine gr_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_getaccb_ns_body + + 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 of on 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 of on parameters + end subroutine gr_vh2pv_body + module subroutine io_dump_param(self, param_file_name) implicit none - class(swiftest_parameters),intent(in) :: self !! Output collection of parameters + 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_base), intent(inout) :: self !! Swiftest base object class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters - character(*), optional, intent(in) :: msg !! Message to display with dump operation + character(*), optional, intent(in) :: msg !! Message to display with dump operation end subroutine io_dump_swiftest module subroutine io_dump_system(self, param, msg) @@ -432,6 +471,15 @@ module function io_get_args(integrator, param_file_name) result(ierr) 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 @@ -445,31 +493,31 @@ 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 + 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_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 - class(swiftest_parameters), intent(inout) :: param + 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(out) :: self !! Current run configuration parameters - character(len=*), intent(in) :: param_file_name !! Parameter input file name (i.e. param.in) + 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) @@ -511,6 +559,11 @@ module subroutine io_write_discard(self, param) 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, encounter_file, out_type) implicit none @@ -615,34 +668,6 @@ module subroutine setup_pl(self,n) integer, intent(in) :: n !! Number of massive bodies to allocate space for end subroutine setup_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 massive body object - end subroutine util_set_rhill - module subroutine setup_tp(self, n) implicit none class(swiftest_tp), intent(inout) :: self !! Swiftest test particle object @@ -682,40 +707,10 @@ module subroutine util_coord_h2b_tp(self, cb) class(swiftest_cb), intent(in) :: cb !! Swiftest central body object end subroutine util_coord_h2b_tp - module subroutine util_copy_body(self, src, mask) - implicit none - class(swiftest_body), intent(inout) :: self !! Swiftest body object to copy into - class(swiftest_base), intent(in) :: src !! Swiftest base object to copy from - logical, dimension(:), intent(in) :: mask !! Mask of elements in src object to copy into self - end subroutine util_copy_body - - module subroutine util_copy_cb(self, src, mask) - implicit none - class(swiftest_cb), intent(inout) :: self !! Swiftest central body object to copy into - class(swiftest_base), intent(in) :: src !! Swiftest base object to copy from - logical, dimension(:), intent(in) :: mask !! Mask of elements in src object to copy into selfk - end subroutine util_copy_cb - - module subroutine util_copy_pl(self, src, mask) - implicit none - class(swiftest_pl), intent(inout) :: self !! Swiftest massive body object to copy into - class(swiftest_base), intent(in) :: src !! Swiftest base object to copy from - logical, dimension(:), intent(in) :: mask !! Mask of elements in src object to copy into self - end subroutine util_copy_pl - - module subroutine util_copy_tp(self, src, mask) + module subroutine util_exit(code) implicit none - class(swiftest_tp), intent(inout) :: self !! Swiftest test particle object to copy into - class(swiftest_base), intent(in) :: src !! Swiftest base object to copy from - logical, dimension(:), intent(in) :: mask !! Mask of elements in src object to copy into self - end subroutine util_copy_tp - - module subroutine util_copy_system(self, src, mask) - implicit none - class(swiftest_nbody_system), intent(inout) :: self !! Swiftest nbody system object to copy into - class(swiftest_base), intent(in) :: src !! Swiftest base object to copy from - logical, dimension(:), intent(in) :: mask !! Mask of elements in src object to copy into self - end subroutine util_copy_system + integer(I4B), intent(in) :: code !! Failure exit code + end subroutine util_exit module subroutine util_fill_body(self, inserts, lfill_list) implicit none @@ -738,6 +733,19 @@ module subroutine util_fill_tp(self, inserts, lfill_list) logical, dimension(:), intent(in) :: lfill_list !! Logical array of bodies to merge into the keeps end subroutine util_fill_tp + module subroutine util_index(arr, index) + implicit none + integer(I4B), dimension(:), intent(out) :: index + real(DP), dimension(:), intent(in) :: arr + end subroutine util_index + + 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 + module subroutine util_reverse_status(self) implicit none class(swiftest_body), intent(inout) :: self !! Swiftest body object @@ -758,6 +766,53 @@ module subroutine util_set_beg_end_pl(self, xbeg, xend, vbeg) 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 massive body object + end subroutine util_set_rhill + 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_sp(arr) + implicit none + real(SP), dimension(:), intent(inout) :: arr + end subroutine util_sort_sp + + module subroutine util_sort_dp(arr) + implicit none + real(DP), dimension(:), intent(inout) :: arr + end subroutine util_sort_dp + end interface + + interface module subroutine util_spill_body(self, discards, lspill_list) implicit none class(swiftest_body), intent(inout) :: self !! Swiftest body object @@ -779,6 +834,15 @@ module subroutine util_spill_tp(self, discards, lspill_list) logical, dimension(:), intent(in) :: lspill_list !! Logical array of bodies to spill into the discards 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 index f738dbad0..256c4124b 100644 --- a/src/modules/swiftest_globals.f90 +++ b/src/modules/swiftest_globals.f90 @@ -109,9 +109,9 @@ module swiftest_globals character(*), parameter :: ENC_OUTFILE = 'encounter.out' character(*), parameter :: DISCARD_FILE = 'discard.out' character(*), parameter :: ENERGY_FILE = 'energy.out' - character(*), parameter :: CB_INFILE = 'cb_out.dat' - character(*), parameter :: PL_INFILE = 'pl_out.dat' - character(*), parameter :: TP_INFILE = 'tp_out.dat' + 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 @@ -121,6 +121,6 @@ module swiftest_globals real(DP), parameter :: VSMALL = 4.0E-15_DP real(DP), parameter :: GC = 6.6743E-11_DP !! Universal gravitational constant in SI units - real(DP), parameter :: einstinC = 299792458.0_DP !! Speed of light 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/symba.f90 b/src/modules/symba.f90 index bb86131f8..41f2de81a 100644 --- a/src/modules/symba.f90 +++ b/src/modules/symba.f90 @@ -8,10 +8,10 @@ module symba use helio implicit none - !integer(I4B), public, parameter :: NENMAX = 32767 - !integer(I4B), public, parameter :: NTENC = 3 - !real(DP), public, parameter :: RHSCALE = 6.5_DP - !real(DP), public, parameter :: RSHELL = 0.48075_DP + 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 !******************************************************************************************************************************** ! symba_tp class definitions and method interfaces diff --git a/src/modules/symba_classes.f90 b/src/modules/symba_classes.f90 new file mode 100644 index 000000000..5b712c9de --- /dev/null +++ b/src/modules/symba_classes.f90 @@ -0,0 +1,273 @@ +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 + use helio_classes, only : helio_cb, helio_pl, helio_tp, helio_nbody_system + 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 + character(*), parameter :: PARTICLE_OUTFILE = 'particle.dat' + integer(I4B), parameter :: PARTICLEUNIT = 44 !! File unit number for the binary particle info output file + + type, public, 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 + private + procedure, public :: reader => symba_io_param_reader + procedure, public :: writer => symba_io_param_writer + end type symba_parameters + + !******************************************************************************************************************************** + ! symba_cb class definitions and method interfaces + !******************************************************************************************************************************* + !> SyMBA central body particle class + type, public, 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 + private + 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, public, 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 + private + procedure, public :: dump => symba_io_dump_particle_info !! I/O routine for dumping particle info to file + procedure, public :: initialize => symba_io_initialize_particle_info !! I/O routine for reading in particle info data + procedure, public :: read_frame => symba_io_read_frame_info !! I/O routine for reading in a single frame of particle info + procedure, public :: 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, public, 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 + 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 + private + procedure, public :: discard => symba_discard_pl !! Process massive body discards + procedure, public :: encounter_check => symba_encounter_check_pl !! Checks if massive bodies are going through close encounters with each other + procedure, public :: setup => symba_setup_pl !! Constructor method - Allocates space for number of particle + end type symba_pl + + !******************************************************************************************************************************** + ! symba_tp class definitions and method interfaces + !******************************************************************************************************************************* + !> SyMBA test particle class + type, public, 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 + private + procedure, public :: discard => symba_discard_tp !! process test particle discards + procedure, public :: encounter_check => symba_encounter_check_tp !! Checks if any test particles are undergoing a close encounter with a massive body + procedure, public :: setup => symba_setup_tp !! Constructor method - Allocates space for number of particle + end type symba_tp + + !******************************************************************************************************************************** + ! symba_pltpenc class definitions and method interfaces + !******************************************************************************************************************************* + !> SyMBA class for tracking pl-tp close encounters in a step + type, public :: symba_pltpenc + 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 :: level !! encounter recursion level + integer(I4B), dimension(:), allocatable :: index1 !! position of the planet in encounter + integer(I4B), dimension(:), allocatable :: index2 !! position of the test particle in encounter + end type symba_pltpenc + + !******************************************************************************************************************************** + ! symba_plplenc class definitions and method interfaces + !******************************************************************************************************************************* + !> SyMBA class for tracking pl-pl close encounters in a step + type, public, extends(symba_pltpenc) :: symba_plplenc + real(DP), dimension(:,:), allocatable :: xh1 !! the heliocentric position of parent 1 in encounter + real(DP), dimension(:,:), allocatable :: xh2 !! the heliocentric position of parent 2 in encounter + real(DP), dimension(:,:), allocatable :: vb1 !! the barycentric velocity of parent 1 in encounter + real(DP), dimension(:,:), allocatable :: vb2 !! the barycentric velocity of parent 2 in encounter + end type symba_plplenc + + !******************************************************************************************************************************** + ! symba_nbody_system class definitions and method interfaces + !******************************************************************************************************************************** + type, public, extends(helio_nbody_system) :: symba_nbody_system + class(symba_pl), allocatable :: mergeadd_list !! List of added bodies in mergers or collisions + class(symba_pl), 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 + class(symba_pl), allocatable :: pl_discards !! Discarded test particle data structure + contains + private + procedure, public :: initialize => symba_setup_system !! Performs SyMBA-specific initilization steps + procedure, public :: step => symba_step_system !! Advance the SyMBA nbody system forward in time by one step + procedure, public :: interp => symba_step_interp_system !! Perform an interpolation step on the SymBA nbody system + end type symba_nbody_system + + interface + 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(in) :: param !! Current run configuration parameters + end subroutine symba_discard_pl + + module subroutine symba_discard_tp(self, system, param) + use swiftest_classes, only : swiftest_nbody_system, swiftest_parameters + implicit none + class(symba_tp), intent(inout) :: self !! 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 + end subroutine symba_discard_tp + + module function symba_encounter_check_pl(self, system, dt) result(lencounter) + 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 + logical :: lencounter !! Returns true if there is at least one close encounter + end function symba_encounter_check_pl + + module function symba_encounter_check_tp(self, system, dt) result(lencounter) + 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 + logical :: lencounter !! Returns true if there is at least one close encounter + end function symba_encounter_check_tp + + 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(in) :: 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 !! 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 + 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 !! 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 + 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_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_pl(self,n) + implicit none + class(symba_pl), intent(inout) :: self !! SyMBA test particle object + integer(I4B), intent(in) :: n !! Number of massive bodies to allocate + end subroutine symba_setup_pl + + module subroutine symba_setup_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_system + + 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_setup_tp(self,n) + implicit none + class(symba_tp), intent(inout) :: self !! SyMBA test particle object + integer(I4B), intent(in) :: n !! Number of test particles to allocate + end subroutine symba_setup_tp + + 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 + end interface +end module symba_classes \ No newline at end of file diff --git a/src/modules/util.f90 b/src/modules/util.f90 deleted file mode 100644 index 874d20789..000000000 --- a/src/modules/util.f90 +++ /dev/null @@ -1,96 +0,0 @@ -module util - use swiftest_globals - use swiftest_classes - implicit none - interface - - module subroutine util_exit(code) - implicit none - integer(I4B), intent(in) :: code - end subroutine util_exit - - module subroutine util_get_energy_and_momentum(self) - implicit none - class(swiftest_nbody_system), intent(inout) :: self !! Swiftest system object - end subroutine util_get_energy_and_momentum - - module subroutine util_hills(npl, swiftest_plA) - implicit none - integer(I4B), intent(in) :: npl - class(swiftest_pl), intent(inout) :: swiftest_plA - end subroutine util_hills - - module subroutine util_index(arr, index) - implicit none - integer(I4B), dimension(:), intent(out) :: index - real(DP), dimension(:), intent(in) :: arr - end subroutine util_index - - module subroutine util_peri(lfirst, ntp, tp, mu, msys, qmin_coord) - logical, intent(in) :: lfirst !! Logical flag indicating whether current invocation is the first - integer(I4B), intent(in) :: ntp !! Number of active test particles - class(swiftest_tp), intent(inout) :: tp !! Swiftest test particle class - real(DP), intent(in) :: mu !! G * (m1 + m2) = mass of the Sun in this routine - real(DP), intent(in) :: msys !! Total system masse - character(len=*), intent(in) :: qmin_coord !! Coordinate frame for qmin (see swiftest_globals for symbolic definitions) - end subroutine util_peri - - module subroutine util_toupper(string) - implicit none - character(*), intent(inout) :: string - end subroutine util_toupper - - 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 - - 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_sp(arr) - implicit none - real(SP), dimension(:), intent(inout) :: arr - end subroutine util_sort_sp - - module subroutine util_sort_dp(arr) - implicit none - real(DP), dimension(:), intent(inout) :: arr - end subroutine util_sort_dp - end interface - - interface - module function calc_qrd_pstar(mtarg,mp,alpha) result(ans) - implicit none - real(DP),intent(in) :: mtarg, mp, alpha - real(DP) :: ans - end function calc_qrd_pstar - - module function calc_qrd_rev(mp,mtarg,mint,den1,den2, vimp) result(ans) - implicit none - real(DP),intent(in) :: mp, mtarg, mint, den1, den2, vimp - real(DP) :: ans - end function calc_qrd_rev - - module function calc_b(mp_pos, mp_vel, mp_r, mtarg_pos, mtarg_vel, mtarg_r) result(b) - implicit none - real(DP), intent(in), dimension(3) :: mp_pos, mp_vel, mtarg_pos, mtarg_vel - real(DP), intent(in) :: mp_r, mtarg_r - real(DP) :: b - end function calc_b - - end interface - - - -end module util diff --git a/src/modules/whm_classes.f90 b/src/modules/whm_classes.f90 index b0f176a0a..6107a719d 100644 --- a/src/modules/whm_classes.f90 +++ b/src/modules/whm_classes.f90 @@ -30,21 +30,19 @@ module whm_classes !! 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_spill_pl contains - procedure, public :: h2j => whm_coord_h2j_pl !! Convert position and velcoity vectors from heliocentric to Jacobi coordinates - procedure, public :: j2h => whm_coord_j2h_pl !! Convert position and velcoity vectors from Jacobi to helliocentric coordinates - procedure, public :: vh2vj => whm_coord_vh2vj_pl !! Convert velocity vectors from heliocentric to Jacobi coordinates - procedure, public :: drift => whm_drift_pl !! Loop through massive bodies and call Danby drift routine - procedure, public :: fill => whm_fill_pl !! "Fills" bodies from one object into another depending on the results of a mask (uses the MERGE intrinsic) - procedure, public :: accel => whm_getacch_pl !! Compute heliocentric accelerations of massive bodies - procedure, public :: accel_gr => whm_gr_getacch_pl !! Acceleration term arising from the post-Newtonian correction - procedure, public :: p4 => whm_gr_p4_pl !! Position kick due to p**4 term in the post-Newtonian correction - procedure, public :: vh2pv => whm_gr_vh2pv_pl !! Converts from heliocentric velocity to psudeovelocity for GR calculations - procedure, public :: pv2vh => whm_gr_pv2vh_pl !! Converts from psudeovelocity to heliocentric velocity for GR calculations - procedure, public :: setup => whm_setup_pl !! Constructor method - Allocates space for number of particles - procedure, public :: set_mu => whm_util_set_mu_eta_pl !! Sets the Jacobi mass value for all massive bodies. - procedure, public :: set_ir3 => whm_setup_set_ir3j !! Sets both the heliocentric and jacobi inverse radius terms (1/rj**3 and 1/rh**3) - procedure, public :: step => whm_step_pl !! Steps the body forward one stepsize - procedure, public :: spill => whm_spill_pl !!"Spills" bodies from one object to another depending on the results of a mask (uses the PACK intrinsic) + procedure, public :: h2j => whm_coord_h2j_pl !! Convert position and velcoity vectors from heliocentric to Jacobi coordinates + procedure, public :: j2h => whm_coord_j2h_pl !! Convert position and velcoity vectors from Jacobi to helliocentric coordinates + procedure, public :: vh2vj => whm_coord_vh2vj_pl !! Convert velocity vectors from heliocentric to Jacobi coordinates + procedure, public :: drift => whm_drift_pl !! Loop through massive bodies and call Danby drift routine + procedure, public :: fill => whm_fill_pl !! "Fills" bodies from one object into another depending on the results of a mask (uses the MERGE intrinsic) + procedure, public :: accel => whm_getacch_pl !! Compute heliocentric accelerations of massive bodies + procedure, public :: accel_gr => whm_gr_getacch_pl !! Acceleration term arising from the post-Newtonian correction + procedure, public :: gr_pos_kick => whm_gr_p4_pl !! Position kick due to p**4 term in the post-Newtonian correction + procedure, public :: setup => whm_setup_pl !! Constructor method - Allocates space for number of particles + procedure, public :: set_mu => whm_util_set_mu_eta_pl !! Sets the Jacobi mass value for all massive bodies. + procedure, public :: set_ir3 => whm_setup_set_ir3j !! Sets both the heliocentric and jacobi inverse radius terms (1/rj**3 and 1/rh**3) + procedure, public :: step => whm_step_pl !! Steps the body forward one stepsize + procedure, public :: spill => whm_spill_pl !!"Spills" bodies from one object to another depending on the results of a mask (uses the PACK intrinsic) end type whm_pl !******************************************************************************************************************************** @@ -57,14 +55,12 @@ module whm_classes !! component list, such as whm_setup_tp and whm_spill_tp contains private - procedure, public :: drift => whm_drift_tp !! Loop through test particles and call Danby drift routine - procedure, public :: accel => whm_getacch_tp !! Compute heliocentric accelerations of test particles - procedure, public :: accel_gr => whm_gr_getacch_tp !! Acceleration term arising from the post-Newtonian correction - procedure, public :: p4 => whm_gr_p4_tp !! Position kick due to p**4 term in the post-Newtonian correction - procedure, public :: vh2pv => whm_gr_vh2pv_tp !! Converts from heliocentric velocity to psudeovelocity for GR calculations - procedure, public :: pv2vh => whm_gr_pv2vh_tp !! Converts from psudeovelocity to heliocentric velocity for GR calculations - procedure, public :: setup => whm_setup_tp !! Allocates new components of the whm class and recursively calls parent allocations - procedure, public :: step => whm_step_tp !! Steps the particle forward one stepsize + procedure, public :: drift => whm_drift_tp !! Loop through test particles and call Danby drift routine + procedure, public :: accel => whm_getacch_tp !! Compute heliocentric accelerations of test particles + procedure, public :: accel_gr => whm_gr_getacch_tp !! Acceleration term arising from the post-Newtonian correction + procedure, public :: gr_pos_kick => whm_gr_p4_tp !! Position kick due to p**4 term in the post-Newtonian correction + procedure, public :: setup => whm_setup_tp !! Allocates new components of the whm class and recursively calls parent allocations + procedure, public :: step => whm_step_tp !! Steps the particle forward one stepsize end type whm_tp !******************************************************************************************************************************** @@ -166,7 +162,7 @@ end subroutine whm_gr_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 !! Swiftest particle object + class(whm_pl), intent(inout) :: self !! WHM massive body object class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of on parameters real(DP), intent(in) :: dt !! Step size end subroutine whm_gr_p4_pl @@ -179,38 +175,10 @@ module pure subroutine whm_gr_p4_tp(self, param, dt) real(DP), intent(in) :: dt !! Step size end subroutine whm_gr_p4_tp - module pure subroutine whm_gr_pv2vh_pl(self, param) - use swiftest_classes, only : swiftest_parameters - implicit none - class(whm_pl), intent(inout) :: self !! Swiftest particle object - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of on parameters - end subroutine whm_gr_pv2vh_pl - - module pure subroutine whm_gr_pv2vh_tp(self, param) - 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 of on parameters - end subroutine whm_gr_pv2vh_tp - - module pure subroutine whm_gr_vh2pv_pl(self, param) - use swiftest_classes, only : swiftest_parameters - implicit none - class(whm_pl), intent(inout) :: self !! Swiftest particle object - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of on parameters - end subroutine whm_gr_vh2pv_pl - - module pure subroutine whm_gr_vh2pv_tp(self, param) - 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 of on parameters - end subroutine whm_gr_vh2pv_tp - !> Reads WHM massive body object in from file module subroutine whm_setup_pl(self,n) implicit none - class(whm_pl), intent(inout) :: self !! Swiftest test particle object + class(whm_pl), intent(inout) :: self !! WHM massive body objectobject integer(I4B), intent(in) :: n !! Number of test particles to allocate end subroutine whm_setup_pl diff --git a/src/rmvs/rmvs_discard.f90 b/src/rmvs/rmvs_discard.f90 index 6dacd7969..14613724e 100644 --- a/src/rmvs/rmvs_discard.f90 +++ b/src/rmvs/rmvs_discard.f90 @@ -22,7 +22,7 @@ module subroutine rmvs_discard_tp(self, system, param) 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%name(i)," q with respect to Planet ",pl%name(iplperP)," is too small at t = ",t + write(*, *) "Particle ",tp%id(i)," q with respect to Planet ",pl%id(iplperP)," is too small at t = ",t tp%ldiscard(i) = .true. end if end if diff --git a/src/rmvs/rmvs_setup.f90 b/src/rmvs/rmvs_setup.f90 index 4c0c27ff1..4607bfbb0 100644 --- a/src/rmvs/rmvs_setup.f90 +++ b/src/rmvs/rmvs_setup.f90 @@ -9,11 +9,10 @@ module subroutine rmvs_setup_pl(self,n) !! 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 test particles to allocate + class(rmvs_pl), intent(inout) :: self !! RMVS test particle object + integer(I4B), intent(in) :: n !! Number of massive bodies to allocate ! Internals - integer(I4B) :: i,j - !type(swiftest_parameters) :: encounter_param + integer(I4B) :: i,j !> Call allocation method for parent class associate(pl => self) @@ -25,7 +24,6 @@ module subroutine rmvs_setup_pl(self,n) 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)) @@ -49,7 +47,7 @@ end subroutine rmvs_setup_pl module subroutine rmvs_setup_system(self, param) !! author: David A. Minton !! - !! nitialize an RMVS nbody system from files and sets up the planetocentric structures. + !! 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 @@ -58,7 +56,7 @@ module subroutine rmvs_setup_system(self, param) !! to use during close encounters. implicit none ! Arguments - class(rmvs_nbody_system), intent(inout) :: self !! RMVS system object + 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 @@ -126,8 +124,8 @@ module subroutine rmvs_setup_tp(self,n) !! 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, intent(in) :: n !! Number of test particles to allocate + class(rmvs_tp), intent(inout) :: self !! RMVS test particle object + integer, intent(in) :: n !! Number of test particles to allocate !> Call allocation method for parent class call whm_setup_tp(self, n) diff --git a/src/rmvs/rmvs_step.f90 b/src/rmvs/rmvs_step.f90 index 71091f6dd..bb6c0d843 100644 --- a/src/rmvs/rmvs_step.f90 +++ b/src/rmvs/rmvs_step.f90 @@ -29,7 +29,6 @@ module subroutine rmvs_step_system(self, param, t, dt) associate(system => self, ntp => tp%nbody, npl => pl%nbody) allocate(xbeg, source=pl%xh) allocate(vbeg, source=pl%vh) - call pl%set_rhill(cb) call pl%set_beg_end(xbeg = xbeg, vbeg = vbeg) ! ****** Check for close encounters ***** ! system%rts = RHSCALE @@ -100,7 +99,7 @@ subroutine rmvs_interp_out(cb, pl, dt) if (any(iflag(1:npl) /= 0)) then do i = 1, npl if (iflag(i) /= 0) then - write(*, *) " Planet ", pl%name(i), " is lost!!!!!!!!!!" + write(*, *) " Planet ", pl%id(i), " is lost!!!!!!!!!!" write(*, *) GMcb(i), dto(i) write(*, *) xtmp(:,i) write(*, *) vtmp(:,i) @@ -122,7 +121,7 @@ subroutine rmvs_interp_out(cb, pl, dt) if (any(iflag(1:npl) /= 0)) then do i = 1, npl if (iflag(i) /= 0) then - write(*, *) " Planet ", pl%name(i), " is lost!!!!!!!!!!" + write(*, *) " Planet ", pl%id(i), " is lost!!!!!!!!!!" write(*, *) GMcb(i), -dto(i) write(*, *) xtmp(:,i) write(*, *) vtmp(:,i) @@ -254,7 +253,7 @@ subroutine rmvs_interp_in(cb, pl, system, param, dt, outer_index) if (any(iflag(1:npl) /= 0)) then do i = 1, npl if (iflag(i) /=0) then - write(*, *) " Planet ", pl%name(i), " is lost!!!!!!!!!!" + write(*, *) " Planet ", pl%id(i), " is lost!!!!!!!!!!" write(*, *) GMcb(i), dti(i) write(*, *) xtmp(:,i) write(*, *) vtmp(:,i) @@ -278,7 +277,7 @@ subroutine rmvs_interp_in(cb, pl, system, param, dt, outer_index) if (any(iflag(1:npl) /= 0)) then do i = 1, npl if (iflag(i) /=0) then - write(*, *) " Planet ", pl%name(i), " is lost!!!!!!!!!!" + write(*, *) " Planet ", pl%id(i), " is lost!!!!!!!!!!" write(*, *) GMcb(i), -dti(i) write(*, *) xtmp(:,i) write(*, *) vtmp(:,i) @@ -413,7 +412,7 @@ subroutine rmvs_make_planetocentric(cb, pl, tp) tpenci%ipleP = i tpenci%status(:) = ACTIVE ! Grab all the encountering test particles and convert them to a planetocentric frame - tpenci%name(:) = pack(tp%name(:), encmask(:)) + 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) @@ -450,7 +449,6 @@ subroutine rmvs_make_planetocentric(cb, pl, tp) return end subroutine rmvs_make_planetocentric - subroutine rmvs_peri_tp(tp, pl, t, dt, lfirst, inner_index, ipleP, param) !! author: David A. Minton !! @@ -498,11 +496,11 @@ subroutine rmvs_peri_tp(tp, pl, t, dt, lfirst, inner_index, ipleP, param) r2 = dot_product(xpc(:, i), xpc(:, i)) if ((abs(tperi) > FACQDT * dt) .or. (r2 > rhill2)) peri = sqrt(r2) if (param%encounter_file /= "") then - id1 = pl%name(ipleP) + id1 = pl%id(ipleP) rpl = pl%radius(ipleP) xh1(:) = pl%inner(inner_index)%x(:, ipleP) vh1(:) = pl%inner(inner_index)%v(:, ipleP) - id2 = tp%name(i) + 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(:), & diff --git a/src/setup/setup.f90 b/src/setup/setup.f90 index 0f16e7c5b..402ef62a4 100644 --- a/src/setup/setup.f90 +++ b/src/setup/setup.f90 @@ -46,7 +46,19 @@ module subroutine setup_construct_system(system, param) allocate(rmvs_tp :: system%tp_discards) end select case (SYMBA) - write(*,*) 'SyMBA integrator not yet enabled' + 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_pl :: system%pl_discards) + allocate(symba_tp :: system%tp_discards) + allocate(symba_pl :: system%mergeadd_list) + allocate(symba_pl :: 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 @@ -72,6 +84,7 @@ module subroutine setup_body(self,n) self%lfirst = .true. !write(*,*) 'Allocating the basic Swiftest particle' + allocate(self%id(n)) allocate(self%name(n)) allocate(self%status(n)) allocate(self%ldiscard(n)) @@ -81,6 +94,7 @@ module subroutine setup_body(self,n) allocate(self%vb(NDIM, n)) allocate(self%ah(NDIM, n)) allocate(self%aobl(NDIM, n)) + allocate(self%agr(NDIM, n)) allocate(self%ir3h(n)) allocate(self%a(n)) allocate(self%e(n)) @@ -90,7 +104,8 @@ module subroutine setup_body(self,n) allocate(self%capm(n)) allocate(self%mu(n)) - self%name(:) = 0 + self%id(:) = 0 + self%name(:) = "UNNAMED" self%status(:) = INACTIVE self%ldiscard(:) = .false. self%xh(:,:) = 0.0_DP @@ -131,20 +146,12 @@ module subroutine setup_pl(self,n) allocate(self%rhill(n)) allocate(self%radius(n)) allocate(self%density(n)) - allocate(self%Ip(NDIM, n)) - allocate(self%rot(NDIM, n)) - allocate(self%k2(n)) - allocate(self%Q(n)) self%mass(:) = 0.0_DP self%Gmass(:) = 0.0_DP self%rhill(:) = 0.0_DP self%radius(:) = 0.0_DP self%density(:) = 0.0_DP - self%Ip(:,:) = 0.0_DP - self%rot(:,:) = 0.0_DP - self%k2(:) = 0.0_DP - self%Q(:) = 0.0_DP self%num_comparisons = 0 return end subroutine setup_pl diff --git a/src/symba/symba_casedisruption.f90 b/src/symba/symba_casedisruption.f90 deleted file mode 100644 index bd8f03330..000000000 --- a/src/symba/symba_casedisruption.f90 +++ /dev/null @@ -1,294 +0,0 @@ -submodule (symba) s_symba_casedisruption -contains - module procedure symba_casedisruption - !! author: Jennifer L. L. Pouplin and Carlisle A. Wishard - !! - !! Disruptive Collision - use swiftest -implicit none - integer(I4B) :: nfrag, i, k, index1, index2, frags_added - integer(I4B) :: index1_parent, index2_parent - integer(I4B) :: name1, name2, nstart - real(DP) :: mtot, msun, avg_d, d_p1, d_p2, semimajor_encounter, e, q, semimajor_inward - real(DP) :: rhill_p1, rhill_p2, r_circle, theta, radius1, radius2, r_smallestcircle - real(DP) :: m_rem, m_test, mass1, mass2, enew, eold, a, b, v_col - real(DP) :: x_com, y_com, z_com, vx_com, vy_com, vz_com - real(DP) :: x_frag, y_frag, z_frag, vx_frag, vy_frag, vz_frag - real(DP), dimension(NDIM) :: vnew, xr, mv, l, kk, p - - !temporary - interface - function cross_product_disruption(ar1,ar2) result(ans) - use swiftest - implicit none - real(DP),dimension(3),intent(in) :: ar1,ar2 - real(DP),dimension(3) :: ans - end function cross_product_disruption - end interface - -! executable code - - write(*,*) "entering casedisruption" - ! set the maximum number of fragments to be added in a disruption collision (nfrag) - nfrag = 5 - ! pull in the information about the two particles involved in the collision - index1 = plplenc_list%index1(index_enc) - index2 = plplenc_list%index2(index_enc) - index1_parent = symba_plA%index_parent(index1) - index2_parent = symba_plA%index_parent(index2) - name1 = symba_plA%name(index1) - name2 = symba_plA%name(index2) - mass1 = symba_plA%mass(index1) ! the mass of the first particle in the collision not including all it's children - mass2 = symba_plA%mass(index2) - radius1 = symba_plA%radius(index1) - radius2 = symba_plA%radius(index2) - msun = symba_plA%mass(1) - - ! find com - x_com = ((x1(1) * m1) + (x2(1) * m2)) / (m1 + m2) - y_com = ((x1(2) * m1) + (x2(2) * m2)) / (m1 + m2) - z_com = ((x1(3) * m1) + (x2(3) * m2)) / (m1 + m2) - - vx_com = ((v1(1) * m1) + (v2(1) * m2)) / (m1 + m2) - vy_com = ((v1(2) * m1) + (v2(2) * m2)) / (m1 + m2) - vz_com = ((v1(3) * m1) + (v2(3) * m2)) / (m1 + m2) - - ! find collision velocity - v_col = norm2(v2(:) - v1(:)) - - ! find energy pre-frag - eold = 0.5_DP*(m1*dot_product(v1(:), v1(:)) + m2*dot_product(v2(:), v2(:))) - xr(:) = x2(:) - x1(:) - eold = eold - (m1*m2/(norm2(xr(:), xr(:))))) - - write(*, *) "disruption between particles ", name1, " and ", name2, " at time t = ",t - - ! add both particles involved in the collision to mergesub_list - nmergesub = nmergesub + 1 - mergesub_list%name(nmergesub) = name1 - mergesub_list%status(nmergesub) = DISRUPTION - mergesub_list%xh(:,nmergesub) = x1(:) - mergesub_list%vh(:,nmergesub) = v1(:) - vbs(:) - mergesub_list%mass(nmergesub) = mass1 - mergesub_list%radius(nmergesub) = radius1 - nmergesub = nmergesub + 1 - mergesub_list%name(nmergesub) = name2 - mergesub_list%status(nmergesub) = DISRUPTION - mergesub_list%xh(:,nmergesub) = x2(:) - mergesub_list%vh(:,nmergesub) = v2(:) - vbs(:) - mergesub_list%mass(nmergesub) = mass2 - mergesub_list%radius(nmergesub) = radius2 - - ! go through the encounter list and look for particles actively encoutering in this timestep - ! prevent them from having further encounters in this timestep by setting status in plplenc_list to merged - do k = 1, nplplenc - if ((plplenc_list%status(k) == ACTIVE) .and. & - ((index1 == plplenc_list%index1(k) .or. index2 == plplenc_list%index2(k)) .or. & - (index2 == plplenc_list%index1(k) .or. index1 == plplenc_list%index2(k)))) then - plplenc_list%status(k) = MERGED - end if - end do - - ! set the status of the particles in symba_plA to disruption - symba_plA%status(index1) = DISRUPTION - symba_plA%status(index2) = DISRUPTION - - l(:) = (v2(:) - v1(:)) / norm2(v2(:)-v1(:)) - p(:) = cross_product_disruption(xr(:) / norm2(xr(:)), l(:)) - kk(:) = cross_product_disruption(l(:),p(:)) - - rhill_p1 = symba_plA%rhill(index1_parent) - rhill_p2 = symba_plA%rhill(index2_parent) - r_smallestcircle = (rhscale * rhill_p1 + rhscale * rhill_p2) / (2.0_DP * sin(pi / 2.0_DP)) - - ! check that no fragments will be added interior of the smallest orbit that the timestep can reliably resolve - semimajor_inward = ((dt * 32.0_DP) ** 2.0_DP) ** (1.0_DP / 3.0_DP) - call orbel_xv2aeq(x1, v1, msun, semimajor_encounter, e, q) - ! if they are going to be added interior to this orbit, give a warning - if (semimajor_inward > (semimajor_encounter - r_smallestcircle)) then - write(*,*) "warning in symba_casedisruption: timestep is too large to resolve fragments." - end if - ! if not, continue through all possible fragments to be added - mtot = 0.0_DP ! running total mass of new fragments - mv = 0.0_DP ! running sum of m*v of new fragments to be used in com calculation - frags_added = 0 ! running total number of new fragments - nstart = nmergeadd ! start of new fragments in mergeadd_list - - d_p1 = (3.0_DP * m1) / (4.0_DP * pi * (rad1 ** 3.0_DP)) - d_p2 = (3.0_DP * m2) / (4.0_DP * pi * (rad2 ** 3.0_DP)) - avg_d = ((m1 * d_p1) + (m2 * d_p2)) / (m1 + m2) - - !do i = 1, nfrag - ! if we are adding the first and largest fragment (lr), it's mass and radius should be taken from - ! util_regime while it's position and velocity should be calculated on the circle of radius - ! r_circle as described above. - !if (i == 1) then - frags_added = frags_added + 1 - nmergeadd = nmergeadd + 1 - mergeadd_list%status(nmergeadd) = DISRUPTION - mergeadd_list%ncomp(nmergeadd) = 2 - mergeadd_list%name(nmergeadd) = param%nplmax + param%ntpmax + fragmax + i - mergeadd_list%mass(nmergeadd) = mres(1) - mergeadd_list%radius(nmergeadd) = rres(1) - mtot = mtot + mergeadd_list%mass(nmergeadd) - !end if - ! if we are adding the second fragment (slr), it's mass and radius should be taken from - ! util_regime while it's position and velocity should be calculated on the circle of - ! radius r_circle as described above. - if ((mres(2) > (1.0_DP / 3.0_DP)*mres(1))) then - write(*,*) "casedisruption 1st if" - ! frags_added is the actual number of fragments added to the simulation vs nfrag which is the total possible - frags_added = frags_added + 1 - nmergeadd = nmergeadd + 1 - mergeadd_list%status(nmergeadd) = DISRUPTION - mergeadd_list%ncomp(nmergeadd) = 2 - mergeadd_list%name(nmergeadd) = param%nplmax + param%ntpmax + fragmax + i - mergeadd_list%mass(nmergeadd) = mres(2) - mergeadd_list%radius(nmergeadd) = rres(2) - mtot = mtot + mergeadd_list%mass(nmergeadd) - do i = 3, nfrag - write(*,*) "casedisruption 1st do" - frags_added = frags_added + 1 - nmergeadd = nmergeadd + 1 - mergeadd_list%status(nmergeadd) = DISRUPTION - mergeadd_list%ncomp(nmergeadd) = 2 - mergeadd_list%name(nmergeadd) = param%nplmax + param%ntpmax + fragmax + i - m_rem = (m1 + m2) - (mres(1) + mres(2)) - mergeadd_list%mass(nmergeadd) = m_rem / (nfrag - 1) - mergeadd_list%radius(nmergeadd) = ((3.0_DP * mergeadd_list%mass(nmergeadd)) / (4.0_DP * pi * avg_d)) & - ** (1.0_DP / 3.0_DP) - mtot = mtot + mergeadd_list%mass(nmergeadd) - end do - end if - - if ((mres(2) < (1.0_DP / 3.0_DP)*mres(1))) then - write(*,*) "casedisruption 2nd if" - do i = 2, nfrag - write(*,*) "casedisruption 2nd do" - m_rem = (m1 + m2) - mres(1) - frags_added = frags_added + 1 - nmergeadd = nmergeadd + 1 - mergeadd_list%name(nmergeadd) = param%nplmax + param%ntpmax + fragmax + i - mergeadd_list%status(nmergeadd) = DISRUPTION - mergeadd_list%ncomp(nmergeadd) = 2 - mergeadd_list%mass(nmergeadd) = m_rem / (nfrag - 1) - mergeadd_list%radius(nmergeadd) = ((3.0_DP * mergeadd_list%mass(nmergeadd)) / (4.0_DP * pi * avg_d)) & - ** (1.0_DP / 3.0_DP) - mtot = mtot + mergeadd_list%mass(nmergeadd) - end do - end if - - ! if we are doing more fragments - !if ((i > 2) .and. (mres(2) > (1.0_DP / 3.0_DP)*mres(1))) then - ! m_rem is the mass needed to be "made up for" in fragments, mres(1) and mres(2) are the mass of the largest - ! and second largest fragments that have already been added, and m1 and m2 are the masses of the original - ! particles involved in the collision. - !frags_added = frags_added + 1 - !nmergeadd = nmergeadd + 1 - !mergeadd_list%status(nmergeadd) = DISRUPTION - !mergeadd_list%ncomp(nmergeadd) = 2 - !mergeadd_list%name(nmergeadd) = param%nplmax + param%ntpmax + fragmax + i - !m_rem = (m1 + m2) - (mres(1) + mres(2)) - !mergeadd_list%mass(nmergeadd) = m_rem / (nfrag - 1) - !mergeadd_list%radius(nmergeadd) = ((3.0_DP * mergeadd_list%mass(nmergeadd)) / (4.0_DP * pi * avg_d)) & - ! ** (1.0_DP / 3.0_DP) - !mtot = mtot + mergeadd_list%mass(nmergeadd) - - !write(*,*) "casedisruption mres(1) and mres(2)", mres(1), mres(2) - - ! check if these fragments will be large enough to be resolved - !if (m_rem > (m2) / 100.0_DP) then - ! if yes, add a fragment using durda et al 2007 figure 2 supercatastrophic: n = (1.5e5)e(-1.3*d) for the mass - - ! create a "test mass" using durda et al 2007 figure 2 supercatastrophic: n = (1.5e5)e(-1.3*d) - !m_test = (((- 1.0_DP / 2.6_DP) * log(i / (1.5_DP * 10.0_DP ** 5.0_DP))) ** 3.0_DP) * ((4.0_DP / 3.0_DP) & - ! * pi * avg_d) - ! if the test mass is smaller than the mass that needs to be "made up for", add it. - !if (m_test < m_rem) then - ! mergeadd_list%mass(nmergeadd) = m_test - ! if not, aka if the test mass is too large, then add a fragment with a mass equal to the difference between - ! the sum of the mass of the parents and the total mass already added. - !else - ! mergeadd_list%mass(nmergeadd) = m_rem !(m1 + m2) - mtot - !end if - - ! calculate the radius of the fragments using the weighted average density of the parents. - !mergeadd_list%radius(nmergeadd) = ((3.0_DP * mergeadd_list%mass(nmergeadd)) / (4.0_DP * pi * avg_d)) & - ! ** (1.0_DP / 3.0_DP) - !mtot = mtot + mergeadd_list%mass(nmergeadd) - - ! if these fragments will not be large enough to be resolved, add the remaining mass that we need to - ! "make up for" to the mass of the most recent fragment and recalculate the radius. - !else - ! mergeadd_list%mass(nmergeadd) = mergeadd_list%mass(nmergeadd) + m_rem - ! mergeadd_list%radius(nmergeadd) = (((3.0_DP/4.0_DP) * pi) * (mergeadd_list%mass(nmergeadd) / avg_d)) & - ! ** (1.0_DP / 3.0_DP) - !end if - !end if - !end do - - ! calculate the positions of the new fragments in a circle with a radius large enough to space - ! all fragments apart by a distance of rhill_p1 + rhill_p2 - r_circle = (2.0_DP * rhill_p1 + 2.0_DP * rhill_p2) / (2.0_DP * sin(pi / frags_added)) - theta = (2.0_DP * pi) / frags_added - - do i=1, frags_added - write(*,*) "casedisruption 3rd do" - - !write(*,*) "casedisruption mfrag/mtot", mergeadd_list%mass(nstart + i) / (m1 + m2) - - ! increment around the circle for positions of fragments - x_frag = (r_circle * cos(theta * i))*l(1) + (r_circle * sin(theta * i))*p(1) + x_com - y_frag = (r_circle * cos(theta * i))*l(2) + (r_circle * sin(theta * i))*p(2) + y_com - z_frag = (r_circle * cos(theta * i))*l(3) + (r_circle * sin(theta * i))*p(3) + z_com - - a = v_col * (m1 + m2) * (1.0_DP / mergeadd_list%mass(nstart + i)) - - vx_frag = ((a * cos(theta * i))*l(1)) + ((a * sin(theta * i))*p(1)) + vx_com - vy_frag = ((a * cos(theta * i))*l(2)) + ((a * sin(theta * i))*p(2)) + vy_com - vz_frag = ((a * cos(theta * i))*l(3)) + ((a * sin(theta * i))*p(3)) + vz_com - - write(*,*) "casedisruption vx_frag", vx_frag - write(*,*) "casedisruption vy_frag", vy_frag - write(*,*) "casedisruption vz_frag", vz_frag - - !vx_frag = ((1.0_DP / frags_added) * (1.0_DP / mergeadd_list%mass(nstart + i)) * ((m1 * v1(1)) + (m2 * v2(1)))) + vx_com !- vbs(1) - !vy_frag = ((1.0_DP / frags_added) * (1.0_DP / mergeadd_list%mass(nstart + i)) * ((m1 * v1(2)) + (m2 * v2(2)))) + vy_com !- vbs(2) - !vz_frag = ((1.0_DP / frags_added) * (1.0_DP / mergeadd_list%mass(nstart + i)) * ((m1 + v1(3)) + (m2 * v2(3)))) + vz_com !- vbs(3) - - !write(*,*) "casedisruption vx_frag", vx_frag - !write(*,*) "casedisruption vy_frag", vy_frag - !write(*,*) "casedisruption vz_frag", vz_frag - - !conservation of angular momentum for velocities of fragments - !a = (((x1(2) * v1(3) * m1) - (x1(3) * v1(2) * m1)) + ((x2(2) * v2(3) * m2) - (x2(3) * v2(2) * m2))) & - ! / mergeadd_list%mass(nmergeadd) - !b = (((x1(3) * v1(1) * m1) - (x1(1) * v1(3) * m1)) + ((x2(3) * v2(1) * m2) - (x2(1) * v2(3) * m2))) & - ! / mergeadd_list%mass(nmergeadd) - !vx_frag = ((1.0_DP / frags_added) * (b / z_frag)) - vbs(1) - !vy_frag = ((1.0_DP / frags_added) * (-a / z_frag)) - vbs(2) - !vz_frag = vz_com - vbs(3) - - mergeadd_list%xh(1,nstart + i) = x_frag - mergeadd_list%xh(2,nstart + i) = y_frag - mergeadd_list%xh(3,nstart + i) = z_frag - mergeadd_list%vh(1,nstart + i) = vx_frag - mergeadd_list%vh(2,nstart + i) = vy_frag - mergeadd_list%vh(3,nstart + i) = vz_frag - - ! tracking linear momentum. - mv = mv + (mergeadd_list%mass(nstart + i) * mergeadd_list%vh(:,nstart + i)) - end do - - write(*, *) "number of fragments added: ", frags_added - ! calculate energy after frag - vnew(:) = mv / mtot ! com of new fragments - enew = 0.5_DP*mtot*dot_product(vnew(:), vnew(:)) - eoffset = eoffset + eold - enew - - ! update fragmax to account for new fragments - fragmax = fragmax + frags_added - write(*,*) "leaving casedisruption" - return - end procedure symba_casedisruption -end submodule s_symba_casedisruption diff --git a/src/symba/symba_casehitandrun.f90 b/src/symba/symba_casehitandrun.f90 deleted file mode 100644 index 201195181..000000000 --- a/src/symba/symba_casehitandrun.f90 +++ /dev/null @@ -1,271 +0,0 @@ -submodule (util) s_symba_casehitandrun -contains - module procedure symba_casehitandrun - !! author: Jennifer L. L. Pouplin and Carlisle A. Wishard - !! - !! Hit-and-run collision - use swiftest -implicit none - integer(I4B) :: nfrag, i, k, index1, index2, frags_added - integer(I4B) :: index1_parent, index2_parent, index_keep_parent, index_rm_parent - integer(I4B) :: name1, name2, index_keep, index_rm, name_keep, name_rm, nstart - real(DP) :: mtot, msun, d_rm, m_rm, r_rm, x_rm, y_rm, z_rm, vx_rm, vy_rm, vz_rm - real(DP) :: rhill_keep, r_circle, theta, radius1, radius2, e, q, semimajor_encounter - real(DP) :: m_rem, m_test, mass1, mass2, enew, eold, semimajor_inward, a, b, v_col - real(DP) :: x_com, y_com, z_com, vx_com, vy_com, vz_com, mass_keep, mass_rm, rhill_rm - real(DP) :: x_frag, y_frag, z_frag, vx_frag, vy_frag, vz_frag, rad_keep, rad_rm - real(DP) :: r_smallestcircle - real(DP), dimension(NDIM) :: vnew, xr, mv, xh_keep, xh_rm, vh_keep, vh_rm, l, kk, p - - !temporary - interface - function cross_product_hitandrun(ar1,ar2) result(ans) - use swiftest - implicit none - real(DP),dimension(3),intent(in) :: ar1,ar2 - real(DP),dimension(3) :: ans - end function cross_product_hitandrun - end interface - -! executable code - - write(*,*) "entering casehitandrun" - - ! set the maximum number of fragments to be added in a hit and run collision (nfrag) - nfrag = 4 - ! pull in the information about the two particles involved in the collision - index1 = plplenc_list%index1(index_enc) - index2 = plplenc_list%index2(index_enc) - index1_parent = symba_plA%index_parent(index1) - index2_parent = symba_plA%index_parent(index2) - name1 = symba_plA%name(index1) - name2 = symba_plA%name(index2) - mass1 = symba_plA%mass(index1) ! the mass of the first particle in the collision not including all it's children - mass2 = symba_plA%mass(index2) - radius1 = symba_plA%radius(index1) - radius2 = symba_plA%radius(index2) - msun = symba_plA%mass(1) - - ! determine which of the two particles in the collision is larger where mass includes the mass of all their children - if (m2 > m1) then - index_keep = index2 - index_rm = index1 - mass_keep = m2 - mass_rm = m1 - rad_keep = rad2 - rad_rm = rad1 - xh_keep = x2 - xh_rm = x1 - vh_keep = v2 - vh_rm = v1 - index_keep_parent = index2_parent - index_rm_parent = index1_parent - name_keep = name2 - name_rm = name1 - else - index_keep = index1 - index_rm = index2 - mass_keep = m1 - mass_rm = m2 - rad_keep = rad1 - rad_rm = rad2 - xh_keep = x1 - xh_rm = x2 - vh_keep = v1 - vh_rm = v2 - index_keep_parent = index1_parent - index_rm_parent = index2_parent - name_keep = name1 - name_rm = name2 - end if - - ! find com - x_com = ((x1(1) * m1) + (x2(1) * m2)) / (m1 + m2) - y_com = ((x1(2) * m1) + (x2(2) * m2)) / (m1 + m2) - z_com = ((x1(3) * m1) + (x2(3) * m2)) / (m1 + m2) - - vx_com = ((v1(1) * m1) + (v2(1) * m2)) / (m1 + m2) - vy_com = ((v1(2) * m1) + (v2(2) * m2)) / (m1 + m2) - vz_com = ((v1(3) * m1) + (v2(3) * m2)) / (m1 + m2) - - ! find collision velocity - v_col = norm2(v2(:) - v1(:)) - - ! find energy pre-frag - eold = 0.5_DP*(m1*dot_product(v1(:), v1(:)) + m2*dot_product(v2(:), v2(:))) - xr(:) = x2(:) - x1(:) - eold = eold - (m1*m2/(norm2(xr(:), xr(:))))) - - write(*, *) "hit and run between particles ", name1, " and ", name2, " at time t = ",t - write(*, *) "particle ", name_keep, " survives; particle ", name_rm, " is fragmented." - - ! add both particles involved in the collision to mergesub_list - nmergesub = nmergesub + 1 - mergesub_list%name(nmergesub) = name1 - mergesub_list%status(nmergesub) = HIT_AND_RUN - mergesub_list%xh(:,nmergesub) = x1(:) - mergesub_list%vh(:,nmergesub) = v1(:) - vbs(:) - mergesub_list%mass(nmergesub) = mass1 - mergesub_list%radius(nmergesub) = rad1 - nmergesub = nmergesub + 1 - mergesub_list%name(nmergesub) = name2 - mergesub_list%status(nmergesub) = HIT_AND_RUN - mergesub_list%xh(:,nmergesub) = x2(:) - mergesub_list%vh(:,nmergesub) = v2(:) - vbs(:) - mergesub_list%mass(nmergesub) = mass2 - mergesub_list%radius(nmergesub) = rad2 - - ! go through the encounter list and look for particles actively encoutering in this timestep - ! prevent them from having further encounters in this timestep by setting status in plplenc_list to merged - do k = 1, nplplenc - if ((plplenc_list%status(k) == ACTIVE) .and. & - ((index1 == plplenc_list%index1(k) .or. index2 == plplenc_list%index2(k)) .or. & - (index2 == plplenc_list%index1(k) .or. index1 == plplenc_list%index2(k)))) then - plplenc_list%status(k) = MERGED - end if - end do - - ! set the status of the particles in symba_plA to hit_and_run - symba_plA%status(index1) = HIT_AND_RUN - symba_plA%status(index2) = HIT_AND_RUN - - l(:) = (v2(:) - v1(:)) / norm2(v2(:)-v1(:)) - p(:) = cross_product_hitandrun(xr(:) / norm2(xr(:)), l(:)) - kk(:) = cross_product_hitandrun(l(:),p(:)) - - mtot = 0.0_DP ! running total mass of new fragments - mv = 0.0_DP ! running sum of m*v of new fragments to be used in com calculation - frags_added = 0 ! running total number of new fragments - nstart = nmergeadd + 1 ! start of new fragments in mergeadd_list - ! increment around the circle for positions of fragments - ! calculate the positions of the new fragments in a circle of radius rhill_keep - rhill_keep = symba_plA%rhill(index_keep_parent) - rhill_rm = symba_plA%rhill(index_rm_parent) - r_smallestcircle = (rhscale * rhill_rm + rhscale * rhill_keep) / (2.0_DP * sin(pi / 2.0_DP)) - - ! check that no fragments will be added interior of the smallest orbit that the timestep can reliably resolve - semimajor_inward = ((dt * 32.0_DP) ** 2.0_DP) ** (1.0_DP / 3.0_DP) - call orbel_xv2aeq(x1, v1, msun, semimajor_encounter, e, q) - ! if they are going to be added interior to this orbit, give a warning - if (semimajor_inward > (semimajor_encounter - r_smallestcircle)) then - write(*,*) "warning in symba_casehitandrun: timestep is too large to resolve fragments." - end if - - ! the largest fragment = the kept parent particle - nmergeadd = nmergeadd + 1 - mergeadd_list%status(nmergeadd) = HIT_AND_RUN - mergeadd_list%ncomp(nmergeadd) = 2 - mergeadd_list%name(nmergeadd) = symba_plA%name(index_keep) - mergeadd_list%mass(nmergeadd) = mass_keep - mergeadd_list%radius(nmergeadd) = rad_keep - mergeadd_list%xh(:,nmergeadd) = xh_keep - mergeadd_list%vh(:,nmergeadd) = vh_keep - mtot = mtot + mergeadd_list%mass(nmergeadd) - - - ! pure hit & run - if (mres(2) > m2 * 0.9_DP) then - frags_added = frags_added + 1 - nmergeadd = nmergeadd + 1 - mergeadd_list%status(nmergeadd) = HIT_AND_RUN - mergeadd_list%ncomp(nmergeadd) = 2 - mergeadd_list%name(nmergeadd) = param%nplmax + param%ntpmax + fragmax + i - 1 - mergeadd_list%mass(nmergeadd) = mass_rm - mergeadd_list%radius(nmergeadd) = rad_rm - mergeadd_list%xh(:,nmergeadd) = xh_rm(:) - mergeadd_list%vh(:,nmergeadd) = vh_rm(:) - mtot = mtot + mergeadd_list%mass(nmergeadd) - else - do i = 1, nfrag - m_rm = mass_rm - r_rm = rad_rm - !x_rm = xh_rm(1) - !y_rm = xh_rm(2) - !z_rm = xh_rm(3) - !vx_rm = vh_rm(1) - !vy_rm = vh_rm(2) - !vz_rm = vh_rm(3) - d_rm = (3.0_DP * m_rm) / (4.0_DP * pi * (r_rm ** 3.0_DP)) - - m_rem = m_rm - mres(2) - frags_added = frags_added + 1 - nmergeadd = nmergeadd + 1 - mergeadd_list%status(nmergeadd) = HIT_AND_RUN - mergeadd_list%ncomp(nmergeadd) = 2 - mergeadd_list%name(nmergeadd) = param%nplmax + param%ntpmax + fragmax + i - 1 - mergeadd_list%mass(nmergeadd) = m_rem / (nfrag - 1) - mergeadd_list%radius(nmergeadd) = ((3.0_DP * mergeadd_list%mass(nmergeadd)) / (4.0_DP * pi * d_rm)) & - ** (1.0_DP / 3.0_DP) - - ! check if these fragments will not be large enough to be resolved and we have only added one fragment - ! previously (aka the slr). this is the perfect hit and run case. - !else if ((i > 2) .and. (mres(2) > m2 * 0.9_DP) .and. frags_added == 1) then - ! if yes, update the mass of the slr to be the mass of the removed particle and give it all the - ! characteristics of the removed particle - - ! mergeadd_list%name(nmergeadd) = symba_plA%name(index_rm) - ! mergeadd_list%mass(nmergeadd) = mass_rm - ! mergeadd_list%radius(nmergeadd) = rad_rm - ! mergeadd_list%xh(:,nmergeadd) = xh_rm - ! mergeadd_list%vh(:,nmergeadd) = vh_rm - ! mtot = mtot - mres(2) + mass_rm - - ! if these fragments will not be large enough to be resolved but we have added more than one fragment - ! previously, add the remaining mass that we need to "make up for" to the mass of the most recent - ! fragment and recalculate the radius. - !else - ! mergeadd_list%mass(nmergeadd) = mergeadd_list%mass(nmergeadd) + m_rem - ! mergeadd_list%radius(nmergeadd) = (((3.0_DP/4.0_DP) * pi) * (mergeadd_list%mass(nmergeadd) / d_rm)) & - ! ** (1.0_DP / 3.0_DP) - !end if - end do - end if - - if (frags_added > 1) then - r_circle = (rhscale * rhill_keep + rhscale * rhill_rm) / (2.0_DP * sin(pi / frags_added)) - theta = (2.0_DP * pi) / (frags_added) - do i=1, frags_added - ! increment around the circle for positions of fragments - x_frag = (r_circle * cos(theta * i))*l(1) + (r_circle * sin(theta * i))*p(1) + x_com - y_frag = (r_circle * cos(theta * i))*l(2) + (r_circle * sin(theta * i))*p(2) + y_com - z_frag = (r_circle * cos(theta * i))*l(3) + (r_circle * sin(theta * i))*p(3) + z_com - - !vx_frag = ((1.0_DP / frags_added) * (1.0_DP / mergeadd_list%mass(nstart + i)) * ((m2 * v2(1)))) !- vbs(1) - !vy_frag = ((1.0_DP / frags_added) * (1.0_DP / mergeadd_list%mass(nstart + i)) * ((m2 * v2(2)))) !- vbs(2) - !vz_frag = ((1.0_DP / frags_added) * (1.0_DP / mergeadd_list%mass(nstart + i)) * ((m2 * v2(3)))) !- vbs(3) - - a = v_col * m2 * (1.0_DP / mergeadd_list%mass(nstart + i)) - - vx_frag = ((a * cos(theta * i))*l(1)) + ((a * sin(theta * i))*p(1)) + vh_rm(1) !+ vx_com - vy_frag = ((a * cos(theta * i))*l(2)) + ((a * sin(theta * i))*p(2)) + vh_rm(2) !+ vy_com - vz_frag = ((a * cos(theta * i))*l(3)) + ((a * sin(theta * i))*p(3)) + vh_rm(3) !+ vz_com - - ! conservation of angular momentum for velocities of fragments - !a = ((y_rm * vz_rm * m_rm) - (z_rm * vy_rm * m_rm)) / mergeadd_list%mass(nmergeadd) - !b = ((z_rm * vx_rm * m_rm) - (x_rm * vz_rm * m_rm)) / mergeadd_list%mass(nmergeadd) - !vx_frag = ((1.0_DP / frags_added) * (b / z_frag)) - vbs(1) - !vy_frag = ((1.0_DP / frags_added) * (-a / z_frag)) - vbs(2) - !vz_frag = vz_com - vbs(3) - - mergeadd_list%xh(1,nstart + i) = x_frag - mergeadd_list%xh(2,nstart + i) = y_frag - mergeadd_list%xh(3,nstart + i) = z_frag - mergeadd_list%vh(1,nstart + i) = vx_frag - mergeadd_list%vh(2,nstart + i) = vy_frag - mergeadd_list%vh(3,nstart + i) = vz_frag - - ! tracking linear momentum. - mv = mv + (mergeadd_list%mass(nmergeadd) * mergeadd_list%vh(:,nmergeadd)) - end do - end if - write(*, *) "number of fragments added: ", (frags_added) - ! calculate energy after frag - vnew(:) = mv / mtot ! com of new fragments - enew = 0.5_DP*mtot*dot_product(vnew(:), vnew(:)) - eoffset = eoffset + eold - enew - ! update fragmax to account for new fragments - fragmax = fragmax + frags_added - write(*,*) "leaving casehitandrun" - return - end procedure symba_casehitandrun -end submodule s_symba_casehitandrun diff --git a/src/symba/symba_casemerge.f90 b/src/symba/symba_casemerge.f90 deleted file mode 100644 index fc45d0964..000000000 --- a/src/symba/symba_casemerge.f90 +++ /dev/null @@ -1,129 +0,0 @@ -submodule (symba) s_symba_casemerge -contains - module procedure symba_casemerge - !! author: Jennifer L. L. Pouplin and Carlisle A. Wishard - !! - !! Merge planetss - !! Adapted from David E. Kaufmann's Swifter routine: symba_merge_pl .f90 - !! Adapted from Hal Levison's Swift routine symba5_merge.f -use swiftest -implicit none - - integer(I4B) :: i, j, k, stat1, stat2, index1, index2, indexchild - integer(I4B) :: index1_child, index2_child, index1_parent, index2_parent - integer(I4B) :: name1, name2 - real(DP) :: mtot - real(DP) :: eold, enew, mass1, mass2 - real(DP), dimension(NDIM) :: xr, xnew, vnew - integer(I4B), dimension(npl) :: array_keep_child, array_rm_child - -! executable code - index1 = plplenc_list%index1(index_enc) - index2 = plplenc_list%index2(index_enc) - index1_parent = symba_plA%index_parent(index1) - index2_parent = symba_plA%index_parent(index2) - mtot = m1 + m2 - xnew(:) = (m1*x1(:) + m2*x2(:))/mtot - vnew(:) = (m1*v1(:) + m2*v2(:))/mtot - name1 = symba_plA%name(index1) - name2 = symba_plA%name(index2) - mass1 = symba_plA%mass(index1) - mass2 = symba_plA%mass(index2) - stat1 = symba_plA%status(index1) - stat2 = symba_plA%status(index2) - write(*, *) "merging particles ", name1, " and ", name2, " at time t = ",t - nmergesub = nmergesub + 1 - mergesub_list%name(nmergesub) = name1 - mergesub_list%status(nmergesub) = MERGED - mergesub_list%xh(:,nmergesub) = x1(:) - mergesub_list%vh(:,nmergesub) = v1(:) - vbs(:) - mergesub_list%mass(nmergesub) = mass1 - mergesub_list%radius(nmergesub) = rad1 - nmergesub = nmergesub + 1 - mergesub_list%name(nmergesub) = name2 - mergesub_list%status(nmergesub) = MERGED - mergesub_list%xh(:,nmergesub) = x2(:) - mergesub_list%vh(:,nmergesub) = v2(:) - vbs(:) - mergesub_list%mass(nmergesub) = mass2 - mergesub_list%radius(nmergesub) = rad2 - nmergeadd = nmergeadd + 1 - if (m2 > m1) then - mergeadd_list%name(nmergeadd) = name2 - mergeadd_list%status(nmergeadd) = stat2 - - else - mergeadd_list%name(nmergeadd) = name1 - mergeadd_list%status(nmergeadd) = stat1 - - end if - mergeadd_list%ncomp(nmergeadd) = 2 - mergeadd_list%xh(:,nmergeadd) = xnew(:) - mergeadd_list%vh(:,nmergeadd) = vnew(:) - vbs(:) - eold = 0.5_DP*(m1*dot_product(v1(:), v1(:)) + m2*dot_product(v2(:), v2(:))) - xr(:) = x2(:) - x1(:) - eold = eold - m1*m2/norm2(xr(:), xr(:))) - enew = 0.5_DP*mtot*dot_product(vnew(:), vnew(:)) - eoffset = eoffset + eold - enew - - do k = 1, nplplenc - if (plplenc_list%status(k) == ACTIVE) then - do i = 0, symba_plA%nchild(index1_parent) - if (i == 0) then - index1_child = index1_parent - else - index1_child = array_index1_child(i) - end if - do j = 0, symba_plA%nchild(index2_parent) - if (j == 0) then - index2_child = index2_parent - else - index2_child = array_index2_child(j) - end if - if ((index1_child == plplenc_list%index1(k)) .and. (index2_child == plplenc_list%index2(k))) then - plplenc_list%status(k) = MERGED - else if ((index1_child == plplenc_list%index2(k)) .and. & - (index2_child == plplenc_list%index1(k))) then - plplenc_list%status(k) = MERGED - end if - end do - end do - end if - end do - - symba_plA%xh(:,index1_parent) = xnew(:) - symba_plA%vb(:,index1_parent) = vnew(:) - symba_plA%xh(:,index2_parent) = xnew(:) - symba_plA%vb(:,index2_parent) = vnew(:) - - ! the children of parent one are the children we are keeping - array_keep_child(1:npl) = symba_plA%index_child(1:npl,index1_parent) - ! go through the children of the kept parent and add those children to the array of kept children - do i = 1, symba_plA%nchild(index1_parent) - indexchild = array_keep_child(i) - symba_plA%xh(:,indexchild) = xnew(:) - symba_plA%vb(:,indexchild) = vnew(:) - end do - ! the removed parent is assigned as a new child to the list of children of the kept parent - ! gives kept parent a new child - symba_plA%index_child((symba_plA%nchild(index1_parent)+1),index1_parent) = index2_parent - array_rm_child(1:npl) = symba_plA%index_child(1:npl,index2_parent) - ! the parent of the removed parent is assigned to be the kept parent - ! gives removed parent a new parent - symba_plA%index_parent(index2) = index1_parent - ! go through the children of the removed parent and add those children to the array of removed children - do i = 1, symba_plA%nchild(index2_parent) - symba_plA%index_parent(array_rm_child(i)) = index1_parent - indexchild = array_rm_child(i) - symba_plA%xh(:,indexchild) = xnew(:) - symba_plA%vb(:,indexchild) = vnew(:) - end do - ! go through the children of the removed parent and add those children to the list of children of the kept parent - do i = 1, symba_plA%nchild(index2_parent) - symba_plA%index_child(symba_plA%nchild(index1_parent)+i+1,index1_parent)= array_rm_child(i) - end do - ! updates the number of children of the kept parent - symba_plA%nchild(index1_parent) = symba_plA%nchild(index1_parent) + symba_plA%nchild(index2_parent) + 1 - - return - end procedure symba_casemerge -end submodule s_symba_casemerge diff --git a/src/symba/symba_caseresolve.f90 b/src/symba/symba_caseresolve.f90 deleted file mode 100644 index cbee34081..000000000 --- a/src/symba/symba_caseresolve.f90 +++ /dev/null @@ -1,46 +0,0 @@ -submodule (symba) s_symba_caseresolve -contains - module procedure symba_caseresolve - !! author: Jennifer L. L. Pouplin and Carlisle A. Wishard - !! - !! Resolve which of the collision regimes to apply -use swiftest -implicit none - -! executable code - - select case (regime) - - case (COLLRESOLVE_REGIME_DISRUPTION) - call symba_casedisruption (t, dt, index_enc, nmergeadd, nmergesub, mergeadd_list, mergesub_list, eoffset, vbs, & - symba_plA, nplplenc, plplenc_list, param%nplmax, param%ntpmax, fragmax, mres, rres, m1, m2, rad1, rad2, x1, x2, v1, v2) - - case (COLLRESOLVE_REGIME_SUPERCATASTROPHIC) - call symba_casesupercatastrophic (t, dt, index_enc, nmergeadd, nmergesub, mergeadd_list, mergesub_list, & - eoffset, vbs, symba_plA, nplplenc, & - plplenc_list, param%nplmax, param%ntpmax, fragmax, mres, rres, m1, m2, rad1, & - rad2, x1, x2, v1, v2) - - case (COLLRESOLVE_REGIME_GRAZE_AND_MERGE) - call symba_casemerge (t, index_enc, nmergeadd, nmergesub, mergeadd_list, mergesub_list, eoffset, vbs, & - npl, symba_plA, nplplenc, plplenc_list, array_index1_child, array_index2_child, m1, m2, rad1, rad2, x1, & - x2, v1, v2) - - case (COLLRESOLVE_REGIME_HIT_AND_RUN) - call symba_casehitandrun (t, dt, index_enc, nmergeadd, nmergesub, mergeadd_list, mergesub_list, eoffset, vbs, & - symba_plA, nplplenc, plplenc_list, & - param%nplmax, param%ntpmax, fragmax, mres, rres, m1, m2, rad1, rad2, x1, x2, v1, v2) - - case (COLLRESOLVE_REGIME_MERGE) - call symba_casemerge (t, index_enc, nmergeadd, nmergesub, mergeadd_list, mergesub_list, eoffset, vbs, & - npl, symba_plA, nplplenc, plplenc_list, array_index1_child, array_index2_child, m1, m2, rad1, rad2, x1, & - x2, v1, v2) - - case default - write(*,*) "Error in symba_caseresolve, no regime selected" - end select - - -return - end procedure symba_caseresolve -end submodule s_symba_caseresolve diff --git a/src/symba/symba_casesupercatastrophic.f90 b/src/symba/symba_casesupercatastrophic.f90 deleted file mode 100644 index 04aa1bfa7..000000000 --- a/src/symba/symba_casesupercatastrophic.f90 +++ /dev/null @@ -1,253 +0,0 @@ -submodule (symba) s_symba_casesupercatastrophic -contains - module procedure symba_casesupercatastrophic - !! author: Jennifer L. L. Pouplin and Carlisle A. Wishard - !! - !! Supercatastrophic disruption event - use swiftest -implicit none - integer(I4B) :: nfrag, i, k, index1, index2, frags_added - integer(I4B) :: index1_parent, index2_parent - integer(I4B) :: name1, name2, nstart - real(DP) :: mtot, msun, avg_d, d_p1, d_p2, semimajor_encounter, e, q, semimajor_inward - real(DP) :: rhill_p1, rhill_p2, r_circle, theta, radius1, radius2, r_smallestcircle - real(DP) :: m_rem, m_test, mass1, mass2, enew, eold, a, b, v_col - real(DP) :: x_com, y_com, z_com, vx_com, vy_com, vz_com - real(DP) :: x_frag, y_frag, z_frag, vx_frag, vy_frag, vz_frag, m1m2_10 - real(DP), dimension(NDIM) :: vnew, xr, mv, l, kk, p - - !temporary - interface - function cross_product_supercatastrophic(ar1,ar2) result(ans) - use swiftest - implicit none - real(DP),dimension(3),intent(in) :: ar1,ar2 - real(DP),dimension(3) :: ans - end function cross_product_supercatastrophic - end interface - -! executable code - - write(*,*) "entering casesupercatastrophic" - ! set the maximum number of fragments to be added in a supercatastrophic disruption collision (nfrag) - nfrag = 10 - ! pull in the information about the two particles involved in the collision - index1 = plplenc_list%index1(index_enc) - index2 = plplenc_list%index2(index_enc) - index1_parent = symba_plA%index_parent(index1) - index2_parent = symba_plA%index_parent(index2) - name1 = symba_plA%name(index1) - name2 = symba_plA%name(index2) - mass1 = symba_plA%mass(index1) ! the mass of the first particle in the collision not including all it's children - mass2 = symba_plA%mass(index2) - radius1 = symba_plA%radius(index1) - radius2 = symba_plA%radius(index2) - msun = symba_plA%mass(1) - - ! find com - x_com = ((x1(1) * m1) + (x2(1) * m2)) / (m1 + m2) - y_com = ((x1(2) * m1) + (x2(2) * m2)) / (m1 + m2) - z_com = ((x1(3) * m1) + (x2(3) * m2)) / (m1 + m2) - - vx_com = ((v1(1) * m1) + (v2(1) * m2)) / (m1 + m2) - vy_com = ((v1(2) * m1) + (v2(2) * m2)) / (m1 + m2) - vz_com = ((v1(3) * m1) + (v2(3) * m2)) / (m1 + m2) - - ! find collision velocity - v_col = norm2(v2(:) - v1(:)) - - ! find energy pre-frag - eold = 0.5_DP*(m1*dot_product(v1(:), v1(:)) + m2*dot_product(v2(:), v2(:))) - xr(:) = x2(:) - x1(:) - eold = eold - (m1*m2/(norm2(xr(:), xr(:))))) - - write(*, *) "supercatastrophic disruption between particles ", name1, " and ", name2, " at time t = ",t - - ! add both particles involved in the collision to mergesub_list - nmergesub = nmergesub + 1 - mergesub_list%name(nmergesub) = name1 - mergesub_list%status(nmergesub) = SUPERCATASTROPHIC - mergesub_list%xh(:,nmergesub) = x1(:) - mergesub_list%vh(:,nmergesub) = v1(:) - vbs(:) - mergesub_list%mass(nmergesub) = mass1 - mergesub_list%radius(nmergesub) = radius1 - nmergesub = nmergesub + 1 - mergesub_list%name(nmergesub) = name2 - mergesub_list%status(nmergesub) = SUPERCATASTROPHIC - mergesub_list%xh(:,nmergesub) = x2(:) - mergesub_list%vh(:,nmergesub) = v2(:) - vbs(:) - mergesub_list%mass(nmergesub) = mass2 - mergesub_list%radius(nmergesub) = radius2 - - ! go through the encounter list and look for particles actively encoutering in this timestep - ! prevent them from having further encounters in this timestep by setting status in plplenc_list to merged - do k = 1, nplplenc - if ((plplenc_list%status(k) == ACTIVE) .and. & - ((index1 == plplenc_list%index1(k) .or. index2 == plplenc_list%index2(k)) .or. & - (index2 == plplenc_list%index1(k) .or. index1 == plplenc_list%index2(k)))) then - plplenc_list%status(k) = MERGED - end if - end do - - ! set the status of the particles in symba_plA to disruption - symba_plA%status(index1) = SUPERCATASTROPHIC - symba_plA%status(index2) = SUPERCATASTROPHIC - - l(:) = (v2(:) - v1(:)) / norm2(v2(:)-v1(:)) - p(:) = cross_product_supercatastrophic(xr(:) / norm2(xr(:)), l(:)) - kk(:) = cross_product_supercatastrophic(l(:),p(:)) - - ! calculate the positions of the new fragments in a circle with a radius large enough to space - ! all fragments apart by a distance of rhill_p1 + rhill_p2 - rhill_p1 = symba_plA%rhill(index1_parent) - rhill_p2 = symba_plA%rhill(index2_parent) - r_smallestcircle = (rhscale * rhill_p1 + rhscale * rhill_p2) / (2.0_DP * sin(pi /2.0_DP)) - - ! check that no fragments will be added interior of the smallest orbit that the timestep can reliably resolve - semimajor_inward = ((dt * 32.0_DP) ** 2.0_DP) ** (1.0_DP / 3.0_DP) - call orbel_xv2aeq(x1, v1, msun, semimajor_encounter, e, q) - ! if they are going to be added interior to this orbit, give a warning - if (semimajor_inward > (semimajor_encounter - r_smallestcircle)) then - write(*,*) "warning in symba_casesupercatastrophic: timestep is too large to resolve fragments." - end if - ! if not, continue through all possible fragments to be added - mtot = 0.0_DP ! running total mass of new fragments - mv = 0.0_DP ! running sum of m*v of new fragments to be used in com calculation - frags_added = 0 ! running total number of new fragments - m1m2_10 = 0.1_DP * (m1 + m2) ! one tenth the total initial mass of the system used to check the size of the fragments - nstart = nmergeadd - - d_p1 = (3.0_DP * m1) / (4.0_DP * pi * (rad1 ** 3.0_DP)) - d_p2 = (3.0_DP * m2) / (4.0_DP * pi * (rad2 ** 3.0_DP)) - avg_d = ((m1 * d_p1) + (m2 * d_p2)) / (m1 + m2) - - ! if we are adding the first and largest fragment (lr), check to see if its mass is smaller than one tenth the total - ! mass of the system aka if it is too small to resolve. if so, add a fragment with a mass of one tenth the total mass - ! of the system and calculate its radius. - if ((mres(1) < m1m2_10)) then - do i = 1, nfrag - frags_added = frags_added + 1 - nmergeadd = nmergeadd + 1 - mergeadd_list%name(nmergeadd) = param%nplmax + param%ntpmax + fragmax + i - mergeadd_list%status(nmergeadd) = SUPERCATASTROPHIC - mergeadd_list%ncomp(nmergeadd) = 2 - mergeadd_list%mass(nmergeadd) = m1m2_10 - mergeadd_list%radius(nmergeadd) = ((3.0_DP * mergeadd_list%mass(nmergeadd)) / (4.0_DP * pi * avg_d)) & - ** (1.0_DP / 3.0_DP) - mtot = mtot + mergeadd_list%mass(nmergeadd) - end do - end if - ! if we are adding the first and largest fragment (lr), check to see if its mass is larger than one tenth the total - ! mass of the system aka if it is large enough to resolve. if so, its mass and radius should be taken from - ! util_regime. - if ((mres(1) > m1m2_10)) then - frags_added = frags_added + 1 - nmergeadd = nmergeadd + 1 - mergeadd_list%name(nmergeadd) = param%nplmax + param%ntpmax + fragmax + i - mergeadd_list%status(nmergeadd) = SUPERCATASTROPHIC - mergeadd_list%ncomp(nmergeadd) = 2 - mergeadd_list%mass(nmergeadd) = mres(1) - mergeadd_list%radius(nmergeadd) = rres(1) - mtot = mtot + mergeadd_list%mass(nmergeadd) - do i = 2, nfrag - frags_added = frags_added + 1 - nmergeadd = nmergeadd + 1 - mergeadd_list%name(nmergeadd) = param%nplmax + param%ntpmax + fragmax + i - mergeadd_list%status(nmergeadd) = SUPERCATASTROPHIC - mergeadd_list%ncomp(nmergeadd) = 2 - mergeadd_list%mass(nmergeadd) = (m1 + m2 - mres(1)) / (nfrag - 1.0_DP) - mergeadd_list%radius(nmergeadd) = ((3.0_DP * mergeadd_list%mass(nmergeadd)) / (4.0_DP * pi * avg_d)) & - ** (1.0_DP / 3.0_DP) - mtot = mtot + mergeadd_list%mass(nmergeadd) - end do - end if - - - !end if - ! if we are adding more than one fragment - !if ((i > 1) .and. (mres(1) > m1m2_10)) then - ! m_rem is the mass needed to be "made up for" in fragments, mres(1) is the mass of the largest fragments - ! that has already been added, and m1 and m2 are the masses of the original particles involved in the collision. - ! m_rem = (m1 + m2) - (mergeadd_list%mass(nmergeadd)) - ! check if these fragments will be large enough to be resolved - ! if (m_rem > (1.0_DP / 10.0_DP)*mres(1))) then - - ! if yes, add a fragment using durda et al 2007 figure 2 supercatastrophic: n = (1.5e5)e(-1.3*d) for the mass - ! frags_added = frags_added + 1 - ! nmergeadd = nmergeadd + 1 - ! mergeadd_list%name(nmergeadd) = param%nplmax + param%ntpmax + fragmax + i - ! mergeadd_list%status(nmergeadd) = SUPERCATASTROPHIC - ! mergeadd_list%ncomp(nmergeadd) = 2 - ! mergeadd_list%mass(nmergeadd) = m_rem / (nfrag - 1) - - ! create a "test mass" using durda et al 2007 figure 2 supercatastrophic: n = (1.5e5)e(-1.3*d) - !m_test = (((- 1.0_DP / 2.6_DP) * log(i / (1.5_DP * 10.0_DP ** 5))) ** 3.0_DP) * ((4.0_DP / 3.0_DP) & - ! * pi * avg_d) - ! if the test mass is smaller than the mass that needs to be "made up for", add it. - !if (m_test < m_rem) then - ! mergeadd_list%mass(nmergeadd) = m_test - ! if not, aka if the test mass is too large, then add a fragment with a mass equal to the difference between - ! the sum of the mass of the parents and the total mass already added. - !else - ! mergeadd_list%mass(nmergeadd) = (m1 + m2) - mtot - !end if - - ! calculate the radius of the fragments using the weighted average density of the parents. - ! mergeadd_list%radius(nmergeadd) = ((3.0_DP * mergeadd_list%mass(nmergeadd)) / (4.0_DP * pi * avg_d)) & - ! ** (1.0_DP / 3.0_DP) - ! mtot = mtot + mergeadd_list%mass(nmergeadd) - ! else - ! mergeadd_list%mass(nmergeadd) = mergeadd_list%mass(nmergeadd) + m_rem - ! mergeadd_list%radius(nmergeadd) = (((3.0_DP/4.0_DP) * pi) * (mergeadd_list%mass(nmergeadd) / avg_d)) & - ! ** (1.0_DP / 3.0_DP) - ! end if - !end if - - r_circle = (rhscale * rhill_p1 + rhscale * rhill_p2) / (2.0_DP * sin(pi / frags_added)) - theta = (2.0_DP * pi) / frags_added - - do i=1, frags_added - - ! increment around the circle for positions of fragments - x_frag = (r_circle * cos(theta * i))*l(1) + (r_circle * sin(theta * i))*p(1) + x_com - y_frag = (r_circle * cos(theta * i))*l(2) + (r_circle * sin(theta * i))*p(2) + y_com - z_frag = (r_circle * cos(theta * i))*l(3) + (r_circle * sin(theta * i))*p(3) + z_com - - a = v_col * (m1 + m2) * (1.0_DP / mergeadd_list%mass(nstart + i)) - - vx_frag = ((a * cos(theta * i))*l(1)) + ((a * sin(theta * i))*p(1)) + vx_com - vy_frag = ((a * cos(theta * i))*l(2)) + ((a * sin(theta * i))*p(2)) + vy_com - vz_frag = ((a * cos(theta * i))*l(3)) + ((a * sin(theta * i))*p(3)) + vz_com - - !conservation of angular momentum for velocities of fragments - !a = (((x1(2) * v1(3) * m1) - (x1(3) * v1(2) * m1)) + ((x2(2) * v2(3) * m2) - (x2(3) * v2(2) * m2))) & - ! / mergeadd_list%mass(nmergeadd) - !b = (((x1(3) * v1(1) * m1) - (x1(1) * v1(3) * m1)) + ((x2(3) * v2(1) * m2) - (x2(1) * v2(3) * m2))) & - ! / mergeadd_list%mass(nmergeadd) - !vx_frag = ((1.0_DP / frags_added) * (b / z_frag)) - vbs(1) - !vy_frag = ((1.0_DP / frags_added) * (-a / z_frag)) - vbs(2) - !vz_frag = vz_com - vbs(3) - - mergeadd_list%xh(1,nstart + i) = x_frag - mergeadd_list%xh(2,nstart + i) = y_frag - mergeadd_list%xh(3,nstart + i) = z_frag - mergeadd_list%vh(1,nstart + i) = vx_frag - mergeadd_list%vh(2,nstart + i) = vy_frag - mergeadd_list%vh(3,nstart + i) = vz_frag - ! tracking linear momentum. - mv = mv + (mergeadd_list%mass(nstart + i) * mergeadd_list%vh(:,nstart + i)) - end do - - write(*, *) "number of fragments added: ", frags_added - ! calculate energy after frag - vnew(:) = mv / mtot ! com of new fragments - enew = 0.5_DP*mtot*dot_product(vnew(:), vnew(:)) - eoffset = eoffset + eold - enew - - ! update fragmax to account for new fragments - fragmax = fragmax + frags_added - write(*,*) "leaving casesupercatastrophic" - - return - end procedure symba_casesupercatastrophic -end submodule s_symba_casesupercatastrophic diff --git a/src/symba/symba_chk.f90 b/src/symba/symba_chk.f90 deleted file mode 100644 index 08f222a07..000000000 --- a/src/symba/symba_chk.f90 +++ /dev/null @@ -1,26 +0,0 @@ -submodule (symba) s_symba_chk -contains - module procedure symba_chk - !! 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 -use swiftest -implicit none - integer(I4B) :: iflag - real(DP) :: rcrit, r2crit, vdotr - - 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 procedure symba_chk -end submodule s_symba_chk diff --git a/src/symba/symba_chk_eucl.f90 b/src/symba/symba_chk_eucl.f90 deleted file mode 100644 index b8e2d1e85..000000000 --- a/src/symba/symba_chk_eucl.f90 +++ /dev/null @@ -1,73 +0,0 @@ -submodule (symba) s_symba_chk_eucl -contains - module procedure symba_chk_eucl - !! author: Jacob R. Elliott - !! - !! Check for an encounter, but use the single-loop blocking to evaluate the Euclidean distance matrix - !! - !! Adapted from David E. Kaufmann's Swifter routine: symba_chk.f90 - !! Adapted from Hal Levison's Swift routine symba5_chk.f -use swiftest -implicit none - ! logical :: iflag lvdotr_flag - real(DP) :: rcrit, r2crit, vdotr, r2, v2, tmin, r2min, term2, rcritmax, r2critmax - integer(I4B) :: k - real(DP), dimension(NDIM):: xr, vr - -! executable code - - nplplenc = 0 - - term2 = rhscale*rshell**0 - - rcritmax = (symba_plA%rhill(2) + symba_plA%rhill(3)) * term2 - r2critmax = rcritmax * rcritmax - -!$omp parallel do default(none) schedule(static) & -!$omp num_threads(min(omp_get_max_threads(),ceiling(num_encounters/10000.))) & -!$omp private(k, rcrit, r2crit, r2, vdotr, v2, tmin, r2min, xr, vr) & -!$omp shared(num_encounters, lvdotr, lencounter, k_plpl, dt, term2, r2critmax, symba_plA) & -!$omp reduction(+:nplplenc) - - do k = 1,num_encounters - xr(:) = symba_plA%xh(:,k_plpl(2,k)) - symba_plA%xh(:,k_plpl(1,k)) - - r2 = dot_product(xr(:), xr(:)) - if (r2 mmax) then - mmax = m - indexk = indexchild - end if - end do - x(:) = x(:)/mtot - v(:) = v(:)/mtot - r = r3**(1.0_DP/3.0_DP) - symba_plA%mass(indexk) = mtot - symba_plA%radius(indexk) = r - symba_plA%xh(:,indexk) = x(:) - symba_plA%vb(:,indexk) = v(:) - symba_plA%vh(:,indexk) = v(:) - vbs(:) - mu = msun*mtot/(msun + mtot) - r = norm2(x(:)) - v(:) = symba_plA%vh(:,indexk) - 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) - symba_plA%rhill(indexk) = ap*(((mu/msun)/3.0_DP)**(1.0_DP/3.0_DP)) - array_child(1:npl) = symba_plA%index_child(1:npl,enc_big) - indexchild = enc_big - ldiscard = .true. - do j = 0, nchild - if (indexchild /= indexk) then - symba_plA%status(indexchild) = MERGED - end if - indexchild = array_child(j+1) - end do - - else if ((symba_plA%status(index1) == DISRUPTION) .and. & - (symba_plA%status(index2) == DISRUPTION)) then - - enc_big = plplenc_list%index1(i) - nchild = symba_plA%nchild(enc_big) - array_child(1:npl) = symba_plA%index_child(1:npl,enc_big) - do j = 1, nchild - symba_plA%status(array_child(j)) = INACTIVE - end do - ldiscard = .true. - else if ((symba_plA%status(index1) == SUPERCATASTROPHIC) .and. & - (symba_plA%status(index2) == SUPERCATASTROPHIC)) then - - enc_big = plplenc_list%index1(i) - nchild = symba_plA%nchild(enc_big) - array_child(1:npl) = symba_plA%index_child(1:npl,enc_big) - do j = 1, nchild - symba_plA%status(array_child(j)) = INACTIVE - end do - ldiscard = .true. - else if ((symba_plA%status(index1) == HIT_AND_RUN) .and. & - (symba_plA%status(index2) == HIT_AND_RUN)) then - - enc_big = plplenc_list%index1(i) - nchild = symba_plA%nchild(enc_big) - array_child(1:npl) = symba_plA%index_child(1:npl,enc_big) - do j = 1, nchild - symba_plA%status(array_child(j)) = INACTIVE - end do - ldiscard = .true. - else if ((symba_plA%status(index1) == GRAZE_AND_MERGE) .and. & - (symba_plA%status(index2) == GRAZE_AND_MERGE)) then - - enc_big = plplenc_list%index1(i) - nchild = symba_plA%nchild(enc_big) - array_child(1:npl) = symba_plA%index_child(1:npl,enc_big) - do j = 1, nchild - symba_plA%status(array_child(j)) = INACTIVE - end do - ldiscard = .true. - end if - end if - end do - - return - - end procedure symba_discard_merge_pl -end submodule s_symba_discard_merge_pl diff --git a/src/symba/symba_discard_peri_pl.f90 b/src/symba/symba_discard_peri_pl.f90 deleted file mode 100644 index a78b6e57d..000000000 --- a/src/symba/symba_discard_peri_pl.f90 +++ /dev/null @@ -1,42 +0,0 @@ -submodule (symba) s_symba_discard_peri_pl -contains - module procedure symba_discard_peri_pl - !! author: David A. Minton - !! - !! Check to see if planets should be discarded based on their pericenter distances - !! - !! Adapted from David E. Kaufmann's Swifter routine: symba_discard_peri_pl.f90 - !! Adapted from Hal Levison's Swift routine discard_mass_peri.f -use swiftest -implicit none - logical , save :: lfirst = .true. - integer(I4B) :: i, j, ih - real(DP) :: r2 - real(DP), dimension(NDIM) :: dx - - -! executable code - if (lfirst) then - call symba_peri(lfirst, npl, symba_plA, msys, qmin_coord) - lfirst = .false. - else - call symba_peri(lfirst, npl, symba_plA, msys, qmin_coord) - do i = 2, npl - if (symba_plA%status(i) == ACTIVE) then - if ((symba_plA%isperi(i) == 0) .and. (symba_plA%nplenc(i)== 0)) then - if ((symba_plA%atp(i) >= qmin_alo) .and. (symba_plA%atp(i) <= qmin_ahi) & - .and. (symba_plA%peri(i) <= qmin)) then - ldiscards = .true. - symba_plA%status(i) = DISCARDED_PERI - write(*, *) "particle ", symba_plA%name(i), & - " perihelion distance too small at t = ", t - end if - end if - end if - end do - end if - - return - - end procedure symba_discard_peri_pl -end submodule s_symba_discard_peri_pl diff --git a/src/symba/symba_discard_pl.f90 b/src/symba/symba_discard_pl.f90 deleted file mode 100644 index e5a7803a7..000000000 --- a/src/symba/symba_discard_pl.f90 +++ /dev/null @@ -1,28 +0,0 @@ -submodule (symba) s_symba_discard_pl -contains - module procedure symba_discard_pl - !! author: David A. Minton - !! - !! Check to see if planets should be discarded based on their positions or because they are unbound - !! - !! Adapted from David E. Kaufmann's Swifter routine: symba_discard_pl.f90 - !! Adapted from Hal Levison's Swift routine discard_massive5.f -use swiftest -implicit none - logical :: ldiscards - integer(I4B) :: i - real(DP) :: msys, ke, pe, tei, tef - real(DP), dimension(NDIM) :: htot - -! executable code - ldiscards = .false. - if ((rmin >= 0.0_DP) .or. (rmax >= 0.0_DP) .or. (param%rmaxu >= 0.0_DP) .or. ((qmin >= 0.0_DP) .and. (qmin_coord == "bary"))) & - call coord_h2b(npl, symba_plA, msys) - if ((rmin >= 0.0_DP) .or. (rmax >= 0.0_DP) .or. (param%rmaxu >= 0.0_DP)) & - call symba_discard_sun_pl(t, npl, msys, symba_plA, rmin, rmax, param%rmaxu, ldiscards) - if (qmin >= 0.0_DP) call symba_discard_peri_pl(t, npl, symba_plA, msys, qmin, qmin_alo, qmin_ahi, qmin_coord, ldiscards) - - return - - end procedure symba_discard_pl -end submodule s_symba_discard_pl diff --git a/src/symba/symba_discard_sun_pl.f90 b/src/symba/symba_discard_sun_pl.f90 deleted file mode 100644 index a66b2f316..000000000 --- a/src/symba/symba_discard_sun_pl.f90 +++ /dev/null @@ -1,49 +0,0 @@ -submodule (symba) s_symba_discard_sun_pl -contains - module procedure symba_discard_sun_pl - !! author: David A. Minton - !! - !! Check to see if planets should be discarded based on their positions relative to the Sun - !! - !! Adapted from David E. Kaufmann's Swifter routine: symba_discard_sun_pl.f90 - !! Adapted from Hal Levison's Swift routine discard_massive5.f -use swiftest -implicit none - integer(I4B) :: i - real(DP) :: energy, vb2, rb2, rh2, rmin2, rmax2, param%rmaxu2 - - -! executable code - rmin2 = rmin*rmin - rmax2 = rmax*rmax - param%rmaxu2 = param%rmaxu*param%rmaxu - do i = 2, npl - if (swiftest_plA%status(i) == ACTIVE) then - rh2 = dot_product(swiftest_plA%xh(:,i), swiftest_plA%xh(:,i)) - if ((rmax >= 0.0_DP) .and. (rh2 > rmax2)) then - ldiscards = .true. - swiftest_plA%status(i) = DISCARDED_RMAX - write(*, *) "particle ", swiftest_plA%name(i), " too far from sun at t = ", t - print *,'rmax: ',rmax - print *,'rh2: ',rh2 - else if ((rmin >= 0.0_DP) .and. (rh2 < rmin2)) then - ldiscards = .true. - swiftest_plA%status(i) = DISCARDED_RMIN - write(*, *) "particle ", swiftest_plA%name(i), " too close to sun at t = ", t - else if (param%rmaxu >= 0.0_DP) then - rb2 = dot_product(swiftest_plA%xb(:,i), swiftest_plA%xb(:,i)) - vb2 = dot_product(swiftest_plA%vb(:,i), swiftest_plA%vb(:,i)) - energy = 0.5_DP*vb2 - msys/sqrt(rb2) - if ((energy > 0.0_DP) .and. (rb2 > param%rmaxu2)) then - ldiscards = .true. - swiftest_plA%status(i) = discarded_param%rmaxu - write(*, *) "particle ", swiftest_plA%name(i), " is unbound and too far from barycenter at t = ", t - end if - end if - end if - end do - - return - - end procedure symba_discard_sun_pl -end submodule s_symba_discard_sun_pl diff --git a/src/symba/symba_discard_tp.f90 b/src/symba/symba_discard_tp.f90 deleted file mode 100644 index 660283b87..000000000 --- a/src/symba/symba_discard_tp.f90 +++ /dev/null @@ -1,21 +0,0 @@ -submodule (symba) s_symba_discard_tp -contains - module procedure symba_discard_tp - !! author: David A. Minton - !! - !! Call discard routine to determine spilled test particles, then remove them from ACTIVE list - !! - !! Adapted from David E. Kaufmann's Swifter routine: symba_discard_tp.f90 -use swiftest -implicit none - logical :: lclosel = .false. - integer(I4B) :: i - -! executable code - call discard_tpt, dt, npl, ntp, symba_plA, symba_tpA, rmin, rmax, param%rmaxu, qmin, & - qmin_alo, qmin_ahi, qmin_coord, lclosel, & - lrhill_present) - return - - end procedure symba_discard_tp -end submodule s_symba_discard_tp diff --git a/src/symba/symba_encounter_check.f90 b/src/symba/symba_encounter_check.f90 new file mode 100644 index 000000000..ce4b53dff --- /dev/null +++ b/src/symba/symba_encounter_check.f90 @@ -0,0 +1,30 @@ +submodule (symba_classes) s_symba_encounter_check + use swiftest +contains + module function symba_encounter_check_pl(self, system, dt) result(lencounter) + 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 + ! Result + logical :: lencounter !! Returns true if there is at least one close encounter + + lencounter = .false. + return + end function symba_encounter_check_pl + + module function symba_encounter_check_tp(self, system, dt) result(lencounter) + 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 + ! Result + logical :: lencounter !! Returns true if there is at least one close encounter + + lencounter = .false. + return + end function symba_encounter_check_tp + +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 deleted file mode 100644 index cc351f180..000000000 --- a/src/symba/symba_fragmentation.f90 +++ /dev/null @@ -1,221 +0,0 @@ -submodule (symba) s_symba_fragmentation -contains - module procedure symba_fragmentation - !! author: Jennifer L. L. Pouplin and Carlisle A. Wishard - !! - !! Generate new particles resulting from collisions -use swiftest -implicit none - - integer(I4B) :: model, nres, i, itarg, iproj - real(DP), dimension(3) :: mres, rres - real(DP), dimension(NDIM, 3) :: pres, vres - integer(I4B) :: regime - integer(I4B) :: index1, index2, index1_child, index2_child, index1_parent, index2_parent - integer(I4B) :: name1, name2, index_big1, index_big2, stat1, stat2 - real(DP) :: r2, rlim, rlim2, vdotr, tcr2, dt2, a, e, q - real(DP) :: rad1, rad2, m1, m2, den1, den2, vol1, vol2, vchild, dentarg, denproj, dentot, mcenter - real(DP) :: mass1, mass2, mmax, mtmp, mtot, m1_si, m2_si - real(DP), dimension(NDIM) :: xr, vr, x1, v1, x2, v2, x1_si, x2_si, v1_si, v2_si, xproj, xtarg, vproj, vtarg - real(DP) :: den1_si, den2_si, rad1_si, rad2_si, rproj, rtarg - logical :: lfrag_add, lmerge - integer(I4B), dimension(npl) :: array_index1_child, array_index2_child - real(DP) :: mlr, mslr, mtarg, mproj - !real(DP) :: k2 = 2.959122082855911e-4 ! in si units - !real(DP) :: msun = 1.98847e30 ! in si units - !real(DP) :: au = 1.495978707e11 ! in si units - !real(DP) :: year = 3.154e7 ! in si units - - -! executable code - - lmerge = .false. - lfrag_add = .false. - ! model 2 is the model for collresolve_resolve (ls12) - model = 2 - - index1 = plplenc_list%index1(index_enc) - index2 = plplenc_list%index2(index_enc) - - rlim = symba_plA%radius(index1) + symba_plA%radius(index2) - xr(:) = symba_plA%xh(:,index2) - symba_plA%xh(:,index1) - r2 = dot_product(xr(:), xr(:)) - rlim2 = rlim*rlim - ! checks if bodies are actively colliding in this time step - if (rlim2 >= r2) then - lfrag_add = .true. - ! 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 - else - vr(:) = symba_plA%vb(:,index2) - symba_plA%vb(:,index1) - vdotr = dot_product(xr(:), vr(:)) - if (plplenc_list%lvdotr(index_enc) .and. (vdotr > 0.0_DP)) then - tcr2 = r2/dot_product(vr(:), vr(:)) - dt2 = dt*dt - if (tcr2 <= dt2) then - mtot = symba_plA%mass(index1) + symba_plA%mass(index2) - call orbel_xv2aeq(xr(:), vr(:), mtot, a, e, q) - if (q < rlim) lfrag_add = .true. - end if - ! if no collision is going to happen, write as close encounter, not merger - if (.not. lfrag_add) then - if (encounter_file /= "") then - name1 = symba_plA%name(index1) - m1 = symba_plA%mass(index1) - rad1 = symba_plA%radius(index1) - x1(:) = symba_plA%xh(:,index1) - v1(:) = symba_plA%vb(:,index1) - vbs(:) - name2 = symba_plA%name(index2) - m2 = symba_plA%mass(index2) - rad2 = symba_plA%radius(index2) - x2(:) = symba_plA%xh(:,index2) - v2(:) = symba_plA%vb(:,index2) - vbs(:) - - call io_write_encounter(t, name1, name2, m1, m2, rad1, rad2, x1(:), x2(:), & - v1(:), v2(:), encounter_file, out_type) - end if - end if - end if - end if - - nres = 2 - if (lfrag_add) then - symba_plA%lmerged(index1) = .true. - symba_plA%lmerged(index2) = .true. - index1_parent = symba_plA%index_parent(index1) - m1 = symba_plA%mass(index1_parent) - mass1 = m1 - x1(:) = m1*symba_plA%xh(:,index1_parent) - v1(:) = m1*symba_plA%vb(:,index1_parent) - mmax = m1 - name1 = symba_plA%name(index1_parent) - index_big1 = index1_parent - stat1 = symba_plA%status(index1_parent) - array_index1_child(1:npl) = symba_plA%index_child(1:npl,index1_parent) - - vol1 = ((4.0_DP / 3.0_DP) * pi * symba_plA%radius(index1_parent)**3.0_DP) - do i = 1, symba_plA%nchild(index1_parent) ! initialize an array of children - index1_child = array_index1_child(i) - mtmp = symba_plA%mass(index1_child) - vchild = ((4.0_DP / 3.0_DP) * pi * symba_plA%radius(index1_child)**3.0_DP) - vol1 = vol1 + vchild - if (mtmp > mmax) then - mmax = mtmp - name1 = symba_plA%name(index1_child) - index_big1 = index1_child - stat1 = symba_plA%status(index1_child) - end if - m1 = m1 + mtmp - x1(:) = x1(:) + mtmp*symba_plA%xh(:,index1_child) - v1(:) = v1(:) + mtmp*symba_plA%vb(:,index1_child) - end do - den1 = m1 / vol1 - rad1 = ((3.0_DP * m1) / (den1 * 4.0_DP * pi)) ** (1.0_DP / 3.0_DP) - x1(:) = x1(:)/m1 - v1(:) = v1(:)/m1 - - index2_parent = symba_plA%index_parent(index2) - m2 = symba_plA%mass(index2_parent) - mass2 = m2 - rad2 = symba_plA%radius(index2_parent) - x2(:) = m2*symba_plA%xh(:,index2_parent) - v2(:) = m2*symba_plA%vb(:,index2_parent) - mmax = m2 - name2 = symba_plA%name(index2_parent) - index_big2 = index2_parent - stat2 = symba_plA%status(index2_parent) - array_index2_child(1:npl) = symba_plA%index_child(1:npl,index2_parent) - - vol2 = ((4.0_DP / 3.0_DP) * pi * symba_plA%radius(index2_parent)**3.0_DP) - do i = 1, symba_plA%nchild(index2_parent) - index2_child = array_index2_child(i) - mtmp = symba_plA%mass(index2_child) - vchild = ((4.0_DP / 3.0_DP) * pi * symba_plA%radius(index2_child)**3.0_DP) - vol2 = vol2 + vchild - if (mtmp > mmax) then - mmax = mtmp - name2 = symba_plA%name(index2_child) - index_big2 = index2_child - stat2 = symba_plA%status(index2_child) - end if - m2 = m2 + mtmp - x2(:) = x2(:) + mtmp*symba_plA%xh(:,index2_child) - v2(:) = v2(:) + mtmp*symba_plA%vb(:,index2_child) - end do - GU = GC / (DU2M**3 / (MU2KG * TU2S**2)) - den2 = m2 / vol2 - rad2 = ((3.0_DP * m2) / (den2 * 4.0_DP * pi)) ** (1.0_DP / 3.0_DP) - x2(:) = x2(:)/m2 - v2(:) = v2(:)/m2 - - m1_si = (m1 / GU) * MU2KG - m2_si = (m2 / GU) * MU2KG - rad1_si = rad1 * DU2M - rad2_si = rad2 * DU2M - x1_si(:) = x1(:) * DU2M - x2_si(:) = x2(:) * DU2M - v1_si(:) = v1(:) * DU2M / TU2S - v2_si(:) = v2(:) * DU2M / TU2S - den1_si = (den1 / GU) * MU2KG / (DU2M ** 3.0_DP) - den2_si = (den2 / GU) * MU2KG / (DU2M ** 3.0_DP) - - mres(:) = 0.0_DP - rres(:) = 0.0_DP - pres(:,:) = 0.0_DP - vres(:,:) = 0.0_DP - - if (m1_si > m2_si) then - itarg = index1 - iproj = index2 - dentarg = den1_si - denproj = den2_si - mtarg = m1_si - mproj = m2_si - rtarg = rad1_si - rproj = rad2_si - xtarg(:) = x1_si(:) - xproj(:) = x2_si(:) - vtarg(:) = v1_si(:) - vproj(:) = v2_si(:) - else - itarg = index2 - iproj = index1 - dentarg = den2_si - denproj = den1_si - mtarg = m2_si - mproj = m1_si - rtarg = rad2_si - rproj = rad1_si - xtarg(:) = x2_si(:) - xproj(:) = x1_si(:) - vtarg(:) = v2_si(:) - vproj(:) = v1_si(:) - end if - mtot = m1_si + m2_si - dentot = (m1_si *den1_si +m2_si*den2_si )/ mtot - mcenter = symba_plA%mass(1) * MU2KG / GU - - !regime = collresolve_resolve(model,mtarg,mproj,rtarg,rproj,xtarg,xproj, vtarg,vproj, nres, mres, rres, pres, vres) - - call util_regime(mcenter, mtarg, mproj, rtarg, rproj, xtarg, xproj, vtarg, vproj, dentarg, denproj, regime, mlr, mslr) - - mres(1) = mlr - mres(2) = mslr - mres(3) = mtot - mlr - mslr - rres(1) = (3.0_DP * mres(1) / (4.0_DP * pi * dentarg)) *(1.0_DP/3.0_DP) - rres(1) = (3.0_DP * mres(1) / (4.0_DP * pi * dentarg)) ** (1.0_DP/3.0_DP) - rres(2) = (3.0_DP * mres(2) / (4.0_DP * pi * denproj)) ** (1.0_DP/3.0_DP) - rres(3) = (3.0_DP * mres(2) / (4.0_DP * pi * dentot)) ** (1.0_DP/3.0_DP) - - mres(:) = (mres(:) / MU2KG) * GU - rres(:) = rres(:) / DU2M - - call symba_caseresolve(t, dt, index_enc, nmergeadd, nmergesub, mergeadd_list, mergesub_list, eoffset, vbs, & - npl, symba_plA, nplplenc, plplenc_list, regime, fragmax, mres, rres, array_index1_child, & - array_index2_child, m1, m2, rad1, rad2, x1, x2, v1, v2, param) - - end if - return - - end procedure symba_fragmentation -end submodule s_symba_fragmentation diff --git a/src/symba/symba_getacch.f90 b/src/symba/symba_getacch.f90 deleted file mode 100644 index 4056a6216..000000000 --- a/src/symba/symba_getacch.f90 +++ /dev/null @@ -1,91 +0,0 @@ -submodule (symba) s_symba_getacch -contains - module procedure symba_getacch - !! author: David A. Minton - !! - !! Compute heliocentric accelerations of planets - !! Accelerations in an encounter are not included here - !! - !! Adapted from David E. Kaufmann's Swifter routine: symba_getacch.f90 - !! Adapted from Hal Levison's Swift routine symba5_getacch.f -use swiftest -implicit none - integer(I4B) :: i, j, index_i, index_j - real(DP) :: rji2, irij3, faci, facj, r2 - real(DP), dimension(NDIM) :: dx - real(DP), dimension(npl) :: irh - real(DP), dimension(npl, NDIM) :: aobl - -! executable code - - do i = 2, npl - symba_plA%ah(:,i) = (/ 0.0_DP, 0.0_DP, 0.0_DP /) - end do - - do i = 2, nplm - do j = i + 1, npl - if ((.not. symba_plA%lmerged(i)) .or. (.not. symba_plA%lmerged(j)) .or. & - (symba_plA%index_parent(i) /= symba_plA%index_parent(j))) then - dx(:) = symba_plA%xh(:,j) - symba_plA%xh(:,i) - rji2 = dot_product(dx(:), dx(:)) - irij3 = 1.0_DP/(rji2*sqrt(rji2)) - if (irij3 .ne. irij3 ) then - write(*,*) "dx==0 for pl: ", i, "name:", symba_plA%name(i), & - "and pl:", j, "name:", symba_plA%name(j) - write(*,*) "dx==0 for pl: ", i, "xh:", symba_plA%xh(1,i), & - "and pl:", j, "xh:", symba_plA%xh(1,j) - write(*,*) "parent pl 1:", symba_plA%name(symba_plA%index_parent(i)) - write(*,*) "parent pl 2:", symba_plA%name(symba_plA%index_parent(j)) - stop - end if - faci = symba_plA%mass(i)*irij3 - facj = symba_plA%mass(j)*irij3 - symba_plA%ah(:,i) = symba_plA%ah(:,i) + facj*dx(:) - symba_plA%ah(:,j) = symba_plA%ah(:,j) - faci*dx(:) - end if - end do - end do - - do i = 1, nplplenc - index_i = plplenc_list%index1(i) - index_j = plplenc_list%index2(i) - if ((.not. symba_plA%lmerged(index_i)) .or. (.not. symba_plA%lmerged(index_j)) & - .or. (symba_plA%index_parent(index_i) /= symba_plA%index_parent(index_j))) then !need to update parent/children - dx(:) = symba_plA%xh(:,index_j) - symba_plA%xh(:,index_i) - rji2 = dot_product(dx(:), dx(:)) - irij3 = 1.0_DP/(rji2*sqrt(rji2)) - if (irij3 .ne. irij3 ) then - write(*,*) "dx==0 for pl: ", i, "name:", symba_plA%name(i), & - "and pl:", j, "name:", symba_plA%name(j) - write(*,*) "dx==0 for pl: ", i, "xh:", symba_plA%xh(1,i), & - "and pl:", j, "xh:", symba_plA%xh(1,j) - write(*,*) "parent pl 1:", symba_plA%name(symba_plA%index_parent(i)) - write(*,*) "parent pl 2:", symba_plA%name(symba_plA%index_parent(j)) - stop - end if - faci = symba_plA%mass(index_i)*irij3 - facj = symba_plA%mass(index_j)*irij3 - symba_plA%ah(:,index_i) = symba_plA%ah(:,index_i) - facj*dx(:) - symba_plA%ah(:,index_j) = symba_plA%ah(:,index_j) + faci*dx(:) - end if - end do - if (param%loblatecb) then - !if (lmalloc) then - !allocate(xh(npl, NDIM),aobl(npl, NDIM), irh(npl)) - !lmalloc = .false. - !end if - do i = 2, npl - r2 = dot_product(symba_plA%xh(:,i), symba_plA%xh(:,i)) - irh(i) = 1.0_DP/sqrt(r2) - end do - call obl_acc(symba_plA, param%j2rp2, param%j4rp4, symba_plA%xh(:,:), irh, aobl) - do i = 2, npl - symba_plA%ah(:,i) = symba_plA%ah(:,i) + aobl(:, i) - aobl(:, 1) - end do - end if - if (lextra_force) call symba_user_getacch(t, npl, symba_plA) - - return - - end procedure symba_getacch -end submodule s_symba_getacch diff --git a/src/symba/symba_getacch_eucl.f90 b/src/symba/symba_getacch_eucl.f90 deleted file mode 100644 index fdb8e699a..000000000 --- a/src/symba/symba_getacch_eucl.f90 +++ /dev/null @@ -1,96 +0,0 @@ -submodule (symba) s_symba_getacch_eucl -contains - module procedure symba_getacch_eucl - !! author: Jacob R. Elliott - !! - !! Same as symba_getacch but now uses the single-loop blocking to evaluate the Euclidean distance matrix - !! Accelerations in an encounter are not included here - !! - !! Adapted from David E. Kaufmann's Swifter routine: symba_getacch.f90 - !! Adapted from Hal Levison's Swift routine symba5_getacch.f -use swiftest -implicit none - logical , save :: lmalloc = .true. - integer(I4B) :: i, j, index_i, index_j, k, counter - real(DP) :: rji2, irij3, faci, facj, r2, fac - real(DP), dimension(NDIM) :: dx - real(DP), dimension(npl, NDIM) :: ah - real(DP), dimension(:), allocatable, save :: irh - real(DP), dimension(:, :), allocatable, save :: xh, aobl - ! real(DP), allocatable, dimension(:,:) :: dist_plpl_array - - -!executable code - - symba_plA%ah(:,2:npl) = 0.0_DP - ah(:,2:npl) = 0.0_DP - - ! call util_dist_eucl_plpl(npl,symba_plA%xh, num_plpl_comparisons, k_plpl, dist_plpl_array) ! does not care about mtiny - -! there is floating point arithmetic round off error in this loop -! for now, we will keep it in the serial operation, so we can easily compare -! it to the older swifter versions - -!$omp parallel do default(none) schedule(static) & -!$omp num_threads(min(omp_get_max_threads(),ceiling(num_plpl_comparisons/10000.))) & -!$omp shared (num_plpl_comparisons, k_plpl, symba_plA) & -!$omp private (i, j, k, dx, rji2, irij3, faci, facj) & -!$omp reduction(+:ah) - do k = 1, num_plpl_comparisons - i = k_plpl(1,k) - j = k_plpl(2,k) - - if ((.not. symba_plA%lmerged(i) .or. (.not. symba_plA%lmerged(j)) .or. & - (symba_plA%index_parent(i) /= symba_plA%index_parent(j)))) then - - dx(:) = symba_plA%xh(:,k_plpl(2,k)) - symba_plA%xh(:,k_plpl(1,k)) - rji2 = dot_product(dx(:), dx(:)) - irij3 = 1.0_DP/(rji2*sqrt(rji2)) - faci = symba_plA%mass(i)*irij3 - facj = symba_plA%mass(j)*irij3 - ah(:,i) = ah(:,i) + facj*dx(:) - ah(:,j) = ah(:,j) - faci*dx(:) - - endif - end do -!$omp end parallel do - - symba_plA%ah(:,2:npl) = ah(:,2:npl) - - do i = 1, nplplenc - index_i = plplenc_list%index1(i) - index_j = plplenc_list%index2(i) - if ((.not. symba_plA%lmerged(index_i)) .or. (.not. symba_plA%lmerged(index_j)) & - .or. (symba_plA%index_parent(index_i) /= symba_plA%index_parent(index_j))) then !need to update parent/children - dx(:) = symba_plA%xh(:,index_j) - symba_plA%xh(:,index_i) - rji2 = dot_product(dx(:), dx(:)) - irij3 = 1.0_DP/(rji2*sqrt(rji2)) - faci = symba_plA%mass(index_i)*irij3 - facj = symba_plA%mass(index_j)*irij3 - symba_plA%ah(:,index_i) = symba_plA%ah(:,index_i) - facj*dx(:) - symba_plA%ah(:,index_j) = symba_plA%ah(:,index_j) + faci*dx(:) - end if - end do - - if (param%loblatecb) then - if (lmalloc) then - allocate(xh(npl, NDIM), aobl(npl, NDIM), irh(npl)) - lmalloc = .false. - end if - do i = 2, npl - - r2 = dot_product(symba_plA%xh(:,i), symba_plA%xh(:,i)) - irh(i) = 1.0_DP/sqrt(r2) - end do - call obl_acc(symba_plA, param%j2rp2, param%j4rp4, symba_plA%xh(:,:), irh, aobl) - do i = 2, npl - symba_plA%ah(:,i) = symba_plA%ah(:,i) + aobl(:, i) - aobl(:, 1) - end do - end if - - if (lextra_force) call symba_user_getacch(t, npl, symba_plA) - - return - - end procedure symba_getacch_eucl -end submodule s_symba_getacch_eucl diff --git a/src/symba/symba_getacch_tp.f90 b/src/symba/symba_getacch_tp.f90 deleted file mode 100644 index 97f52eef1..000000000 --- a/src/symba/symba_getacch_tp.f90 +++ /dev/null @@ -1,83 +0,0 @@ -submodule (symba) s_symba_getacch_tp -contains - module procedure symba_getacch_tp - !! author: David A. Minton - !! - !! Compute heliocentric accelerations of test particles - !! - !! Adapted from David E. Kaufmann's Swifter routine: symba_getacch_tp.f90 - !! Adapted from Hal Levison's Swift routine symba5_getacch.f - use swiftest - implicit none - logical , save :: lmalloc = .true. - integer(I4B) :: i, j, index_pl, index_tp - 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 - -! executable code - !removed by d. minton - !helio_tpp => symba_tp1p - !^^^^^^^^^^^^^^^^^^^^ - ! openmp parallelization added by d. minton - do i = 1, ntp - !added by d. minton - !helio_tpp => symba_tp1p%symba_tppa(i)%thisp - !^^^^^^^^^^^^^^^^^^ - symba_tpA%ah(:,i) = (/ 0.0_DP, 0.0_DP, 0.0_DP /) - if (symba_tpA%status(i) == ACTIVE) then - !swifter_plp => swifter_pl1p - !do j = 2, nplm - do j = 2, nplm - !swifter_plp => swifter_plp%nextp - dx(:) = symba_tpA%xh(:,i) - xh(:, j) - r2 = dot_product(dx(:), dx(:)) - fac = symba_plA%mass(j)/(r2*sqrt(r2)) - symba_tpA%ah(:,i) = symba_tpA%ah(:,i) - fac*dx(:) - end do - end if - !removed by d. minton - !helio_tpp => helio_tpp%nextp - !^^^^^^^^^^^^^^^^^^^^ - end do - do i = 1, npltpenc - !swifter_plp => pltpenc_list(i)%plp%swifter - !helio_tpp => pltpenc_list(i)%tpp - index_pl = pltpenc_list%indexpl(i) - index_tp = pltpenc_list%indextp(i) - if (symba_tpA%status(index_tp) == ACTIVE) then - dx(:) = symba_tpA%xh(:,index_tp) - symba_plA%xh(:,index_pl) - r2 = dot_product(dx(:), dx(:)) - fac = symba_plA%mass(index_pl)/(r2*sqrt(r2)) - symba_tpA%ah(:,index_tp) = symba_tpA%ah(:,index_tp) + fac*dx(:) - end if - end do - if (param%loblatecb) then - if (lmalloc) then - allocate(aobl(NDIM, param%nplmax), irh(param%nplmax), xht(NDIM, param%ntpmax), aoblt(NDIM, param%ntpmax), irht(param%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(symba_plA, param%j2rp2, param%j4rp4, symba_plA%xh(:,:), irh, aobl) - mu = symba_plA%mass(1) - do i = 1, ntp - xht(:, i) = symba_tpA%xh(:,i) !optimize - r2 = dot_product(xht(:, i), xht(:, i)) - irht(i) = 1.0_DP/sqrt(r2) - end do - call obl_acc_tp(ntp, xht, param%j2rp2, param%j4rp4, irht, aoblt, mu) - do i = 1, ntp - if (symba_tpA%status(i) == ACTIVE) & - symba_tpA%ah(:,i) = symba_tpA%ah(:,i) + aoblt(:, i) - aobl(:, 1) - end do - end if - if (lextra_force) call symba_user_getacch_tp(t, ntp, symba_tpA) - - return - - end procedure symba_getacch_tp -end submodule s_symba_getacch_tp diff --git a/src/symba/symba_getacch_tp_eucl.f90 b/src/symba/symba_getacch_tp_eucl.f90 deleted file mode 100644 index 0cd4c16cd..000000000 --- a/src/symba/symba_getacch_tp_eucl.f90 +++ /dev/null @@ -1,85 +0,0 @@ -submodule (symba) s_symba_getacch_tp_eucl -contains - module procedure symba_getacch_tp_eucl - !! author: Jacob R. Elliott - !! - !! Compute heliocentric accelerations of test particles. - !! Accelerations in an encounter are not included here - !! Uses the single-loop blocking to evaluate the Euclidean distance matrix - !! - !! Adapted from David E. Kaufmann's Swifter routine: symba_getacch_tp_eucl.f90 - !! Adapted from Hal Levison's Swift routine symba5_getacch.f -use swiftest -implicit none - logical , save :: lmalloc = .true. - integer(I4B) :: i, j, k, index_pl, index_tp - 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 - real(DP), dimension(ntp, NDIM) :: ah - -! executable code - - ah(:, 1:ntp) = 0.0_DP - - ! call util_dist_eucl_pltp(npl, ntp, symba_plA%xh, symba_tpA%xh, & - ! num_pltp_comparisons, k_pltp, dist_pltp_array) - -!$omp parallel do default(none) schedule(static) & -!$omp shared(num_pltp_comparisons, symba_plA, symba_tpA, k_pltp) & -!$omp private(k, i, j, dx, r2, fac) & -!$omp reduction(+:ah) - do k = 1,num_pltp_comparisons - j = k_pltp(2,k) - if (symba_tpA%status(j) == ACTIVE) then - i = k_pltp(1,k) - dx(:) = symba_tpA%xh(:,k_pltp(2,k)) - symba_plA%xh(:,k_pltp(1,k)) - r2 = dot_product(dx(:), dx(:)) - fac = symba_plA%mass(i)/(r2*sqrt(r2)) - ah(:,j) = ah(:,j) - fac*dx(:) - endif - enddo -!$omp end parallel do - - symba_tpA%ah(:, 1:ntp) = ah(:, 1:ntp) - - do i = 1, npltpenc - index_pl = pltpenc_list%indexpl(i) - index_tp = pltpenc_list%indextp(i) - if (symba_tpA%status(index_tp) == ACTIVE) then - dx(:) = symba_tpA%xh(:,index_tp) - symba_plA%xh(:,index_pl) - r2 = dot_product(dx(:), dx(:)) - fac = symba_plA%mass(index_pl)/(r2*sqrt(r2)) - symba_tpA%ah(:,index_tp) = symba_tpA%ah(:,index_tp) + fac*dx(:) - end if - end do - ! $omp end parallel do - if (param%loblatecb) then - if (lmalloc) then - allocate(aobl(NDIM, param%nplmax), irh(param%nplmax), xht(NDIM, param%ntpmax), aoblt(NDIM, param%ntpmax), irht(param%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(symba_plA, param%j2rp2, param%j4rp4, symba_plA%xh(:,:), irh, aobl) - mu = symba_plA%mass(1) - do i = 1, ntp - xht(:, i) = symba_tpA%xh(:,i) !optimize - r2 = dot_product(xht(:, i), xht(:, i)) - irht(i) = 1.0_DP/sqrt(r2) - end do - call obl_acc_tp(ntp, xht, param%j2rp2, param%j4rp4, irht, aoblt, mu) - do i = 1, ntp - if (symba_tpA%status(i) == ACTIVE) & - symba_tpA%ah(:,i) = symba_tpA%ah(:,i) + aoblt(:, i) - aobl(:, 1) - end do - end if - if (lextra_force) call symba_user_getacch_tp(t, ntp, symba_tpA) - - return - - end procedure symba_getacch_tp_eucl -end submodule s_symba_getacch_tp_eucl diff --git a/src/symba/symba_helio_drift.f90 b/src/symba/symba_helio_drift.f90 deleted file mode 100644 index 07b8d97a5..000000000 --- a/src/symba/symba_helio_drift.f90 +++ /dev/null @@ -1,38 +0,0 @@ -submodule (symba) s_symba_helio_drift -contains - module procedure symba_helio_drift - !! author: David A. Minton - !! - !! Loop through planets and call Danby drift routine - !! - !! Adapted from David E. Kaufmann's Swifter routine: symba_helio_drift.f90 - !! Adapted from Hal Levison's Swift routine symba5_helio_drift.f -use swiftest -implicit none - integer(I4B) :: i, iflag - real(DP) :: mu - -! executable code - mu = symba_plA%mass(1) -!$omp parallel do default(none) & -!$omp shared (symba_plA, npl, mu, dt, irec) & -!$omp private (i, iflag) - do i = 2, npl - if ((symba_plA%levelg(i) == irec) .and. (symba_plA%status(i) == ACTIVE)) then - call drift_one(mu, symba_plA%xh(1,i), symba_plA%xh(2,i), symba_plA%xh(3,i), symba_plA%vb(1,i), symba_plA%vb(2,i), symba_plA%vb(3,i), dt, iflag) - if (iflag /= 0) then - write(*, *) " massive body ", symba_plA%name(i), " is lost!!!!!!!!!!" - write(*, *) mu, dt - write(*, *) symba_plA%xh(:,i) - write(*, *) symba_plA%vb(:,i) - write(*, *) " stopping " - call util_exit(FAILURE) - end if - end if - end do -!$omp end parallel do - - return - - end procedure symba_helio_drift -end submodule s_symba_helio_drift diff --git a/src/symba/symba_helio_drift_tp.f90 b/src/symba/symba_helio_drift_tp.f90 deleted file mode 100644 index 05d248360..000000000 --- a/src/symba/symba_helio_drift_tp.f90 +++ /dev/null @@ -1,28 +0,0 @@ -submodule (symba) s_symba_helio_drift_tp -contains - module procedure symba_helio_drift_tp - !! author: David A. Minton - !! - !! Loop through test particles and call Danby drift routine - !! - !! Adapted from David E. Kaufmann's Swifter routine: symba_helio_drift_tp.f90 - !! Adapted from Hal Levison's Swift routine symba5_helio_drift.f - use swiftest - implicit none - integer(I4B) :: i, iflag - - associate(symba_tpA%xh => xh, symba_tpA%vb => vb) - do i = 1, ntp - if ((symba_tpA%levelg(i) == irec) .and. (symba_tpA%status(i) == ACTIVE)) then - call drift_one(mu, xh(1,i), xh(2,i), xh(3,i), vb(1,i), vb(2,i), vb(3,i), dt, iflag) - if (iflag /= 0) then - symba_tpA%status(i) = DISCARDED_DRIFTERR - write(*, *) "particle ", symba_tpA%name(i), " lost due to error in danby drift" - end if - end if - end do - - return - - end procedure symba_helio_drift_tp -end submodule s_symba_helio_drift_tp diff --git a/src/symba/symba_helio_getacch.f90 b/src/symba/symba_helio_getacch.f90 deleted file mode 100644 index 6d69de2b9..000000000 --- a/src/symba/symba_helio_getacch.f90 +++ /dev/null @@ -1,50 +0,0 @@ -submodule (symba) s_symba_helio_getacch -contains - module procedure symba_helio_getacch - !! author: David A. Minton - !! - !! Compute heliocentric accelerations of planets - !! - !! Adapted from David E. Kaufmann's Swifter routine: symba_helio_getacch.f90 - !! Adapted from Hal Levison's Swift routine symba5_helio_getacch.f -use swiftest -implicit none - logical , save :: lmalloc = .true. - integer(I4B) :: i - real(DP) :: r2 - real(DP), dimension(:), allocatable, save :: irh - real(DP), dimension(:, :), allocatable, save :: xh, aobl - - -! executable code - if (lflag) then - do i = 2, npl - helio_plA%ah(:,i) = (/ 0.0_DP, 0.0_DP, 0.0_DP /) - end do - call symba_helio_getacch_int(npl, nplm, helio_plA) - end if - if (param%loblatecb) then - if (lmalloc) then - allocate(xh(NDIM, param%nplmax), aobl(NDIM, param%nplmax), irh(param%nplmax)) - lmalloc = .false. - end if - do i = 2, npl - xh(:, i) = helio_plA%xh(:,i) - r2 = dot_product(xh(:, i), xh(:, i)) - irh(i) = 1.0_DP/sqrt(r2) - end do - call obl_acc(helio_plA, param%j2rp2, param%j4rp4, xh, irh, aobl) - do i = 2, npl - helio_plA%ah(:,i) = helio_plA%ah(:,i) + aobl(:, i) - aobl(:, 1) - end do - else - do i = 2, npl - helio_plA%ah(:,i) = helio_plA%ah(:,i) - end do - end if - if (lextra_force) call helio_user_getacch(t, npl, helio_plA) - - return - - end procedure symba_helio_getacch -end submodule s_symba_helio_getacch diff --git a/src/symba/symba_helio_getacch_int.f90 b/src/symba/symba_helio_getacch_int.f90 deleted file mode 100644 index 8093c48d7..000000000 --- a/src/symba/symba_helio_getacch_int.f90 +++ /dev/null @@ -1,31 +0,0 @@ -submodule (symba) s_symba_helio_getacch_int -contains - module procedure symba_helio_getacch_int - !! author: David A. Minton - !! - !! Compute direct cross term heliocentric accelerations of planets - !! - !! Adapted from David E. Kaufmann's Swifter routine: symba_helio_getacch_int.f90 - !! Adapted from Hal Levison's Swift routine symba5_helio_getacch.f -use swiftest -implicit none - integer(I4B) :: i, j - real(DP) :: rji2, irij3, faci, facj - real(DP), dimension(NDIM) :: dx - -! executable code - do i = 2, nplm - do j = i + 1, npl - dx(:) = helio_plA%swiftest%xh(:,j) - helio_plA%swiftest%xh(:,i) - rji2 = dot_product(dx(:), dx(:)) - irij3 = 1.0_DP/(rji2*sqrt(rji2)) - faci = helio_plA%swiftest%mass(i)*irij3 - facj = helio_plA%swiftest%mass(j)*irij3 - helio_plA%ah(:,i) = helio_plA%ah(:,i) + facj*dx(:) - helio_plA%ah(:,j) = helio_plA%ah(:,j) - faci*dx(:) - end do - end do - return - - end procedure symba_helio_getacch_int -end submodule s_symba_helio_getacch_int diff --git a/src/symba/symba_io.f90 b/src/symba/symba_io.f90 new file mode 100644 index 000000000..bebb225b5 --- /dev/null +++ b/src/symba/symba_io.f90 @@ -0,0 +1,213 @@ +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(in) :: 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)) + 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 + 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_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 deleted file mode 100644 index f62be3259..000000000 --- a/src/symba/symba_kick.f90 +++ /dev/null @@ -1,104 +0,0 @@ -submodule (symba) s_symba_kick -contains - module procedure symba_kick - !! author: David A. Minton - !! - !! Kick barycentric velocities of planets and ACTIVE test particles within SyMBA recursion - !! - !! Adapted from David E. Kaufmann's Swifter routine: symba_kick.f90 - !! Adapted from Hal Levison's Swift routine symba5_kick.f -use swiftest -implicit none - integer(I4B) :: i, irm1, irecl, index_i,index_j,index_tp,index_pl - real(DP) :: r, rr, ri, ris, rim1, r2, ir3, fac, faci, facj - real(DP), dimension(NDIM) :: dx - -! executable code - irm1 = irec - 1 - if (sgn < 0.0_DP) then - irecl = irec - 1 - else - irecl = irec - end if - do i = 1, nplplenc - index_i = plplenc_list%index1(i) - index_j = plplenc_list%index2(i) - symba_plA%ah(:,index_i) = (/ 0.0_DP, 0.0_DP, 0.0_DP /) - symba_plA%ah(:,index_j) = (/ 0.0_DP, 0.0_DP, 0.0_DP /) - end do - do i = 1, npltpenc - index_tp = pltpenc_list%indextp(i) - symba_tpA%ah(:,index_tp) = (/ 0.0_DP, 0.0_DP, 0.0_DP /) - end do - do i = 1, nplplenc - if (plplenc_list%status(i) == ACTIVE) then - index_i = plplenc_list%index1(i) - index_j = plplenc_list%index2(i) - if ((symba_plA%levelg(index_i) >= irm1) .and. (symba_plA%levelg(index_j) >= irm1)) then - ri = ((symba_plA%rhill(index_i) & - + symba_plA%rhill(index_j))**2)*(rhscale**2)*(rshell**(2*irecl)) - rim1 = ri*(rshell**2) - dx(:) = symba_plA%xh(:,index_j) - symba_plA%xh(:,index_i) - 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*symba_plA%mass(index_i) - facj = fac*symba_plA%mass(index_j) - symba_plA%ah(:,index_i) = symba_plA%ah(:,index_i) + facj*dx(:) - symba_plA%ah(:,index_j) = symba_plA%ah(:,index_j) - faci*dx(:) - end if - end if - end do - do i = 1, npltpenc - if (pltpenc_list%status(i) == ACTIVE) then - index_pl = pltpenc_list%indexpl(i) - index_tp = pltpenc_list%indextp(i) - if ((symba_plA%levelg(index_pl) >= irm1) .and. (symba_tpA%levelg(index_tp) >= irm1)) then - ri = ((symba_plA%rhill(index_pl))**2)*(rhscale**2)*(rshell**(2*irecl)) - rim1 = ri*(rshell**2) - dx(:) = symba_tpA%xh(:,index_tp) - symba_plA%xh(:,index_pl) - 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*symba_plA%mass(index_pl) - symba_tpA%ah(:,index_tp) = symba_tpA%ah(:,index_tp) - faci*dx(:) - end if - end if - end do - do i = 1, nplplenc - index_i = plplenc_list%index1(i) - index_j = plplenc_list%index2(i) - symba_plA%vb(:,index_i) = symba_plA%vb(:,index_i) + sgn*dt*symba_plA%ah(:,index_i) - symba_plA%vb(:,index_j) = symba_plA%vb(:,index_j) + sgn*dt*symba_plA%ah(:,index_j) - symba_plA%ah(:,index_i) = (/ 0.0_DP, 0.0_DP, 0.0_DP /) - symba_plA%ah(:,index_j) = (/ 0.0_DP, 0.0_DP, 0.0_DP /) - end do - do i = 1, npltpenc - index_tp = pltpenc_list%indextp(i) - if (symba_tpA%status(index_tp) == ACTIVE) & - symba_tpA%vb(:,index_tp) = symba_tpA%vb(:,index_tp) + sgn*dt*symba_tpA%ah(:,index_tp) - symba_tpA%ah(:,index_tp) = (/ 0.0_DP, 0.0_DP, 0.0_DP /) - end do - - return - - end procedure symba_kick -end submodule s_symba_kick diff --git a/src/symba/symba_merge_pl.f90 b/src/symba/symba_merge_pl.f90 deleted file mode 100644 index 486da9f82..000000000 --- a/src/symba/symba_merge_pl.f90 +++ /dev/null @@ -1,221 +0,0 @@ -submodule (symba) s_symba_merge_pl -contains - module procedure symba_merge_pl - !! author: David A. Minton - !! - !! Check whether or not bodies are colliding or on collision path - !! - !! Adapted from David E. Kaufmann's Swifter routine: symba_merge_pl.f90 - !! Adapted from Hal Levison's Swift routine symba5_merge.f - use swiftest - implicit none - logical :: lmerge - integer(I4B) :: i, j, k, stat1, stat2, index1, index2, index_keep, index_rm, indexchild - integer(I4B) :: index1_child, index2_child, index1_parent, index2_parent, index_big1, index_big2 - integer(I4B) :: name1, name2 - real(DP) :: r2, rlim, rlim2, vdotr, tcr2, dt2, mtot, a, e, q, m1, m2, mtmp, mmax - real(DP) :: eold, enew, rad1, rad2, mass1, mass2 - real(DP), dimension(NDIM) :: xr, vr, x1, v1, x2, v2, xnew, vnew - integer(I4B), dimension(npl) :: array_index1_child, array_index2_child, array_keep_child, array_rm_child - -! executable code - lmerge = .false. - - index1 = plplenc_list%index1(index_enc) - index2 = plplenc_list%index2(index_enc) - - rlim = symba_plA%radius(index1) + symba_plA%radius(index2) - xr(:) = symba_plA%xh(:,index2) - symba_plA%xh(:,index1) - r2 = dot_product(xr(:), xr(:)) - rlim2 = rlim*rlim - ! checks if bodies are actively colliding in this time step - if (rlim2 >= r2) then - lmerge = .true. - ! 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 - else - vr(:) = symba_plA%vb(:,index2) - symba_plA%vb(:,index1) - vdotr = dot_product(xr(:), vr(:)) - if (plplenc_list%lvdotr(index_enc) .and. (vdotr > 0.0_DP)) then - tcr2 = r2/dot_product(vr(:), vr(:)) - dt2 = dt*dt - if (tcr2 <= dt2) then - mtot = symba_plA%mass(index1) + symba_plA%mass(index2) - call orbel_xv2aeq(xr(:), vr(:), mtot, a, e, q) - if (q < rlim) lmerge = .true. - end if - ! if no collision is going to happen, write as close encounter, not merger - if (.not. lmerge) then - if (encounter_file /= "") then - name1 = symba_plA%name(index1) - m1 = symba_plA%mass(index1) - rad1 = symba_plA%radius(index1) - x1(:) = symba_plA%xh(:,index1) - v1(:) = symba_plA%vb(:,index1) - vbs(:) - name2 = symba_plA%name(index2) - m2 = symba_plA%mass(index2) - rad2 = symba_plA%radius(index2) - x2(:) = symba_plA%xh(:,index2) - v2(:) = symba_plA%vb(:,index2) - vbs(:) - - call io_write_encounter(t, name1, name2, m1, m2, rad1, rad2, x1(:), x2(:), & - v1(:), v2(:), encounter_file, out_type) - end if - end if - end if - end if - !set up the merger for symba_discard_merge_pl - if (lmerge) then - symba_plA%lmerged(index1) = .true. - symba_plA%lmerged(index2) = .true. - index1_parent = symba_plA%index_parent(index1) - m1 = symba_plA%mass(index1_parent) - mass1 = m1 - rad1 = symba_plA%radius(index1_parent) - x1(:) = m1*symba_plA%xh(:,index1_parent) - v1(:) = m1*symba_plA%vb(:,index1_parent) - mmax = m1 - name1 = symba_plA%name(index1_parent) - index_big1 = index1_parent - stat1 = symba_plA%status(index1_parent) - array_index1_child(1:npl) = symba_plA%index_child(1:npl,index1_parent) - do i = 1, symba_plA%nchild(index1_parent) ! initialize an array of children - index1_child = array_index1_child(i) - mtmp = symba_plA%mass(index1_child) - if (mtmp > mmax) then - mmax = mtmp - name1 = symba_plA%name(index1_child) - index_big1 = index1_child - stat1 = symba_plA%status(index1_child) - end if - m1 = m1 + mtmp - x1(:) = x1(:) + mtmp*symba_plA%xh(:,index1_child) - v1(:) = v1(:) + mtmp*symba_plA%vb(:,index1_child) - end do - x1(:) = x1(:)/m1 - v1(:) = v1(:)/m1 - index2_parent = symba_plA%index_parent(index2) - m2 = symba_plA%mass(index2_parent) - mass2 = m2 - rad2 = symba_plA%radius(index2_parent) - x2(:) = m2*symba_plA%xh(:,index2_parent) - v2(:) = m2*symba_plA%vb(:,index2_parent) - mmax = m2 - name2 = symba_plA%name(index2_parent) - index_big2 = index2_parent - stat2 = symba_plA%status(index2_parent) - array_index2_child(1:npl) = symba_plA%index_child(1:npl,index2_parent) - do i = 1, symba_plA%nchild(index2_parent) - index2_child = array_index2_child(i) - mtmp = symba_plA%mass(index2_child) - if (mtmp > mmax) then - mmax = mtmp - name2 = symba_plA%name(index2_child) - index_big2 = index2_child - stat2 = symba_plA%status(index2_child) - end if - m2 = m2 + mtmp - x2(:) = x2(:) + mtmp*symba_plA%xh(:,index2_child) - v2(:) = v2(:) + mtmp*symba_plA%vb(:,index2_child) - 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 ", name1, " and ", name2, " at time t = ",t - nmergesub = nmergesub + 1 - mergesub_list%name(nmergesub) = name1 - mergesub_list%status(nmergesub) = MERGED - mergesub_list%xh(:,nmergesub) = x1(:) - mergesub_list%vh(:,nmergesub) = v1(:) - vbs(:) - mergesub_list%mass(nmergesub) = mass1 - mergesub_list%radius(nmergesub) = rad1 - nmergesub = nmergesub + 1 - mergesub_list%name(nmergesub) = name2 - mergesub_list%status(nmergesub) = MERGED - mergesub_list%xh(:,nmergesub) = x2(:) - mergesub_list%vh(:,nmergesub) = v2(:) - vbs(:) - mergesub_list%mass(nmergesub) = mass2 - mergesub_list%radius(nmergesub) = rad2 - nmergeadd = nmergeadd + 1 - if (m2 > m1) then - index_keep = index_big2 - index_rm = index_big1 - mergeadd_list%name(nmergeadd) = name2 - mergeadd_list%status(nmergeadd) = stat2 - - else - index_keep = index_big1 - index_rm = index_big2 - mergeadd_list%name(nmergeadd) = name1 - mergeadd_list%status(nmergeadd) = stat1 - - end if - mergeadd_list%ncomp(nmergeadd) = 2 - mergeadd_list%xh(:,nmergeadd) = xnew(:) - mergeadd_list%vh(:,nmergeadd) = vnew(:) - vbs(:) - eold = 0.5_DP*(m1*dot_product(v1(:), v1(:)) + m2*dot_product(v2(:), v2(:))) - xr(:) = x2(:) - x1(:) - eold = eold - m1*m2/norm2(xr(:)) - enew = 0.5_DP*mtot*dot_product(vnew(:), vnew(:)) - eoffset = eoffset + eold - enew - - !write(*,*) "symba_merge_pl.f90 name", mergeadd_list%name(nmergeadd) - !write(*,*) "symba_merge_pl.f90 xh", mergeadd_list%xh(:,nmergeadd) - !write(*,*) "symba_merge_pl.f90 vh", mergeadd_list%vh(:,nmergeadd) - !write(*,*) "symba_merge_pl.f90 eoffset", eoffset - do k = 1, nplplenc !go through the encounter list and for particles actively encoutering, get their children - if (plplenc_list%status(k) == ACTIVE) then - do i = 0, symba_plA%nchild(index1_parent) - if (i == 0) then - index1_child = index1_parent - else - index1_child = array_index1_child(i) - end if - do j = 0, symba_plA%nchild(index2_parent) - if (j == 0) then - index2_child = index2_parent - else - index2_child = array_index2_child(j) - end if - if ((index1_child == plplenc_list%index1(k)) .and. (index2_child == plplenc_list%index2(k))) then - plplenc_list%status(k) = MERGED - else if ((index1_child == plplenc_list%index2(k)) .and. (index2_child == plplenc_list%index1(k))) then - plplenc_list%status(k) = MERGED - end if - end do - end do - end if - end do - symba_plA%xh(:,index1_parent) = xnew(:) - symba_plA%vb(:,index1_parent) = vnew(:) - symba_plA%xh(:,index2_parent) = xnew(:) - symba_plA%vb(:,index2_parent) = vnew(:) - array_keep_child(1:npl) = symba_plA%index_child(1:npl,index1_parent) - do i = 1, symba_plA%nchild(index1_parent) - indexchild = array_keep_child(i) - symba_plA%xh(:,indexchild) = xnew(:) - symba_plA%vb(:,indexchild) = vnew(:) - end do - - symba_plA%index_child((symba_plA%nchild(index1_parent)+1),index1_parent) = index2_parent - array_rm_child(1:npl) = symba_plA%index_child(1:npl,index2_parent) - symba_plA%index_parent(index2) = index1_parent - - do i = 1, symba_plA%nchild(index2_parent) - symba_plA%index_parent(array_rm_child(i)) = index1_parent - indexchild = array_rm_child(i) - symba_plA%xh(:,indexchild) = xnew(:) - symba_plA%vb(:,indexchild) = vnew(:) - end do - do i = 1, symba_plA%nchild(index2_parent) - symba_plA%index_child(symba_plA%nchild(index1_parent)+i+1,index1_parent)= array_rm_child(i) - end do - symba_plA%nchild(index1_parent) = symba_plA%nchild(index1_parent) + symba_plA%nchild(index2_parent) + 1 - end if - - return - - end procedure symba_merge_pl -end submodule s_symba_merge_pl diff --git a/src/symba/symba_merge_tp.f90 b/src/symba/symba_merge_tp.f90 deleted file mode 100644 index 728d0b8a0..000000000 --- a/src/symba/symba_merge_tp.f90 +++ /dev/null @@ -1,65 +0,0 @@ -submodule (symba) s_symba_merge_tp -contains - module procedure symba_merge_tp - !! author: David A. Minton - !! - !! Check for merger between planet and test particle in SyMBAs - !! - !! Adapted from David E. Kaufmann's Swifter routine: symba_merge_tp.f90 - !! Adapted from Hal Levison's Swift routine symba5_merge.f -use swiftest -implicit none - logical :: lmerge - integer(I4B) :: name1, name2, indexpl, indextp - real(DP) :: r2, rlim, rlim2, vdotr, tcr2, dt2, mu, a, e, q, rad1 - real(DP), dimension(NDIM) :: xr, vr, xh1, vh1, xh2, vh2 - -! executable code - lmerge = .false. - - indexpl = pltpenc_list%indexpl(index_enc) - indextp = pltpenc_list%indextp(index_enc) - - rlim = symba_plA%radius(indexpl) - xr(:) = symba_tpA%xh(:,indextp) - symba_plA%xh(:,indexpl) - r2 = dot_product(xr(:), xr(:)) - rlim2 = rlim*rlim - if (rlim2 >= r2) then - lmerge = .true. - else - vr(:) = symba_tpA%vb(:,indextp) - symba_plA%vb(:,indexpl) - vdotr = dot_product(xr(:), vr(:)) - if (pltpenc_list%lvdotr(index_enc) .and. (vdotr > 0.0_DP)) then - mu = symba_plA%mass(indexpl) - 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 - name1 = symba_plA%name(indexpl) - rad1 = symba_plA%radius(indexpl) - xh1(:) = symba_plA%xh(:,indexpl) - vh1(:) = symba_plA%vb(:,indexpl) - vbs(:) - name2 = symba_tpA%name(indextp) - xh2(:) = symba_tpA%xh(:,indextp) - vh2(:) = symba_tpA%vb(:,indextp) - vbs(:) - call io_write_encounter(t, name1, name2, 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%status(index_enc) = MERGED - symba_tpA%status = DISCARDED_PLR - write(*, *) "particle ", symba_tpA%name, " too close to massive body ", & - symba_plA%name, " at t = ", t - end if - - return - - end procedure symba_merge_tp -end submodule s_symba_merge_tp diff --git a/src/symba/symba_peri.f90 b/src/symba/symba_peri.f90 deleted file mode 100644 index 654d507fa..000000000 --- a/src/symba/symba_peri.f90 +++ /dev/null @@ -1,89 +0,0 @@ -submodule (symba) s_symba_peri -contains - module procedure symba_peri - !! author: David A. Minton - !! - !! Determine system pericenter passages for planets in SyMBA - !! If the coordinate system used is barycentric, then this routine assumes that the barycentric coordinates in the - !! massive body structures are up-to-date and are not recomputed - !! - !! Adapted from David E. Kaufmann's Swifter routine: symba_peri.f90 - !! Adapted from Hal Levison's Swift routine util_mass_peri.f -use swiftest -implicit none - integer(I4B) :: i - real(DP) :: vdotr, e, mu, msun - -! executable code - msun = symba_plA%mass(1) - if (lfirst) then - if (qmin_coord == "helio") then - do i = 2, npl - if (symba_plA%status(i) == ACTIVE) then - vdotr = dot_product(symba_plA%xh(:,i), symba_plA%vh(:,i)) - if (vdotr > 0.0_DP) then - symba_plA%isperi(i) = 1 - else - symba_plA%isperi(i) = -1 - end if - end if - end do - else - do i = 2, npl - if (symba_plA%status(i) == ACTIVE) then - vdotr = dot_product(symba_plA%xb(:,i), symba_plA%vb(:,i)) - if (vdotr > 0.0_DP) then - symba_plA%isperi(i) = 1 - else - symba_plA%isperi(i) = -1 - end if - end if - end do - end if - else - if (qmin_coord == "helio") then - do i = 2, npl - if (symba_plA%status(i) == ACTIVE) then - vdotr = dot_product(symba_plA%xh(:,i), symba_plA%vh(:,i)) - if (symba_plA%isperi(i) == -1) then - if (vdotr >= 0.0_DP) then - symba_plA%isperi(i) = 0 - mu = msun + symba_plA%mass(i) - call orbel_xv2aeq(symba_plA%xh(:,i), & - symba_plA%vh(:,i), mu, symba_plA%atp(i), e, symba_plA%peri(i)) - end if - else - if (vdotr > 0.0_DP) then - symba_plA%isperi(i) = 1 - else - symba_plA%isperi(i) = -1 - end if - end if - end if - end do - else - do i = 2, npl - if (symba_plA%status(i) == ACTIVE) then - vdotr = dot_product(symba_plA%xb(:,i), symba_plA%vb(:,i)) - if (symba_plA%isperi(i) == -1) then - if (vdotr >= 0.0_DP) then - symba_plA%isperi(i) = 0 - call orbel_xv2aeq(symba_plA%xb(:,i), & - symba_plA%vb(:,i), msys, symba_plA%atp(i), e, symba_plA%peri(i)) - end if - else - if (vdotr > 0.0_DP) then - symba_plA%isperi(i) = 1 - else - symba_plA%isperi(i) = -1 - end if - end if - end if - end do - end if - end if - - return - - end procedure symba_peri -end submodule s_symba_peri diff --git a/src/symba/symba_rearray.f90 b/src/symba/symba_rearray.f90 deleted file mode 100644 index 46a81b28d..000000000 --- a/src/symba/symba_rearray.f90 +++ /dev/null @@ -1,182 +0,0 @@ -submodule (symba) s_symba_rearray -contains - module procedure symba_rearray - !! author: Jennifer L. L. Pouplin, Carlisle A. Wishard, and David A. Minton - !! - !! Redo array of pl and tp based on discarded and added pl and tp - use swiftest - implicit none - integer(I4B) :: i, nkpl, nktp, nfrag - real(DP) :: mu, energy, ap, r, v2 - logical, dimension(npl) :: discard_l_pl, frag_l_add - logical, dimension(ntp) :: discard_l_tp - -! executable code - - if (ldiscard) then - nsppl = 0 - nkpl = 0 - discard_l_pl(1:npl) = (symba_plA%status(1:npl) /= ACTIVE) - nsppl = count(discard_l_pl) - nkpl = npl - nsppl - frag_l_add = [(.false.,i=1,npl)] - if (param%lfragmentation) then - do i = 1, npl - if (mergeadd_list%status(i) == DISRUPTION) then - frag_l_add(i) = .true. - else if (mergeadd_list%status(i) == HIT_AND_RUN) then - frag_l_add(i) = .true. - else if (mergeadd_list%status(i) == SUPERCATASTROPHIC) then - frag_l_add(i) = .true. - else - frag_l_add(i) = .false. - end if - end do - end if - nfrag = count(frag_l_add) - - call discard_plA%alloc(nsppl) - - discard_plA%name(1:nsppl) = pack(symba_plA%name(1:npl), discard_l_pl) - discard_plA%status(1:nsppl) = pack(symba_plA%status(1:npl), discard_l_pl) - discard_plA%mass(1:nsppl) = pack(symba_plA%mass(1:npl), discard_l_pl) - discard_plA%radius(1:nsppl) = pack(symba_plA%radius(1:npl), discard_l_pl) - discard_plA%xh(1:nsppl, 1) = pack(symba_plA%xh(1:npl, 1), discard_l_pl) - discard_plA%xh(1:nsppl, 2) = pack(symba_plA%xh(1:npl, 2), discard_l_pl) - discard_plA%xh(1:nsppl, 3) = pack(symba_plA%xh(1:npl, 3), discard_l_pl) - discard_plA%vh(1:nsppl, 1) = pack(symba_plA%vh(1:npl, 1), discard_l_pl) - discard_plA%vh(1:nsppl, 2) = pack(symba_plA%vh(1:npl, 2), discard_l_pl) - discard_plA%vh(1:nsppl, 3) = pack(symba_plA%vh(1:npl, 3), discard_l_pl) - discard_plA%rhill(1:nsppl) = pack(symba_plA%rhill(1:npl), discard_l_pl) - discard_plA%xb(1:nsppl, 1) = pack(symba_plA%xb(1:npl, 1), discard_l_pl) - discard_plA%xb(1:nsppl, 2) = pack(symba_plA%xb(1:npl, 2), discard_l_pl) - discard_plA%xb(1:nsppl, 3) = pack(symba_plA%xb(1:npl, 3), discard_l_pl) - discard_plA%vb(1:nsppl, 1) = pack(symba_plA%vb(1:npl, 1), discard_l_pl) - discard_plA%vb(1:nsppl, 2) = pack(symba_plA%vb(1:npl, 2), discard_l_pl) - discard_plA%vb(1:nsppl, 3) = pack(symba_plA%vb(1:npl, 3), discard_l_pl) - if (param%lfragmentation .and. (nkpl + nfrag > npl)) then - symba_plA%name(1:nkpl) = pack(symba_plA%name(1:npl), .not. discard_l_pl) - symba_plA%status(1:nkpl) = pack(symba_plA%status(1:npl), .not. discard_l_pl) - symba_plA%mass(1:nkpl) = pack(symba_plA%mass(1:npl), .not. discard_l_pl) - symba_plA%radius(1:nkpl) = pack(symba_plA%radius(1:npl), .not. discard_l_pl) - symba_plA%xh(1:nkpl, 1) = pack(symba_plA%xh(1:npl, 1), .not. discard_l_pl) - symba_plA%xh(1:nkpl, 2) = pack(symba_plA%xh(1:npl, 2), .not. discard_l_pl) - symba_plA%xh(1:nkpl, 3) = pack(symba_plA%xh(1:npl, 3), .not. discard_l_pl) - symba_plA%vh(1:nkpl, 1) = pack(symba_plA%vh(1:npl, 1), .not. discard_l_pl) - symba_plA%vh(1:nkpl, 2) = pack(symba_plA%vh(1:npl, 2), .not. discard_l_pl) - symba_plA%vh(1:nkpl, 3) = pack(symba_plA%vh(1:npl, 3), .not. discard_l_pl) - symba_plA%rhill(1:nkpl) = pack(symba_plA%rhill(1:npl), .not. discard_l_pl) - symba_plA%xb(1:nkpl, 1) = pack(symba_plA%xb(1:npl, 1), .not. discard_l_pl) - symba_plA%xb(1:nkpl, 2) = pack(symba_plA%xb(1:npl, 2), .not. discard_l_pl) - symba_plA%xb(1:nkpl, 3) = pack(symba_plA%xb(1:npl, 3), .not. discard_l_pl) - symba_plA%vb(1:nkpl, 1) = pack(symba_plA%vb(1:npl, 1), .not. discard_l_pl) - symba_plA%vb(1:nkpl, 2) = pack(symba_plA%vb(1:npl, 2), .not. discard_l_pl) - symba_plA%vb(1:nkpl, 3) = pack(symba_plA%vb(1:npl, 3), .not. discard_l_pl) - symba_plA%ah(1:nkpl, 1) = pack(symba_plA%ah(1:npl, 1), .not. discard_l_pl) - symba_plA%ah(1:nkpl, 2) = pack(symba_plA%ah(1:npl, 2), .not. discard_l_pl) - symba_plA%ah(1:nkpl, 3) =pack(symba_plA%ah(1:npl, 3), .not. discard_l_pl) - - call util_resize_pl(symba_plA, nkpl+nfrag, npl) - - npl = nkpl + nfrag - !add fragments - symba_plA%name(nkpl+1:npl) = pack(mergeadd_list%name(1:nmergeadd), frag_l_add) - symba_plA%status(nkpl+1:npl) = [(ACTIVE,i=1,nfrag)]!array of ACTIVE status - symba_plA%mass(nkpl+1:npl) = pack(mergeadd_list%mass(1:nmergeadd), frag_l_add) - symba_plA%radius(nkpl+1:npl) = pack(mergeadd_list%radius(1:nmergeadd), frag_l_add) - symba_plA%xh(1,nkpl+1:npl) = pack(mergeadd_list%xh(1:n, 1mergeadd), frag_l_add) - symba_plA%xh(2,nkpl+1:npl) = pack(mergeadd_list%xh(1:n, 2mergeadd), frag_l_add) - symba_plA%xh(3,nkpl+1:npl) = pack(mergeadd_list%xh(1:n, 3mergeadd), frag_l_add) - symba_plA%vh(1,nkpl+1:npl) = pack(mergeadd_list%vh(1:n, 1mergeadd), frag_l_add) - symba_plA%vh(2,nkpl+1:npl) = pack(mergeadd_list%vh(1:n, 2mergeadd), frag_l_add) - symba_plA%vh(3,nkpl+1:npl) = pack(mergeadd_list%vh(1:n, 3mergeadd), frag_l_add) - - do i = nkpl+1, npl - mu = symba_plA%mass(1) + symba_plA%mass(i) - r = norm2(symba_plA%xh(:,i)) - v2 = dot_product(symba_plA%vh(:,i), symba_plA%vh(:,i)) - energy = 0.5_DP*v2 - mu/r - ap = -0.5_DP*mu/energy - symba_plA%rhill(i) = ap*(((symba_plA%mass(i)/mu)/3.0_DP)**(1.0_DP/3.0_DP)) - end do - - else - symba_plA%name(1:nkpl) = pack(symba_plA%name(1:npl), .not. discard_l_pl) - symba_plA%status(1:nkpl) = pack(symba_plA%status(1:npl), .not. discard_l_pl) - symba_plA%mass(1:nkpl) = pack(symba_plA%mass(1:npl), .not. discard_l_pl) - symba_plA%radius(1:nkpl) = pack(symba_plA%radius(1:npl), .not. discard_l_pl) - symba_plA%xh(1:nkpl, 1) = pack(symba_plA%xh(1:npl, 1), .not. discard_l_pl) - symba_plA%xh(1:nkpl, 2) = pack(symba_plA%xh(1:npl, 2), .not. discard_l_pl) - symba_plA%xh(1:nkpl, 3) = pack(symba_plA%xh(1:npl, 3), .not. discard_l_pl) - symba_plA%vh(1:nkpl, 1) = pack(symba_plA%vh(1:npl, 1), .not. discard_l_pl) - symba_plA%vh(1:nkpl, 2) = pack(symba_plA%vh(1:npl, 2), .not. discard_l_pl) - symba_plA%vh(1:nkpl, 3) = pack(symba_plA%vh(1:npl, 3), .not. discard_l_pl) - symba_plA%rhill(1:nkpl) = pack(symba_plA%rhill(1:npl), .not. discard_l_pl) - symba_plA%xb(1:nkpl, 1) = pack(symba_plA%xb(1:npl, 1), .not. discard_l_pl) - symba_plA%xb(1:nkpl, 2) = pack(symba_plA%xb(1:npl, 2), .not. discard_l_pl) - symba_plA%xb(1:nkpl, 3) = pack(symba_plA%xb(1:npl, 3), .not. discard_l_pl) - symba_plA%vb(1:nkpl, 1) = pack(symba_plA%vb(1:npl, 1), .not. discard_l_pl) - symba_plA%vb(1:nkpl, 2) = pack(symba_plA%vb(1:npl, 2), .not. discard_l_pl) - symba_plA%vb(1:nkpl, 3) = pack(symba_plA%vb(1:npl, 3), .not. discard_l_pl) - symba_plA%ah(1:nkpl, 1) = pack(symba_plA%ah(1:npl, 1), .not. discard_l_pl) - symba_plA%ah(1:nkpl, 2) = pack(symba_plA%ah(1:npl, 2), .not. discard_l_pl) - symba_plA%ah(1:nkpl, 3) = pack(symba_plA%ah(1:npl, 3), .not. discard_l_pl) - npl = nkpl - symba_plA%nbody = npl - end if - end if - - if (ldiscard_tp) then - nktp = 0 - nsptp = 0 - - discard_l_tp(1:ntp) = (symba_tpA%status(1:ntp) /= ACTIVE) - nsptp = count(discard_l_tp) - nktp = ntp - nsptp - - call discard_tpA%alloc(nsptp) - - discard_tpA%name(1:nsptp) = pack(symba_tpA%name(1:ntp), discard_l_tp) - discard_tpA%status(1:nsptp) = pack(symba_tpA%status(1:ntp), discard_l_tp) - discard_tpA%xh(1:nsptp, 1) = pack(symba_tpA%xh(1:ntp, 1), discard_l_tp) - discard_tpA%xh(1:nsptp, 2) = pack(symba_tpA%xh(1:ntp, 2), discard_l_tp) - discard_tpA%xh(1:nsptp, 3) = pack(symba_tpA%xh(1:ntp, 3), discard_l_tp) - discard_tpA%vh(1:nsptp, 1) = pack(symba_tpA%vh(1:ntp, 1), discard_l_tp) - discard_tpA%vh(1:nsptp, 2) = pack(symba_tpA%vh(1:ntp, 2), discard_l_tp) - discard_tpA%vh(1:nsptp, 3) = pack(symba_tpA%vh(1:ntp, 3), discard_l_tp) - discard_tpA%isperi(1:nsptp) = pack(symba_tpA%isperi(1:ntp), discard_l_tp) - discard_tpA%peri(1:nsptp) = pack(symba_tpA%peri(1:ntp), discard_l_tp) - discard_tpA%atp(1:nsptp) = pack(symba_tpA%atp(1:ntp), discard_l_tp) - discard_tpA%xb(1:nsptp, 1) = pack(symba_tpA%xb(1:ntp, 1), discard_l_tp) - discard_tpA%xb(1:nsptp, 2) = pack(symba_tpA%xb(1:ntp, 2), discard_l_tp) - discard_tpA%xb(1:nsptp, 3) = pack(symba_tpA%xb(1:ntp, 3), discard_l_tp) - discard_tpA%vb(1:nsptp, 1) = pack(symba_tpA%vb(1:ntp, 1), discard_l_tp) - discard_tpA%vb(1:nsptp, 2) = pack(symba_tpA%vb(1:ntp, 2), discard_l_tp) - discard_tpA%vb(1:nsptp, 3) = pack(symba_tpA%vb(1:ntp, 3), discard_l_tp) - - symba_tpA%name(1:nktp) = pack(symba_tpA%name(1:ntp), .not. discard_l_tp) - symba_tpA%status(1:nktp) = pack(symba_tpA%status(1:ntp), .not. discard_l_tp) - symba_tpA%xh(1:nktp, 1) = pack(symba_tpA%xh(1:ntp, 1), .not. discard_l_tp) - symba_tpA%xh(1:nktp, 2) = pack(symba_tpA%xh(1:ntp, 2), .not. discard_l_tp) - symba_tpA%xh(1:nktp, 3) = pack(symba_tpA%xh(1:ntp, 3), .not. discard_l_tp) - symba_tpA%vh(1:nktp, 1) = pack(symba_tpA%vh(1:ntp, 1), .not. discard_l_tp) - symba_tpA%vh(1:nktp, 2) = pack(symba_tpA%vh(1:ntp, 2), .not. discard_l_tp) - symba_tpA%vh(1:nktp, 3) = pack(symba_tpA%vh(1:ntp, 3), .not. discard_l_tp) - symba_tpA%xb(1:nktp, 1) = pack(symba_tpA%xb(1:ntp, 1), .not. discard_l_tp) - symba_tpA%xb(1:nktp, 2) = pack(symba_tpA%xb(1:ntp, 2), .not. discard_l_tp) - symba_tpA%xb(1:nktp, 3) = pack(symba_tpA%xb(1:ntp, 3), .not. discard_l_tp) - symba_tpA%vb(1:nktp, 1) = pack(symba_tpA%vb(1:ntp, 1), .not. discard_l_tp) - symba_tpA%vb(1:nktp, 2) = pack(symba_tpA%vb(1:ntp, 2), .not. discard_l_tp) - symba_tpA%vb(1:nktp, 3) = pack(symba_tpA%vb(1:ntp, 3), .not. discard_l_tp) - symba_tpA%isperi(1:nktp) = pack(symba_tpA%isperi(1:ntp), .not. discard_l_tp) - symba_tpA%peri(1:nktp) = pack(symba_tpA%peri(1:ntp), .not. discard_l_tp) - symba_tpA%atp(1:nktp) = pack(symba_tpA%atp(1:ntp), .not. discard_l_tp) - symba_tpA%ah(1:nktp, 1) = pack(symba_tpA%ah(1:ntp, 1), .not. discard_l_tp) - symba_tpA%ah(1:nktp, 2) = pack(symba_tpA%ah(1:ntp, 2), .not. discard_l_tp) - symba_tpA%ah(1:nktp, 3) = pack(symba_tpA%ah(1:ntp, 3), .not. discard_l_tp) - ntp = nktp - symba_tpA%nbody = ntp - end if - - end procedure symba_rearray -end submodule s_symba_rearray diff --git a/src/symba/symba_reorder_pl.f90 b/src/symba/symba_reorder_pl.f90 deleted file mode 100644 index ac142bd7f..000000000 --- a/src/symba/symba_reorder_pl.f90 +++ /dev/null @@ -1,67 +0,0 @@ -submodule (symba) s_symba_reorder_pl -contains - module procedure symba_reorder_pl - !! author: David A. Minton - !! - !! Rearrange SyMBA planet arrays in order of decreasing mass - !! - !! Adapted from David E. Kaufmann's Swifter routine: symba_reorder_pl.f90 - use swiftest - implicit none - integer(I4B) :: i - integer(I4B), dimension(:), allocatable :: index - real(DP), dimension(:), allocatable :: mass - real(DP), dimension(:,:), allocatable :: symba_plwkspa - integer(I4B), dimension(:,:), allocatable :: symba_plwkspa_id_status - -! executable code - allocate(index(npl), mass(npl)) - allocate(symba_plwkspa(12,npl)) - allocate(symba_plwkspa_id_status(2,npl)) - - do i = 1, npl - mass(i) = symba_plA%mass(i) - symba_plwkspa_id_status(1,i) = symba_plA%name(i) - symba_plwkspa_id_status(2,i) = symba_plA%status(i) - symba_plwkspa(1,i) = symba_plA%mass(i) - symba_plwkspa(2,i) = symba_plA%radius(i) - symba_plwkspa(3,i) = symba_plA%xh(1,i) - symba_plwkspa(4,i) = symba_plA%xh(2,i) - symba_plwkspa(5,i) = symba_plA%xh(3,i) - symba_plwkspa(6,i) = symba_plA%vh(1,i) - symba_plwkspa(7,i) = symba_plA%vh(2,i) - symba_plwkspa(8,i) = symba_plA%vh(3,i) - symba_plwkspa(9,i) = symba_plA%rhill(i) - symba_plwkspa(10,i) = symba_plA%ah(1,i) - symba_plwkspa(11,i) = symba_plA%ah(2,i) - symba_plwkspa(12,i) = symba_plA%ah(3,i) - end do - call util_index(mass, index) - write(*,*) "************ Reorder ***************" - do i = 1, npl - symba_plA%name(i) = symba_plwkspa_id_status(1,index(npl-i+1)) - symba_plA%status(i) = symba_plwkspa_id_status(2,index(npl-i+1)) - symba_plA%mass(i) = symba_plwkspa(1,index(npl-i+1)) - symba_plA%radius(i) = symba_plwkspa(2,index(npl-i+1)) - symba_plA%xh(1,i) = symba_plwkspa(3,index(npl-i+1)) - symba_plA%xh(2,i) = symba_plwkspa(4,index(npl-i+1)) - symba_plA%xh(3,i) = symba_plwkspa(5,index(npl-i+1)) - symba_plA%vh(1,i) = symba_plwkspa(6,index(npl-i+1)) - symba_plA%vh(2,i) = symba_plwkspa(7,index(npl-i+1)) - symba_plA%vh(3,i) = symba_plwkspa(8,index(npl-i+1)) - symba_plA%rhill(i) = symba_plwkspa(9,index(npl-i+1)) - symba_plA%ah(1,i) = symba_plwkspa(10,index(npl-i+1)) - symba_plA%ah(2,i) = symba_plwkspa(11,index(npl-i+1)) - symba_plA%ah(3,i) = symba_plwkspa(12,index(npl-i+1)) - - - end do - if (allocated(symba_plwkspa)) deallocate(symba_plwkspa) - if (allocated(symba_plwkspa_id_status)) deallocate(symba_plwkspa_id_status) - if (allocated(mass)) deallocate(mass) - if (allocated(index)) deallocate(index) - - return - - end procedure symba_reorder_pl -end submodule s_symba_reorder_pl diff --git a/src/symba/symba_set_initial_conditions.f90 b/src/symba/symba_set_initial_conditions.f90 deleted file mode 100644 index 49a58aad5..000000000 --- a/src/symba/symba_set_initial_conditions.f90 +++ /dev/null @@ -1,36 +0,0 @@ -submodule (symba) s_symba_set_initial_conditions -contains - module procedure symba_set_initial_conditions - !! author: David A. Minton - !! - !! Sets up initial conditions for a run. Currently, it reads in all the ICs from input files, but future versions could also - !! initialize them in some other way - use swiftest - implicit none - - ! read in the total number of bodies from the input files - call symba_plA%read_from_file(param) - call symba_tpA%read_from_file(param) - - ! Save central body mass in vector form so that elemental functions can be evaluated with it - call symba_tpA%set_vec(symba_plA%mass(1),param%dt) - call symba_plA%set_vec(symba_plA%mass(1),param%dt) - - ! Save system mass to both objects - call symba_plA%set_msys(symba_plA) - call symba_tpA%set_msys(symba_plA) - - ! create arrays of data structures big enough to store the number of bodies we are adding - call mergeadd_list%alloc(10*npl)!DM: Why 10*npl? - call mergesub_list%alloc(npl) - call plplenc_list%alloc(10*npl)!DM: See ^ - call pltpenc_list%alloc(ntp)!DM: See ^ - - ! reads in initial conditions of all massive bodies from input file - ! reorder by mass - call symba_plA%reorder() - call util_valid(symba_plA, symba_tpA) - - return - end procedure symba_set_initial_conditions -end submodule s_symba_set_initial_conditions diff --git a/src/symba/symba_setup.f90 b/src/symba/symba_setup.f90 new file mode 100644 index 000000000..6449013dd --- /dev/null +++ b/src/symba/symba_setup.f90 @@ -0,0 +1,71 @@ +submodule(symba_classes) s_symba_setup + use swiftest +contains + module subroutine symba_setup_pl(self,n) + !! 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 test particle object + integer(I4B), intent(in) :: n !! Number of massive bodies to allocate + ! Internals + integer(I4B) :: i,j + + !> Call allocation method for parent class + !call helio_setup_pl(self, n) + call setup_pl(self, n) + if (n <= 0) return + return + end subroutine symba_setup_pl + + module subroutine symba_setup_system(self, param) + !! author: David A. Minton + !! + !! Initialize an SyMBA nbody system from files and sets up the planetocentric structures. + !! + 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 + call whm_setup_system(self, param) + + select type(pl => self%pl) + class is(symba_pl) + select type(cb => self%cb) + class is (symba_cb) + select type (tp => self%tp) + class is (symba_tp) + + + end select + end select + end select + + end subroutine symba_setup_system + + module subroutine symba_setup_tp(self,n) + !! 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, intent(in) :: n !! Number of test particles to allocate + + !> Call allocation method for parent class + !call helio_setup_tp(self, n) + call setup_tp(self, n) + if (n <= 0) return + return + end subroutine symba_setup_tp + +end submodule s_symba_setup diff --git a/src/symba/symba_spill_pl.f90 b/src/symba/symba_spill_pl.f90 deleted file mode 100644 index f92d4f51d..000000000 --- a/src/symba/symba_spill_pl.f90 +++ /dev/null @@ -1,46 +0,0 @@ -submodule (symba) s_symba_spill_pl -contains - module procedure symba_spill_pl - !! author: The Purdue Swiftest Team - David A. Minton, Carlisle A. Wishard, Jennifer L.L. Pouplin, and Jacob R. Elliott - !! - !! Move spilled (discarded) symba massive body structure from active list to discard list - use swiftest - integer(I4B) :: i,nspill, npl - - npl = self%nbody - nspill = self%nspill - if (.not. self%lspill) then - call discard%alloc(nspill) ! Create the discard object for this type - self%lspill = .true. - end if - - ! Pack the discarded bodies into the discard object - discard%lmerged(:) = pack(self%lmerged(1:npl), self%lspill_list(1:npl)) - discard%nplenc(:) = pack(self%nplenc(1:npl), self%lspill_list(1:npl)) - discard%nchild(:) = pack(self%nchild(1:npl), self%lspill_list(1:npl)) - discard%index_parent(:) = pack(self%index_parent(1:npl), self%lspill_list(1:npl)) - - ! Pack the kept bodies back into the original object - self%lmerged(:)= pack(self%lmerged(1:npl), .not. self%lspill_list(1:npl)) - self%nplenc(:) = pack(self%nplenc(1:npl), .not. self%lspill_list(1:npl)) - self%nchild(:)= pack(self%nchild(1:npl), .not. self%lspill_list(1:npl)) - self%index_parent(:)= pack(self%index_parent(1:npl), .not. self%lspill_list(1:npl)) - - do concurrent (i = 1:NDIM) - discard%index_child(:, i) = pack(self%index_child(1:npl, i), self%lspill_list(1:npl)) - self%index_child(:, i)= pack(self%index_child(1:npl, i), .not. self%lspill_list(1:npl)) - end do - - ! Call the spill method for the parent class - call symba_spill_tp(self,discard) - - return - - end procedure symba_spill_pl -end submodule s_symba_spill_pl - - - - - - diff --git a/src/symba/symba_spill_tp.f90 b/src/symba/symba_spill_tp.f90 deleted file mode 100644 index cc3299908..000000000 --- a/src/symba/symba_spill_tp.f90 +++ /dev/null @@ -1,33 +0,0 @@ -submodule (symba) s_symba_spill_tp -contains - module procedure symba_spill_tp - !! author: The Purdue Swiftest Team - David A. Minton, Carlisle A. Wishard, Jennifer L.L. Pouplin, and Jacob R. Elliott - !! - !! Move spilled (discarded) symba test particle structure from active list to discard list - use swiftest - integer(I4B) :: nspill, ntp - - ntp = self%nbody - nspill = self%nspill - if (.not. self%lspill) then - call discard%alloc(nspill) ! Create the discard object for this type - self%lspill = .true. - end if - - ! Pack the discarded bodies into the discard object - discard%nplenc(:) = pack(self%nplenc(1:ntp), self%lspill_list(1:ntp)) - discard%levelg(:) = pack(self%levelg(1:ntp), self%lspill_list(1:ntp)) - discard%levelm(:) = pack(self%levelm(1:ntp), self%lspill_list(1:ntp)) - - ! Pack the kept bodies back into the original object - self%nplenc(:) = pack(self%nplenc(1:ntp), .not. self%lspill_list(1:ntp)) - self%levelg(:)= pack(self%levelg(1:ntp), .not. self%lspill_list(1:ntp)) - self%levelm(:)= pack(self%levelm(1:ntp), .not. self%lspill_list(1:ntp)) - - ! Call the spill method for the parent class - call helio_spill_pl(self,discard) - - return - - end procedure symba_spill_tp -end submodule s_symba_spill_tp diff --git a/src/symba/symba_step.f90 b/src/symba/symba_step.f90 index cb1361833..b04caa74e 100644 --- a/src/symba/symba_step.f90 +++ b/src/symba/symba_step.f90 @@ -1,127 +1,47 @@ -submodule (symba) s_symba_step +submodule (symba_classes) s_symba_step + use swiftest contains - module procedure symba_step - !! 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 -use swiftest -implicit none - logical :: lencounter, lvdotr - integer(I4B) :: i, j, irec, nplm - real(DP), dimension(NDIM) :: xr, vr - logical, save :: lfirst = .true. - -! executable code - - do i = 1,npl - symba_plA%nplenc(i) = 0 - symba_plA%ntpenc(i) = 0 - symba_plA%levelg(i) = -1 - symba_plA%levelm(i) = -1 - symba_plA%index_parent(i) = i - symba_plA%index_child(:,i) = 0 - end do - do i =1,ntp - symba_tpA%nplenc(i) = 0 - symba_tpA%levelg(i) = -1 - symba_tpA%levelm(i) = -1 - end do - - - !there should be some parallel bits in here - - nplplenc = 0 - npltpenc = 0 - if (symba_plA%mass(1) < param%mtiny) then - nplm = 0 - else - nplm = 1 - end if - irec = 0 - -! all this needs to be changed to the tree search function for encounters - - do i = 2, npl - if (symba_plA%mass(i) < param%mtiny) exit - nplm = nplm + 1 - do j = i + 1, npl - xr(:) = symba_plA%xh(:,j) - symba_plA%xh(:,i) - vr(:) = symba_plA%vh(:,j) - symba_plA%vh(:,i) - call symba_chk(xr(:), vr(:), symba_plA%rhill(i), & - symba_plA%rhill(j), dt, irec, lencounter, lvdotr) - if (lencounter) then - nplplenc = nplplenc + 1 - if (nplplenc > nenmax) then - write(*, *) "Swiftest Error:" - write(*, *) " pl-pl encounter list is full." - write(*, *) " stopping..." - call util_exit(FAILURE) - end if - plplenc_list%status(nplplenc) = ACTIVE - plplenc_list%lvdotr(nplplenc) = lvdotr - plplenc_list%level(nplplenc) = irec - plplenc_list%index1(nplplenc) = i - plplenc_list%index2(nplplenc) = j - symba_plA%lmerged(i) = .false. - symba_plA%nplenc(i) = symba_plA%nplenc(i) + 1 - symba_plA%levelg(i) = irec - symba_plA%levelm(i) = irec - symba_plA%nchild(i) = 0 - symba_plA%lmerged(j) = .false. - symba_plA%nplenc(j) = symba_plA%nplenc(j) + 1 - symba_plA%levelg(j) = irec - symba_plA%levelm(j) = irec - symba_plA%nchild(j) = 0 - end if - end do - do j = 1, ntp - xr(:) = symba_tpA%xh(:,j) - symba_plA%xh(:,i) - vr(:) = symba_tpA%vh(:,j) - symba_plA%vh(:,i) - call symba_chk(xr(:), vr(:), symba_plA%rhill(i), 0.0_DP, dt, irec, lencounter, lvdotr) - if (lencounter) then - npltpenc = npltpenc + 1 - symba_plA%ntpenc(i) = symba_plA%ntpenc(i) + 1 - symba_plA%levelg(i) = irec - symba_plA%levelm(i) = irec - symba_tpA%nplenc(j) = symba_tpA%nplenc(j) + 1 - symba_tpA%levelg(j) = irec - symba_tpA%levelm(j) = irec - if (npltpenc > nenmax) then - write(*, *) "Swiftest Error:" - write(*, *) " pl-tp encounter list is full." - write(*, *) " stopping..." - call util_exit(FAILURE) + 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_pl, lencounter_tp, lencounter + + select type(pl => self%pl) + class is (symba_pl) + select type(tp => self%tp) + class is (symba_tp) + lencounter = pl%encounter_check(self, dt) .or. tp%encounter_check(self, dt) + if (lencounter) then + call self%interp(param, t, dt) + else + call helio_step_system(self, param, t, dt) end if - pltpenc_list%status(npltpenc) = ACTIVE - pltpenc_list%lvdotr(npltpenc) = lvdotr - pltpenc_list%level(npltpenc) = irec - pltpenc_list%indexpl(npltpenc) = i - pltpenc_list%indextp(npltpenc) = j - end if - end do - end do + end select + end select -! end of things that need to be changed in the tree + return - lencounter = ((nplplenc > 0) .or. (npltpenc > 0)) - if (lencounter) then - call symba_step_interp(param%lextra_force, param%lclose, t, npl, nplm, param%nplmax, & - ntp, param%ntpmax, symba_plA, symba_tpA, param%j2rp2, param%j4rp4, & - dt, eoffset, nplplenc, npltpenc, plplenc_list, pltpenc_list, nmergeadd, & - nmergesub, mergeadd_list, mergesub_list, param%encounter_file, param%out_type, & - fragmax, param) - lfirst = .true. - else - call symba_step_helio(lfirst, param%lextra_force, t, npl, nplm, param%nplmax, ntp,& - param%ntpmax, symba_plA, symba_tpA, & - param%j2rp2, param%j4rp4, dt) - end if + end subroutine symba_step_system - return + module subroutine symba_step_interp_system(self, param, t, dt) + 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 procedure symba_step + return + end subroutine symba_step_interp_system end submodule s_symba_step diff --git a/src/symba/symba_step_eucl.f90 b/src/symba/symba_step_eucl.f90 deleted file mode 100644 index a5075a415..000000000 --- a/src/symba/symba_step_eucl.f90 +++ /dev/null @@ -1,156 +0,0 @@ -submodule (symba) s_symba_step_eucl -contains - module procedure symba_step_eucl - !! author: Jacob R. Elliott - !! - !! Step planets and active test particles ahead in democratic heliocentric coordinates, descending the recursive - !! branch if necessary to handle possible close encounters. - !! Uses the single-loop blocking to evaluate the Euclidean distance matri - !! - !! Adapted from David E. Kaufmann's Swifter routine: symba_step.f90 - !! Adapted from Hal Levison's Swift routine symba5_step_pl.f -use swiftest -implicit none - logical :: lencounter, lvdotr - integer(I4B) :: i, j, irec, nplm, k, counter - integer(I4B), allocatable :: plpl_encounters_indices(:), pltp_encounters_indices(:) - real(DP), dimension(NDIM) :: xr, vr - - integer(I4B), allocatable, dimension(:) :: pltp_encounters, pltp_lvdotr - integer(I4B), allocatable, dimension(:) :: plpl_encounters, plpl_lvdotr - -! executable code - - ! initialize massive bodies - symba_plA%nplenc(1:npl) = 0 ! number of massive body encounters this particular massive body has - symba_plA%ntpenc(1:npl) = 0 ! number of test particle encounters this particle massive body has - symba_plA%levelg(1:npl) = -1 ! - symba_plA%levelm(1:npl) = -1 ! - symba_plA%index_parent(1:npl) = (/ (i, i=1,npl)/) - symba_plA%index_child(:, 1:npl) = 0 - - ! initialize test particles - symba_tpA%nplenc(1:ntp) = 0 - symba_tpA%levelg(1:ntp) = -1 - symba_tpA%levelm(1:ntp) = -1 - - nplplenc = 0 ! number of encounters in the entire run - npltpenc = 0 - -! all this needs to be changed to the tree search function for encounters - allocate(plpl_encounters(num_plpl_comparisons)) - allocate(plpl_lvdotr(num_plpl_comparisons)) - plpl_encounters = 0 - plpl_lvdotr = 0 - - ! call util_dist_eucl_plpl(npl,symba_plA%xh, num_plpl_comparisons, k_plpl, dist_plpl_array) - ! call util_dist_eucl_plpl(npl,symba_plA%vh, num_plpl_comparisons, k_plpl, vel_plpl_array) - call symba_chk_eucl(num_plpl_comparisons, k_plpl, symba_plA, dt, plpl_encounters, plpl_lvdotr, nplplenc) - - ! here i'll order the encounters - ! nplplenc = count(plpl_encounters > 0) - ! print *,'step nplplenc: ',nplplenc - if(nplplenc>0)then - - allocate(plpl_encounters_indices(nplplenc)) - - ! plpl_encounters_indices = pack(plpl_encounters,plpl_encounters > 0) - ! so it turns out this is significantly faster than the pack command - counter = 1 - do k = 1,num_plpl_comparisons - if(plpl_encounters(k).gt.0)then - plpl_encounters_indices(counter) = k - counter = counter + 1 - endif - enddo - - symba_plA%lmerged(k_plpl(1,plpl_encounters_indices)) = .false. ! they have not merged yet - symba_plA%nplenc(k_plpl(1,plpl_encounters_indices)) = symba_plA%nplenc(k_plpl(1,plpl_encounters_indices)) + 1 ! number of particles that massive body "i" has close encountered - symba_plA%levelg(k_plpl(1,plpl_encounters_indices)) = 0 ! recursion level - symba_plA%levelm(k_plpl(1,plpl_encounters_indices)) = 0 ! recursion level - symba_plA%nchild(k_plpl(1,plpl_encounters_indices)) = 0 - ! for the j particle - symba_plA%lmerged(k_plpl(2,plpl_encounters_indices)) = .false. - symba_plA%nplenc(k_plpl(2,plpl_encounters_indices)) = symba_plA%nplenc(k_plpl(2,plpl_encounters_indices)) + 1 - symba_plA%levelg(k_plpl(2,plpl_encounters_indices)) = 0 - symba_plA%levelm(k_plpl(2,plpl_encounters_indices)) = 0 - symba_plA%nchild(k_plpl(2,plpl_encounters_indices)) = 0 - - plplenc_list%status(1:nplplenc) = ACTIVE ! you are in an encounter - plplenc_list%lvdotr(1:nplplenc) = plpl_lvdotr(plpl_encounters_indices)! flag of relative accelerations to say if there will be a close encounter in next timestep - plplenc_list%level(1:nplplenc) = 0 ! recursion level - plplenc_list%index1(1:nplplenc) = k_plpl(1,plpl_encounters_indices) ! index of first massive body in encounter - plplenc_list%index2(1:nplplenc) = k_plpl(2,plpl_encounters_indices) ! index of second massive body in encounter - deallocate(plpl_encounters_indices) - endif - - deallocate(plpl_encounters, plpl_lvdotr) - - if(ntp>0)then - allocate(pltp_encounters(num_pltp_comparisons)) - allocate(pltp_lvdotr(num_pltp_comparisons)) - - - pltp_encounters = 0 - pltp_lvdotr = 0 - - ! call util_dist_eucl_pltp(npl, ntp, symba_plA%xh, symba_tpA%xh, & - ! num_pltp_comparisons, k_pltp, dist_pltp_array) - ! call util_dist_eucl_pltp(npl, ntp, symba_plA%vh, symba_tpA%vh, & - ! num_pltp_comparisons, k_pltp, vel_pltp_array) - call symba_chk_eucl_pltp(num_pltp_comparisons, k_pltp, symba_plA, symba_tpA, dt, pltp_encounters, pltp_lvdotr, npltpenc) - - ! npltpenc = count(pltp_encounters > 0) - ! print *,'step npltpenc: ',npltpenc - if(npltpenc>0)then - - allocate(pltp_encounters_indices(npltpenc)) - - counter = 1 - do k = 1,num_pltp_comparisons - if(pltp_encounters(k).gt.0)then - pltp_encounters_indices(counter) = k - counter = counter + 1 - endif - enddo - - symba_plA%ntpenc(k_pltp(1,pltp_encounters_indices)) = symba_plA%ntpenc(k_pltp(1,pltp_encounters_indices)) + 1 - symba_plA%levelg(k_pltp(1,pltp_encounters_indices)) = 0 - symba_plA%levelm(k_pltp(1,pltp_encounters_indices)) = 0 - - symba_tpA%nplenc(k_pltp(2,pltp_encounters_indices)) = symba_tpA%nplenc(k_pltp(2,pltp_encounters_indices)) + 1 - symba_tpA%levelg(k_pltp(2,pltp_encounters_indices)) = 0 - symba_tpA%levelm(k_pltp(2,pltp_encounters_indices)) = 0 - - pltpenc_list%status(1:npltpenc) = ACTIVE - pltpenc_list%lvdotr(1:npltpenc) = pltp_lvdotr(pltp_encounters_indices) - pltpenc_list%level(1:npltpenc) = 0 - pltpenc_list%indexpl(1:npltpenc) = k_pltp(1,pltp_encounters_indices) - pltpenc_list%indextp(1:npltpenc) = k_pltp(1,pltp_encounters_indices) - - deallocate(pltp_encounters_indices) - endif - - deallocate(pltp_encounters, pltp_lvdotr) - endif - -! end of things that need to be changed in the tree - - nplm = count(symba_plA%mass > mtiny) - ! flag to see if there was an encounter - lencounter = ((nplplenc > 0) .or. (npltpenc > 0)) - - if (lencounter) then ! if there was an encounter, we need to enter symba_step_interp to see if we need recursion - call symba_step_interp_eucl(lextra_force, lclose, t, npl, nplm, param%nplmax, ntp, param%ntpmax, symba_plA, symba_tpA, param%j2rp2, param%j4rp4,& - dt, eoffset, mtiny, nplplenc, npltpenc, plplenc_list, pltpenc_list, nmergeadd, nmergesub, mergeadd_list,& - mergesub_list, encounter_file, out_type, num_plpl_comparisons, k_plpl, num_pltp_comparisons, k_pltp) - lfirst = .true. - else ! otherwise we can just advance the particles - call symba_step_helio(lfirst, lextra_force, t, npl, nplm, param%nplmax, ntp, param%ntpmax, symba_plA, symba_tpA, & - param%j2rp2, param%j4rp4, dt) - end if - - return - - end procedure symba_step_eucl -end submodule s_symba_step_eucl diff --git a/src/symba/symba_step_helio.f90 b/src/symba/symba_step_helio.f90 deleted file mode 100644 index 3d3284c0a..000000000 --- a/src/symba/symba_step_helio.f90 +++ /dev/null @@ -1,24 +0,0 @@ -submodule (symba) s_symba_step_helio -contains - module procedure symba_step_helio - !! author: David A. Minton - !! - !! Step planets and test particles ahead in democratic heliocentric coordinates - !! - !! Adapted from David E. Kaufmann's Swifter routine: symba_step_helio.f90 - use swiftest - implicit none - logical :: lfirsttp - real(DP), dimension(NDIM) :: ptbeg, ptend - real(DP), dimension(npl, NDIMm) :: xbeg, xend - -! executable code - lfirsttp = lfirst - call symba_step_helio_pl(lfirst, lextra_force, t, npl, nplm, param%nplmax, helio_plA, param%j2rp2, param%j4rp4, dt, xbeg, xend, ptbeg, ptend) - if (ntp > 0) call helio_step_tp(lfirsttp, lextra_force, t, nplm, param%nplmax, ntp, param%ntpmax, helio_plA, helio_tpA, param%j2rp2, param%j4rp4, & - dt, xbeg, xend, ptbeg, ptend) - - return - - end procedure symba_step_helio -end submodule s_symba_step_helio diff --git a/src/symba/symba_step_helio_pl.f90 b/src/symba/symba_step_helio_pl.f90 deleted file mode 100644 index bcf2cfc40..000000000 --- a/src/symba/symba_step_helio_pl.f90 +++ /dev/null @@ -1,52 +0,0 @@ -submodule (symba) s_symba_step_helio_pl -contains - module procedure symba_step_helio_pl - !! author: David A. Minton - !! - !! Step planets ahead in democratic heliocentric coordinates - !! - !! Adapted from David E. Kaufmann's Swifter routine: symba_step_helio_pl.f90 - !! Adapted from Hal Levison's Swift routines symba5_step_helio.f and helio_step_pl.f -use swiftest -implicit none - logical :: lflag - integer(I4B) :: i - real(DP) :: dth, msys - -! executable code - - - dth = 0.5_DP*dt - lflag = lfirst - if (lfirst) then - call coord_vh2vb(npl, helio_plA%swiftest, msys) - lfirst = .false. - end if - - call helio_lindrift(npl, helio_plA%swiftest, dth, ptbeg) - - call symba_helio_getacch(lflag, lextra_force, t, npl, nplm, param%nplmax, helio_plA, param%j2rp2, param%j4rp4) - lflag = .true. - - call helio_kickvb(npl, helio_plA, dth) - - do i = 2, nplm - xbeg(:, i) = helio_plA%swiftest%xh(:,i) - end do - call helio_drift(npl, helio_plA%swiftest, dt) - - do i = 2, nplm - xend(:, i) = helio_plA%swiftest%xh(:,i) - end do - call symba_helio_getacch(lflag, lextra_force, t+dt, npl, nplm, param%nplmax, helio_plA, param%j2rp2, param%j4rp4) - - call helio_kickvb(npl, helio_plA, dth) - - call helio_lindrift(npl, helio_plA%swiftest, dth, ptend) - - call coord_vb2vh(npl, helio_plA%swiftest) - - return - - end procedure symba_step_helio_pl -end submodule s_symba_step_helio_pl diff --git a/src/symba/symba_step_interp.f90 b/src/symba/symba_step_interp.f90 deleted file mode 100644 index 7ec056ec8..000000000 --- a/src/symba/symba_step_interp.f90 +++ /dev/null @@ -1,72 +0,0 @@ -submodule (symba) s_symba_step_interp -contains - module procedure symba_step_interp - !! 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 - use swiftest - implicit none - logical , save :: lmalloc = .true. - integer( I4B) :: i, irec - real(DP) :: dth, msys - real(DP), dimension(NDIM) :: ptbeg, ptend - real(DP), dimension(:, :), allocatable, save :: xbeg, xend - -! executable code - - if (lmalloc) then - allocate(xbeg(NDIM, param%nplmax), xend(NDIM, param%nplmax)) - lmalloc = .false. - end if - dth = 0.5_DP*dt - - call coord_vh2vb(npl, symba_plA, msys) - - call helio_lindrift(npl, symba_plA, dth, ptbeg) - if (ntp > 0) then - call coord_vh2vb_tp(ntp, symba_tpA, -ptbeg) - call helio_lindrift_tp(ntp, symba_tpA, dth, ptbeg) - do i = 2, npl - xbeg(:, i) = symba_plA%xh(:,i) - end do - end if - - call symba_getacch(lextra_force, t, npl, nplm, symba_plA, param%j2rp2, param%j4rp4, nplplenc, plplenc_list) - if (ntp > 0) call symba_getacch_tp(lextra_force, t, npl, nplm, param%nplmax, ntp, param%ntpmax, symba_plA, symba_tpA, xbeg, param%j2rp2, & - param%j4rp4, npltpenc, pltpenc_list) - - call helio_kickvb(npl, symba_plA, dth) - if (ntp > 0) call helio_kickvb_tp(ntp, symba_tpA, dth) - irec = -1 - - call symba_helio_drift(irec, npl, symba_plA, dt) - if (ntp > 0) call symba_helio_drift_tp(irec, ntp, symba_tpA, symba_plA%mass(1), dt) - irec = 0 - - call symba_step_recur(lclose, t, irec, npl, nplm, ntp, symba_plA, symba_tpA, dt, eoffset, nplplenc, npltpenc, & - plplenc_list, pltpenc_list, nmergeadd, nmergesub, mergeadd_list, mergesub_list, encounter_file, out_type, & - param%nplmax, param%ntpmax, fragmax, param) - if (ntp > 0) then - do i = 2, npl - xend(:, i) = symba_plA%xh(:,i) - end do - end if - call symba_getacch(lextra_force, t+dt, npl, nplm, symba_plA, param%j2rp2, param%j4rp4, nplplenc, plplenc_list) - if (ntp > 0) call symba_getacch_tp(lextra_force, t+dt, npl, nplm, param%nplmax, ntp, param%ntpmax, symba_plA, symba_tpA, xend, param%j2rp2, & - param%j4rp4, npltpenc, pltpenc_list) - call helio_kickvb(npl, symba_plA, dth) - if (ntp > 0) call helio_kickvb_tp(ntp, symba_tpA, dth) - call coord_vb2vh(npl, symba_plA) - call helio_lindrift(npl, symba_plA, dth, ptend) - if (ntp > 0) then - call coord_vb2vh_tp(ntp, symba_tpA, -ptend) - call helio_lindrift_tp(ntp, symba_tpA, dth, ptend) - end if - return - - end procedure symba_step_interp -end submodule s_symba_step_interp diff --git a/src/symba/symba_step_interp_eucl.f90 b/src/symba/symba_step_interp_eucl.f90 deleted file mode 100644 index 2036ae9aa..000000000 --- a/src/symba/symba_step_interp_eucl.f90 +++ /dev/null @@ -1,73 +0,0 @@ -submodule (symba) s_symba_step_interp_eucl -contains - module procedure symba_step_interp_eucl - !! author: Jacob R. Elliott - !! - !! Same as symba_step_interp, but with th new single loop-blocking Euclidean distance matrix evaluation - !! - !! Adapted from David E. Kaufmann's Swifter routine: symba_step_interp.f90 - !! Adapted from Hal Levison's Swift routine symba5_step_interp.f - use swiftest - implicit none - logical , save :: lmalloc = .true. - integer(I4B) :: i, irec - real(DP) :: dth, msys - real(DP), dimension(NDIM) :: ptbeg, ptend - real(DP), dimension(:, :), allocatable, save :: xbeg, xend - -! executable code - - if (lmalloc) then - allocate(xbeg(NDIM, param%nplmax), xend(NDIM, param%nplmax)) - lmalloc = .false. - end if - dth = 0.5_DP*dt - - call coord_vh2vb(npl, symba_plA, msys) - - call helio_lindrift(npl, symba_plA, dth, ptbeg) - if (ntp > 0) then - call coord_vh2vb_tp(ntp, symba_tpA, -ptbeg) - call helio_lindrift_tp(ntp, symba_tpA, dth, ptbeg) - do i = 2, npl - xbeg(:, i) = symba_plA%xh(:,i) - end do - end if - - call symba_getacch_eucl(lextra_force, t, npl, nplm, param%nplmax, symba_plA, param%j2rp2, param%j4rp4, nplplenc, plplenc_list, & - num_plpl_comparisons, k_plpl) - if (ntp > 0) call symba_getacch_tp_eucl(lextra_force, t, npl, nplm, param%nplmax, ntp, param%ntpmax, symba_plA, symba_tpA, xbeg, param%j2rp2,& - param%j4rp4, npltpenc, pltpenc_list, num_pltp_comparisons, k_pltp) - - call helio_kickvb(npl, symba_plA, dth) - if (ntp > 0) call helio_kickvb_tp(ntp, symba_tpA, dth) - irec = -1 - - call symba_helio_drift(irec, npl, symba_plA, dt) - if (ntp > 0) call symba_helio_drift_tp(irec, ntp, symba_tpA, symba_plA%mass(1), dt) - irec = 0 - - call symba_step_recur(lclose, t, irec, npl, nplm, ntp, symba_plA, symba_tpA, dt, eoffset, nplplenc, npltpenc,& - plplenc_list, pltpenc_list, nmergeadd, nmergesub, mergeadd_list, mergesub_list, encounter_file, out_type) - if (ntp > 0) then - do i = 2, npl - xend(:, i) = symba_plA%xh(:,i) - end do - end if - call symba_getacch_eucl(lextra_force, t+dt, npl, nplm, param%nplmax, symba_plA, param%j2rp2, param%j4rp4, nplplenc, plplenc_list, & - num_plpl_comparisons, k_plpl) - if (ntp > 0) call symba_getacch_tp_eucl(lextra_force, t+dt, npl, nplm, param%nplmax, ntp, param%ntpmax, symba_plA, symba_tpA, xend, & - param%j2rp2,param%j4rp4, npltpenc, pltpenc_list, num_pltp_comparisons, k_pltp) - call helio_kickvb(npl, symba_plA, dth) - if (ntp > 0) call helio_kickvb_tp(ntp, symba_tpA, dth) - call coord_vb2vh(npl, symba_plA) - call helio_lindrift(npl, symba_plA, dth, ptend) - if (ntp > 0) then - call coord_vb2vh_tp(ntp, symba_tpA, -ptend) - call helio_lindrift_tp(ntp, symba_tpA, dth, ptend) - end if - - return - - end procedure symba_step_interp_eucl -end submodule s_symba_step_interp_eucl diff --git a/src/symba/symba_step_recur.f90 b/src/symba/symba_step_recur.f90 deleted file mode 100644 index b380a75c8..000000000 --- a/src/symba/symba_step_recur.f90 +++ /dev/null @@ -1,226 +0,0 @@ -submodule (symba) s_symba_step_recur -contains - module procedure symba_step_recur - !! 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 necessary - !! - !! Adapted from David E. Kaufmann's Swifter routine: symba_step_recur.f90 - !! Adapted from Hal Levison's Swift routine symba5_step_recur.F -use swiftest -implicit none - logical :: lencounter - integer(I4B) :: i, j, irecp, icflg, index_i, index_j, index_pl, index_tp - real(DP) :: dtl, dth, sgn - real(DP), dimension(NDIM) :: xr, vr, vbs - -! executable code - dtl = dt0/(ntenc**ireci) - dth = 0.5_DP*dtl - if (dtl/dt0 < VSMALL) then - write(*, *) "swiftest warning:" - write(*, *) " in symba_step_recur, 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 - icflg = 0 - do i = 1, nplplenc - if ((plplenc_list%status(i) == ACTIVE) .and. (plplenc_list%level(i) == ireci)) then - index_i = plplenc_list%index1(i) - index_j = plplenc_list%index2(i) - xr(:) = symba_plA%xh(:,index_j) - symba_plA%xh(:,index_i) - vr(:) = symba_plA%vb(:,index_j) - symba_plA%vb(:,index_i) - call symba_chk(xr(:), vr(:), symba_plA%rhill(index_i), & - symba_plA%rhill(index_j), dtl, irecp, lencounter, & - plplenc_list%lvdotr(i)) - if (lencounter) then - icflg = 1 - symba_plA%levelg(index_i) = irecp - symba_plA%levelm(index_i) = max(irecp, symba_plA%levelm(index_i)) - symba_plA%levelg(index_j) = irecp - symba_plA%levelm(index_j) = max(irecp, symba_plA%levelm(index_j)) - plplenc_list%level(i) = irecp - end if - end if - end do - do i = 1, npltpenc - if ((pltpenc_list%status(i) == ACTIVE) .and. (pltpenc_list%level(i) == ireci)) then - index_pl = pltpenc_list%indexpl(i) - index_tp = pltpenc_list%indextp(i) - - xr(:) = symba_tpA%xh(:,index_tp) - symba_plA%xh(:,index_pl) - vr(:) = symba_tpA%vb(:,index_tp) - symba_plA%vb(:,index_pl) - call symba_chk(xr(:), vr(:), symba_plA%rhill(index_pl), 0.0_DP, & - dtl, irecp, lencounter, pltpenc_list%lvdotr(i)) - if (lencounter) then - icflg = 1 - symba_plA%levelg(index_pl) = irecp - symba_plA%levelm(index_pl) = max(irecp, symba_plA%levelm(index_pl)) - symba_tpA%levelg(index_tp) = irecp - symba_tpA%levelm(index_tp) = max(irecp, symba_tpA%levelm(index_tp)) - pltpenc_list%level(i) = 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,symba_plA, symba_tpA) - call symba_helio_drift(ireci, npl, symba_plA, dtl) - if (ntp > 0) call symba_helio_drift_tp(ireci, ntp, symba_tpA, symba_plA%mass(1), dtl) - if (lencounter) call symba_step_recur(lclose, t, irecp, npl, nplm, ntp, symba_plA, symba_tpA, dt0, eoffset, nplplenc, & - npltpenc, plplenc_list, pltpenc_list, nmergeadd, nmergesub, mergeadd_list, mergesub_list, encounter_file, out_type, & - param%nplmax, param%ntpmax, fragmax, param) - sgn = 1.0_DP - call symba_kick(irecp, nplplenc, npltpenc, plplenc_list, pltpenc_list, dth, sgn,symba_plA, symba_tpA) - if (lclose) then - vbs(:) = symba_plA%vb(:,1) - do i = 1, nplplenc - index_i = plplenc_list%index1(i) - index_j = plplenc_list%index2(i) - if (((plplenc_list%status(i) == ACTIVE) .and. & - (symba_plA%levelg(index_i) >= ireci) .and. & - (symba_plA%levelg(index_j) >= ireci))) then - ! create if statement to check for collisions (ls12) or merger depending on flag lfrag in param.in - ! determines collisional regime if lfrag=.true. for close encounter massive bodies - ! call symba_frag_pl(...) - ! determines if close encounter leads to merger if lfrag=.false. - if (param%lfragmentation) then - call symba_fragmentation (t, dtl, i, nmergeadd, nmergesub, mergeadd_list, mergesub_list, & - eoffset, vbs, encounter_file, out_type, npl, symba_plA, nplplenc, plplenc_list, param%nplmax, & - param%ntpmax, fragmax) - else - call symba_merge_pl(t, dtl, i, nplplenc, plplenc_list, nmergeadd, nmergesub, mergeadd_list, & - mergesub_list, eoffset, vbs, encounter_file, out_type, npl, symba_plA) - end if - end if - end do - do i = 1, npltpenc - index_pl = pltpenc_list%indexpl(i) - index_tp = pltpenc_list%indextp(i) - if ((pltpenc_list%status(i) == ACTIVE) .and. & - (symba_plA%levelg(index_pl) >= ireci) .and. & - (symba_tpA%levelg(index_tp) >= ireci)) then - call symba_merge_tp(t, dtl, i, pltpenc_list, vbs, encounter_file, out_type, symba_plA, symba_tpA) !check later - end if - end do - end if - do i = 1, nplplenc - index_i = plplenc_list%index1(i) - index_j = plplenc_list%index2(i) - if (symba_plA%levelg(index_i) == irecp) symba_plA%levelg(index_i) = ireci - if (symba_plA%levelg(index_j) == irecp) symba_plA%levelg(index_j) = ireci - if (plplenc_list%level(i) == irecp) plplenc_list%level(i) = ireci - end do - do i = 1, npltpenc - index_pl = pltpenc_list%indexpl(i) - index_tp = pltpenc_list%indextp(i) - if (symba_plA%levelg(index_pl) == irecp) symba_plA%levelg(index_pl) = ireci - if (symba_tpA%levelg(index_tp) == irecp) symba_tpA%levelg(index_tp) = ireci - if (pltpenc_list%level(i) == irecp) pltpenc_list%level(i) = ireci - end do - else - do j = 1, ntenc - icflg = 0 - do i = 1, nplplenc - if ((plplenc_list%status(i) == ACTIVE) .and. (plplenc_list%level(i) == ireci)) then - index_i = plplenc_list%index1(i) - index_j = plplenc_list%index2(i) - xr(:) = symba_plA%xh(:,index_j) - symba_plA%xh(:,index_i) - vr(:) = symba_plA%vb(:,index_j) - symba_plA%vb(:,index_i) - call symba_chk(xr(:), vr(:), symba_plA%rhill(index_i), & - symba_plA%rhill(index_j), dtl, irecp, lencounter, & - plplenc_list%lvdotr(i)) - if (lencounter) then - icflg = 1 - symba_plA%levelg(index_i) = irecp - symba_plA%levelm(index_i) = max(irecp, symba_plA%levelm(index_i)) - symba_plA%levelg(index_j) = irecp - symba_plA%levelm(index_j) = max(irecp, symba_plA%levelm(index_j)) - plplenc_list%level(i) = irecp - end if - end if - end do - do i = 1, npltpenc - if ((pltpenc_list%status(i) == ACTIVE) .and. (pltpenc_list%level(i) == ireci)) then - index_pl = pltpenc_list%indexpl(i) - index_tp = pltpenc_list%indextp(i) - xr(:) = symba_tpA%xh(:,index_tp) - symba_plA%xh(:,index_pl) - vr(:) = symba_tpA%vb(:,index_tp) - symba_plA%vb(:,index_pl) - call symba_chk(xr(:), vr(:), symba_plA%rhill(index_pl), 0.0_DP, & - dtl, irecp, lencounter, pltpenc_list%lvdotr(i)) - if (lencounter) then - icflg = 1 - symba_plA%levelg(index_pl) = irecp - symba_plA%levelm(index_pl) = max(irecp, symba_plA%levelm(index_pl)) - symba_tpA%levelg(index_tp) = irecp - symba_tpA%levelm(index_tp) = max(irecp, symba_tpA%levelm(index_tp)) - pltpenc_list%level(i) = 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,symba_plA, symba_tpA) - sgn = -1.0_DP - call symba_kick(irecp, nplplenc, npltpenc, plplenc_list, pltpenc_list, dth, sgn,symba_plA, symba_tpA) - call symba_helio_drift(ireci, npl, symba_plA, dtl) - if (ntp > 0) call symba_helio_drift_tp(ireci, ntp, symba_tpA, symba_plA%mass(1), dtl) - if (lencounter) call symba_step_recur(lclose, t, irecp, npl, nplm, ntp, symba_plA, symba_tpA, dt0, eoffset, & - nplplenc, npltpenc, plplenc_list, pltpenc_list, nmergeadd, nmergesub, mergeadd_list, mergesub_list, & - encounter_file, out_type, param%nplmax, param%ntpmax, fragmax, param) - sgn = 1.0_DP - call symba_kick(irecp, nplplenc, npltpenc, plplenc_list, pltpenc_list, dth, sgn,symba_plA, symba_tpA) - sgn = -1.0_DP - call symba_kick(irecp, nplplenc, npltpenc, plplenc_list, pltpenc_list, dth, sgn,symba_plA, symba_tpA) - if (lclose) then - vbs(:) = symba_plA%vb(:,1) - do i = 1, nplplenc - index_i = plplenc_list%index1(i) - index_j = plplenc_list%index2(i) - if ((plplenc_list%status(i) == ACTIVE) .and. & - (symba_plA%levelg(index_i) >= ireci) .and. & - (symba_plA%levelg(index_j) >= ireci)) then - if (param%lfragmentation) then - call symba_fragmentation (t, dtl, i, nmergeadd, nmergesub, mergeadd_list, mergesub_list, & - eoffset, vbs, encounter_file, out_type, npl, symba_plA, nplplenc, plplenc_list, param%nplmax, & - param%ntpmax, fragmax) - else - call symba_merge_pl(t, dtl, i, nplplenc, plplenc_list, nmergeadd, nmergesub, mergeadd_list, & - mergesub_list, eoffset, vbs, encounter_file, out_type, npl, symba_plA) - end if - end if - end do - do i = 1, npltpenc - index_pl = pltpenc_list%indexpl(i) - index_tp = pltpenc_list%indextp(i) - if ((pltpenc_list%status(i) == ACTIVE) .and. & - (symba_plA%levelg(index_pl) >= ireci) .and. & - (symba_tpA%levelg(index_tp) >= ireci)) & - call symba_merge_tp(t, dtl, i, pltpenc_list, vbs, encounter_file, out_type, symba_plA, symba_tpA) !check that later - end do - end if - do i = 1, nplplenc - index_i = plplenc_list%index1(i) - index_j = plplenc_list%index2(i) - if (symba_plA%levelg(index_i) == irecp) symba_plA%levelg(index_i) = ireci - if (symba_plA%levelg(index_j) == irecp) symba_plA%levelg(index_j) = ireci - if (plplenc_list%level(i) == irecp) plplenc_list%level(i) = ireci - end do - do i = 1, npltpenc - index_pl = pltpenc_list%indexpl(i) - index_tp = pltpenc_list%indextp(i) - if (symba_plA%levelg(index_pl) == irecp) symba_plA%levelg(index_pl) = ireci - if (symba_tpA%levelg(index_tp) == irecp) symba_tpA%levelg(index_tp) = ireci - if (pltpenc_list%level(i) == irecp) pltpenc_list%level(i) = ireci - end do - end do - end if - - return - - end procedure symba_step_recur -end submodule s_symba_step_recur diff --git a/src/symba/symba_user_getacch.f90 b/src/symba/symba_user_getacch.f90 deleted file mode 100644 index 4b4e6080b..000000000 --- a/src/symba/symba_user_getacch.f90 +++ /dev/null @@ -1,17 +0,0 @@ -submodule (symba) s_symba_user_getacch -contains - module procedure symba_user_getacch - !! author: David A. Minton - !! - !! Add user-supplied heliocentric accelerations to planetss - !! - !! Adapted from David E. Kaufmann's Swifter routine: symba_user_getacch.f90 -use swiftest -implicit none - -! executable code - - return - - end procedure symba_user_getacch -end submodule s_symba_user_getacch diff --git a/src/symba/symba_user_getacch_tp.f90 b/src/symba/symba_user_getacch_tp.f90 deleted file mode 100644 index 148effcc0..000000000 --- a/src/symba/symba_user_getacch_tp.f90 +++ /dev/null @@ -1,22 +0,0 @@ -submodule (symba) s_symba_user_getacch_tp -contains - module procedure symba_user_getacch_tp - !! author: David A. Minton - !! - !! Add user-supplied heliocentric accelerations to test particles - !! - !! Adapted from David E. Kaufmann's Swifter routine: symba_user_getacch_tp.f90 - !! Adapted from Hal Levison's Swift routine symba_user_getacch_tp.f -! -! Notes : -! -!********************************************************************************************************************************** -use swiftest -implicit none - -! executable code - - return - - end procedure symba_user_getacch_tp -end submodule s_symba_user_getacch_tp diff --git a/src/util/util_copy.f90 b/src/util/util_copy.f90 deleted file mode 100644 index 9731e9eff..000000000 --- a/src/util/util_copy.f90 +++ /dev/null @@ -1,154 +0,0 @@ -submodule (swiftest_classes) s_util_copy - use swiftest -contains - module procedure util_copy_cb - !! author: David A. Minton - !! - !! Copies elements of one Swiftest central body object to another. The mask is ignored for this case - !! - implicit none - select type(src) - class is(swiftest_cb) - self%mass = src%mass - self%Gmass = src%Gmass - self%radius = src%radius - self%density = src%density - self%j2rp2 = src%j2rp2 - self%j4rp4 = src%j4rp4 - self%aobl = src%aobl - self%xb = src%xb - self%vb = src%vb - self%Ip = src%Ip - self%rot = src%rot - self%k2 = src%k2 - self%Q = src%Q - class default - write(*,*) 'Error copying swiftest_cb object. Incompatible type.' - call util_exit(FAILURE) - end select - return - end procedure util_copy_cb - - module procedure util_copy_body - !! author: David A. Minton - !! - !! Copies elements of one Swiftest generic body object to another. The elements are determined by a mask. - !! - implicit none - - select type(src) - class is(swiftest_body) - where (mask(:)) - self%name(:) = src%name(:) - self%status(:) = src%status(:) - self%ldiscard(:) = src%ldiscard(:) - self%xh(1,:) = src%xh(1,:) - self%xh(2,:) = src%xh(2,:) - self%xh(3,:) = src%xh(3,:) - self%vh(1,:) = src%vh(1,:) - self%vh(2,:) = src%vh(2,:) - self%vh(3,:) = src%vh(3,:) - self%xb(1,:) = src%xb(1,:) - self%xb(2,:) = src%xb(2,:) - self%xb(3,:) = src%xb(3,:) - self%vb(1,:) = src%vb(1,:) - self%vb(2,:) = src%vb(2,:) - self%vb(3,:) = src%vb(3,:) - self%ah(1,:) = src%ah(1,:) - self%ah(2,:) = src%ah(2,:) - self%ah(3,:) = src%ah(3,:) - self%aobl(1,:) = src%aobl(1,:) - self%aobl(3,:) = src%aobl(2,:) - self%aobl(2,:) = src%aobl(3,:) - self%ir3h(:) = src%ir3h(:) - self%a(:) = src%a(:) - self%e(:) = src%e(:) - self%inc(:) = src%inc(:) - self%capom(:) = src%capom(:) - self%omega(:) = src%omega(:) - self%capm(:) = src%capm(:) - self%mu(:) = src%mu(:) - end where - class default - write(*,*) 'Error copying swiftest_body object. Incompatible type.' - call util_exit(FAILURE) - end select - - end procedure util_copy_body - - module procedure util_copy_pl - !! author: David A. Minton - !! - !! Copies elements of one Swiftest massive body object to another. The elements are determined by a mask. - !! - implicit none - select type(src) - class is(swiftest_pl) - where (mask(:)) - self%mass(:) = src%mass(:) - self%Gmass(:) = src%Gmass(:) - self%rhill(:) = src%rhill(:) - self%radius(:) = src%radius(:) - self%density(:) = src%density(:) - self%Ip(1,:) = src%Ip(1,:) - self%Ip(2,:) = src%Ip(2,:) - self%Ip(3,:) = src%Ip(3,:) - self%rot(1,:) = src%rot(1,:) - self%rot(2,:) = src%rot(2,:) - self%rot(3,:) = src%rot(3,:) - self%k2(:) = src%k2(:) - self%Q(:) = src%Q(:) - end where - call util_copy_body(self, src, mask) - class default - write(*,*) 'Error copying swiftest_pl object. Incompatible type.' - call util_exit(FAILURE) - end select - - end procedure util_copy_pl - - module procedure util_copy_tp - !! author: David A. Minton - !! - !! Copies elements of one swiftest test particle object to another. The elements are determined by a mask. - implicit none - - select type(src) - class is(swiftest_tp) - where (mask(:)) - self%isperi(:) = src%isperi(:) - self%peri(:) = src%peri(:) - self%atp(:) = src%atp(:) - end where - call util_copy_body(self, src, mask) - class default - write(*,*) 'Error copying swiftest_tp object. Incompatible type.' - call util_exit(FAILURE) - end select - - return - end procedure util_copy_tp - - module procedure util_copy_system - !! author: David A. Minton - !! - !! Copies elements of one Swiftest nbody system object to another. The elements are determined by a mask. - !! In this case the mask contains the pl elements followed by the tp elements. - !! - implicit none - - associate(pl => self%pl, tp => self%tp, npl => self%pl%nbody, ntp => self%tp%nbody) - - select type(src) - class is(swiftest_nbody_system) - call pl%copy(src%pl, mask(1:npl)) - call tp%copy(src%tp, mask(npl+1:npl+ntp)) - class default - write(*,*) 'Error copying swiftest_nbody_system object. Incompatible type.' - call util_exit(FAILURE) - end select - - - end associate - end procedure util_copy_system -end submodule s_util_copy \ No newline at end of file diff --git a/src/util/util_exit.f90 b/src/util/util_exit.f90 index ecf8d096d..4413bd9b3 100644 --- a/src/util/util_exit.f90 +++ b/src/util/util_exit.f90 @@ -1,29 +1,33 @@ -submodule (util) s_util_exit +submodule (swiftest_classes) s_util_exit use swiftest contains - module procedure util_exit - !! 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 - character(*), parameter :: BAR = '("------------------------------------------------")' + 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) - end select + 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) + end select - stop + stop - end procedure util_exit + end subroutine util_exit end submodule s_util_exit diff --git a/src/util/util_get.f90 b/src/util/util_get.f90 deleted file mode 100644 index 2bb1c5f2d..000000000 --- a/src/util/util_get.f90 +++ /dev/null @@ -1,77 +0,0 @@ -! submodule (swiftest_classes) s_util_get_energy_and_momentum -! contains -! module procedure util_get_energy_and_momentum -! !! author: David A. Minton -! !! -! !! Compute total system angular momentum vector and kinetic, potential and total system energy -! !! -! !! Adapted from David E. Kaufmann's Swifter routine: symba_energy.f90 -! !! Adapted from Martin Duncan's Swift routine anal_energy.f -! use swiftest -! implicit none - -! integer(I4B) :: i, j -! real(DP) :: mass, msys, r2, v2, oblpot, ke, pe -! real(DP), dimension(NDIM) :: h, x, v, dx, htot -! real(DP), dimension(:), allocatable :: irh - -! select type(pl => self%pl) -! class is (swiftest_pl) -! call pl%h2b(self%cb) -! htot(:) = 0.0_DP -! ke = 0.0_DP -! pe = 0.0_DP - -! !!$omp parallel do default(private) & -! !!$omp shared (self) & -! !!$omp reduction (+:ke, pe, htot) -! do i = 1, pl%nbody -! x(:) = pl%xb(:, i) -! v(:) = pl%vb(:, i) -! mass = pl%Gmass(i) -! h(:) = x(:) .cross. v(:) -! htot(:) = htot(:) + mass * h(:) -! v2 = dot_product(v(:), v(:)) -! ke = ke + 0.5_DP * mass * v2 -! do j = i + 1, pl%nbody -! dx(:) = pl%xb(:, j) - x(:) -! r2 = dot_product(dx(:), dx(:)) -! if (r2 /= 0) then -! pe = pe - mass * pl%Gmass(j) / sqrt(r2) -! end if -! end do -! end do -! !!$omp end parallel do -! end select - -! select type(cb => self%cb) -! class is (swiftest_cb) -! ! Add in the central body -! x(:) = cb%xb(:) -! v(:) = cb%vb(:) -! mass = cb%Gmass -! h(:) = x(:) .cross. v(:) -! htot(:) = htot(:) + mass * h(:) -! v2 = dot_product(v(:), v(:)) -! ke = ke + 0.5_DP * mass * v2 -! if (cb%j2rp2 /= 0.0_DP) then -! allocate(irh(self%pl%nbody)) -! do i = 1, self%pl%nbody -! r2 = dot_product(self%pl%xh(:, i), self%pl%xh(:, i)) -! irh(i) = 1.0_DP / sqrt(r2) -! end do -! oblpot = self%pl%obl_pot(cb, irh) -! deallocate(irh) -! pe = pe + oblpot -! end if -! end select - -! self%pe = pe -! self%ke = ke -! self%te = ke + pe -! self%htot(:) = htot(:) - -! return - -! end procedure util_get_energy_and_momentum -! end submodule s_util_get_energy_and_momentum diff --git a/src/util/util_hills.f90 b/src/util/util_hills.f90 deleted file mode 100644 index b743e1f31..000000000 --- a/src/util/util_hills.f90 +++ /dev/null @@ -1,32 +0,0 @@ -submodule (util) s_util_hills - use swiftest -contains - module procedure util_hills - !! author: David A. Minton - !! - !! Compute Hill sphere radii of planets - !! - !! Adapted from David E. Kaufmann's Swifter routine: util_hills.f90 - !! Adapted from Hal Levison's Swift routine util_hills.f - integer(I4B) :: i - real(DP) :: msun, mp, mu, energy, ap, r, v2 - - msun = swiftest_plA%mass(1) - do i = 2, npl - mp = swiftest_plA%mass(i) - if (mp > 0.0_DP) then - mu = msun + mp - r = norm2(swiftest_plA%xh(:, i)) - v2 = dot_product(swiftest_plA%vh(:, i), swiftest_plA%vh(:, i)) - energy = 0.5_DP*v2 - mu/r - ap = -0.5_DP*mu/energy - swiftest_plA%rhill(i) = ap*(((mp/mu)/3.0_DP)**(1.0_DP/3.0_DP)) - else - swiftest_plA%rhill(i) = 0.0_DP - end if - end do - - return - - end procedure util_hills -end submodule s_util_hills diff --git a/src/util/util_index.f90 b/src/util/util_index.f90 index 4bc760ec2..fcece8809 100644 --- a/src/util/util_index.f90 +++ b/src/util/util_index.f90 @@ -1,73 +1,78 @@ -submodule (util) s_util_index +submodule (swiftest_classes) s_util_index use swiftest contains - module procedure util_index - !! author: David A. Minton - !! - !! Index input real array into ascending numerical order using Quicksort algorithm - !! - !! Adapted from David E. Kaufmann's Swifter routine: util_index.f90 - !! Adapted from Numerical Recipes in Fortran 90: The Art of Parallel Scientific Computing, by Press, Teukolsky, - !! Vetterling, and Flannery, 2nd ed., pp. 1173-4 - 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 + module subroutine util_index(arr, index) + !! author: David A. Minton + !! + !! Index input real array into ascending numerical order using Quicksort algorithm + !! + !! Adapted from David E. Kaufmann's Swifter routine: util_index.f90 + !! Adapted from Numerical Recipes in Fortran 90: The Art of Parallel Scientific Computing, by Press, Teukolsky, + !! Vetterling, and Flannery, 2nd ed., pp. 1173-4 + 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 - n = size(arr) - if (n /= size(index)) then - write(*, *) "Swiftest Error:" - write(*, *) " array size mismatch in util_index" - call util_exit(FAILURE) - end if - index = arth(1, 1, n) - jstack = 0 - ! l is the counter ie 'the one we are at' - l = 1 - ! r is the length of the array ie 'the total number of particles' - 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 the mass of the particle we are at in our counting is greater than the mass of the last particle then put the particle we are at above the last one - if (arr(index(l)) > arr(index(r))) then - dum = index(l); index(l) = index(r); index(r) = dum - end if - ! if the mass of the particle above the one we are at in our counting is greater than the last particle then put that particle above the last one - if (arr(index(l+1)) > arr(index(r))) then - dum = index(l+1); index(l+1) = index(r); index(r) = dum - end if - ! if the mass of teh particle we are at in our counting is greater than the one above it, then put it above the one above it - 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 + n = size(arr) + if (n /= size(index)) then + write(*, *) "Swiftest Error:" + write(*, *) " array size mismatch in util_index" + call util_exit(FAILURE) + end if + index = arth(1, 1, n) + jstack = 0 + ! l is the counter ie 'the one we are at' + l = 1 + ! r is the length of the array ie 'the total number of particles' + 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 the mass of the particle we are at in our counting is greater than the mass of the last particle then put the particle we are at above the last one + if (arr(index(l)) > arr(index(r))) then + dum = index(l); index(l) = index(r); index(r) = dum + end if + ! if the mass of the particle above the one we are at in our counting is greater than the last particle then put that particle above the last one + if (arr(index(l+1)) > arr(index(r))) then + dum = index(l+1); index(l+1) = index(r); index(r) = dum + end if + ! if the mass of teh particle we are at in our counting is greater than the one above it, then put it above the one above it + 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 - j = j - 1 - if (arr(index(j)) <= a) exit + 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 @@ -94,5 +99,5 @@ return - end procedure util_index + end subroutine util_index end submodule s_util_index diff --git a/src/util/util_peri.f90 b/src/util/util_peri.f90 index bcface016..1884728da 100644 --- a/src/util/util_peri.f90 +++ b/src/util/util_peri.f90 @@ -1,80 +1,62 @@ -submodule (util) s_util_peri +submodule (swiftest_classes) s_util_peri use swiftest contains - module procedure util_peri - !! 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 - - integer(I4B) :: i - real(DP) :: e - real(DP), dimension(:), allocatable, save :: vdotr + 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(ntp => tp%nbody, xht => tp%xh, vht => tp%vh, status => tp%status, isperi => tp%isperi, & - xbt => tp%xb, vbt => tp%vb, atp => tp%atp, peri => tp%peri) - if (lfirst) then - if (.not. allocated(vdotr)) allocate(vdotr(ntp)) - if (qmin_coord == "HELIO") then - !do concurrent(i = 1:ntp, status(i) == ACTIVE) + associate(tp => self, ntp => self%nbody) + allocate(vdotr(ntp)) + if (param%qmin_coord == "HELIO") then do i = 1, ntp - vdotr(i) = dot_product(xht(:, i), vht(:, i)) - end do - else - !do concurrent(i = 1:ntp, status(i) == ACTIVE) - do i = 1, ntp - vdotr(i) = dot_product(xbt(:, i), vbt(:, i)) - end do - end if - where(vdotr(1:ntp) > 0.0_DP) - isperi(1:ntp) = 1 - elsewhere - isperi = -1 - end where - else - if (qmin_coord == "HELIO") then - !do concurrent (i = 1:ntp, status(i) == ACTIVE) - do i = 1, ntp - vdotr(i) = dot_product(xht(:, i), vht(:, i)) - if (isperi(i) == -1) then + vdotr(i) = dot_product(tp%xh(:, i), tp%vh(:, i)) + if (tp%isperi(i) == -1) then if (vdotr(i) >= 0.0_DP) then - isperi(i) = 0 - call orbel_xv2aeq(mu, xht(:, i), vht(:, i), atp(i), e, peri(i)) + 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 - isperi(i) = 1 + tp%isperi(i) = 1 else - isperi(i) = -1 + tp%isperi(i) = -1 end if end if end do else - !do concurrent (i = 1:ntp, status(i) == ACTIVE) do i = 1, ntp - vdotr(i) = dot_product(xbt(:, i), vbt(:, i)) - if (isperi(i) == -1) then + vdotr(i) = dot_product(tp%xb(:, i), tp%vb(:, i)) + if (tp%isperi(i) == -1) then if (vdotr(i) >= 0.0_DP) then - isperi(i) = 0 - call orbel_xv2aeq(msys, xbt(:, i), vbt(:, i), atp(i), e, peri(i)) + tp%isperi(i) = 0 + call orbel_xv2aeq(system%msys, tp%xb(:, i), tp%vb(:, i), tp%atp(i), e, tp%peri(i)) end if else if (vdotr(i) > 0.0_DP) then - isperi(i) = 1 + tp%isperi(i) = 1 else - isperi(i) = -1 + tp%isperi(i) = -1 end if end if end do end if - end if - end associate - return + end associate + return - end procedure util_peri + end subroutine util_peri_tp end submodule s_util_peri diff --git a/src/util/util_reverse_status.f90 b/src/util/util_reverse_status.f90 index 253d10fde..5fc0d0f22 100644 --- a/src/util/util_reverse_status.f90 +++ b/src/util/util_reverse_status.f90 @@ -1,16 +1,18 @@ submodule (swiftest_classes) s_util_reverse_status use swiftest contains - module procedure util_reverse_status + module subroutine util_reverse_status(self) !! author: David A. Minton !! !! Reverses the active/inactive status of all particles in a structure implicit none + ! Arguments + class(swiftest_body), intent(inout) :: self !! Swiftest body object where (self%status(:) == ACTIVE) self%status(:) = INACTIVE elsewhere (self%status(:) == INACTIVE) self%status(:) = ACTIVE end where - end procedure util_reverse_status + end subroutine util_reverse_status end submodule s_util_reverse_status \ 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..126f4f12d --- /dev/null +++ b/src/util/util_sort.f90 @@ -0,0 +1,263 @@ +submodule (swiftest_classes) s_util_sort + use swiftest +contains + module subroutine util_sort_dp(arr) + !! author: David A. Minton + !! + !! Sort input double precision array into ascending numerical order using Quicksort algorithm + !! + !! Adapted from David E. Kaufmann's Swifter routine: util_sort_dp.f90 + !! Adapted from Numerical Recipes in Fortran 90: The Art of Parallel Scientific Computing, by Press, Teukolsky, + !! Vetterling, and Flannery, 2nd ed., pp. 1169-70 + 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(*, *) "Swiftest 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 + + module subroutine util_sort_i4b(arr) + !! author: David A. Minton + !! + !! Sort input double precision array into ascending numerical order using Quicksort algorithm + !! + !! Adapted from David E. Kaufmann's Swifter routine: util_sort_i4b.f90 + !! Adapted from Numerical Recipes in Fortran 90: The Art of Parallel Scientific Computing, by Press, Teukolsky, + !! Vetterling, and Flannery, 2nd ed., pp. 1169-70 + 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(*, *) "Swiftest 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 + + module subroutine util_sort_sp(arr) + !! author: David A. Minton + !! + !! Sort input single precision array into ascending numerical order using Quicksort algorithm + !! + !! Adapted from David E. Kaufmann's Swifter routine: util_sort_DP.f90 + !! Adapted from Numerical Recipes in Fortran 90: The Art of Parallel Scientific Computing, by Press, Teukolsky, + !! Vetterling, and Flannery, 2nd ed., pp. 1169-70 + 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(*, *) "Swiftest 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 +end submodule s_util_sort diff --git a/src/util/util_sort_dp.f90 b/src/util/util_sort_dp.f90 deleted file mode 100644 index 5d02a82c1..000000000 --- a/src/util/util_sort_dp.f90 +++ /dev/null @@ -1,86 +0,0 @@ -submodule (util) s_util_sort_dp - use swiftest -contains - module procedure util_sort_dp - !! author: David A. Minton - !! - !! Sort input double precision array into ascending numerical order using Quicksort algorithm - !! - !! Adapted from David E. Kaufmann's Swifter routine: util_sort_dp.f90 - !! Adapted from Numerical Recipes in Fortran 90: The Art of Parallel Scientific Computing, by Press, Teukolsky, - !! Vetterling, and Flannery, 2nd ed., pp. 1169-70 - 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(*, *) "Swiftest 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 procedure util_sort_dp -end submodule s_util_sort_dp diff --git a/src/util/util_sort_i4b.f90 b/src/util/util_sort_i4b.f90 deleted file mode 100644 index 7c1e0d08b..000000000 --- a/src/util/util_sort_i4b.f90 +++ /dev/null @@ -1,85 +0,0 @@ -submodule (util) s_util_sort_i4b - use swiftest -contains - module procedure util_sort_i4b - !! author: David A. Minton - !! - !! Sort input double precision array into ascending numerical order using Quicksort algorithm - !! - !! Adapted from David E. Kaufmann's Swifter routine: util_sort_i4b.f90 - !! Adapted from Numerical Recipes in Fortran 90: The Art of Parallel Scientific Computing, by Press, Teukolsky, - !! Vetterling, and Flannery, 2nd ed., pp. 1169-70 - 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(*, *) "Swiftest 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 procedure util_sort_i4b -end submodule s_util_sort_i4b diff --git a/src/util/util_sort_sp.f90 b/src/util/util_sort_sp.f90 deleted file mode 100644 index baa82e941..000000000 --- a/src/util/util_sort_sp.f90 +++ /dev/null @@ -1,86 +0,0 @@ -submodule (util) s_util_sort_sp - use swiftest -contains - module procedure util_sort_sp - !! author: David A. Minton - !! - !! Sort input single precision array into ascending numerical order using Quicksort algorithm - !! - !! Adapted from David E. Kaufmann's Swifter routine: util_sort_DP.f90 - !! Adapted from Numerical Recipes in Fortran 90: The Art of Parallel Scientific Computing, by Press, Teukolsky, - !! Vetterling, and Flannery, 2nd ed., pp. 1169-70 - 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(*, *) "Swiftest 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 procedure util_sort_sp -end submodule s_util_sort_sp diff --git a/src/util/util_spill_and_fill.f90 b/src/util/util_spill_and_fill.f90 index da00ae72a..1a51c06c5 100644 --- a/src/util/util_spill_and_fill.f90 +++ b/src/util/util_spill_and_fill.f90 @@ -17,39 +17,43 @@ module subroutine util_spill_body(self, discards, lspill_list) ! 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) - discards%name(:) = pack(keeps%name(:), lspill_list(:)) - discards%status(:) = pack(keeps%status(:), lspill_list(:)) - discards%a(:) = pack(keeps%a(:), lspill_list(:)) - discards%e(:) = pack(keeps%e(:), lspill_list(:)) - discards%capom(:) = pack(keeps%capom(:), lspill_list(:)) - discards%omega(:) = pack(keeps%omega(:), lspill_list(:)) - discards%capm(:) = pack(keeps%capm(:), lspill_list(:)) - discards%mu(:) = pack(keeps%mu(:), lspill_list(:)) + discards%id(:) = pack(keeps%id(:), lspill_list(:)) + discards%name(:) = pack(keeps%name(:), lspill_list(:)) + discards%status(:) = pack(keeps%status(:), lspill_list(:)) + discards%a(:) = pack(keeps%a(:), lspill_list(:)) + discards%e(:) = pack(keeps%e(:), lspill_list(:)) + discards%capom(:) = pack(keeps%capom(:), lspill_list(:)) + discards%omega(:) = pack(keeps%omega(:), lspill_list(:)) + discards%capm(:) = pack(keeps%capm(:), lspill_list(:)) + discards%mu(:) = pack(keeps%mu(:), lspill_list(:)) do i = 1, NDIM - discards%xh(i, :) = pack(keeps%xh(i, :), lspill_list(:)) - discards%vh(i, :) = pack(keeps%vh(i, :), lspill_list(:)) - discards%xb(i, :) = pack(keeps%xb(i, :), lspill_list(:)) - discards%vb(i, :) = pack(keeps%vb(i, :), lspill_list(:)) - discards%ah(i, :) = pack(keeps%ah(i, :), lspill_list(:)) - discards%aobl(i, :) = pack(keeps%aobl(i, :), lspill_list(:)) + discards%xh(i, :) = pack(keeps%xh(i, :), lspill_list(:)) + discards%vh(i, :) = pack(keeps%vh(i, :), lspill_list(:)) + discards%xb(i, :) = pack(keeps%xb(i, :), lspill_list(:)) + discards%vb(i, :) = pack(keeps%vb(i, :), lspill_list(:)) + discards%ah(i, :) = pack(keeps%ah(i, :), lspill_list(:)) + discards%aobl(i, :) = pack(keeps%aobl(i, :), lspill_list(:)) + discards%agr(i, :) = pack(keeps%agr(i, :), lspill_list(:)) end do if (count(.not.lspill_list(:)) > 0) then - keeps%name(:) = pack(keeps%name(:), .not. lspill_list(:)) - keeps%status(:) = pack(keeps%status(:), .not. lspill_list(:)) - keeps%a(:) = pack(keeps%a(:), .not. lspill_list(:)) - keeps%e(:) = pack(keeps%e(:), .not. lspill_list(:)) - keeps%inc(:) = pack(keeps%inc(:), .not. lspill_list(:)) - keeps%capom(:) = pack(keeps%capom(:), .not. lspill_list(:)) - keeps%omega(:) = pack(keeps%omega(:), .not. lspill_list(:)) - keeps%capm(:) = pack(keeps%capm(:), .not. lspill_list(:)) - keeps%mu(:) = pack(keeps%mu(:), .not. lspill_list(:)) + keeps%id(:) = pack(keeps%id(:), .not. lspill_list(:)) + keeps%name(:) = pack(keeps%name(:), .not. lspill_list(:)) + keeps%status(:) = pack(keeps%status(:), .not. lspill_list(:)) + keeps%a(:) = pack(keeps%a(:), .not. lspill_list(:)) + keeps%e(:) = pack(keeps%e(:), .not. lspill_list(:)) + keeps%inc(:) = pack(keeps%inc(:), .not. lspill_list(:)) + keeps%capom(:) = pack(keeps%capom(:), .not. lspill_list(:)) + keeps%omega(:) = pack(keeps%omega(:), .not. lspill_list(:)) + keeps%capm(:) = pack(keeps%capm(:), .not. lspill_list(:)) + keeps%mu(:) = pack(keeps%mu(:), .not. lspill_list(:)) do i = 1, NDIM - keeps%xh(i, :) = pack(keeps%xh(i, :), .not. lspill_list(:)) - keeps%vh(i, :) = pack(keeps%vh(i, :), .not. lspill_list(:)) - keeps%xb(i, :) = pack(keeps%xb(i, :), .not. lspill_list(:)) - keeps%vb(i, :) = pack(keeps%vb(i, :), .not. lspill_list(:)) - keeps%ah(i, :) = pack(keeps%ah(i, :), .not. lspill_list(:)) - keeps%aobl(i, :) = pack(keeps%aobl(i, :), .not. lspill_list(:)) + keeps%xh(i, :) = pack(keeps%xh(i, :), .not. lspill_list(:)) + keeps%vh(i, :) = pack(keeps%vh(i, :), .not. lspill_list(:)) + keeps%xb(i, :) = pack(keeps%xb(i, :), .not. lspill_list(:)) + keeps%vb(i, :) = pack(keeps%vb(i, :), .not. lspill_list(:)) + keeps%ah(i, :) = pack(keeps%ah(i, :), .not. lspill_list(:)) + keeps%aobl(i, :) = pack(keeps%aobl(i, :), .not. lspill_list(:)) + keeps%agr(i, :) = pack(keeps%agr(i, :), .not. lspill_list(:)) end do end if ! This is the base class, so will be the last to be called in the cascade. @@ -82,7 +86,9 @@ module subroutine util_fill_body(self, inserts, lfill_list) ! 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, insname => inserts%name, keepname => self%name) + associate(keeps => self) + keeps%id(:) = unpack(keeps%id(:), .not.lfill_list(:), keeps%id(:)) + keeps%id(:) = unpack(inserts%id(:), lfill_list(:), keeps%id(:)) keeps%name(:) = unpack(keeps%name(:), .not.lfill_list(:), keeps%name(:)) keeps%name(:) = unpack(inserts%name(:), lfill_list(:), keeps%name(:)) @@ -112,6 +118,8 @@ module subroutine util_fill_body(self, inserts, lfill_list) keeps%aobl(i, :) = unpack(keeps%aobl(i, :), .not.lfill_list(:), keeps%aobl(i, :)) keeps%aobl(i, :) = unpack(inserts%aobl(i, :), lfill_list(:), keeps%aobl(i, :)) + keeps%agr(i, :) = unpack(keeps%agr(i, :), .not.lfill_list(:), keeps%agr(i, :)) + keeps%agr(i, :) = unpack(inserts%agr(i, :), lfill_list(:), keeps%agr(i, :)) end do keeps%a(:) = unpack(keeps%a(:), .not.lfill_list(:), keeps%a(:)) @@ -137,7 +145,7 @@ module subroutine util_fill_body(self, inserts, lfill_list) ! This is the base class, so will be the last to be called in the cascade. - keeps%nbody = size(keeps%name(:)) + keeps%nbody = size(keeps%id(:)) end associate end subroutine util_fill_body @@ -161,24 +169,12 @@ end subroutine util_fill_body discards%rhill(:) = pack(keeps%rhill(:), lspill_list(:)) discards%radius(:) = pack(keeps%radius(:), lspill_list(:)) discards%density(:) = pack(keeps%density(:), lspill_list(:)) - discards%k2(:) = pack(keeps%k2(:), lspill_list(:)) - discards%Q(:) = pack(keeps%Q(:), lspill_list(:)) - do i = 1, NDIM - discards%Ip(i, :) = pack(keeps%Ip(i, :), lspill_list(:)) - discards%rot(i, :) = pack(keeps%rot(i, :), lspill_list(:)) - end do if (count(.not.lspill_list(:)) > 0) then keeps%mass(:) = pack(keeps%mass(:), .not. lspill_list(:)) keeps%Gmass(:) = pack(keeps%Gmass(:), .not. lspill_list(:)) keeps%rhill(:) = pack(keeps%rhill(:), .not. lspill_list(:)) keeps%radius(:) = pack(keeps%radius(:), .not. lspill_list(:)) keeps%density(:) = pack(keeps%density(:), .not. lspill_list(:)) - keeps%k2(:) = pack(keeps%k2(:), .not. lspill_list(:)) - keeps%Q(:) = pack(keeps%Q(:), .not. lspill_list(:)) - do i = 1, NDIM - keeps%Ip(i, :) = pack(keeps%Ip(i, :), .not. lspill_list(:)) - keeps%rot(i, :) = pack(keeps%rot(i, :), .not. lspill_list(:)) - end do end if call util_spill_body(keeps, discards, lspill_list) @@ -219,20 +215,6 @@ end subroutine util_fill_body keeps%density(:) = unpack(keeps%density(:),.not.lfill_list(:), keeps%density(:)) keeps%density(:) = unpack(inserts%density(:),lfill_list(:), keeps%density(:)) - do i = 1, NDIM - keeps%Ip(i, :) = unpack(keeps%Ip(i, :), .not.lfill_list(:), keeps%Ip(i, :)) - keeps%Ip(i, :) = unpack(inserts%Ip(i, :), lfill_list(:), keeps%Ip(i, :)) - - keeps%rot(i, :) = unpack(keeps%rot(i, :), .not.lfill_list(:), keeps%rot(i, :)) - keeps%rot(i, :) = unpack(inserts%rot(i, :), lfill_list(:), keeps%rot(i, :)) - - end do - keeps%k2(:) = unpack(keeps%k2(:), .not.lfill_list(:), keeps%k2(:)) - keeps%k2(:) = unpack(inserts%k2(:), lfill_list(:), keeps%k2(:)) - - keeps%Q(:) = unpack(keeps%Q(:), .not.lfill_list(:), keeps%Q(:)) - keeps%Q(:) = unpack(inserts%Q(:), lfill_list(:), keeps%Q(:)) - call util_fill_body(keeps, inserts, lfill_list) class default write(*,*) 'Error! fill method called for incompatible return type on swiftest_pl' diff --git a/src/util/util_toupper.f90 b/src/util/util_toupper.f90 deleted file mode 100644 index f5bf8b979..000000000 --- a/src/util/util_toupper.f90 +++ /dev/null @@ -1,24 +0,0 @@ -submodule (util) s_util_toupper - use swiftest -contains - module procedure util_toupper - !! author: David A. Minton - !! - !! Convert string to uppercase - !! - !! Adapted from David E. Kaufmann's Swifter routine: util_toupper.f90 - 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 procedure util_toupper -end submodule s_util_toupper diff --git a/src/util/util_valid.f90 b/src/util/util_valid.f90 index 7dd755646..ac81673ca 100644 --- a/src/util/util_valid.f90 +++ b/src/util/util_valid.f90 @@ -1,37 +1,41 @@ -submodule (util) s_util_valid +submodule (swiftest_classes) s_util_valid use swiftest contains - module procedure util_valid - !! 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 - integer(I4B) :: i - integer(I4B), dimension(:), allocatable :: idarr + 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 -! executable code - associate(npl => pl%nbody, ntp => tp%nbody) - allocate(idarr(npl+ntp)) - do i = 1, npl - idarr(i) = pl%name(i) - end do - do i = 1, ntp - idarr(npl+i) = tp%name(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 - deallocate(idarr) - end associate + 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 + deallocate(idarr) + end associate - return + return - end procedure util_valid + end subroutine util_valid end submodule s_util_valid diff --git a/src/util/util_version.f90 b/src/util/util_version.f90 index 0c0888f21..2b2c351be 100644 --- a/src/util/util_version.f90 +++ b/src/util/util_version.f90 @@ -1,7 +1,7 @@ -submodule (util) s_util_version +submodule (swiftest_classes) s_util_version use swiftest contains - module procedure util_version + module subroutine util_version() !! author: David A. Minton !! !! Print program version information to terminale @@ -47,6 +47,6 @@ "************************************************", /) return - end procedure util_version + end subroutine util_version end submodule s_util_version diff --git a/src/whm/whm_drift.f90 b/src/whm/whm_drift.f90 index 0ac170991..a27897cfa 100644 --- a/src/whm/whm_drift.f90 +++ b/src/whm/whm_drift.f90 @@ -45,7 +45,7 @@ module subroutine whm_drift_pl(self, system, param, dt) if (any(iflag(1:npl) /= 0)) then do i = 1, npl if (iflag(i) /= 0) then - write(*, *) " Planet ", self%name(i), " is lost!!!!!!!!!!" + write(*, *) " Planet ", self%id(i), " is lost!!!!!!!!!!" write(*, *) pl%xj(:,i) write(*, *) pl%vj(:,i) write(*, *) " stopping " @@ -102,7 +102,7 @@ module subroutine whm_drift_tp(self, system, param, dt) if (any(iflag(1:ntp) /= 0)) then where(iflag(1:ntp) /= 0) tp%status(1:ntp) = DISCARDED_DRIFTERR do i = 1, ntp - if (iflag(i) /= 0) write(*, *) "Particle ", self%name(i), " lost due to error in Danby drift" + if (iflag(i) /= 0) write(*, *) "Particle ", self%id(i), " lost due to error in Danby drift" end do end if end associate diff --git a/src/whm/whm_getacch.f90 b/src/whm/whm_getacch.f90 index 26a3acb19..c4ee90592 100644 --- a/src/whm/whm_getacch.f90 +++ b/src/whm/whm_getacch.f90 @@ -32,7 +32,7 @@ module subroutine whm_getacch_pl(self, system, param, t, lbeg) call whm_getacch_ah2(cb, pl) call whm_getacch_ah3(pl) - if (param%loblatecb) then + if (param%loblatecb) then cb%aoblbeg = cb%aobl call pl%accel_obl(system) cb%aoblend = cb%aobl @@ -97,13 +97,14 @@ function whm_getacch_ah0(mu, xhp, n) result(ah0) ! Result real(DP), dimension(NDIM) :: ah0 ! Internals - real(DP) :: fac, r2, ir3h + real(DP) :: fac, r2, ir3h, irh integer(I4B) :: i ah0(:) = 0.0_DP do i = 1, n r2 = dot_product(xhp(:, i), xhp(:, i)) - ir3h = 1.0_DP / (r2 * sqrt(r2)) + irh = 1.0_DP / sqrt(r2) + ir3h = irh / r2 fac = mu(i) * ir3h ah0(:) = ah0(:) - fac * xhp(:, i) end do diff --git a/src/whm/whm_gr.f90 b/src/whm/whm_gr.f90 index 363ce5ad4..3cf159504 100644 --- a/src/whm/whm_gr.f90 +++ b/src/whm/whm_gr.f90 @@ -17,20 +17,19 @@ module subroutine whm_gr_getacch_pl(self, param) !! author: David A. Minton real(DP), dimension(:, :), allocatable :: aj real(DP) :: beta, rjmag4 - associate(n => self%nbody, mu => self%muj, c2 => param%inv_c2, & - ah => self%ah, xj => self%xj, GMpl => self%Gmass, eta => self%eta) - if (n == 0) return - allocate(aj, mold = ah) - do i = 1, n - rjmag4 = (dot_product(xj(:, i), xj(:, i)))**2 - beta = - mu(i)**2 * c2 - aj(:, i) = 2 * beta * xj(:, i) / rjmag4 + associate(pl => self, npl => self%nbody, inv_c2 => param%inv_c2) + if (npl == 0) return + allocate(aj, mold = pl%ah) + do i = 1, npl + rjmag4 = (dot_product(pl%xj(:, i), pl%xj(:, i)))**2 + beta = -pl%muj(i)**2 * inv_c2 + aj(:, i) = 2 * beta * pl%xj(:, i) / rjmag4 end do suma(:) = 0.0_DP - ah(:, 1) = ah(:, 1) + aj(:, 1) - do i = 2, n - suma(:) = suma(:) + GMpl(i) * aj(:, i) / eta(i) - ah(:, i) = ah(:, i) + aj(:, i) + suma(:) + pl%ah(:, 1) = pl%ah(:, 1) + aj(:, 1) + do i = 2, npl + suma(:) = suma(:) + pl%Gmass(i) * aj(:, i) / pl%eta(i) + pl%ah(:, i) = pl%ah(:, i) + aj(:, i) + suma(:) end do end associate return @@ -51,13 +50,12 @@ module subroutine whm_gr_getacch_tp(self, param) integer(I4B) :: i real(DP) :: rjmag4, beta - associate(n => self%nbody, mu => self%mu,& - c2 => param%inv_c2, ah => self%ah, xh => self%xh, status => self%status) - if (n == 0) return - do i = 1, n - rjmag4 = (dot_product(xh(:, i), xh(:, i)))**2 - beta = - mu(i)**2 * c2 - ah(:, i) = ah(:, i) + beta * xh(:, i) / rjmag4 + associate(tp => self, ntp => self%nbody, inv_c2 => param%inv_c2) + if (ntp == 0) return + do i = 1, ntp + rjmag4 = (dot_product(tp%xh(:, i), tp%xh(:, i)))**2 + beta = - tp%mu(i)**2 * inv_c2 + tp%ah(:, i) = tp%ah(:, i) + beta * tp%xh(:, i) / rjmag4 end do end associate return @@ -78,10 +76,10 @@ module pure subroutine whm_gr_p4_pl(self, param, dt) ! Internals integer(I4B) :: i - associate(n => self%nbody, xj => self%xj, vj => self%vj, status => self%status, c2 => param%inv_c2) - if (n == 0) return - do i = 1,n - call p4_func(xj(:, i), vj(:, i), dt, c2) + associate(pl => self, npl => self%nbody) + if (npl == 0) return + do i = 1, npl + call gr_p4_pos_kick(param, pl%xj(:, i), pl%vj(:, i), dt) end do end associate @@ -97,239 +95,20 @@ module pure subroutine whm_gr_p4_tp(self, param, dt) !! 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(whm_tp), intent(inout) :: self !! Swiftest particle object class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of on parameters - real(DP), intent(in) :: dt !! Step size + real(DP), intent(in) :: dt !! Step size ! Internals - integer(I4B) :: i + integer(I4B) :: i - associate(n => self%nbody, xh => self%xh, vh => self%vh, status => self%status, c2 => param%inv_c2) - if (n == 0) return - !do concurrent (i = 1:n, status(i) == ACTIVE) - do i = 1, n - call p4_func(xh(:, i), vh(:, i), dt, c2) + associate(tp => self, ntp => self%nbody) + if (ntp == 0) return + do i = 1, ntp + call gr_p4_pos_kick(param, tp%xh(:, i), tp%vh(:, i), dt) end do end associate return end subroutine whm_gr_p4_tp - module pure subroutine whm_gr_pv2vh_pl(self, param) - !! author: David A. Minton - !! - !! Wrapper function that converts from pseudovelocity to heliocentric velocity for massive bodies - !! in a WHM object - implicit none - ! Arguments - class(whm_pl), intent(inout) :: self !! Swiftest particle object - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of on parameters - ! Internals - integer(I4B) :: i - real(DP), dimension(:,:), allocatable :: vh !! Temporary holder of pseudovelocity for in-place conversion - - associate(n => self%nbody, xh => self%xh, pv => self%vh, status => self%status, mu => self%muj) - if (n == 0) return - allocate(vh, mold = pv) - !do concurrent(i = 1:n, status(i) == ACTIVE) - do i = 1, n - call gr_pseudovel2vel(param, mu(i), xh(:, i), pv(:, i), vh(:, i)) - pv(:, i) = vh(:, i) - end do - deallocate(vh) - end associate - return - end subroutine whm_gr_pv2vh_pl - - module pure subroutine whm_gr_pv2vh_tp(self, param) - !! author: David A. Minton - !! - !! Wrapper function that converts from pseudovelocity to heliocentric velocity for test particles bodies - !! in a WHM object - implicit none - ! Arguments - class(whm_tp), intent(inout) :: self !! Swiftest particle object - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of on parameters - ! Internals - integer(I4B) :: i - real(DP), dimension(:,:), allocatable :: vh !! Temporary holder of pseudovelocity for in-place conversion - - associate(n => self%nbody, xh => self%xh, pv => self%vh, status => self%status, mu => self%mu) - if (n == 0) return - allocate(vh, mold = pv) - !do concurrent(i = 1:n, status(i) == ACTIVE) - do i = 1, n - call gr_pseudovel2vel(param, mu(i), xh(:, i), pv(:, i), vh(:, i)) - pv(:, i) = vh(:, i) - end do - deallocate(vh) - end associate - return - end subroutine whm_gr_pv2vh_tp - - module pure subroutine whm_gr_vh2pv_pl(self, param) - !! author: David A. Minton - !! - !! Wrapper function that converts from heliocentric velocity to pseudovelocity for massive bodies - !! in a WHM object - implicit none - ! Arguments - class(whm_pl), intent(inout) :: self !! Swiftest particle object - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of on parameters - ! Internals - integer(I4B) :: i - real(DP), dimension(:,:), allocatable :: pv !! Temporary holder of pseudovelocity for in-place conversion - - associate(n => self%nbody, xh => self%xh, vh => self%vh, status => self%status, mu => self%muj) - if (n == 0) return - allocate(pv, mold = vh) - !do concurrent(i = 1:n, status(i) == ACTIVE) - do i = 1, n - call gr_vel2pseudovel(param, mu(i), xh(:, i), vh(:, i), pv(:, i)) - vh(:, i) = pv(:, i) - end do - deallocate(pv) - end associate - return - end subroutine whm_gr_vh2pv_pl - - module pure subroutine whm_gr_vh2pv_tp(self, param) - !! author: David A. Minton - !! - !! Wrapper function that converts from heliocentric velocity to pseudovelocity for teset particles - !! in a WHM object - implicit none - ! Arguments - class(whm_tp), intent(inout) :: self !! Swiftest particle object - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of on parameters - ! Internals - integer(I4B) :: i - real(DP), dimension(:,:), allocatable :: pv !! Temporary holder of pseudovelocity for in-place conversion - - associate(n => self%nbody, xh => self%xh, vh => self%vh, status => self%status, mu => self%mu) - if (n == 0) return - allocate(pv, mold = vh) - !do concurrent(i = 1:n, status(i) == ACTIVE) - do i = 1, n - call gr_vel2pseudovel(param, mu(i), xh(:, i), vh(:, i), pv(:, i)) - vh(:, i) = pv(:, i) - end do - deallocate(pv) - end associate - return - end subroutine whm_gr_vh2pv_tp - - 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). - !! - !! Adapted from David A. Minton's Swifter routine gr_vel2pseudovel.f90 - 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) - - 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 (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 - c2 * (0.5_DP * pv2 + rterm) - F(:) = pv(:) * G - vh(:) - if (abs(sum(F) / v2 ) < TOL) exit ! Root found - - ! Calculate the Jacobian - !do concurrent (k = 1:NDIM) - ! do concurrent (i = 1:NDIM) - do k = 1, NDIM - do i = 1, NDIM - if (i == k) then - J(i,k) = G - c2 * pv(k) - else - J(i,k) = - 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 - - 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 - !! - !! Adapted from David A. Minton's Swifter routine gr_pseudovel2vel.f90 - 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 - - real(DP) :: vmag2, rmag, grterm - - associate(c2 => param%inv_c2) - vmag2 = dot_product(pv(:), pv(:)) - rmag = norm2(xh(:)) - grterm = 1.0_DP - c2 * (0.5_DP * vmag2 + 3 * mu / rmag) - vh(:) = pv(:) * grterm - end associate - return - end subroutine gr_pseudovel2vel - - pure subroutine p4_func(x, v, dt, c2) - implicit none - real(DP), dimension(:), intent(inout) :: x - real(DP), dimension(:), intent(in) :: v - real(DP), intent(in) :: dt, c2 - real(DP), dimension(NDIM) :: dr - real(DP) :: vmag2 - - vmag2 = dot_product(v(:), v(:)) - dr(:) = -2 * c2 * vmag2 * v(:) - x(:) = x(:) + dr(:) * dt - - return - end subroutine p4_func - end submodule s_whm_gr \ No newline at end of file diff --git a/src/whm/whm_setup.f90 b/src/whm/whm_setup.f90 index 9598b61ea..9f0f9b1b7 100644 --- a/src/whm/whm_setup.f90 +++ b/src/whm/whm_setup.f90 @@ -58,15 +58,14 @@ module subroutine whm_util_set_mu_eta_pl(self, cb) ! Internals integer(I4B) :: i - associate(pl => self, npl => self%nbody, GMpl => self%Gmass, muj => self%muj, & - eta => self%eta, GMcb => cb%Gmass) + associate(pl => self, npl => self%nbody) if (npl == 0) return call util_set_mu_pl(pl, cb) - eta(1) = GMcb + GMpl(1) - muj(1) = eta(1) + pl%eta(1) = cb%Gmass + pl%Gmass(1) + pl%muj(1) = pl%eta(1) do i = 2, npl - eta(i) = eta(i - 1) + GMpl(i) - muj(i) = GMcb * eta(i) / eta(i - 1) + 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 @@ -79,27 +78,17 @@ module subroutine whm_setup_system(self, param) !! implicit none ! Arguments - class(whm_nbody_system), intent(inout) :: self !! Swiftest system object + class(whm_nbody_system), intent(inout) :: self !! Swiftest system object class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters of on parameters + call io_read_initialize_system(self, param) ! Make sure that the discard list gets allocated initially call self%tp_discards%setup(self%tp%nbody) - - if (self%pl%nbody > 0) then - select type(pl => self%pl) - class is (whm_pl) - call pl%set_mu(self%cb) - if (param%lgr) call pl%vh2pv(param) - !call pl%eucl_index() - end select - end if - - if (self%tp%nbody > 0) then - select type(tp => self%tp) - class is (whm_tp) - call tp%set_mu(self%cb) - if (param%lgr) call tp%vh2pv(param) - end select + 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 end subroutine whm_setup_system diff --git a/src/whm/whm_step.f90 b/src/whm/whm_step.f90 index fb84fe49e..ce00b86b1 100644 --- a/src/whm/whm_step.f90 +++ b/src/whm/whm_step.f90 @@ -16,8 +16,7 @@ module subroutine whm_step_system(self, param, t, dt) 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, ntp => self%tp%nbody) - call pl%set_rhill(cb) + associate(system => self, cb => self%cb, pl => self%pl, tp => self%tp) call pl%step(system, param, t, dt) call tp%step(system, param, t, dt) end associate @@ -54,9 +53,9 @@ module subroutine whm_step_pl(self, system, param, t, dt) call pl%set_beg_end(xbeg = pl%xh) call pl%kick(dth) call pl%vh2vj(cb) - if (param%lgr) call pl%p4(param, dth) + if (param%lgr) call pl%gr_pos_kick(param, dth) call pl%drift(system, param, dt) - if (param%lgr) call pl%p4(param, dth) + if (param%lgr) call pl%gr_pos_kick(param, dth) call pl%j2h(cb) call pl%accel(system, param, t + dt) call pl%kick(dth) @@ -93,9 +92,9 @@ module subroutine whm_step_tp(self, system, param, t, dt) tp%lfirst = .false. end if call tp%kick(dth) - if (param%lgr) call tp%p4(param, dth) + if (param%lgr) call tp%gr_pos_kick(param, dth) call tp%drift(system, param, dt) - if (param%lgr) call tp%p4(param, dth) + if (param%lgr) call tp%gr_pos_kick(param, dth) call tp%accel(system, param, t + dt, lbeg=.false.) call tp%kick(dth) end associate