diff --git a/examples/swifter_conversion/param.swiftest.in b/examples/swifter_conversion/param.swiftest.in deleted file mode 100644 index c80aa8ca0..000000000 --- a/examples/swifter_conversion/param.swiftest.in +++ /dev/null @@ -1,29 +0,0 @@ -! File generated by swifter2swiftest.py -VERSION ! Swifter parameter input file -T0 0.0 -TSTOP 80.0 -DT 1.0 -PL_IN pl.swiftest.in -TP_IN tp.swiftest.in -IN_TYPE ASCII -ISTEP_OUT 1 -BIN_OUT bin.dat -OUT_TYPE REAL8 -OUT_FORM XV -OUT_STAT NEW -ISTEP_DUMP 1 -CHK_CLOSE YES -CHK_RMIN 0.004650467260962157 -CHK_RMAX 1000.0 -CHK_EJECT 1000.0 -CHK_QMIN 0.004650467260962157 -CHK_QMIN_COORD HELIO -CHK_QMIN_RANGE 0.004650467260962157 1000.0 -ENC_OUT enc.dat -EXTRA_FORCE NO -BIG_DISCARD NO -GR NO -CB_IN cb.swiftest.in -MU2KG 1.988409870698051e+30 -DU2M 149597870700.0 -TU2S 86400 diff --git a/examples/swifter_conversion/swifter2swiftest.py b/examples/swifter_conversion/swifter2swiftest.py deleted file mode 100755 index 689fa0380..000000000 --- a/examples/swifter_conversion/swifter2swiftest.py +++ /dev/null @@ -1,24 +0,0 @@ -import sys -import argparse -import swiftestio as swio -import csv -""" - Converts initial conditions files from Swifter to Swiftest -""" - -if __name__ == '__main__': - ap = argparse.ArgumentParser() - ap.add_argument("-i", "--input_swifter_param", required=True, help="Input Swifter parameter file to convert") - ap.add_argument("-o", "--output_swiftest_param", required=True, help="Converted Swiftest parameter file") - args = vars(ap.parse_args()) - inparam = args['input_swifter_param'] - outparam = args['output_swiftest_param'] - print(f"Swifter parameter is {inparam}") - print(f"Swiftest parameter file is {outparam}") - swifter_param = swio.read_swifter_param(inparam) - swiftest_param = swio.swifter2swiftest(swifter_param, outparam) - outfile = open(outparam, 'w') - print("! File generated by swifter2swiftest.py", file=outfile) - for key,val in swiftest_param.items(): - print(f"{key:<16} {val}",file=outfile) - outfile.close() diff --git a/python/swiftest/swiftest/simulation_class.py b/python/swiftest/swiftest/simulation_class.py index 2adcec70b..415af15c1 100644 --- a/python/swiftest/swiftest/simulation_class.py +++ b/python/swiftest/swiftest/simulation_class.py @@ -24,7 +24,7 @@ def read_param(self, param_file_name, codename="Swiftest"): def write_param(self, param_file_name): # Check to see if the parameter type matches the output type. If not, we need to convert - codename = self.param['VERSION'].split()[1] + codename = self.param['! VERSION'].split()[0] if codename == "Swifter" or codename == "Swiftest": swiftestio.write_labeled_param(self.param, param_file_name) elif codename == "Swift": @@ -33,6 +33,23 @@ def write_param(self, param_file_name): print('Cannot process unknown code type. Call the read_param method with a valid code name. Valid options are "Swiftest", "Swifter", or "Swift".') return + def convert(self, param_file_name, newcodename="Swiftest", plname="pl.swiftest.in", tpname="tp.swiftest.in", cbname="cb.swiftest.in"): + """ + Converts simulation input files from one code type to another (Swift, Swifter, or Swiftest). Returns the old parameter configuration. + """ + oldparam = self.param + if self.codename == newcodename: + print(f"This parameter configuration is already in {newcodename} format") + return oldparam + if newcodename != "Swift" and newcodename != "Swifter" and newcodename != "Swiftest": + print(f'{newcodename} is an invalid code type. Valid options are "Swiftest", "Swifter", or "Swift".') + return oldparam + if self.codename == "Swifter": + if newcodename == "Swiftest": + self.param = swiftestio.swifter2swiftest(self.param, plname, tpname, cbname) + self.write_param(param_file_name) + return oldparam + def bin2xr(self): if self.codename == "Swiftest": self.ds = swiftestio.swiftest2xr(self.param) diff --git a/python/swiftest/swiftest/swiftestio.py b/python/swiftest/swiftest/swiftestio.py index e7505a10f..2ba0ad2f9 100644 --- a/python/swiftest/swiftest/swiftestio.py +++ b/python/swiftest/swiftest/swiftestio.py @@ -1,8 +1,10 @@ +import swiftest import numpy as np from scipy.io import FortranFile import xarray as xr from astroquery.jplhorizons import Horizons import datetime +import sys def read_swiftest_param(param_file_name): """ @@ -19,7 +21,7 @@ def read_swiftest_param(param_file_name): A dictionary containing the entries in the user parameter file """ param = { - 'VERSION': "! Swiftest parameter input file", + '! VERSION': f"Swiftest parameter input from file {param_file_name}", 'T0': "0.0", 'TSTOP': "0.0", 'DT': "0.0", @@ -41,8 +43,6 @@ def read_swiftest_param(param_file_name): 'CHK_QMIN': "-1.0", 'CHK_QMIN_COORD': "HELIO", 'CHK_QMIN_RANGE': "", - 'QMIN_ALO': "-1.0", - 'QMIN_AHI': "-1.0", 'ENC_OUT': "", 'MTINY': "-1.0", 'MU2KG': "-1.0", @@ -64,51 +64,47 @@ def read_swiftest_param(param_file_name): # Read param.in file print(f'Reading Swiftest file {param_file_name}') - with open(param_file_name, 'r') as f: - for line in f.readlines(): - fields = line.split() - if len(fields) > 0: - for key in param: - if (key == fields[0].upper()): param[key] = fields[1] - # Special case of CHK_QMIN_RANGE requires a second input - if fields[0].upper() == 'CHK_QMIN_RANGE': - param['QMIN_ALO'] = fields[1] - param['QMIN_AHI'] = fields[2] - param['CHK_QMIN_RANGE'] = f"{fields[1]} {fields[2]}" - - param['ISTEP_OUT'] = int(param['ISTEP_OUT']) - param['ISTEP_DUMP'] = int(param['ISTEP_DUMP']) - param['T0'] = float(param['T0'].replace('d', 'E').replace('D', 'E')) - param['TSTOP'] = float(param['TSTOP'].replace('d', 'E').replace('D', 'E')) - param['DT'] = float(param['DT'].replace('d', 'E').replace('D', 'E')) - param['J2'] = float(param['J2'].replace('d', 'E').replace('D', 'E')) - param['J4'] = float(param['J4'].replace('d', 'E').replace('D', 'E')) - param['CHK_RMIN'] = float(param['CHK_RMIN'].replace('d', 'E').replace('D', 'E')) - param['CHK_RMAX'] = float(param['CHK_RMAX'].replace('d', 'E').replace('D', 'E')) - param['CHK_EJECT'] = float(param['CHK_EJECT'].replace('d', 'E').replace('D', 'E')) - param['CHK_QMIN'] = float(param['CHK_QMIN'].replace('d', 'E').replace('D', 'E')) - param['QMIN_ALO'] = float(param['QMIN_ALO'].replace('d', 'E').replace('D', 'E')) - param['QMIN_AHI'] = float(param['QMIN_AHI'].replace('d', 'E').replace('D', 'E')) - param['MTINY'] = float(param['MTINY'].replace('d', 'E').replace('D', 'E')) - param['DU2M'] = float(param['DU2M'].replace('d', 'E').replace('D', 'E')) - param['MU2KG'] = float(param['MU2KG'].replace('d', 'E').replace('D', 'E')) - param['TU2S'] = float(param['TU2S'].replace('d', 'E').replace('D', 'E')) - param['EXTRA_FORCE'] = param['EXTRA_FORCE'].upper() - param['BIG_DISCARD'] = param['BIG_DISCARD'].upper() - param['CHK_CLOSE'] = param['CHK_CLOSE'].upper() - param['FRAGMENTATION'] = param['FRAGMENTATION'].upper() - param['ROTATION'] = param['ROTATION'].upper() - param['TIDES'] = param['TIDES'].upper() - param['ENERGY'] = param['ENERGY'].upper() - param['GR'] = param['GR'].upper() - param['YORP'] = param['YORP'].upper() - - param['GU'] = GC / (param['DU2M'] ** 3 / (param['MU2KG'] * param['TU2S'] ** 2)) - param['INV_C2'] = einsteinC * param['TU2S'] / param['DU2M'] - param['INV_C2'] = param['INV_C2'] ** (-2) + try: + with open(param_file_name, 'r') as f: + for line in f.readlines(): + fields = line.split() + if len(fields) > 0: + for key in param: + if (key == fields[0].upper()): param[key] = fields[1] + # Special case of CHK_QMIN_RANGE requires a second input + if fields[0].upper() == 'CHK_QMIN_RANGE': + alo = float(fields[1].replace('d', 'E').replace('D', 'E')) + ahi = float(fields[2].replace('d', 'E').replace('D', 'E')) + param['CHK_QMIN_RANGE'] = f"{alo} {ahi}" + + param['ISTEP_OUT'] = int(param['ISTEP_OUT']) + param['ISTEP_DUMP'] = int(param['ISTEP_DUMP']) + param['T0'] = float(param['T0'].replace('d', 'E').replace('D', 'E')) + param['TSTOP'] = float(param['TSTOP'].replace('d', 'E').replace('D', 'E')) + param['DT'] = float(param['DT'].replace('d', 'E').replace('D', 'E')) + param['J2'] = float(param['J2'].replace('d', 'E').replace('D', 'E')) + param['J4'] = float(param['J4'].replace('d', 'E').replace('D', 'E')) + param['CHK_RMIN'] = float(param['CHK_RMIN'].replace('d', 'E').replace('D', 'E')) + param['CHK_RMAX'] = float(param['CHK_RMAX'].replace('d', 'E').replace('D', 'E')) + param['CHK_EJECT'] = float(param['CHK_EJECT'].replace('d', 'E').replace('D', 'E')) + param['CHK_QMIN'] = float(param['CHK_QMIN'].replace('d', 'E').replace('D', 'E')) + param['MTINY'] = float(param['MTINY'].replace('d', 'E').replace('D', 'E')) + param['DU2M'] = float(param['DU2M'].replace('d', 'E').replace('D', 'E')) + param['MU2KG'] = float(param['MU2KG'].replace('d', 'E').replace('D', 'E')) + param['TU2S'] = float(param['TU2S'].replace('d', 'E').replace('D', 'E')) + param['EXTRA_FORCE'] = param['EXTRA_FORCE'].upper() + param['BIG_DISCARD'] = param['BIG_DISCARD'].upper() + param['CHK_CLOSE'] = param['CHK_CLOSE'].upper() + param['FRAGMENTATION'] = param['FRAGMENTATION'].upper() + param['ROTATION'] = param['ROTATION'].upper() + param['TIDES'] = param['TIDES'].upper() + param['ENERGY'] = param['ENERGY'].upper() + param['GR'] = param['GR'].upper() + param['YORP'] = param['YORP'].upper() + except IOError: + print(f"{param_file_name} not found.") return param - def read_swifter_param(param_file_name): """ Reads in a Swifter param.in file and saves it as a dictionary @@ -124,7 +120,7 @@ def read_swifter_param(param_file_name): A dictionary containing the entries in the user parameter file """ param = { - 'VERSION': "! Swifter parameter input file", + '! VERSION': f"Swifter parameter input from file {param_file_name}", 'T0': "0.0", 'TSTOP': "0.0", 'DT': "0.0", @@ -146,53 +142,51 @@ def read_swifter_param(param_file_name): 'CHK_QMIN': "-1.0", 'CHK_QMIN_COORD': "HELIO", 'CHK_QMIN_RANGE': "", - 'QMIN_ALO': "-1.0", - 'QMIN_AHI': "-1.0", 'ENC_OUT': "", 'EXTRA_FORCE': 'NO', 'BIG_DISCARD': 'NO', 'RHILL_PRESENT': 'NO', - 'GR': 'NO', - 'C2': "-1.0", + 'C': "-1.0", } # Read param.in file print(f'Reading Swifter file {param_file_name}') - with open(param_file_name, 'r') as f: - for line in f.readlines(): - fields = line.split() - if len(fields) > 0: - for key in param: - if (key == fields[0].upper()): param[key] = fields[1] - # Special case of CHK_QMIN_RANGE requires a second input - if fields[0].upper() == 'CHK_QMIN_RANGE': - param['QMIN_ALO'] = fields[1] - param['QMIN_AHI'] = fields[2] - param['CHK_QMIN_RANGE'] = f"{fields[1]} {fields[2]}" - - param['ISTEP_OUT'] = int(param['ISTEP_OUT']) - param['ISTEP_DUMP'] = int(param['ISTEP_DUMP']) - param['T0'] = float(param['T0'].replace('d', 'E').replace('D', 'E')) - param['TSTOP'] = float(param['TSTOP'].replace('d', 'E').replace('D', 'E')) - param['DT'] = float(param['DT'].replace('d', 'E').replace('D', 'E')) - param['J2'] = float(param['J2'].replace('d', 'E').replace('D', 'E')) - param['J4'] = float(param['J4'].replace('d', 'E').replace('D', 'E')) - param['CHK_RMIN'] = float(param['CHK_RMIN'].replace('d', 'E').replace('D', 'E')) - param['CHK_RMAX'] = float(param['CHK_RMAX'].replace('d', 'E').replace('D', 'E')) - param['CHK_EJECT'] = float(param['CHK_EJECT'].replace('d', 'E').replace('D', 'E')) - param['CHK_QMIN'] = float(param['CHK_QMIN'].replace('d', 'E').replace('D', 'E')) - param['QMIN_ALO'] = float(param['QMIN_ALO'].replace('d', 'E').replace('D', 'E')) - param['QMIN_AHI'] = float(param['QMIN_AHI'].replace('d', 'E').replace('D', 'E')) - param['C2'] = float(param['C2'].replace('d', 'E').replace('D', 'E')) - param['INV_C2'] = param['C2'] - param['EXTRA_FORCE'] = param['EXTRA_FORCE'].upper() - param['BIG_DISCARD'] = param['BIG_DISCARD'].upper() - param['CHK_CLOSE'] = param['CHK_CLOSE'].upper() - param['RHILL_PRESENT'] = param['RHILL_PRESENT'].upper() - param['GR'] = param['GR'].upper() - - return param + try: + with open(param_file_name, 'r') as f: + for line in f.readlines(): + fields = line.split() + if len(fields) > 0: + for key in param: + if (key == fields[0].upper()): param[key] = fields[1] + # Special case of CHK_QMIN_RANGE requires a second input + if fields[0].upper() == 'CHK_QMIN_RANGE': + alo = float(fields[1].replace('d', 'E').replace('D', 'E')) + ahi = float(fields[2].replace('d', 'E').replace('D', 'E')) + param['CHK_QMIN_RANGE'] = f"{alo} {ahi}" + + param['ISTEP_OUT'] = int(param['ISTEP_OUT']) + param['ISTEP_DUMP'] = int(param['ISTEP_DUMP']) + param['T0'] = float(param['T0'].replace('d', 'E').replace('D', 'E')) + param['TSTOP'] = float(param['TSTOP'].replace('d', 'E').replace('D', 'E')) + param['DT'] = float(param['DT'].replace('d', 'E').replace('D', 'E')) + param['J2'] = float(param['J2'].replace('d', 'E').replace('D', 'E')) + param['J4'] = float(param['J4'].replace('d', 'E').replace('D', 'E')) + param['CHK_RMIN'] = float(param['CHK_RMIN'].replace('d', 'E').replace('D', 'E')) + param['CHK_RMAX'] = float(param['CHK_RMAX'].replace('d', 'E').replace('D', 'E')) + param['CHK_EJECT'] = float(param['CHK_EJECT'].replace('d', 'E').replace('D', 'E')) + param['CHK_QMIN'] = float(param['CHK_QMIN'].replace('d', 'E').replace('D', 'E')) + param['EXTRA_FORCE'] = param['EXTRA_FORCE'].upper() + param['BIG_DISCARD'] = param['BIG_DISCARD'].upper() + param['CHK_CLOSE'] = param['CHK_CLOSE'].upper() + param['RHILL_PRESENT'] = param['RHILL_PRESENT'].upper() + if param['C'] != '-1.0': + param['C'] = float(param['C'].replace('d', 'E').replace('D', 'E')) + else: + param.pop('C', None) + except IOError: + print(f"{param_file_name} not found.") + return param def read_swift_param(param_file_name): """ @@ -209,7 +203,7 @@ def read_swift_param(param_file_name): A dictionary containing the entries in the user parameter file """ param = { - 'VERSION': "! Swift parameter input file", + '! VERSION': f"Swift parameter input from file {param_file_name}", 'T0': 0.0, 'TSTOP': 0.0, 'DT': 0.0, @@ -665,15 +659,15 @@ def solar_system_pl(param, ephemerides_start_date): } # Unit conversion factors - DCONV = AU2M / param['DU2M'] - VCONV = (AU2M / JD2S) / (param['DU2M'] / param['TU2S']) + DCONV = swiftest.AU2M / param['DU2M'] + VCONV = (swiftest.AU2M / swiftest.JD2S) / (param['DU2M'] / param['TU2S']) THIRDLONG = np.longdouble(1.0) / np.longdouble(3.0) # Central body value vectors - GMcb = np.array([GMSunSI * param['TU2S'] ** 2 / param['DU2M'] ** 3]) - Rcb = np.array([RSun / param['DU2M']]) - J2RP2 = np.array([J2Sun * (RSun / param['DU2M']) ** 2]) - J4RP4 = np.array([J4Sun * (RSun / param['DU2M']) ** 4]) + GMcb = np.array([swiftest.GMSunSI * param['TU2S'] ** 2 / param['DU2M'] ** 3]) + Rcb = np.array([swiftest.RSun / param['DU2M']]) + J2RP2 = np.array([swiftest.J2Sun * (swiftest.RSun / param['DU2M']) ** 2]) + J4RP4 = np.array([swiftest.J4Sun * (swiftest.RSun / param['DU2M']) ** 4]) cbid = np.array([0]) cvec = np.vstack([GMcb, Rcb, J2RP2, J4RP4]) @@ -724,7 +718,6 @@ def solar_system_pl(param, ephemerides_start_date): dims = ['time', 'id', 'vec'] cb = [] pl = [] - tp = [] t = np.array([0.0]) clab, plab, tlab = make_swiftest_labels(param) @@ -841,86 +834,99 @@ def swiftest_xr2_infile(ds, param, framenum=-1): else: print(f"{param['IN_TYPE']} is an unknown file type") - -def swifter2swiftest(swifter_param, outparam): +def swifter2swiftest(swifter_param, plname="pl.swiftest.in", tpname="tp.swiftest.in", cbname="cb.swiftest.in"): swiftest_param = swifter_param.copy() - swiftest_param['PL_IN'] = 'pl.swiftest.in' - swiftest_param['TP_IN'] = 'tp.swiftest.in' - swiftest_param['CB_IN'] = 'cb.swiftest.in' - print(f"Swiftest parameter file : {outparam}") + swiftest_param['PL_IN'] = plname + swiftest_param['TP_IN'] = tpname + swiftest_param['CB_IN'] = cbname print(f"Swiftest massive body file : {swiftest_param['PL_IN']}") print(f"Swiftest test particle file: {swiftest_param['TP_IN']}") print(f"Swiftest central body file : {swiftest_param['CB_IN']}") - - plnew = open(swiftest_param['PL_IN'], 'w') - - print(f'Writing out new PL file: {swiftest_param["PL_IN"]}') - with open(swifter_param['PL_IN'], 'r') as plold: - line = plold.readline() - line = line.split("!")[0] # Ignore comments - i_list = [i for i in line.split(" ") if i.strip()] - npl = int(i_list[0]) - print(npl - 1, file=plnew) - line = plold.readline() - i_list = [i for i in line.split(" ") if i.strip()] - GMcb = float(i_list[1]) # Store central body GM for later - line = plold.readline() # Ignore the two zero vector lines - line = plold.readline() - for n in range(1, npl): # Loop over planets + + try: + plnew = open(swiftest_param['PL_IN'], 'w') + except IOError: + print(f"Cannot write to file {swiftest_param['PL_IN']}") + return swifter_param + + print(f"Converting PL file: {swifter_param['PL_IN']} -> {swiftest_param['PL_IN']}") + try: + with open(swifter_param['PL_IN'], 'r') as plold: line = plold.readline() + line = line.split("!")[0] # Ignore comments i_list = [i for i in line.split(" ") if i.strip()] - name = int(i_list[0]) - GMpl = float(i_list[1]) - print(name, GMpl, file=plnew) - if swifter_param['CHK_CLOSE'] == 'YES': - line = plold.readline() - i_list = [i for i in line.split(" ") if i.strip()] - plrad = float(i_list[0]) - print(plrad, file=plnew) + npl = int(i_list[0]) + print(npl - 1, file=plnew) line = plold.readline() i_list = [i for i in line.split(" ") if i.strip()] - xh = float(i_list[0]) - yh = float(i_list[1]) - zh = float(i_list[2]) - print(xh, yh, zh, file=plnew) + GMcb = float(i_list[1]) # Store central body GM for later + line = plold.readline() # Ignore the two zero vector lines line = plold.readline() - i_list = [i for i in line.split(" ") if i.strip()] - vx = float(i_list[0]) - vy = float(i_list[1]) - vz = float(i_list[2]) - print(vx, vy, vz, file=plnew) - - plold.close() - plnew.close() - tpnew = open(swiftest_param['TP_IN'], 'w') + for n in range(1, npl): # Loop over planets + line = plold.readline() + i_list = [i for i in line.split(" ") if i.strip()] + name = int(i_list[0]) + GMpl = float(i_list[1]) + print(name, GMpl, file=plnew) + if swifter_param['CHK_CLOSE'] == 'YES': + line = plold.readline() + i_list = [i for i in line.split(" ") if i.strip()] + plrad = float(i_list[0]) + print(plrad, file=plnew) + line = plold.readline() + i_list = [i for i in line.split(" ") if i.strip()] + xh = float(i_list[0]) + yh = float(i_list[1]) + zh = float(i_list[2]) + print(xh, yh, zh, file=plnew) + line = plold.readline() + i_list = [i for i in line.split(" ") if i.strip()] + vx = float(i_list[0]) + vy = float(i_list[1]) + vz = float(i_list[2]) + print(vx, vy, vz, file=plnew) - print(f'Writing out new TP file: {swiftest_param["TP_IN"]}') - with open(swifter_param['TP_IN'], 'r') as tpold: - line = tpold.readline() - line = line.split("!")[0] # Ignore comments - i_list = [i for i in line.split(" ") if i.strip()] - ntp = int(i_list[0]) - print(ntp, file=tpnew) - for n in range(0, ntp): # Loop over test particles - line = tpold.readline() - i_list = [i for i in line.split(" ") if i.strip()] - name = int(i_list[0]) - print(name, file=tpnew) - line = tpold.readline() - i_list = [i for i in line.split(" ") if i.strip()] - xh = float(i_list[0]) - yh = float(i_list[1]) - zh = float(i_list[2]) - print(xh, yh, zh, file=tpnew) + plnew.close() + plold.close() + except IOError: + print(f"Error converting PL file") + + try: + tpnew = open(swiftest_param['TP_IN'], 'w') + except IOError: + print(f"Cannot write to file {swiftest_param['TP_IN']}") + + print(f"Converting TP file: {swifter_param['TP_IN']} -> {swiftest_param['TP_IN']}") + try: + print(f'Writing out new TP file: {swiftest_param["TP_IN"]}') + with open(swifter_param['TP_IN'], 'r') as tpold: line = tpold.readline() + line = line.split("!")[0] # Ignore comments i_list = [i for i in line.split(" ") if i.strip()] - vx = float(i_list[0]) - vy = float(i_list[1]) - vz = float(i_list[2]) - print(vx, vy, vz, file=tpnew) - - tpold.close() - tpnew.close() + ntp = int(i_list[0]) + print(ntp, file=tpnew) + for n in range(0, ntp): # Loop over test particles + line = tpold.readline() + i_list = [i for i in line.split(" ") if i.strip()] + name = int(i_list[0]) + print(name, file=tpnew) + line = tpold.readline() + i_list = [i for i in line.split(" ") if i.strip()] + xh = float(i_list[0]) + yh = float(i_list[1]) + zh = float(i_list[2]) + print(xh, yh, zh, file=tpnew) + line = tpold.readline() + i_list = [i for i in line.split(" ") if i.strip()] + vx = float(i_list[0]) + vy = float(i_list[1]) + vz = float(i_list[2]) + print(vx, vy, vz, file=tpnew) + + tpold.close() + tpnew.close() + except IOError: + print(f"Error converting TP file") print(f"\nCentral body G*M = {GMcb}\n") print("Select the unit system to use:") @@ -941,14 +947,14 @@ def swifter2swiftest(swifter_param, outparam): sys.exit(-1) if unit_type == 1: print("Unit system is MSun-AU-year") - swiftest_param['MU2KG'] = MSun - swiftest_param['DU2M'] = AU2M - swiftest_param['TU2S'] = YR2S + swiftest_param['MU2KG'] = swiftest.MSun + swiftest_param['DU2M'] = swiftest.AU2M + swiftest_param['TU2S'] = swiftest.YR2S elif unit_type == 2: # MSun-AU-day print("Unit system is MSun-AU-day") - swiftest_param['MU2KG'] = MSun - swiftest_param['DU2M'] = AU2M - swiftest_param['TU2S'] = JD2S + swiftest_param['MU2KG'] = swiftest.MSun + swiftest_param['DU2M'] = swiftest.AU2M + swiftest_param['TU2S'] = swiftest.JD2S elif unit_type == 3: # SI: kg-m-s print("Unit system is SI: kg-m-s") swiftest_param['MU2KG'] = 1.0 @@ -965,7 +971,7 @@ def swifter2swiftest(swifter_param, outparam): swiftest_param['MU2KG'] = input("Mass value in kilograms: ") swiftest_param['DU2M'] = input("Distance value in meters: ") swiftest_param['TU2S'] = input("Time unit in seconds: ") - GU = GC / (swiftest_param['DU2M'] ** 3 / (swiftest_param['MU2KG'] * swiftest_param['TU2S'] ** 2)) + GU = swiftest.GC / (swiftest_param['DU2M'] ** 3 / (swiftest_param['MU2KG'] * swiftest_param['TU2S'] ** 2)) print(f"Central body mass: {GMcb / GU} MU ({(GMcb / GU) * swiftest_param['MU2KG']} kg)") print("Set central body radius:") @@ -988,21 +994,26 @@ def swifter2swiftest(swifter_param, outparam): print(f'Writing out new CB file: {swiftest_param["CB_IN"]}') # Write out new central body file - cbnew = open(swiftest_param['CB_IN'], 'w') - - print(GMcb, file=cbnew) - print(cbrad, file=cbnew) - print(swifter_param['J2'], file=cbnew) - print(swifter_param['J4'], file=cbnew) - - cbnew.close() + try: + cbnew = open(swiftest_param['CB_IN'], 'w') + print(GMcb, file=cbnew) + print(cbrad, file=cbnew) + print(swifter_param['J2'], file=cbnew) + print(swifter_param['J4'], file=cbnew) + cbnew.close() + except IOError: + print(f"Cannot write to file {swiftest_param['CB_IN']}") + MTINY = input(f"Value of MTINY if this is a SyMBA simulation (enter nothing if this is not a SyMBA parameter file)> ") + if MTINY != '': + swiftest_param['MTINY'] = float(MTINY.strip().replace('d', 'E').replace('D', 'E')) + # Remove the unneeded parameters - swiftest_param.pop('INV_C2', None) - swiftest_param.pop('C2', None) - swiftest_param.pop('QMIN_ALO', None) - swiftest_param.pop('QMIN_AHI', None) + if 'C' in swiftest_param: + swiftest_param['GR'] = 'YES' + swiftest_param.pop('C', None) swiftest_param.pop('J2', None) swiftest_param.pop('J4', None) swiftest_param.pop('RHILL_PRESENT', None) + swiftest_param['! VERSION'] = "Swiftest parameter file converted from Swifter" return swiftest_param diff --git a/python/swiftest/tests/__init__.py b/python/swiftest/tests/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/swifter_conversion/cb.swiftest.in b/python/swiftest/tests/convert_code_type/cb.swifter2swiftest.in similarity index 100% rename from examples/swifter_conversion/cb.swiftest.in rename to python/swiftest/tests/convert_code_type/cb.swifter2swiftest.in diff --git a/examples/swifter_conversion/param.in b/python/swiftest/tests/convert_code_type/param.swifter.in similarity index 91% rename from examples/swifter_conversion/param.in rename to python/swiftest/tests/convert_code_type/param.swifter.in index 98cb8a5ce..5d250c0b1 100644 --- a/examples/swifter_conversion/param.in +++ b/python/swiftest/tests/convert_code_type/param.swifter.in @@ -2,8 +2,8 @@ T0 0 TSTOP 80.0 DT 1.0 -PL_IN pl.in -TP_IN tp.in +PL_IN pl.swifter.in +TP_IN tp.swifter.in IN_TYPE ASCII ISTEP_OUT 1 ISTEP_DUMP 1 diff --git a/examples/swifter_conversion/pl.in b/python/swiftest/tests/convert_code_type/pl.swifter.in similarity index 100% rename from examples/swifter_conversion/pl.in rename to python/swiftest/tests/convert_code_type/pl.swifter.in diff --git a/examples/swifter_conversion/pl.swiftest.in b/python/swiftest/tests/convert_code_type/pl.swifter2swiftest.in similarity index 100% rename from examples/swifter_conversion/pl.swiftest.in rename to python/swiftest/tests/convert_code_type/pl.swifter2swiftest.in diff --git a/python/swiftest/tests/convert_code_type/swifter2swiftest.py b/python/swiftest/tests/convert_code_type/swifter2swiftest.py new file mode 100644 index 000000000..fd41f6c59 --- /dev/null +++ b/python/swiftest/tests/convert_code_type/swifter2swiftest.py @@ -0,0 +1,14 @@ +import swiftest +""" + Reads in an example parameter file for each of the codes (Swift, Swifter, and Swiftest) and outputs an equivalent + parameter file in another code type. + + Input files are param.swift[er|est].in and output files are param.[src]2[dest].new, where [src] is the original file type + and [dest] is the new one. The user may be prompted to answer questions regarding how to convert between the different + simulation types. + """ +inparam = "param.swifter.in" +outparam = "param.swifter2swiftest.new" +print(f"Reading Swift parameter {inparam} and saving it to {outparam}") +sim = swiftest.Simulation(inparam, codename="Swifter") +oldparam = sim.convert(outparam, newcodename="Swiftest", plname="pl.swifter2swiftest.in", tpname="tp.swifter2swiftest.in", cbname="cb.swifter2swiftest.in") \ No newline at end of file diff --git a/examples/swifter_conversion/tp.in b/python/swiftest/tests/convert_code_type/tp.swifter.in similarity index 100% rename from examples/swifter_conversion/tp.in rename to python/swiftest/tests/convert_code_type/tp.swifter.in diff --git a/examples/swifter_conversion/tp.swiftest.in b/python/swiftest/tests/convert_code_type/tp.swifter2swiftest.in similarity index 100% rename from examples/swifter_conversion/tp.swiftest.in rename to python/swiftest/tests/convert_code_type/tp.swifter2swiftest.in diff --git a/python/swiftest/tests/param.swift.in b/python/swiftest/tests/param_readers/param.swift.in similarity index 100% rename from python/swiftest/tests/param.swift.in rename to python/swiftest/tests/param_readers/param.swift.in diff --git a/python/swiftest/tests/param_readers/param.swifter.in b/python/swiftest/tests/param_readers/param.swifter.in new file mode 100644 index 000000000..5834d2dcc --- /dev/null +++ b/python/swiftest/tests/param_readers/param.swifter.in @@ -0,0 +1,26 @@ +! Swifter input file generated using init_cond.py +T0 0 +TSTOP 1.0 +DT 0.0006844626967830253 +PL_IN pl.swifter.in +TP_IN tp.swifter.in +IN_TYPE ASCII +ISTEP_OUT 1 +ISTEP_DUMP 1 +BIN_OUT bin.swifter.dat +OUT_TYPE REAL8 +OUT_FORM EL +OUT_STAT NEW +J2 4.7535806948127355e-12 +J4 -2.2473967953572827e-18 +CHK_CLOSE yes +CHK_RMIN 0.004650467260962157 +CHK_RMAX 1000.0 +CHK_EJECT 1000.0 +CHK_QMIN 0.004650467260962157 +CHK_QMIN_COORD HELIO +CHK_QMIN_RANGE 0.004650467260962157 1000.0 +ENC_OUT enc.swifter.dat +EXTRA_FORCE no +BIG_DISCARD no +RHILL_PRESENT yes diff --git a/python/swiftest/tests/param_readers/param.swiftest.in b/python/swiftest/tests/param_readers/param.swiftest.in new file mode 100644 index 000000000..6e623a5dd --- /dev/null +++ b/python/swiftest/tests/param_readers/param.swiftest.in @@ -0,0 +1,29 @@ +! Swiftest input file generated using init_cond.py +T0 0 +TSTOP 1.0 +DT 0.0006844626967830253 +CB_IN cb.swiftest.in +PL_IN pl.swiftest.in +TP_IN tp.swiftest.in +IN_TYPE REAL8 +ISTEP_OUT 1 +ISTEP_DUMP 1 +BIN_OUT bin.swiftest.dat +OUT_TYPE REAL8 +OUT_FORM EL +OUT_STAT REPLACE +CHK_CLOSE yes +CHK_RMIN 0.004650467260962157 +CHK_RMAX 1000.0 +CHK_EJECT 1000.0 +CHK_QMIN 0.004650467260962157 +CHK_QMIN_COORD HELIO +CHK_QMIN_RANGE 0.004650467260962157 1000.0 +ENC_OUT enc.swiftest.dat +EXTRA_FORCE no +BIG_DISCARD no +ROTATION no +GR no +MU2KG 1.988409870698051e+30 +DU2M 149597870700.0 +TU2S 31557600.0 diff --git a/python/swiftest/tests/param_readers/param_readers.py b/python/swiftest/tests/param_readers/param_readers.py new file mode 100644 index 000000000..c5b72b57d --- /dev/null +++ b/python/swiftest/tests/param_readers/param_readers.py @@ -0,0 +1,24 @@ +import swiftest +""" + Reads in an example parameter file for each of the codes (Swift, Swifter, and Swiftest) and outputs a copy using the + internal parsing system. Input files are param.swift[er|est].in and output files are param.swift[er|est].new. + The contents of the parameter files should be the same, though the new version may be formatted differently and also + contain explicit values for default parameters. + """ +inparam = "param.swift.in" +outparam = "param.swift.new" +print(f"Reading Swift parameter {inparam} and saving it to {outparam}") +sim = swiftest.Simulation(inparam, codename="Swift") +sim.write_param(outparam) + +inparam = "param.swifter.in" +outparam = "param.swifter.new" +print(f"Reading Swifter parameter {inparam} and saving it to {outparam}") +sim = swiftest.Simulation(inparam, codename="Swifter") +sim.write_param(outparam) + +inparam = "param.swiftest.in" +outparam = "param.swiftest.new" +print(f"Reading Swifter parameter {inparam} and saving it to {outparam}") +sim = swiftest.Simulation(inparam) # The default value of codename is "Swiftest" +sim.write_param(outparam) \ No newline at end of file diff --git a/python/swiftest/tests/swift_reader.py b/python/swiftest/tests/swift_reader.py deleted file mode 100644 index de62d59c1..000000000 --- a/python/swiftest/tests/swift_reader.py +++ /dev/null @@ -1,6 +0,0 @@ -import swiftest -inparam = "param.swift.in" -outparam = "param.swift.new" -print(f"Reading Swift parameter {inparam} and saving it to {outparam}") -sim = swiftest.Simulation(inparam, codename="Swift") -sim.write_param(outparam) \ No newline at end of file