def simulate(self, Tend, nIntervals, gridWidth): problem = Explicit_Problem(self.rhs, self.y0) problem.name = 'CVode' # solver.rhs = self.right_hand_side problem.handle_result = self.handle_result problem.state_events = self.state_events problem.handle_event = self.handle_event problem.time_events = self.time_events problem.finalize = self.finalize simulation = CVode(problem) # Change multistep method: 'adams' or 'VDF' if self.discr == 'Adams': simulation.discr = 'Adams' simulation.maxord = 12 else: simulation.discr = 'BDF' simulation.maxord = 5 # Change iteration algorithm: functional(FixedPoint) or newton if self.iter == 'FixedPoint': simulation.iter = 'FixedPoint' else: simulation.iter = 'Newton' # Sets additional parameters simulation.atol = self.atol simulation.rtol = self.rtol simulation.verbosity = self.verbosity if hasattr(simulation, 'continuous_output'): simulation.continuous_output = False # default 0, if one step approach should be used elif hasattr(simulation, 'report_continuously'): simulation.report_continuously = False # default 0, if one step approach should be used # '''Initialize problem ''' # self.t_cur = self.t0 # self.y_cur = self.y0 # Calculate nOutputIntervals: if gridWidth <> None: nOutputIntervals = int((Tend - self.t0) / gridWidth) else: nOutputIntervals = nIntervals # Check for feasible input parameters if nOutputIntervals == 0: print 'Error: gridWidth too high or nIntervals set to 0! Continue with nIntervals=1' nOutputIntervals = 1 # Perform simulation simulation.simulate( Tend, nOutputIntervals ) # to get the values: t_new, y_new = simulation.simulate
def simulate(self, Tend, nIntervals, gridWidth): problem = Explicit_Problem(self.rhs, self.y0) problem.name = 'CVode' # solver.rhs = self.right_hand_side problem.handle_result = self.handle_result problem.state_events = self.state_events problem.handle_event = self.handle_event problem.time_events = self.time_events problem.finalize = self.finalize simulation = CVode(problem) # Change multistep method: 'adams' or 'VDF' if self.discr == 'Adams': simulation.discr = 'Adams' simulation.maxord = 12 else: simulation.discr = 'BDF' simulation.maxord = 5 # Change iteration algorithm: functional(FixedPoint) or newton if self.iter == 'FixedPoint': simulation.iter = 'FixedPoint' else: simulation.iter = 'Newton' # Sets additional parameters simulation.atol = self.atol simulation.rtol = self.rtol simulation.verbosity = self.verbosity if hasattr(simulation, 'continuous_output'): simulation.continuous_output = False # default 0, if one step approach should be used elif hasattr(simulation, 'report_continuously'): simulation.report_continuously = False # default 0, if one step approach should be used # '''Initialize problem ''' # self.t_cur = self.t0 # self.y_cur = self.y0 # Calculate nOutputIntervals: if gridWidth <> None: nOutputIntervals = int((Tend - self.t0) / gridWidth) else: nOutputIntervals = nIntervals # Check for feasible input parameters if nOutputIntervals == 0: print 'Error: gridWidth too high or nIntervals set to 0! Continue with nIntervals=1' nOutputIntervals = 1 # Perform simulation simulation.simulate(Tend, nOutputIntervals) # to get the values: t_new, y_new = simulation.simulate
def make_explicit_sim(self): explicit_sim = CVode(self.explicit_problem) explicit_sim.iter = 'Newton' explicit_sim.discr = 'BDF' explicit_sim.rtol = 1e-7 explicit_sim.atol = 1e-7 explicit_sim.sensmethod = 'SIMULTANEOUS' explicit_sim.suppress_sens = True explicit_sim.report_continuously = False explicit_sim.usesens = False explicit_sim.verbosity = 50 if self.use_jac and self.model_jac is not None: explicit_sim.usejac = True else: explicit_sim.usejac = False return explicit_sim
def run_example(with_plots=True): """ Example of the use of CVode for a differential equation with a iscontinuity (state event) and the need for an event iteration. on return: - :dfn:`exp_mod` problem instance - :dfn:`exp_sim` solver instance """ #Create an instance of the problem exp_mod = Extended_Problem() #Create the problem exp_sim = CVode(exp_mod) #Create the solver exp_sim.verbosity = 0 exp_sim.report_continuously = True #Simulate t, y = exp_sim.simulate( 10.0, 1000) #Simulate 10 seconds with 1000 communications points exp_sim.print_event_data() #Plot if with_plots: import pylab as P P.plot(t, y) P.title(exp_mod.name) P.ylabel('States') P.xlabel('Time') P.show() #Basic test nose.tools.assert_almost_equal(y[-1][0], 8.0) nose.tools.assert_almost_equal(y[-1][1], 3.0) nose.tools.assert_almost_equal(y[-1][2], 2.0) return exp_mod, exp_sim
def mySolve(xf,boltz_eqs,rtol,atol,verbosity=50): """Sets the main options for the ODE solver and solve the equations. Returns the array of x,y points for all components. If numerical instabilities are found, re-do the problematic part of the evolution with smaller steps""" boltz_solver = CVode(boltz_eqs) #Define solver method boltz_solver.rtol = rtol boltz_solver.atol = atol boltz_solver.verbosity = verbosity boltz_solver.linear_solver = 'SPGMR' boltz_solver.maxh = xf/300. xfinal = xf xres = [] yres = [] sw = boltz_solver.sw[:] while xfinal <= xf: try: boltz_solver.re_init(boltz_eqs.t0,boltz_eqs.y0) boltz_solver.sw = sw[:] x,y = boltz_solver.simulate(xfinal) xres += x for ypt in y: yres.append(ypt) if xfinal == xf: break #Evolution has been performed until xf -> exit except Exception,e: print e if not e.t or 'first call' in e.msg[e.value]: logger.error("Error solving equations:\n "+str(e)) return False xfinal = max(e.t*random.uniform(0.85,0.95),boltz_eqs.t0+boltz_solver.maxh) #Try again, but now only until the error logger.warning("Numerical instability found. Restarting evolution from x = " +str(boltz_eqs.t0)+" to x = "+str(xfinal)) continue xfinal = xf #In the next step try to evolve from xfinal -> xf sw = boltz_solver.sw[:] x0 = float(x[-1]) y0 = [float(yval) for yval in y[-1]] boltz_eqs.updateValues(x0,y0,sw)
def simulate(self, Tend, nIntervals, gridWidth): # define assimulo problem:(has to be done here because of the starting value in Explicit_Problem solver = Explicit_Problem(self.rhs, self.y0) ''' *******DELETE LATER ''''''''' # problem.handle_event = handle_event # problem.state_events = state_events # problem.init_mode = init_mode solver.handle_result = self.handle_result solver.name = 'Simple Explicit Example' simulation = CVode(solver) # Create a RungeKutta34 solver # simulation.inith = 0.1 #Sets the initial step, default = 0.01 # Change multistep method: 'adams' or 'VDF' if self.discr == 'Adams': simulation.discr = 'Adams' simulation.maxord = 12 else: simulation.discr = 'BDF' simulation.maxord = 5 # Change iteration algorithm: functional(FixedPoint) or newton if self.iter == 'FixedPoint': simulation.iter = 'FixedPoint' else: simulation.iter = 'Newton' # Sets additional parameters simulation.atol = self.atol simulation.rtol = self.rtol simulation.verbosity = 0 if hasattr(simulation, 'continuous_output'): simulation.continuous_output = False # default 0, if one step approach should be used elif hasattr(simulation, 'report_continuously'): simulation.report_continuously = False # default 0, if one step approach should be used # Create Solver and set settings # noRootFunctions = np.size(self.state_events(self.t0, np.array(self.y0))) # solver = sundials.CVodeSolver(RHS = self.f, ROOT = self.rootf, SW = [False]*noRootFunctions, # abstol = self.atol, reltol = self.rtol) # solver.settings.JAC = None #Add user-dependent jacobian here '''Initialize problem ''' # solver.init(self.t0, self.y0) self.handle_result(self.t0, self.y0) nextTimeEvent = self.time_events(self.t0, self.y0) self.t_cur = self.t0 self.y_cur = self.y0 state_event = False # # if gridWidth <> None: nOutputIntervals = int((Tend - self.t0) / gridWidth) else: nOutputIntervals = nIntervals # Define step length depending on if gridWidth or nIntervals has been chosen if nOutputIntervals > 0: # Last point on grid (does not have to be Tend:) if(gridWidth <> None): dOutput = gridWidth else: dOutput = (Tend - self.t0) / nIntervals else: dOutput = Tend outputStepCounter = long(1) nextOutputPoint = min(self.t0 + dOutput, Tend) while self.t_cur < Tend: # Time-Event detection and step time adjustment if nextTimeEvent is None or nextOutputPoint < nextTimeEvent: time_event = False self.t_cur = nextOutputPoint else: time_event = True self.t_cur = nextTimeEvent try: # #Integrator step # self.y_cur = solver.step(self.t_cur) # self.y_cur = np.array(self.y_cur) # state_event = False # Simulate # take a step to next output point: t_new, y_new = simulation.simulate(self.t_cur) # 5, 10) #5, 10 self.t_cur self.t_cur 2. argument nsteps Simulate 5 seconds # t_new, y_new are both vectors of the time and states at t_cur and all intermediate # points before it! So take last values: self.t_cur = t_new[-1] self.y_cur = y_new[-1] state_event = False except: import sys print "Unexpected error:", sys.exc_info()[0] # except CVodeRootException, info: # self.t_cur = info.t # self.y_cur = info.y # self.y_cur = np.array(self.y_cur) # time_event = False # state_event = True # # # Depending on events have been detected do different tasks if time_event or state_event: event_info = [state_event, time_event] if not self.handle_event(self, event_info): break solver.init(self.t_cur, self.y_cur) nextTimeEvent = self.time_events(self.t_cur, self.y_cur) # If no timeEvent happens: if nextTimeEvent <= self.t_cur: nextTimeEvent = None if self.t_cur == nextOutputPoint: # Write output if not happened before: if not time_event and not state_event: self.handle_result(nextOutputPoint, self.y_cur) outputStepCounter += 1 nextOutputPoint = min(self.t0 + outputStepCounter * dOutput, Tend) self.finalize()
def RunModel(flagD,th,STIM,xoutS,xoutG,dataS,dataG,kTCleak,kTCmaxs, inds_to_watch = []): # going to return [tout_all,xoutG_all,xoutS_all] # This function runs the model and outputs timecourse simulation results. # Required Inputs: # flagD: 1 for deterministic simulations, 0 for stochastic simulations. # th: simulation time (hours) # STIM: stimulus vector # # Outputs: # tout_all: n-by-1 vector of time values (seconds) # xoutG_all: n-by-g matrix of species (g) through time (n) (g indices lines up to gm tab in Names.xls sheet) # xoutS_all: n-by-p matrix of speices (p) through time (n) (p indices lines up to PARCDL tab in Names.xls sheet) # # %% RUN ts=dataS.ts; ts_up=ts; N_STEPS=th*3600/ts; N_STEPS = int(N_STEPS) # % IMPORT INITIALIZED PARAMETERS pathi='initialized/'; # % for PARCDL kbR0 = float(open(pathi + "i_kbR0.txt").read()) kTL = [] with open(pathi + 'i_kTLF.txt') as f: for line in f: kTL.append(float(line)) kTL = np.array(kTL) kC173 = float(open(pathi + "i_kC173.txt").read()) kC82 = float(open(pathi + "i_kC82.txt").read()) kA77 = float(open(pathi + "i_kA77.txt").read())*5 # ^ forgot to add the *5 to this line and spent sooooo long looking for this mistake lol kA87 = float(open(pathi + "i_kA87.txt").read()) Rt = float(open(pathi + "i_Rt.txt").read()) EIF4Efree = float(open(pathi + "i_EIF4Efree.txt").read()) kDDbasal = float(open(pathi + "i_kDDbasal.txt").read()) Vc = dataS.kS[2] # % for gm if len(kTCleak)==0: for line in open(pathi + "i_kTCleakF.txt").readlines(): kTCleak.append(float(line)) kTCleak = np.matrix.transpose(np.matrix(kTCleak)) if len(kTCmaxs)==0: for line in open(pathi + "i_kTCmaxsF.txt").readlines(): kTCmaxs.append(float(line)) kTCmaxs = np.matrix.transpose(np.matrix(kTCmaxs)) kTCmaxs = np.array(kTCmaxs) # % modifying data.S structure dataS.kS[0]=Rt; dataS.kS[1]=EIF4Efree; dataS.kS[11]=kbR0; dataS.kS[16:157]=kTL; dataS.kS[631]=kC173; dataS.kS[540]=kC82; dataS.kS[708]=kA77; dataS.kS[718]=kA87; dataS.kS[449]=kDDbasal; # % modifying data.G structure dataG.kTCleak=kTCleak; dataG.kTCmaxs=kTCmaxs; # %species if len(xoutS) == 0: xoutS = [] with open(pathi + 'i_xoutF.csv', newline='') as csvfile: spamreader = csv.reader(csvfile, delimiter=' ', quotechar='|') for row in spamreader: x = ', '.join(row) x = x.split(',') to_append = [] for item in x: to_append.append(float(item)) xoutS.append(to_append) xoutS = np.matrix(xoutS) xoutS = xoutS[24,:] if len(xoutG) == 0: if flagD: xoutG = dataG.x0gm_mpc_D else: xoutG = dataG.x0gm_mpc indsD=dataG.indsD xoutG[indsD] = dataG.x0gm_mpc_D[indsD] xoutG[indsD+141] = dataG.x0gm_mpc_D[indsD+141] xoutG[indsD+141*2] = dataG.x0gm_mpc_D[indsD+141*2] # % Apply STIM Etop = STIM[len(STIM)-1] STIM = STIM[0:len(STIM)-1] # code for logical if np.any(STIM): xoutS[0,STIM.astype(bool)] = STIM[STIM.astype(bool)] dataS.kS[452] = Etop # NOTE - matlab code # % Instantiation # t0 = 0; # optionscvodes = CVodeSetOptions('UserData', dataS,... # 'RelTol',1.e-3,... # 'LinearSolver','Dense',... # 'JacobianFn',@Jeval774); # CVodeInit(@createODEs, 'BDF', 'Newton', t0, xoutS', optionscvodes); # # %ODE15s options # %optionsode15s=odeset('RelTol',1e-3,'Jacobian',@Jeval774ode15s); # tout_all = np.zeros(shape=(N_STEPS+1)) xoutG_all = np.zeros(shape=(N_STEPS+1,len(xoutG))) xoutS_all = np.zeros(shape=(N_STEPS+1,xoutS.shape[1])) tout_all[0] = 0 xoutG_all[0,:] = np.matrix.transpose(xoutG) xoutS_all[0,:] = xoutS # % Starting simulations print("... Starting Sims") start_time = time.time() for i in range(0,int(N_STEPS)+1): # gm [xginN,xgacN,AllGenesVecN,xmN,vTC] = gm(flagD,dataG,ts,xoutG,xoutS); xoutG = np.append(np.append(np.squeeze(np.asarray(xgacN)),np.squeeze(np.asarray(xginN))),np.squeeze(np.asarray(xmN))) # NOTE - matrix to array syntax xoutG = np.matrix.transpose(np.matrix(xoutG)) dataS.mMod=xmN*(1E9/(Vc*6.023E+23)); #convert mRNAs from mpc to nM dataG.AllGenesVec=AllGenesVecN; xoutG_all[i,:] = np.matrix.transpose(xoutG) try: xoutS_all[i,:] = np.squeeze(np.asarray(xoutS)) except: xoutS_all[i,:] = np.squeeze(np.asarray(xoutS[1])) if xoutS[0,103]<xoutS[0,105]: print("Apoptosis happened") tout_all = tout_all[0:i+1] xoutG_all = xoutG_all[0:i+1] xoutS_all = xoutS_all[0:i+1] return [tout_all, xoutG_all, xoutS_all] # scipy.odeint -- takes forever # xoutS = odeint(createODEs, xoutS_all[i,:],np.array([ts_up-ts, ts_up]), args=(dataS.kS,dataS.VvPARCDL,dataS.VxPARCDL,dataS.S_PARCDL,dataS.mExp_nM.as_matrix(),dataS.mMod,dataS.flagE)) # assimulo -- much faster ode_start_time = time.time() exp_mod = MyProblem(y0=xoutS_all[i,:],dataS=dataS, Jeval774 = Jeval774) exp_sim = CVode(exp_mod) exp_sim.verbosity=50 exp_sim.re_init(ts_up-ts,xoutS_all[i,:] ) t1, xoutS = exp_sim.simulate(ts_up, 1) try: print(xoutS[1,inds_to_watch]) except: print(xoutS) print("--- %s seconds ---" % (time.time() - ode_start_time)) print("Percent complete: " + str(i/N_STEPS)) # xoutG_all[i,:] = np.matrix.transpose(xoutG); try: tout_all[i+1] = ts_up except: pass ts_up = ts_up + ts print("ODEs done") print("--- %s seconds ---" % (time.time() - start_time)) return [tout_all, xoutG_all, xoutS_all]
def run_sim(Y, time, Y_AER1, YICE): def dy_dt_func(t, Y): dy_dt = np.zeros(len(Y)) # add condensed semi-vol mass into bins if n.SV_flag: MBIN2[-1 * n.n_sv:, :] = np.reshape(Y[INDSV1:INDSV2], [n.n_sv, nbins * nmodes]) # calculate saturation vapour pressure over liquid svp1 = f.svp_liq(Y[ITEMP]) # saturation ratio SL = svp1 * Y[IRH] / (Y[IPRESS] - svp1) SL = (SL * Y[IPRESS] / (1 + SL)) / svp1 # water vapour mixing ratio WV = c.eps * Y[IRH] * svp1 / (Y[IPRESS] - svp1) WL = np.sum(Y[IND1:IND2] * Y[:IND1]) # LIQUID MIXING RATIO WI = np.sum(YICE[IND1:IND2] * YICE[:IND1]) # ice mixing ratio RM = c.RA + WV * c.RV CPM = c.CP + WV * c.CPV + WL * c.CPW + WI * c.CPI if simulation_type.lower() == 'chamber': # CHAMBER MODEL - pressure change dy_dt[IPRESS] = -100 * PRESS1 * PRESS2 * np.exp(-PRESS2 * (time + t)) elif simulation_type.lower() == 'parcel': # adiabatic parcel dy_dt[IPRESS] = -Y[IPRESS] / RM / Y[ ITEMP] * c.g * w #! HYDROSTATIC EQUATION else: print('simulation type unknown') return # ----------------------------change in vapour content: ----------------------- # 1. equilibruim size of particles if n.kappa_flag: #if n.SV_flag: # need to recalc kappa taking into acount the condensed semi-vols Kappa = np.sum( (MBIN2[:, :] / RHOBIN2[:, :]) * KAPPABIN2[:, :], axis=0) / np.sum(MBIN2[:, :] / RHOBIN2[:, :], axis=0) # print(Kappa) # print(MBIN2/RHOBIN2) KK01 = f.kk01(Y[0:IND1], Y[ITEMP], MBIN2, RHOBIN2, Kappa) else: KK01 = f.K01(Y[0:IND1], Y[ITEMP], MBIN2, n.n_sv, RHOBIN2, NUBIN2, MOLWBIN2) # print(KK01[0]) Dw = KK01[2] # wet diameter RHOAT = KK01[1] # density of particles inc water and aerosol mass RH_EQ = KK01[0] # equilibrium RH # print(MBIN2/MOLWBIN2) # 2. growth rate of particles, Jacobson p455 # rate of change of radius growth_rate = f.DROPGROWTHRATE(Y[ITEMP], Y[IPRESS], SL, RH_EQ, RHOAT, Dw) growth_rate[np.isnan(growth_rate)] = 0 # get rid of nans growth_rate = np.where(Y[IND1:IND2] < 1e-9, 0.0, growth_rate) # 3. Mass of water condensing # change in mass of water per particle dy_dt[:IND1] = (np.pi * RHOAT * Dw**2) * growth_rate # 4. Change in vapour content # change in water vapour mixing ratio dwv_dt = -1 * np.sum( Y[IND1:IND2] * dy_dt[:IND1]) # change to np.sum for speed # mass # ----------------------------------------------------------------------------- if simulation_type.lower() == 'chamber': # CHAMBER MODEL - temperature change dy_dt[ITEMP] = -Temp1 * Temp2 * np.exp(-Temp2 * (time + t)) elif simulation_type.lower() == 'parcel': # adiabatic parcel dy_dt[ITEMP] = RM / Y[IPRESS] * dy_dt[IPRESS] * Y[ ITEMP] / CPM # TEMPERATURE CHANGE: EXPANSION dy_dt[ITEMP] = dy_dt[ITEMP] - c.LV / CPM * dwv_dt else: print('simulation type unknown') return # --------------------------------RH change------------------------------------ dy_dt[IRH] = svp1 * dwv_dt * (Y[IPRESS] - svp1) dy_dt[IRH] = dy_dt[IRH] + svp1 * WV * dy_dt[IPRESS] dy_dt[IRH] = ( dy_dt[IRH] - WV * Y[IPRESS] * derivative(f.svp_liq, Y[ITEMP], dx=1.0) * dy_dt[ITEMP]) dy_dt[IRH] = dy_dt[IRH] / (c.eps * svp1**2) # ----------------------------------------------------------------------------- # ------------------------------ SEMI-VOLATILES ------------------------------- if n.SV_flag: # SV_mass = np.reshape(Y[INDSV1:INDSV2],[n.n_sv,n.nmodes*n.nbins]) # SV_mass = np.where(SV_mass == 0.0,1e-30,SV_mass) # MBIN2[n.n_sv*-1:,:] = SV_mass RH_EQ_SV = f.K01SV(Y[:IND1], Y[ITEMP], MBIN2, n.n_sv, RHOBIN2, NUBIN2, MOLWBIN2) RH_EQ = RH_EQ_SV[0] RHOAT = RH_EQ_SV[1] DW = RH_EQ_SV[2] SVP_ORG = f.SVP_GASES(n.semi_vols, Y[ITEMP], n.n_sv) #C-C equation #RH_ORG = [x*Y[IPRESS]/c.RA/Y[ITEMP] for x in Y[IRH_SV]] RH_ORG = [x for x in Y[IRH_SV]] RH_ORG = [(x / c.aerosol_dict[key][0]) * c.R * Y[ITEMP] for x, key in zip(RH_ORG, n.semi_vols[:n.n_sv]) ] # just for n_sv keys in dictionary RH_ORG = [RH_ORG[x] / SVP_ORG[x] for x in range(n.n_sv)] dy_dt[INDSV1:INDSV2] = f.SVGROWTHRATE(Y[ITEMP], Y[IPRESS], SVP_ORG, RH_ORG, RH_EQ, DW, n.n_sv, n.nbins, n.nmodes, MOLWBIN2) dy_dt[IRH_SV] = -np.sum(np.reshape( dy_dt[INDSV1:INDSV2], [n.n_sv, IND1]) * Y[IND1:IND2], axis=1) #see line 137 return dy_dt #--------------------- SET-UP solver ------------------------------------------ y0 = Y t0 = 0.0 #define assimulo problem exp_mod = Explicit_Problem(dy_dt_func, y0, t0) # define an explicit solver exp_sim = CVode(exp_mod) exp_sim.iter = 'Newton' exp_sim.discr = 'BDF' #set parameters tol_list = np.zeros_like(Y) tol_list[0:IND1] = 1e-40 # this is now different to ACPIM (1e-25) tol_list[IND1:IND2] = 10 # number tol_list[IND2:IND3] = 1e-30 # capacitance tol_list[IND3:INDSV2] = 1e-26 #condendensed semi-vol mass tol_list[IRH_SV] = 1e-26 # RH of each semi-vol compound tol_list[IPRESS] = 10 tol_list[ITEMP] = 1e-4 tol_list[IRH] = 1e-8 # set tolerance for each dydt function exp_sim.atol = tol_list exp_sim.rtol = 1.0e-8 exp_sim.inith = 0 # initial time step-size exp_sim.usejac = False exp_sim.maxncf = 100 # max number of convergence failures allowed by solver exp_sim.verbosity = 40 t_output, y_output = exp_sim.simulate(1) return y_output[-1, :], t_output[:]
def run_sim_ice(Y, YLIQ): def dy_dt_func(t, Y): dy_dt = np.zeros(len(Y)) svp = f.svp_liq(Y[ITEMP]) svp_ice = f.svp_ice(Y[ITEMP]) # vapour mixing ratio WV = c.eps * Y[IRH_ICE] * svp / (Y[IPRESS_ICE] - svp) # liquid mixing ratio WL = sum(YLIQ[IND1:IND2] * YLIQ[0:IND1]) # ice mixing ratio WI = sum(Y[IND1:IND2] * Y[0:IND1]) Cpm = c.CP + WV * c.CPV + WL * c.CPW + WI * c.CPI # RH with respect to ice RH_ICE = WV / (c.eps * svp_ice / (Y[IPRESS_ICE] - svp_ice)) # ------------------------- growth rate of ice -------------------------- RH_EQ = 1e0 # from ACPIM, FPARCELCOLD - MICROPHYSICS.f90 CAP = f.CAPACITANCE01(Y[0:IND1], np.exp(Y[IND2:IND3])) growth_rate = f.ICEGROWTHRATE(Y[ITEMP_ICE], Y[IPRESS_ICE], RH_ICE, RH_EQ, Y[0:IND1], np.exp(Y[IND2:IND3]), CAP) growth_rate[np.isnan(growth_rate)] = 0 # get rid of nans growth_rate = np.where(Y[IND1:IND2] < 1e-6, 0.0, growth_rate) # Mass of water condensing dy_dt[:IND1] = growth_rate #---------------------------aspect ratio--------------------------------------- DELTA_RHO = c.eps * svp / (Y[IPRESS_ICE] - svp) DELTA_RHOI = c.eps * svp_ice / (Y[IPRESS_ICE] - svp_ice) DELTA_RHO = Y[IRH_ICE] * DELTA_RHO - DELTA_RHOI DELTA_RHO = DELTA_RHO * Y[IPRESS_ICE] / Y[ITEMP_ICE] / c.RA RHO_DEP = f.DEP_DENSITY(DELTA_RHO, Y[ITEMP_ICE]) # this is the rate of change of LOG of the aspect ratio dy_dt[IND2:IND3] = (dy_dt[0:IND1] * ((f.INHERENTGROWTH(Y[ITEMP_ICE]) - 1) / (f.INHERENTGROWTH(Y[ITEMP_ICE]) + 2)) / (Y[0:IND1] * c.rhoi * RHO_DEP)) #------------------------------------------------------------------------------ # Change in vapour content dwv_dt = -1 * sum(Y[IND1:IND2] * dy_dt[0:IND1]) # change in water vapour mixing ratio DRI = -1 * dwv_dt dy_dt[ITEMP_ICE] = 0.0 #+c.LS/Cpm*DRI # if n.Simulation_type.lower() == 'parcel': # dy_dt[ITEMP_ICE]=dy_dt[ITEMP_ICE] + c.LS/Cpm*DRI #---------------------------RH change------------------------------------------ dy_dt[IRH_ICE] = (Y[IPRESS_ICE] - svp) * svp * dwv_dt dy_dt[IRH_ICE] = ( dy_dt[IRH_ICE] - WV * Y[IPRESS_ICE] * derivative(f.svp_liq, Y[ITEMP_ICE], dx=1.0) * dy_dt[ITEMP_ICE]) dy_dt[IRH_ICE] = dy_dt[IRH_ICE] / (c.eps * svp**2) #------------------------------------------------------------------------------ return dy_dt #--------------------- SET-UP solver -------------------------------------- y0 = Y t0 = 0.0 #define assimulo problem exp_mod = Explicit_Problem(dy_dt_func, y0, t0) # define an explicit solver exp_sim = CVode(exp_mod) exp_sim.iter = 'Newton' exp_sim.discr = 'BDF' # set tolerance for each dydt function tol_list = np.zeros_like(Y) tol_list[0:IND1] = 1e-30 # mass tol_list[IND1:IND2] = 10 # number tol_list[IND2:IND3] = 1e-30 # aspect ratio # tol_list[IND3:IRH_SV_ICE] = 1e-26 #tol_list[IRH_SV_ICE] = 1e-26 tol_list[IPRESS_ICE] = 10 tol_list[ITEMP_ICE] = 1e-4 tol_list[IRH_ICE] = 1e-8 exp_sim.atol = tol_list exp_sim.rtol = 1.0e-8 exp_sim.inith = 1.0e-2 # initial time step-size exp_sim.usejac = False exp_sim.maxncf = 100 # max number of convergence failures allowed by solver exp_sim.verbosity = 40 t_output, y_output = exp_sim.simulate(1) return y_output[-1, :]
gamma = p[3] flux = np.array( [alpha * y[0], beta * y[0] * y[1], delta * y[0] * y[1], gamma * y[1]]) rhs = np.array([flux[0] - flux[1], flux[2] - flux[3]]) return rhs if __name__ == '__main__': p = np.array([.5, .02, .4, .004]) ode_function = lambda t, x: rhs_fun(t, x, p) # define explicit assimulo problem prob = Explicit_Problem(ode_function, y0=np.array([10, .0001])) # create solver instance solver = CVode(prob) solver.iter = 'Newton' solver.discr = 'Adams' solver.atol = 1e-10 solver.rtol = 1e-10 solver.display_progress = True solver.verbosity = 10 # simulate system time_course, y_result = solver.simulate(10, 200) print time_course print y_result