def make_param(snapshot, filename=None): """ Generates a default param dictionary. Can be saved using diskpy.utils.configsave EXAMPLE snapshot = pynbody.load('snapshot.std') # Load snapshot param_dict = make_param(snapshot) # Make default param dict diskpy.utils.configsave(param_dict, 'snapshot.param', ftype='param') # Save Optionally, the user can set the snapshot filename manually """ param = configparser(_paramdefault, ftype='param') if filename is not None: param['achInFile'] = filename param['achOutName'] = os.path.splitext(filename)[0] elif snapshot.filename != '<created>': param['achInFile'] = snapshot.filename param['achOutName'] = os.path.splitext(snapshot.filename)[0] # Set up the length units param['dKpcUnit'] = snapshot['pos'].units.ratio('kpc') # Set up the mass units param['dMsolUnit'] = snapshot['mass'].units.ratio('Msol') # Set the mean molecular mass param['dMeanMolWeight'] = snapshot.gas['mu'][0] return param
def getpar(key, param={}): """ Attempts to retrieve the key from param or from the ChaNGa default param options. Raises ValueError if key not found in either. Parameters ---------- key : object param : str or dict Paramname or param dict (see diskpy.utils.configparser). If not supplied, only the ChaNGa defaults are searched Returns ------- value The value, taken from param if present, otherwise taken from the ChaNGa default params """ if isinstance(param, str): param = configparser(param, 'param') if key in param: value = param[key] elif key in _changadefault: value = _changadefault[key] else: raise ValueError, "Could not find {0} in param or defaults".format(key) return value
def _load_units(param): # Load param if necessary if isinstance(param, str): param = configparser(param, 'param') # Universal G G = pynbody.units.G # Load units dKpcUnit = param['dKpcUnit'] dMsolUnit = param['dMsolUnit'] # Set up pynbody units m_unit = pynbody.units.Unit('{0} Msol'.format(dMsolUnit)) l_unit = pynbody.units.Unit('{0} kpc'.format(dKpcUnit)) t_unit = (l_unit**3/(G*m_unit))**(1,2) # Convert the time unit to something sensible years = t_unit.in_units('yr') t_unit = pynbody.units.Unit('{0} yr'.format(years)) # Return outdict = {'l_unit':l_unit, 'm_unit':m_unit, 't_unit':t_unit} return outdict
def find_param_names(simdir='.', paramfile=None, prefix=None): """ Tries to find the .param and associated .log file for a simulation Returns paramfile, logfile If a filename is not found it will be returned as None """ import path prefix = str(prefix) with path.Path(simdir) as directory: if paramfile is None: paramfile = prefix + '.param' if not os.path.isfile(paramfile): import glob names = glob.glob('*.param') if len(names) != 1: print "could not find .param file" paramfile = None else: paramfile = names[0] logfile = None if paramfile is not None: try: # Load the param file param = configparser(paramfile, 'param') # Try to load the log file achOutName = getpar('achOutName', param) if os.path.isfile(achOutName + '.log'): logfile = achOutName + '.log' except IOError: paramfile = None if logfile is None: if os.path.isfile(prefix + '.log'): logfile = prefix + '.log' if paramfile is not None: paramfile = os.path.join(simdir, paramfile) if logfile is not None: logfile = os.path.join(simdir, logfile) return paramfile, logfile
def setup_param(param, snapshot=None, r_orb=1.0, n_orb=10.0, n_image=None, n_snap=100, \ n_check=None): """ Sets up the following for a .param file: nSteps dDumpFrameStep iOutInterval iCheckInterval **ARGUMENTS** param : str or param_dict (see diskpy.utils.configparser, configsave) parameter file for the simulation, must already have dDelta and units set properly IF a str, assumed to be a filename snapshot : str or TipsySnap(see pynbody) or None Snapshot for the simulation. Needed to estimate the outer orbital period. IF a str, assumed to be a filename IF None, the file pointed to by param is used r_orb : float radius to calculate the outer orbital period at as a fraction of the radius of the farthest out particle. Must be between 0 and 1 n_orb : float number of outer orbital periods to run simulation for n_image : int or None Total number of frames to dump (ie, dDumpFrameStep) If None, defaults to n_snap n_snap : int Total number of simulation outputs n_check : int or None Total number of simulation checkpoints. If None, defaults to n_snap """ if (r_orb > 1) | (r_orb < 0): raise ValueError, 'r_orb must be between 0 and 1' if isinstance(snapshot, str): # A filename has been passed, not a tipsy snapshot snapshot = pynbody.load(snapshot) if isinstance(param, str): # A filename has been passed. Load the dictionary param = configparser(param, 'param') else: # Copy so as to not overwrite the input dict param = copy.deepcopy(param) R_max = r_orb * snapshot.g['rxy'].max() M_star = snapshot.s['mass'] # Read in .param stuff l_unit = '{} kpc'.format(param['dKpcUnit']) m_unit = '{} Msol'.format(SimArray(param['dMsolUnit'], 'Msol')) # Outer radius and star mass in simulation units r = float(R_max.in_units(l_unit)) M = float(M_star.in_units(m_unit)) # Calculate the number of time steps to use dt = param['dDelta'] period = 2 * np.pi * np.sqrt(r**3 / M) N = int(np.round(n_orb * period / dt)) param['nSteps'] = N # Calculate how often to output snapshots, frames, checkpoints if n_check is None: n_check = n_snap if n_image is None: n_image = n_snap param['dDumpFrameStep'] = int(N / n_image) param['iOutInterval'] = int(N / n_snap) param['iCheckInterval'] = int(N / n_check) return param
def units_from_param(param): """ Figures out the simulation units from a .param file **ARGUMENTS** param : str or param dict (see configparser) Simulation .param file or param dict loaded by configparser Can also be a list or numpy array of these in which case a list of units dicts is returned **RETURNS** units : dict A dictionary of the units used in the simulation, returned as pynbody units """ # Iterate over param if necessary if isinstance(param, (list, np.ndarray)): outlist = [] for par in param: outlist.append(units_from_param(par)) return outlist # Load param if necessary if isinstance(param, str): param = configparser(param, 'param') # Universal G G = pynbody.units.G # Load units dKpcUnit = getpar('dKpcUnit', param) dMsolUnit = getpar('dMsolUnit', param) # Set up pynbody units m_unit = pynbody.units.Unit('{0} Msol'.format(dMsolUnit)) l_unit = pynbody.units.Unit('{0} kpc'.format(dKpcUnit)) t_unit = (l_unit**3 / (G * m_unit))**(1, 2) # Convert the time unit to something sensible years = t_unit.in_units('yr') t_unit = pynbody.units.Unit('{0} yr'.format(years)) # Calculate a couple derived units as well v_unit = l_unit / t_unit rho_unit = m_unit / l_unit**3 acc_unit = l_unit / t_unit**2 pres_unit = rho_unit * v_unit**2 # Return outdict = { 'l_unit': l_unit, 'm_unit': m_unit, 't_unit': t_unit, 'v_unit': v_unit, 'rho_unit': rho_unit, 'acc_unit': acc_unit, 'pres_unit': pres_unit } return outdict
import pynbody SimArray = pynbody.array.SimArray from diskpy.utils import configparser, strip_units, get_units # Constants G = SimArray(1.0, 'G') # Set up default filenames _dir = os.path.dirname(os.path.realpath(__file__)) _paramdefault = os.path.join(_dir, 'default.param') _directordefault = os.path.join(_dir, 'default.director') _changadefault = os.path.join(_dir, 'changadefaults.param') # Load the default parameters _paramdefault = configparser(_paramdefault, 'param') _directordefault = configparser(_directordefault, 'director') _changadefault = configparser(_changadefault, 'param') def getpar(key, param={}): """ Attempts to retrieve the key from param or from the ChaNGa default param options. Raises ValueError if key not found in either. Parameters ---------- key : object param : str or dict Paramname or param dict (see diskpy.utils.configparser). If not supplied, only the ChaNGa defaults are searched
def find_clumps(f, n_smooth=32, param=None, arg_string=None, seed=None, verbose=True): """ Uses skid (https://github.com/N-BodyShop/skid) to find clumps in a gaseous protoplanetary disk. The linking length used is equal to the gravitational softening length of the gas particles. The density cut-off comes from the criterion that there are n_smooth particles within the Hill sphere of a particle. This is formulated mathematically as: rho_min = 3*n_smooth*Mstar/R^3 where R is the distance from the star. The trick used here is to multiply all particle masses by R^3 before running skid so the density cut-off is: rho_min = 3*n_smooth*Mstar **ARGUMENTS** *f* : TipsySnap, or str A tipsy snapshot loaded/created by pynbody -OR- a filename pointing to a snapshot. *n_smooth* : int (optional) Number of particles used in SPH calculations. Should be the same as used in the simulation. Default = 32 *param* : str (optional) filename for a .param file for the simulation *arg_string* : str (optional) Additional arguments to be passed to skid. Cannot use -tau, -d, -m, -s, -o *seed* : int An integer used to seed the random filename generation for temporary files. Necessary for multiprocessing and should be unique for each thread. *verbose* : bool Verbosity flag. Default is True **RETURNS** *clumps* : array, int-like Array containing the group number each particle belongs to, with star particles coming after gas particles. A zero means the particle belongs to no groups """ # Parse areguments if isinstance(f, str): f = pynbody.load(f, paramfile=param) if seed is not None: np.random.seed(seed) # Estimate the linking length as the gravitational softening length tau = f.g['eps'][0] # Calculate minimum density rho_min = 3 * n_smooth * f.s['mass'][0] # Center on star. This is done because R used in hill-sphere calculations # is relative to the star star_pos = f.s['pos'].copy() f['pos'] -= star_pos # Scale mass by R^3 R = utils.strip_units(f['rxy']) m0 = f['mass'].copy() f['mass'] *= (R + tau)**3 # Save temporary snapshot f_prefix = str(np.random.randint(np.iinfo(int).max)) f_name = f_prefix + '.std' # Save temporary .param file if param is not None: param_name = f_prefix + '.param' param_dict = utils.configparser(param, 'param') utils.configsave(param_dict, param_name) f.write(filename=f_name, fmt=pynbody.tipsy.TipsySnap) f['pos'] += star_pos f['mass'] = m0 command = 'totipnat < {} | skid -tau {:.2e} -d {:.2e} -m {:d} -s {:d} -o {}'\ .format(f_name, tau, rho_min, n_smooth, n_smooth, f_prefix) p = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) if verbose: for line in iter(p.stdout.readline, ''): print line, p.wait() # Load clumps clumps = loadhalos(f_prefix + '.grp') # Cleanup for name in glob.glob(f_prefix + '*'): os.remove(name) return clumps
def find_clumps(f, n_smooth=32, param=None, arg_string=None, seed=None, verbose=True): """ Uses skid (https://github.com/N-BodyShop/skid) to find clumps in a gaseous protoplanetary disk. Also requires tipsy tools (https://github.com/N-BodyShop/tipsy_tools), specifically totipnat The linking length used is equal to the gravitational softening length of the gas particles. The density cut-off comes from the criterion that there are n_smooth particles within the Hill sphere of a particle. This is formulated mathematically as: rho_min = 3*n_smooth*Mstar/R^3 where R is the distance from the star. The trick used here is to multiply all particle masses by R^3 before running skid so the density cut-off is: rho_min = 3*n_smooth*Mstar **ARGUMENTS** *f* : TipsySnap, or str A tipsy snapshot loaded/created by pynbody -OR- a filename pointing to a snapshot. *n_smooth* : int (optional) Number of particles used in SPH calculations. Should be the same as used in the simulation. Default = 32 *param* : str (optional) filename for a .param file for the simulation *arg_string* : str (optional) Additional arguments to be passed to skid. Cannot use -tau, -d, -m, -s, -o *seed* : int An integer used to seed the random filename generation for temporary files. Necessary for multiprocessing and should be unique for each thread. *verbose* : bool Verbosity flag. Default is True **RETURNS** *clumps* : array, int-like Array containing the group number each particle belongs to, with star particles coming after gas particles. A zero means the particle belongs to no groups """ # Check for skid and totipnat err = [] skid_path = utils.which('skid') if skid_path is None: err.append('<skid not found : https://github.com/N-BodyShop/skid>') totipnat_path = utils.which('totipnat') if totipnat_path is None: err.append('<totipnat (part of tipsy tools) not found : ' 'https://github.com/N-BodyShop/tipsy_tools>') if len(err) > 0: err = '\n'.join(err) raise RuntimeError, err # Parse areguments if isinstance(f, str): f = pynbody.load(f, paramfile=param) if seed is not None: np.random.seed(seed) # Estimate the linking length as the gravitational softening length tau = f.g['eps'][0] # Calculate minimum density rho_min = 3*n_smooth*f.s['mass'][0] # Center on star. This is done because R used in hill-sphere calculations # is relative to the star star_pos = f.s['pos'].copy() f['pos'] -= star_pos # Scale mass by R^3 R = utils.strip_units(f['rxy']) m0 = f['mass'].copy() f['mass'] *= (R+tau)**3 # Save temporary snapshot f_prefix = str(np.random.randint(np.iinfo(int).max)) f_name = f_prefix + '.std' # Save temporary .param file if param is not None: param_name = f_prefix + '.param' param_dict = utils.configparser(param, 'param') utils.configsave(param_dict, param_name) f.write(filename=f_name, fmt=pynbody.tipsy.TipsySnap) f['pos'] += star_pos f['mass'] = m0 command = 'totipnat < {} | skid -tau {:.2e} -d {:.2e} -m {:d} -s {:d} -o {}'\ .format(f_name, tau, rho_min, n_smooth, n_smooth, f_prefix) p = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) if verbose: for line in iter(p.stdout.readline, ''): print line, p.wait() # Load clumps clumps = loadhalos(f_prefix + '.grp') # Cleanup for name in glob.glob(f_prefix + '*'): os.remove(name) return clumps
def setup_param(param, snapshot=None, r_orb=1.0, n_orb=10.0, n_image=None, n_snap=100, \ n_check=None): """ Sets up the following for a .param file: nSteps dDumpFrameStep iOutInterval iCheckInterval **ARGUMENTS** param : str or param_dict (see diskpy.utils.configparser, configsave) parameter file for the simulation, must already have dDelta and units set properly IF a str, assumed to be a filename snapshot : str or TipsySnap(see pynbody) or None Snapshot for the simulation. Needed to estimate the outer orbital period. IF a str, assumed to be a filename IF None, the file pointed to by param is used r_orb : float radius to calculate the outer orbital period at as a fraction of the radius of the farthest out particle. Must be between 0 and 1 n_orb : float number of outer orbital periods to run simulation for n_image : int or None Total number of frames to dump (ie, dDumpFrameStep) If None, defaults to n_snap n_snap : int Total number of simulation outputs n_check : int or None Total number of simulation checkpoints. If None, defaults to n_snap """ if (r_orb > 1) | (r_orb < 0): raise ValueError, 'r_orb must be between 0 and 1' if isinstance(snapshot, str): # A filename has been passed, not a tipsy snapshot snapshot = pynbody.load(snapshot) if isinstance(param, str): # A filename has been passed. Load the dictionary param = configparser(param, 'param') else: # Copy so as to not overwrite the input dict param = copy.deepcopy(param) R_max = r_orb * snapshot.g['rxy'].max() M_star = snapshot.s['mass'] # Read in .param stuff l_unit = '{} kpc'.format(param['dKpcUnit']) m_unit = '{} Msol'.format(SimArray(param['dMsolUnit'], 'Msol')) # Outer radius and star mass in simulation units r = float(R_max.in_units(l_unit)) M = float(M_star.in_units(m_unit)) # Calculate the number of time steps to use dt = param['dDelta'] period = 2*np.pi*np.sqrt(r**3/M) N = int(np.round(n_orb * period/dt)) param['nSteps'] = N # Calculate how often to output snapshots, frames, checkpoints if n_check is None: n_check = n_snap if n_image is None: n_image = n_snap param['dDumpFrameStep'] = int(N/n_image) param['iOutInterval'] = int(N/n_snap) param['iCheckInterval'] = int(N/n_check) return param
def make_continue_sub(simdir='.', paramname='snapshot.param', \ newparam='continue.param', t=None, t_extra=None, oldsub='subber.sh', \ newsub='cont_subber.sh'): """ Makes a submission script for continuing a simulation from a previous output. Also makes a .param file for the continued simulation. The simulation will be continued in the same directory, with snapshot numbering scheme for outputs being the same. Parameters for the original simulation cannot be altered (except the number of steps you want to continue the simulation by). PBS runtime parameters also cannot be changed (number of nodes, walltime, etc...) Any checkpoints will be deleted. Requires a submission script be present for the original simulation NOTE: if nSteps, nSteps_extra are not set, the total number of steps to simulate is not changed. **ARGUMENTS** simdir : str The simulation directory paramname : str Filename of the .param file for the simulation newparam : str filename for the .param file for the continued simulation t : float or SimArray Total simulation time to run. If no units are specified, it is in simulation units t_extra : float or SimArray Extra simulation time to run If no units are specified, it is in simulation units OVERIDES t!!! oldsub : str Filename for the original submission script newsub : str Filename for the new submission script **RETURNS** sub_path : str Full path to the PBS submission script """ # Lazy man's way of dealing with files in another directory cwd = os.getcwd() os.chdir(simdir) # Load param file param = configparser(paramname, 'param') fprefix = param['achOutName'] # Find all the outputs. They should be of the format fprefix.000000 search_exp = '^' + fprefix + '.(?:(?<!\d)\d{6}(?!\d))$' flist = [] for fname in glob.glob(fprefix + '*'): if re.search(search_exp, fname) is not None: flist.append(fname) # Find the number of the last output (the last 6 chars should be an int) flist.sort() iStartStep = int(flist[-1][-6:]) param['iStartStep'] = iStartStep param['achInFile'] = flist[-1] dDelta = param['dDelta'] # Set the number of steps to run if t_extra is not None: # Convert to simulation units if needed if pynbody.units.has_units(t_extra): t_unit = units_from_param(param)['t_unit'] t_extra.convert_units(t_unit) # Assign output param['nSteps'] = iStartStep + int(round(t_extra/dDelta)) elif t is not None: # Convert to simulation units if needed if pynbody.units.has_units(t): t_unit = units_from_param(param)['t_unit'] t.convert_units(t_unit) # Assign output param['nSteps'] = int(round(t/dDelta)) # Save new param file configsave(param, newparam, ftype='param') # Delete old checkpoints for checkpoint in glob.glob(fprefix + '.chk*'): print 'removing ' + checkpoint os.system('rm -rf ' + checkpoint) if os.path.exists('lastcheckpoint'): print 'removing lastcheckpoint' os.remove('lastcheckpoint') # Create a submission script for the simulation continuation oldsubfile = open(oldsub, 'r') newsubfile = open(newsub, 'w') for line in oldsubfile: newsubfile.write(line.replace(paramname, newparam)) oldsubfile.close() newsubfile.close() # Make the submission script executable os.chmod(newsub, 0777) sub_path = os.path.abspath(newsub) # Change back to original working directory os.chdir(cwd) return sub_path
def load_acc(filename, param_name = None, low_mem = False): """ Loads accelerations from a ChaNGa acceleration file (.acc2), ignoring the star particle. IF param_name is None, a .param file is searched for, otherwise param_name should be a string specifying a .param file name IF no param_file is found, the defaults are used: length unit: AU mass unit : Msol Setting low_mem=True decreases memory usage by about 2x but also increases readtime by about 2x """ if param_name is None: prefix = filename.split('.')[0] param_list = glob.glob('*' + prefix +'*param') if len(param_list) > 0: param_name = param_list[0] elif len(glob.glob('*.param')) > 0: param_name = glob.glob('*.param')[0] else: warnings.warn('Could not find .param file. Assuming default units') if param_name is not None: # If a param name is set or a param file has been found: print 'Loading param file: {}'.format(param_name) param = configparser(param_name, ftype='param') else: # Set the default parameters param = {} # Assume AU as length unit param['dKpcUnit'] = pynbody.units.au.ratio('kpc') # Assume mass units as Msol param['dMsolUnit'] = 1.0 # Figure out units G = pynbody.units.G l_unit = param['dKpcUnit']*pynbody.units.kpc m_unit = param['dMsolUnit']*pynbody.units.Msol t_unit = ((l_unit**3) * G**-1 * m_unit**-1)**(1,2) a_unit = l_unit * t_unit**-2 if low_mem: acc_file = open(filename, 'r') n_particles = int(acc_file.readline().strip()) acc = SimArray(np.zeros(3*n_particles, dtype=np.float32), a_unit) for i, line in enumerate(acc_file): acc[i] = np.float32(line.strip()) acc_file.close() return acc.reshape([n_particles, 3], order='F')[0:-1] else: # Load acceleration file as numpy array acc = np.genfromtxt(filename, skip_header=1).astype(np.float32) n_particles = len(acc)/3 # Reshape and make it a SimArray with proper units acc = SimArray(acc.reshape([n_particles, 3], order='F'), a_unit) return acc[0:-1]
def load_acc(filename, param_name=None, low_mem=False): """ Loads accelerations from a ChaNGa acceleration file (.acc2), ignoring the star particle. ASSUMES A SINGLE STAR PARTICLE IF param_name is None, a .param file is searched for, otherwise param_name should be a string specifying a .param file name. this is used to specify units IF no param_file is found, the defaults are used: length unit: AU mass unit : Msol Setting low_mem=True decreases memory usage by about 2x but also increases readtime by about 2x """ # Try to infer units if param_name is None: prefix = filename.split('.')[0] param_list = glob.glob('*' + prefix + '*param') if len(param_list) > 0: param_name = param_list[0] elif len(glob.glob('*.param')) > 0: param_name = glob.glob('*.param')[0] else: warnings.warn( 'Could not find .param file. Assuming default units') if param_name is not None: # If a param name is set or a param file has been found: print 'Loading param file: {}'.format(param_name) param = configparser(param_name, ftype='param') else: # Set the default parameters param = {} # Assume AU as length unit param['dKpcUnit'] = pynbody.units.au.ratio('kpc') # Assume mass units as Msol param['dMsolUnit'] = 1.0 # Figure out units G = pynbody.units.G l_unit = param['dKpcUnit'] * pynbody.units.kpc m_unit = param['dMsolUnit'] * pynbody.units.Msol t_unit = ((l_unit**3) * G**-1 * m_unit**-1)**(1, 2) a_unit = l_unit * t_unit**-2 # LOAD acc = _load_tipsyarray3d_ascii(filename, low_mem=low_mem) acc.units = a_unit return acc
def make_continue_sub(simdir='.', paramname='snapshot.param', \ newparam='continue.param', t=None, t_extra=None, oldsub='subber.sh', \ newsub='cont_subber.sh'): """ Makes a submission script for continuing a simulation from a previous output. Also makes a .param file for the continued simulation. The simulation will be continued in the same directory, with snapshot numbering scheme for outputs being the same. Parameters for the original simulation cannot be altered (except the number of steps you want to continue the simulation by). PBS runtime parameters also cannot be changed (number of nodes, walltime, etc...) Any checkpoints will be deleted. Requires a submission script be present for the original simulation NOTE: if nSteps, nSteps_extra are not set, the total number of steps to simulate is not changed. **ARGUMENTS** simdir : str The simulation directory paramname : str Filename of the .param file for the simulation newparam : str filename for the .param file for the continued simulation t : float or SimArray Total simulation time to run. If no units are specified, it is in simulation units t_extra : float or SimArray Extra simulation time to run If no units are specified, it is in simulation units OVERIDES t!!! oldsub : str Filename for the original submission script newsub : str Filename for the new submission script **RETURNS** sub_path : str Full path to the PBS submission script """ # Lazy man's way of dealing with files in another directory cwd = os.getcwd() os.chdir(simdir) # Load param file param = configparser(paramname, 'param') fprefix = param['achOutName'] # Find all the outputs. They should be of the format fprefix.000000 search_exp = '^' + fprefix + '.(?:(?<!\d)\d{6}(?!\d))$' flist = [] for fname in glob.glob(fprefix + '*'): if re.search(search_exp, fname) is not None: flist.append(fname) # Find the number of the last output (the last 6 chars should be an int) flist.sort() iStartStep = int(flist[-1][-6:]) param['iStartStep'] = iStartStep param['achInFile'] = flist[-1] dDelta = param['dDelta'] # Set the number of steps to run if t_extra is not None: # Convert to simulation units if needed if pynbody.units.has_units(t_extra): t_unit = units_from_param(param)['t_unit'] t_extra.convert_units(t_unit) # Assign output param['nSteps'] = iStartStep + int(round(t_extra / dDelta)) elif t is not None: # Convert to simulation units if needed if pynbody.units.has_units(t): t_unit = units_from_param(param)['t_unit'] t.convert_units(t_unit) # Assign output param['nSteps'] = int(round(t / dDelta)) # Save new param file configsave(param, newparam, ftype='param') # Delete old checkpoints for checkpoint in glob.glob(fprefix + '.chk*'): print 'removing ' + checkpoint os.system('rm -rf ' + checkpoint) if os.path.exists('lastcheckpoint'): print 'removing lastcheckpoint' os.remove('lastcheckpoint') # Create a submission script for the simulation continuation oldsubfile = open(oldsub, 'r') newsubfile = open(newsub, 'w') for line in oldsubfile: newsubfile.write(line.replace(paramname, newparam)) oldsubfile.close() newsubfile.close() # Make the submission script executable os.chmod(newsub, 0777) sub_path = os.path.abspath(newsub) # Change back to original working directory os.chdir(cwd) return sub_path
def make_director(sigma_min, sigma_max, r, resolution=1200, filename='snapshot'): """ Makes a director dictionary for ChaNGa runs based on the min/max surface density, maximum image radius, and image resolution for a gaseous protoplanetary disk. The created dictionary can be saved with diskpy.utils.configsave The method is to use an example director file (saved as default.director) which works for one simulation and scale the various parameters accordingly. default.director should have a commented line in it which reads: #sigma_max float where float is the maximum surface density of the simulation in simulation units. **ARGUMENTS** sigma_min : float The surface density that corresponds to 0 density on the image (ie the minimum threshold). Required for setting the dynamic range sigma_max : float Maximum surface density in the simulation r : float Maximum radius to plot out to resolution : int or float Number of pixels in image. The image is shape (resolution, resolution) filename : str prefix to use for saving the images. Example: if filename='snapshot', then the outputs will be of form 'snapshot.000000000.ppm' **RETURNS** director : dict A .director dictionary. Can be saved with diskpy.utils.configsave """ # ----------------------------------------------------------- # Parse defaults to get scale factor for c # ----------------------------------------------------------- sigma_min, sigma_max, r = strip_units([sigma_min, sigma_max, r]) defaults = configparser(_directordefault) if '#sigma_max' not in defaults: raise KeyError,'Default .director file should have a line e.g. << #sigma_max 0.01 >>' sigma_max0 = defaults['#sigma_max'] c0 = defaults['colgas'][3] n0 = defaults['size'][0] r0 = defaults['eye'][2] A = (c0 * float(n0)**2)/(sigma_max0 * r0**2) # ----------------------------------------------------------- # Create new director dictionary # ----------------------------------------------------------- director = copy.deepcopy(defaults) director.pop('#sigma_max', None) logscale_min = sigma_min/sigma_max if pynbody.units.has_units(logscale_min): logscale_min = float(logscale_min.in_units('1')) c = A * float(sigma_max * r**2 /float(resolution)**2) director['colgas'][3] = c director['size'] = [resolution, resolution] director['eye'][2] = r director['file'] = filename return director
import pynbody SimArray = pynbody.array.SimArray from diskpy.utils import configparser, strip_units, get_units # Constants G = SimArray(1.0,'G') # Set up default filenames _dir = os.path.dirname(os.path.realpath(__file__)) _paramdefault = os.path.join(_dir, 'default.param') _directordefault = os.path.join(_dir, 'default.director') _changadefault = os.path.join(_dir, 'changadefaults.param') # Load the default parameters _paramdefault = configparser(_paramdefault, 'param') _directordefault = configparser(_directordefault, 'director') _changadefault = configparser(_changadefault, 'param') def getpar(key, param={}): """ Attempts to retrieve the key from param or from the ChaNGa default param options. Raises ValueError if key not found in either. Parameters ---------- key : object param : str or dict Paramname or param dict (see diskpy.utils.configparser). If not supplied, only the ChaNGa defaults are searched