def step(self, dt = 1.0): ode.integrate(self, self.t + dt, step = 1) self.xs = np.append(self.xs, [self.y[:self.N]], axis = 0) self.vs = np.append(self.vs, [self.y[self.N:]], axis = 0 ) self.rs = np.append(self.rs, [self.r(self.xs[-1])], axis = 0) self.vels = np.append(self.vels, [np.dot(self.j(self.xs[-1]), self.vs[-1])], axis = 0) self.ts = np.append(self.ts, self.t)
def step(self, dt = 1.0): """ Integrate the geodesic for one step dt = target time step to use """ ode.integrate(self, self.t + dt, step = 1) self.xs = np.append(self.xs, [self.y[:self.N]], axis = 0) self.vs = np.append(self.vs, [self.y[self.N:]], axis = 0 ) self.rs = np.append(self.rs, [self.r(self.xs[-1])], axis = 0) self.vels = np.append(self.vels, [np.dot(self.j(self.xs[-1]), self.vs[-1])], axis = 0) self.ts = np.append(self.ts, self.t)
def step(self, dt = 1.0): ''' take a step along the geodesic''' ode.integrate(self, self.t + dt, step = 1) self.xs = np.append(self.xs, [self.y[:self.N]], axis = 0) self.vs = np.append(self.vs, [self.y[self.N:]], axis = 0 ) self.rs = np.append(self.rs, [self.r(self.xs[-1])], axis = 0) self.vels = np.append(self.vels, [np.dot(self.j(self.xs[-1]), self.vs[-1])], axis = 0) self.ts = np.append(self.ts, self.t) vol, sloppyv = self.get_vol_sloppyv(self.xs[-1]) self.vols = np.append(self.vols, vol) self.sloppyvs = np.append(self.sloppyvs, [sloppyv], axis=0)
def integrate(self, t, step=False, relax=False): """Find y=y(t), set y as an initial condition, and return y. Args: t (float): The endpoint of the integration step. step (bool): If True, and if the integrator supports the step method, then perform a single integration step and return. This parameter is provided in order to expose internals of the implementation, and should not be changed from its default value in most cases. relax (bool): If True and if the integrator supports the run_relax method, then integrate until t_1 >= t and return. ``relax`` is not referenced if ``step=True``. This parameter is provided in order to expose internals of the implementation, and should not be changed from its default value in most cases. Returns: float: The integrated value at t. """ if t < self.t0: y = array(self.cint(t)) else: y = array(ode.integrate(self, t, step, relax), 'float32') self.cint.append(t, y) return y
def integrate(ode, x, x_init, y_init): """ Integrate the given ordinary differential equation on the given values of x with the initial condition f(x_init) = y_init. Args: ode (ode): ode object from scipy.integrate. Initial conditions should be already set x (float or iterable): integrand values x_init (float): x-value of initial condition y_init (float or iterable): y-value of initial condition Returns: If xValues is a float, returns a float. If xValues is an array, return a numpy array with shape (len(x), len(y_init)). """ try: iter(x) except TypeError: return ode.integrate(x) if x != x_init else y_init else: return np.asarray( [ode.integrate(s) if s != x_init else y_init for s in x])
def compute_viscel_numbers(ns, ts, zarray, params, atol=1e-4, rtol=1e-4, h=1, hmin=0.001, Q=1, scaled=False, logtime=False, comp=True, verbose=False): """ Compute the viscoelastic Love numbers associated with params at times ts. Parameters ---------- ns : order numbers to compute ts : times at which to compute zarray : array of depths (only length used if scaled == True) params : <giapy.earth_tools.earthParams.EarthParams> Object for storing and interpolating the earth's material parameters. atol, rtol : tolerances for Odeint (default 1e-4, 1e-4) h, hmin : initial and minimum step sizes for Odeint (default 1, 0.001) Q : code for gravity flux (see note above, default 1) scaled_time : scales the time dimension into log(t) comp : indicates compressibility (default True) Returns ------- hLkt : array size (len(ns), 4, len(ts)) of love numbers Vertical Displacement, Horizontal Displacement, Geoid, Viscous """ ns = np.atleast_1d(ns) vels = SphericalLoveVelocities(params, zarray, ns[0], comp=comp, scaled=scaled, logtime=logtime) # Initialize viscous Love numbers, vertical and horizontal hvLv0 = np.zeros(2*len(zarray)) hLkt = np.zeros((len(ns), 3, len(ts))) # Save output times for n-dependent lithospheric acceleration. tets = ts.copy() for i, n in enumerate(ns): tau = params.tau*(n+0.5)/params.getLithFilter(n=n) ts = tets/tau # Initialize the difeq matrices for relaxation method vels.updateProps(n=n, z=zarray, reset_b=True) # Initialize the output object for the integration (inds=-1 means we # are looking only at the surface response). extout = SphericalEarthOutput(vels, ts, zs=zarray, inds=-1) ode = Odeint(vels, hvLv0.copy(), ts[0], ts[-1], giapy.numTools.odeintJit.StepperDopr5, atol, rtol, h, hmin, xsave=ts, extout=extout) out = ode.integrate(verbose=verbose) if verbose: print(n, ode.h, (ode.nbad+ode.nok), ode.nbad/(ode.nbad+ode.nok)) # Save the Love numbers for this order number. hLkt[i,0,:] = out.extout.outArray[:,0,0]+out.extout.outArray[:,0,1] hLkt[i,1,:] = out.extout.outArray[:,0,2]+out.extout.outArray[:,0,3] hLkt[i,2,:] = out.extout.outArray[:,0,4] #hLkt[i,3,:] = out.extout.outArray[:,0,1] # Correct n=1 case if ns[0] == 1: hLkt[0,:2,:] += hLkt[0,2,:] hLkt[0,2,:] -= hLkt[0,2,:] return np.squeeze(hLkt)
afstand = r/AU mi, mc, nc, ac = input_mass_distribution(a_min,a_max, a_maxp, n_a, r) nc = np.asarray(nc) sig_d0 = nc * mc K,C = coagulation_kernel(ac, mc, r,'bm_pp_set_az') ode = spi.ode(ndot_coagulation2,jacobian) # BDF method suitable to stiff systems of ODE's atol = 1e0 # absolute error rtol = 1e-6 # relative error with_jacobian = True ode.set_integrator('vode', method='bdf', with_jacobian=with_jacobian, nsteps=5000, atol=atol, rtol=rtol) ode.set_initial_value(nc, t) while ode.successful() and ode.t < tend: nf = ode.integrate(ode.t + tstep) plt.figure(1) plt.loglog() plt.plot(ac*1e2,nf*mc,label="Radial distance: %s AU" %afstand) plt.ylim(1e-19, 1e0) plt.title('Dust distribution, Brownian motion') plt.xlabel('Particle size [cm]') plt.ylabel('Surface density per size bin [$g \cdot cm^{-2}$]') plt.legend(bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0.) plt.show()