def time_evolve(self): ''' Evolve the spatial grid, time grid, accumulation rate, age, density, mass, stress, temperature, and diffusivity through time based on the user specified number of timesteps in the model run. Updates the firn density using a user specified ''' # load in model parameters gridLen, dx, dt, t, modeltime, years, stp, Ts, T_mean, bdot, bdotSec, rhos0, D_surf = define_parameters() steps = 1 / t if not self.c['physGrain']: r2_time = None for iter in xrange(stp): mtime = modeltime[iter] # getting the right physics for firn density based on user input physics = { 'HLdynamic', HLdynamic, 'HLSigfus', HLSigfus, 'Barnola1991', Barnola1991, 'Li2004', Li2004, 'Li2011', Li2011, 'Ligtenberg2011', Ligtenberg2011, 'Arthern2010S', Arthern2010S, 'Simonsen2013', Simonsen2013, 'Morris2013', MorrisHL2013, 'Helsen2008', Helsen2008, 'Arthern2010T', Arthern2010T, 'Spencer2001', Spencer2001, 'Goujon2003', Goujon2003, } parameters = { 'HLdynamic', [steps, gridLen, bdotSec, self.diffu.Tz, self.rho], 'HLSigfus', [steps, gridLen, bdotSec, self.diffu.Tz, self.rho, sigma], 'Barnola1991', [steps, gridLen, bdotSec, self.diffu.Tz, self.rho, sigma], 'Li2004', [steps, gridLen, bdotSec, T_mean, self.rho], 'Li2011', [steps, gridLen, bdotSec, self.bdot_mean, self.c['bdot_type'], self.diffu.Tz, T_mean, self.rho], 'Ligtenberg2011', [steps, gridLen, bdotSec, self.bdot_mean, self.c['bdot_type'], self.diffu.Tz, T_mean, self.rho], 'Arthern2010S', [steps, gridLen, bdotSec, self.bdot_mean, self.c['bdot_type'], self.diffu.Tz, T_mean, self.rho], 'Simonsen2013', [steps, gridLen, bdotSec, self.bdot_mean, self.c['bdot_type'], self.diffu.Tz, T_mean, self.rho], 'Morris2013', [steps, gridLen, self.diffu.Tz, dt, self.rho, True, iter], 'Helsen2008', [steps, bdotSec, self.c['bdot_type'], self.bdot_mean, self.diffu.Tz, Ts, self.rho], 'Arthern2010T', [gridLen, self.diffu.Tz, self.rho, self.sigma, self.r2, self.c['physGrain']], 'Spencer2001', [], 'Goujon2003', [], } try: drho_dt = physics[self.c['physRho']](parameters[self.c['physRho']]) except KeyError: default() # update density and age of firn self.age = np.concatenate(([0], self.age[:-1])) + dt self.rho = self.rho + dt * drho_dt self.rho = np.concatenate(([rhos0[iter]], self.rho[:-1])) self.Dcon = np.concatenate(([D_surf[iter]], self.Dcon[:-1])) # update temperature grid and isotope grid if user specifies if self.c['heatDiff']: self.diffu.heatDiff(self.z, self.dz, Ts, self.rho) if self.c['heatDiff']: self.diffu.isoDiff(iter, self.z, self.dz, self.rho, self.c['iso']) # update model grid dzNew = bdotSec[iter] * RHO_I / rhos0[iter] * S_PER_YEAR self.dz = self.mass / self.rho * dx self.dz = np.concatenate(([dzNew], self.dz[:-1])) self.z = self.dz.cumsum(axis = 0) self.z = np.concatenate(([0], self.z[:-1])) # update mass, stress, and mean accumulation rate massNew = bdotSec[iter] * S_PER_YEAR * RHO_I self.mass = np.concatenate(([massNew], self.mass[:-1])) self.sigma = self.mass * dx * GRAVITY self.sigma = self.sigma.cumsum(axis = 0) self.mass_sum = self.mass.cumsum(axis = 0) self.bdot_mean = np.concatenate(([mass_sum[0] / (RHO_I * S_PER_YEAR)], self.mass_sum[1:] * t / (self.age[1:] * RHO_I))) # update grain radius if self.c['physGrain']: self.r2 = grainGrowth(self.diffu.Tz, Ts, iter, dt) # write results as often as specified in the init method if [True for iter in self.TWrite if iter == mtime] == [True]: rho_time = np.append(mtime, self.rho) Tz_time = np.append(mtime, self.diffu.Tz) age_time = np.append(mtime, self.age) z_time = np.append(mtime, self.z) Dcon_time = np.append(mtime, self.Dcon) Clim_time = np.append(mtime, [bdot[iter], Ts[iter]]) bdot_time = np.append(mtime, self.bdot_mean) if c['physGrain']: r2_time = np.append(mtime, self.r2) write_nospin(self.c['resultsFolder'], self.c['physGrain'], rho_time, Tz_time, age_time, z_time, D_time, Clim_time, bdot_time, r2_time) update_BCO() update_LIZ() update_DIP() # write BCO, LIZ, DIP at the end of the time evolution write_nospin_BCO(self.c['resultsFolder'], self.bcoAgeMartAll, self.bcoDepMartAll, self.bcoAge815All, self.bcoDep815All) write_nospin_LIZ(self.c['resultsFolder'], self.LIZAgeAll, self.LIZDepAll) write_nospin_DIP(self.c['resultsFolder'], self.intPhiAll)
def __init__(self, configName): ''' Sets up the initial spatial grid, time grid, accumulation rate, age, density, mass, stress, temperature, and diffusivity of the model run :param configName: name of json config file containing model configurations ''' # load in json config file and parses the user inputs to a dictionary with open(configName, "r") as f: jsonString = f.read() self.c = json.loads(jsonString) # read in initial depth, age, density, temperature initDepth, initAge, initDensity, initTemp = read_init(self.c['resultsFolder']) # set up the initial age and density of the firn column self.age = initAge[1:] self.rho = initDensity[1:] # set up model grid self.z = initDepth[1:] self.dz = np.diff(self.z) self.dz = np.append(self.dz, self.dz[-1]) # load in model parameters gridLen, dx, dt, t, modeltime, years, stp, Ts, T_mean, bdot, bdotSec, rhos0, D_surf = self.define_parameters() # set up the initial grid of diffusivity constant self.Dcon = self.c['D_surf'] * np.ones(gridLen) # set up vector of times data will be written self.TWrite = modeltime[INTE::INTE] # set up initial mass, stress, and mean accumulation rate self.mass = self.rho * self.dz self.sigma = self.mass * dx * GRAVITY self.sigma = self.sigma.cumsum(axis = 0) self.mass_sum = self.mass.cumsum(axis = 0) self.bdot_mean = np.concatenate(([self.mass_sum[0] / (RHO_I * S_PER_YEAR)], self.mass_sum[1:] / (self.age[1:] * RHO_I / t))) # set up class to handle heat/isotope diffusion using user provided data for initial temperature vector self.diffu = Diffusion(self.z, stp, gridLen, initTemp[1:]) # set up initial values for density, temperature, age, depth, diffusivity, Clim??, and accumulation to write rho_time = np.append(modeltime[0], self.rho) Tz_time = np.append(modeltime[0], self.diffu.Tz) age_time = np.append(modeltime[0], self.age) z_time = np.append(modeltime[0], self.z) D_time = np.append(modeltime[0], self.Dcon) Clim_time = np.append(modeltime[0], [bdot[0], Ts[0]]) # not sure if bdot or bdotSec bdot_time = np.append(modeltime[0], self.bdot_mean) # set up initial grain growth (if specified in config file) if self.c['physGrain']: initr2 = np.genfromtxt(r2Path, delimiter = ',') self.r2 = initr2 r20 = r2 r2_time = np.append(modeltime[0], self.r2) else: r2_time = None # write initial values to the results folder write_nospin(self.c['resultsFolder'], self.c['physGrain'], rho_time, Tz_time, age_time, z_time, D_time, Clim_time, bdot_time, r2_time) # set up initial values for bubble close-off depth & age, lock-in zone depth & age, and depth integrated porosity self.bcoAgeMartAll = [] self.bcoDepMartAll = [] self.bcoAge815All = [] self.bcoDep815All = [] self.LIZAgeAll = [] self.LIZDepAll = [] self.intPhiAll = [] update_BCO() update_LIZ() update_DIP()