Ejemplo n.º 1
0
    def solver(sigma_d, c, x_end, psi_guess=None):

        # Calculated values
        rho_Na_bulk = c * 1000 * N_A  # bulk number density of Na+	(m^-3)
        rho_H_bulk = 10**(-pH) * 1000 * N_A
        rho_Cl_bulk = rho_Na_bulk + rho_H_bulk  # bulk number density of Cl-	(m^-3)
        kappa = np.sqrt(2 * e**2 * (rho_Na_bulk + rho_H_bulk + rho_Cl_bulk) /
                        (eps_0 * eps_bulk * k * T))

        # Poisson-Boltzmann equation system
        def fun(x, psi):
            rho_Na = rho_Na_bulk * np.exp(-z_Na * e * psi[0] / (k * T))
            rho_H = rho_H_bulk * np.exp(-e * psi[0] / (k * T))
            rho_Cl = rho_Cl_bulk * np.exp(-z_Cl * e * psi[0] / (k * T))
            dpsi_dx = psi[1]
            d2psi_dx2 = -e / (eps_0 * eps_bulk) * (z_Na * rho_Na + rho_H +
                                                   z_Cl * rho_Cl)
            return np.vstack((dpsi_dx, d2psi_dx2))

        # Boundary conditions
        def bc(psia, psib):
            return np.array([psia[1] - sigma_d / (eps_0 * eps_bulk), psib[0]])

        size = 50
        x_dist = np.linspace(0, x_end, size)

        if psi_guess is None:
            psi_guess = -sigma_d / (eps_0 * eps_bulk * kappa) * np.exp(
                -kappa * x_dist)
            dpsi_guess = sigma_d / (eps_0 * eps_bulk) * np.exp(-kappa * x_dist)
            psi_guess = np.vstack((psi_guess, dpsi_guess))

        res = solve_bvp(fun, bc, x_dist, psi_guess)
        psi = res.sol(x_dist)[0]
        dpsi = res.sol(x_dist)[1]
        rho_Na = rho_Na_bulk * np.exp(-z_Na * e * psi / (k * T))
        rho_H = rho_H_bulk * np.exp(-e * psi / (k * T))
        rho_Cl = rho_Cl_bulk * np.exp(-z_Cl * e * psi / (k * T))
        x_dist = append_1plate(x_dist, -(x_2 + x_1), -x_2)
        psi_beta = psi_beta_calc(psi[0], sigma_d, C_2)
        sigma_0, sigma_beta, psi_0 = sigma_0_beta_calc_1cation_pH(
            c, pH, K_ads, pKa, L, C_1, C_2, psi_beta)
        psi = append_1plate(psi, psi_0, psi_beta)
        dpsi = append_1plate(dpsi, 0, 0)
        rho_Na = append_1plate(rho_Na, 0, 0)
        rho_H = append_1plate(rho_H, 0, 0)
        rho_Cl = append_1plate(rho_Cl, 0, 0)

        # return np.vstack((x_dist, psi, rho_Na, rho_Cl, dpsi))
        solution = np.vstack((x_dist, psi, rho_Na, rho_H, rho_Cl, dpsi))
        # sigma_0, sigma_beta = sigma_0_beta_calc_1cation_pH(c, pH, K_ads, pKa, L, psi_beta)
        return Solution_1cation_pH(solution, sigma_0, sigma_beta, sigma_d)
Ejemplo n.º 2
0
def bvp_fwd_bwd(f, y0, t0, t1, f_args, adj_y_t1, init_num_nodes=2):
    z_bc = (y0, adj_y_t1, 0.0, zeros_like_tree(f_args))
    z_bc_flat, unravel = ravel_pytree(z_bc)

    def dynamics_one(t, aug, args):
        y, adj_y, _, _ = aug
        ydot, vjpfun = vjp(f, y, t, args)
        return (ydot, *tree_map(jnp.negative, vjpfun(adj_y)))

    def dynamics_one_flat(t, aug, args):
        flat, _ = ravel_pytree(dynamics_one(t, unravel(aug), args))
        return flat

    @jit
    def dynamics_many_flat(ts, augs, args):
        return vmap(dynamics_one_flat, in_axes=(0, 1, None))(ts, augs, args).T

    def bc(aug_t0, aug_t1):
        y_t0_, _, _, _ = aug_t0
        _, adj_y_t1_, adj_t_t1_, adj_args_t1_ = aug_t1
        return tree_multimap(jnp.subtract,
                             (y_t0_, adj_y_t1_, adj_t_t1_, adj_args_t1_), z_bc)

    @jit
    def bc_flat(aug_t0, aug_t1):
        error_flat, _ = ravel_pytree(bc(unravel(aug_t0), unravel(aug_t1)))
        return error_flat

    dynamics_one_jac = jacrev(dynamics_one_flat, argnums=1)

    @jit
    def dynamics_jac(ts, augs, args):
        return jnp.transpose(vmap(dynamics_one_jac,
                                  in_axes=(0, 1, None))(ts, augs, args),
                             axes=(1, 2, 0))

    # If fun_jac isn't provided then the number of nodes blows up, and we reach
    # memory errors, even on a machine with 90G. See the full error for more info:
    # https://gist.github.com/samuela/8c5f6463e08d15c9ffad1f352d1a5513.

    # Adding the bc_jac is super important for numerical stability.
    bvp_soln = solve_bvp(
        lambda ts, augs: dynamics_many_flat(ts, augs, f_args),
        bc_flat,
        jnp.linspace(t0, t1, num=init_num_nodes),
        jnp.array([z_bc_flat] * init_num_nodes).T,
        fun_jac=lambda ts, augs: dynamics_jac(ts, augs, f_args),
        bc_jac=jit(jacrev(bc_flat, argnums=(0, 1))))

    z_t1, _, _, _ = unravel(bvp_soln.y[:, -1])
    _, adj_y_t0, adj_t_t0, adj_args_t0 = unravel(bvp_soln.y[:, 0])
    return z_t1, adj_y_t0, adj_t_t0, adj_args_t0, bvp_soln
Ejemplo n.º 3
0
    def calc_GM(self):
        r"""
    Compute the eddy (Gent & Mcwilliams) transport based on the meridionally
    averaged isopycnal slope.

    .. math::
      \begin{aligned}
      \Psi_{GM} &= K_{GM}\cdot s \\
      s\left(b\right) &\equiv \frac{z_B\left(b\right)}{L_y - y_{SO}\left(b\right)}
      \end{aligned}

    Where :math:`z_B\left(b\right)` is the depth of isopycnals of density class :math:`b`
    in the adjoining basin, and :math:`y_{SO}\left(b\right)` is the outcropping latitude
    of isopycnals of density class :math:`b` in the Southern Ocean, available via
    :meth:`pymoc.modules.Psi_SO.ys`.

    Returns
    -------

    Psi_GM : ndarray
             An array representing the meridional average of the eddy transport at
             each vertical level of the Southern Ocean model.

    """

        dy_atz = 0 * self.z
        eps = 0.1  # minimum dy (in meters) (to avoid div. by 0)
        for ii in range(0, np.size(self.z)):
            dy_atz[ii] = max(self.y[-1] - self.ys(self.b(self.z[ii])), eps)
        bottaper = self.calc_bottom_taper(self.Htaperbot, self.z)
        toptaper = self.calc_top_taper(self.Htapertop, self.z)
        if self.c is not None:
            temp = make_func(
                self.KGM * self.z / dy_atz * self.L * toptaper * bottaper,
                self.z, 'psiGM')
            N2 = self.calc_N2()

            def ode(z, y):
                return np.vstack((y[1], N2(z) / self.c**2. * (y[0] - temp(z))))

            #Solve the boundary value problem
            res = integrate.solve_bvp(ode, self.bc_GM, self.z,
                                      np.zeros((2, np.size(self.z))))
            # return solution interpolated onto original grid
            temp = res.sol(self.z)[0, :]
        else:
            temp = self.KGM * np.maximum(
                self.z / dy_atz, -self.smax) * self.L * toptaper * bottaper
        # limit Psi_GM to -Psi_Ek on isopycnals that don't outcrop:
        idx = dy_atz > self.y[-1] - self.y[0]
        temp[idx] = np.maximum(temp[idx], -self.Psi_Ek[idx] * 1e6)
        return temp
Ejemplo n.º 4
0
    def compute(self, x, initial = None, p_guess = None,  type = None):
        """
        MAIN COMPUTE CALL
        type == None calls extra parameter function
        type == 'c' or 'a' calls normal function
        """
        if initial is None:
            initial = self.init(x)
        if p_guess is None:
            p_guess = np.array([1])
    
        if type == None:
            sol = solve_bvp(self.fun, self.bc, x,  initial, p = p_guess, tol = 1e-5, max_nodes = 10000, verbose = 1)
            print(sol.success, sol.status)
        elif type == 'new_fun':
            sol = solve_bvp(self.new_fun, self.bc_new_fun, x,  initial, p =p_guess, max_nodes = 100000, verbose = 1, tol = 1e-5)
            print(sol.success, sol.status)
        else:
            sol = solve_bvp(self.fun_no_f, self.bc_no_f, x,  initial, max_nodes = 10000, verbose = 1, tol = 1e-5)
            print(sol.success, sol.status)

        return sol
Ejemplo n.º 5
0
Archivo: demo7.py Proyecto: pkgw/vernon
def bvp():
    from scipy.integrate import solve_bvp

    def fun(x, y):
        return np.vstack((y[1], -0.25 * np.pi**2 * y[0]))

    def bc(ya, yb):
        return np.array([ya[0] - 1, yb[0]])

    x = np.linspace(0, 1, 64)
    y0 = np.vstack([-0.1 * np.ones(64), np.zeros(64)])
    soln = solve_bvp(fun, bc, x, y0)
    return x, soln['y'][0]
Ejemplo n.º 6
0
 def send_it(self,TL,nA,nB,tA,tB):
     """Solves boundary value problem between starshade star alignments
     
     This method solves the boundary value problem for starshade star alignments
     with two given stars at times tA and tB. It uses scipy's solve_bvp method.
     
     Args:
         TL (float 1x3 ndarray):
             TargetList class object
         nA (integer):
             Integer index of the current star of interest
         nB (integer):
             Integer index of the next star of interest
         tA (astropy Time array):
             Current absolute mission time in MJD
         tB (astropy Time array):
             Absolute mission time for next star alignment in MJD
             
     Returns:
         float nx6 ndarray:
             State vectors in rotating frame in normalized units
     """
     
     angle,uA,uB,r_tscp = self.lookVectors(TL,nA,nB,tA,tB)
     
     vA = self.haloVelocity(tA)[0].value/(2*np.pi)
     vB = self.haloVelocity(tB)[0].value/(2*np.pi)
     
     #position vector of occulter in heliocentric frame
     self.rA = uA*self.occulterSep.to('au').value + r_tscp[ 0]
     self.rB = uB*self.occulterSep.to('au').value + r_tscp[-1]
     
     a = ((np.mod(tA.value,self.equinox[0].value)*u.d)).to('yr').value * (2*np.pi)
     b = ((np.mod(tB.value,self.equinox[0].value)*u.d)).to('yr').value * (2*np.pi)
     
     #running shooting algorithm
     t = np.linspace(a,b,2)
     
     sG = np.array([  [ self.rA[0],self.rB[0] ], \
                      [ self.rA[1],self.rB[1] ], \
                      [ self.rA[2],self.rB[2] ], \
                      [      vA[0],     vB[0] ], \
                      [      vA[1],     vB[1] ], \
                      [      vA[2],     vB[2] ] ])            
         
     sol = solve_bvp(self.equationsOfMotion_CRTBP,self.boundary_conditions,t,sG,tol=1e-10)
     
     s = sol.y.T
     t_s = sol.x
         
     return s,t_s
Ejemplo n.º 7
0
 def send_it(self,TL,nA,nB,tA,tB):
     """Solves boundary value problem between starshade star alignments
     
     This method solves the boundary value problem for starshade star alignments
     with two given stars at times tA and tB. It uses scipy's solve_bvp method.
     
     Args:
         TL (float 1x3 ndarray):
             TargetList class object
         nA (integer):
             Integer index of the current star of interest
         nB (integer):
             Integer index of the next star of interest
         tA (astropy Time array):
             Current absolute mission time in MJD
         tB (astropy Time array):
             Absolute mission time for next star alignment in MJD
             
     Returns:
         s (float nx6 ndarray):
             State vectors in rotating frame in normalized units
     """
     
     angle,uA,uB,r_tscp = self.lookVectors(TL,nA,nB,tA,tB)
     
     vA = self.haloVelocity(tA)[0].value/(2*np.pi)
     vB = self.haloVelocity(tB)[0].value/(2*np.pi)
     
     #position vector of occulter in heliocentric frame
     self.rA = uA*self.occulterSep.to('au').value + r_tscp[ 0]
     self.rB = uB*self.occulterSep.to('au').value + r_tscp[-1]
     
     a = ((np.mod(tA.value,self.equinox.value)*u.d)).to('yr') / u.yr * (2*np.pi)
     b = ((np.mod(tB.value,self.equinox.value)*u.d)).to('yr') / u.yr * (2*np.pi)
     
     #running shooting algorithm
     t = np.linspace(a,b,2)
     
     sG = np.array([  [ self.rA[0],self.rB[0] ], \
                      [ self.rA[1],self.rB[1] ], \
                      [ self.rA[2],self.rB[2] ], \
                      [      vA[0],     vB[0] ], \
                      [      vA[1],     vB[1] ], \
                      [      vA[2],     vB[2] ] ])            
         
     sol = solve_bvp(self.equationsOfMotion_CRTBP,self.boundary_conditions,t,sG,tol=1e-10)
     
     s = sol.y.T
     t_s = sol.x
         
     return s,t_s
Ejemplo n.º 8
0
    def solve(self, phi, C0=0.2):
        '''
        Solve for the function roots to get the C(0) values
        '''
        self.phi = phi
        sol = solve_bvp(lambda x,y,y0: self.ode(x, y, y0, phi), \
                        self.bc, self.xinit, self.yinit, p=[C0], \
                        tol=1e-5, bc_tol=1e-5, max_nodes=1e5,verbose=0)

        if sol.success:
            return sol
        else:
            print('error: solving bvp failed!')
            return sol
Ejemplo n.º 9
0
def biomass(): # Something wrong?
    gammavary = linspace(0,15,100)
    b = []
    x_mesh = linspace(-el/2,el/2,n_mesh) 
    y_solver = zeros((4,x_mesh.size)) 
    y_solver[0] = 0.5 
    y_solver[3] = -0.4
    for gamma in gammavary:
        sol = solve_bvp(lambda x,y: function_i(x,y,gamma = gamma),
                lambda ya, yb: bc_i(ya,yb, gamma = gamma),x_mesh,y_solver)
        y = sol.sol(x) 
        u = y[0]
        b.append(dx*sum(u))
    return array(b)
Ejemplo n.º 10
0
    def solver(sigma_d, c, psi_guess=False):

        # Calculated values
        rho_Na_bulk = c * 1000 * N_A  # bulk number density of Na+	(m^-3)
        rho_Cl_bulk = c * 1000 * N_A  # bulk number density of Cl-	(m^-3)
        kappa = np.sqrt(2 * e**2 * rho_Na_bulk / (eps_0 * eps_bulk * k * T))

        # Poisson-Boltzmann equation system
        def fun(x, psi):
            rho_Na = rho_Na_bulk * np.exp(-z_Na * e * psi[0] / (k * T))
            rho_Cl = rho_Cl_bulk * np.exp(-z_Cl * e * psi[0] / (k * T))
            dpsi_dx = psi[1]
            d2psi_dx2 = -e / (eps_0 * eps_bulk) * (z_Na * rho_Na +
                                                   z_Cl * rho_Cl)
            return np.vstack((dpsi_dx, d2psi_dx2))

        # Boundary conditions
        def bc(psia, psib):
            return np.array(
                [psia[1] - sigma_d / (eps_0 * eps_bulk), psib[1] + psia[1]])

        size = 50
        x_dist = np.linspace(0, D, size)
        if type(psi_guess) == bool:
            psi_guess = -sigma_d / (eps_0 * eps_bulk * kappa) * np.exp(
                -kappa * x_dist[0:size // 2])
            psi_guess = np.concatenate((psi_guess, list(reversed(psi_guess))))
            dpsi_guess = sigma_d / (eps_0 * eps_bulk) * np.exp(
                -kappa * x_dist[0:size // 2])
            dpsi_guess = np.concatenate(
                (dpsi_guess, list(reversed(dpsi_guess))))
            psi_guess = np.vstack((psi_guess, dpsi_guess))

        res = solve_bvp(fun, bc, x_dist, psi_guess)
        psi = res.sol(x_dist)[0]
        dpsi = res.sol(x_dist)[1]
        rho_Na = rho_Na_bulk * np.exp(-z_Na * e * psi / (k * T))
        rho_Cl = rho_Cl_bulk * np.exp(-z_Cl * e * psi / (k * T))
        x_dist = append_2plate(x_dist, -(x_2 + x_1), -x_2, True)
        psi_beta = psi_beta_calc(psi[0], sigma_d, C_2)
        psi_0 = psi_0_calc(psi_beta, sigma_0, C_1)
        psi = append_2plate(psi, psi_0, psi_beta)
        dpsi = append_2plate(dpsi, 0, 0)
        rho_Na = append_2plate(rho_Na, 0, 0)
        rho_Cl = append_2plate(rho_Cl, 0, 0)

        # return np.vstack((x_dist, psi, rho_Na, rho_Cl, dpsi))
        solution = np.vstack((x_dist, psi, rho_Na, rho_Cl, dpsi))
        sigma_beta = sigma_beta_calc_1cation(c, K_ads, L, psi_beta)
        return Solution_1cation(solution, sigma_0, sigma_beta, sigma_d)
Ejemplo n.º 11
0
    def compute_solution(self):
        """
        :return: vertical velocity profile
        """

        # initial guess for v and v derivatives
        v_init = np.zeros((2, self.x.size))

        # Compute the result
        res = solve_bvp(self.ode, self.bc, self.x, v_init)

        # Get the vertical velocity out of the result
        v_analytic = res.sol(self.x)[0]
        return v_analytic
Ejemplo n.º 12
0
def getTFScreeningFunction():

  y1 = getgradphi0('numeric','data/phi0_NACI_format_mod.txt')
  y0 = getphi0('numeric','data/phi0_NACI_format_mod.txt')
  y1v = np.vectorize(y0)
  y0v = np.vectorize(y1)
  yguess = np.stack((np.asarray(y0(xmesh),dtype=np.float64),np.asarray(y1(xmesh),dtype=np.float64)),axis=0)

  a = integrate.solve_bvp(TFdiffeqsys,TFbc,xmesh,yguess,max_nodes=5000000,verbose=1)
  print(a.status)
  print(a.success)


  return a.sol
Ejemplo n.º 13
0
def ode_fit(ta, tb):
    """
    Fit s(t), i(t) from day ta to tb
    """
    global sa, sb, ia, ib
    sa = si[0, ta]
    sb = si[0, tb]
    ia = si[1, ta]
    ib = si[1, tb]

    prd = tb - ta + 1
    y0 = si[:, ta:tb + 1]
    t = np.arange(prd)
    sol = solve_bvp(fun, bc, t, y0, p=[0.1], tol=1e-10)
    return sol
Ejemplo n.º 14
0
 def moving_wall_calc(y_vals,Eh):
     R=np.abs(Eh)*Re_0
     RHS_fun = lambda x,y: np.array([y[1],y[2],y[3],-R*(y[0]*y[3]-y[1]*y[2])])
     bc = lambda ya,yb: np.array([yb[0],yb[2],ya[0],1-ya[1]])
     # y_vals=np.linspace(0,1,100)
     f1_init=y_vals
     f2_init=np.exp(y_vals)
     f3_init=np.exp(y_vals)
     f4_init=np.exp(y_vals)
     finit = np.column_stack((f1_init,f2_init,f3_init,f4_init))
     
     
     sol = solve_bvp(RHS_fun,bc,y_vals,finit.T)
     f = sol.sol(y_vals)
     return f
Ejemplo n.º 15
0
def y2_value_at_rD(rD):
    def dydr(r, y):
        return np.vstack(
            (y[1], -y[1] / r + k * y[0] * F / (DG * (k * y[0] + 1 / tau))))

    def y_bc(ya, yb):
        return np.array([ya[0] - y1a, yb[0]])

    rmesh = np.linspace(rD, rb - (rDi - rD), rdivs)
    y_guess = np.zeros((2, rmesh.size))
    return solve_bvp(dydr,
                     y_bc,
                     rmesh,
                     y_guess,
                     tol=tolerance,
                     max_nodes=max_mesh_nodes).sol(rD)[1]
Ejemplo n.º 16
0
    def calculate_stimulated_raman_scattering(self, carriers, raman_pumps):
        """ Returns stimulated Raman scattering solution including
        fiber gain/loss profile.
        :return: None
        """
        # fiber parameters
        fiber_length = self.fiber.params.length
        raman_efficiency = self.fiber.params.raman_efficiency
        simulation = Simulation.get_simulation()
        sim_params = simulation.sim_params

        if not sim_params.raman_params.flag_raman:
            raman_efficiency['cr'] = zeros(len(raman_efficiency['cr']))
        # raman solver parameters
        z_resolution = sim_params.raman_params.space_resolution
        tolerance = sim_params.raman_params.tolerance

        logger.debug('Start computing fiber Stimulated Raman Scattering')

        power_spectrum, freq_array, prop_direct, _ = self._compute_power_spectrum(carriers, raman_pumps)

        alphap_fiber = self.fiber.alpha(freq_array)

        freq_diff = abs(freq_array - reshape(freq_array, (len(freq_array), 1)))
        interp_cr = interp1d(raman_efficiency['frequency_offset'], raman_efficiency['cr'])
        cr = interp_cr(freq_diff)

        # z propagation axis
        z = arange(0, fiber_length + 1, z_resolution)

        def ode_function(z, p):
            return self._ode_stimulated_raman(z, p, alphap_fiber, freq_array, cr, prop_direct)

        def boundary_residual(ya, yb):
            return self._residuals_stimulated_raman(ya, yb, power_spectrum, prop_direct)

        initial_guess_conditions = self._initial_guess_stimulated_raman(z, power_spectrum, alphap_fiber, prop_direct)

        # ODE SOLVER
        bvp_solution = solve_bvp(ode_function, boundary_residual, z, initial_guess_conditions, tol=tolerance)

        rho = (bvp_solution.y.transpose() / power_spectrum).transpose()
        rho = sqrt(rho)    # From power attenuation to field attenuation
        stimulated_raman_scattering = StimulatedRamanScattering(freq_array, bvp_solution.x, rho, bvp_solution.y)

        self._stimulated_raman_scattering = stimulated_raman_scattering
Ejemplo n.º 17
0
def y2_value_at_rD(rD):
    def dydr(r, y):
        return np.vstack(
            (y[1], -y[1] / r + k * y[0] * y[2] / DG, y[3],
             -y[3] / r + k * y[0] * y[2] / DA - F / DA + y[2] / (DA * tau)))

    def y_bc(ya, yb):
        return np.array([ya[0] - y1a, yb[0], ya[2] - y3a, yb[2] - F * tau])

    rmesh = np.linspace(rD, rb - (rDi - rD), rdivs)
    y_guess = np.zeros((4, rmesh.size))
    return solve_bvp(dydr,
                     y_bc,
                     rmesh,
                     y_guess,
                     tol=tolerance,
                     max_nodes=max_mesh_nodes).sol(rD)[1]
def get_J_sc_diffusion_vs_WL(xa, xb, g, D, L, y0, S, wl, ph, side='top'):
    zz = np.linspace(
        xa, xb, 1001, endpoint=False
    )  # excluding the last point - depending on the mesh/floating point errors, sometimes this is actually in the next layer
    gg = g(zz) * ph
    out = np.zeros_like(wl)

    for i in range(len(wl)):

        if np.all(
                gg[:, i] == 0
        ):  # no reason to solve anything if no generation at this wavelength
            out[i] = 0

        else:
            A = lambda x: np.interp(x, zz, gg[:, i]) / D + y0 / L**2

            def fun(x, y):
                out1 = y[1]
                out2 = y[0] / L**2 - A(x)
                return np.vstack((out1, out2))

            if side == 'top':

                def bc(ya, yb):
                    left = ya[1] - S / D * (ya[0] - y0)
                    right = yb[0]
                    return np.array([left, right])
            else:

                def bc(ya, yb):
                    left = ya[0]
                    right = yb[1] - S / D * (yb[0] - y0)
                    return np.array([left, right])

            guess = y0 * np.ones((2, zz.size))
            guess[1] = np.zeros_like(guess[0])
            solution = solve_bvp(fun, bc, zz, guess)

            if side == 'top':
                out[i] = solution.y[1][-1]
            else:
                out[i] = solution.y[1][0]

    return out
Ejemplo n.º 19
0
def Append_solution(rD):
    def dydr(r, y):
        return np.vstack(
            (y[1], -y[1] / r + k * y[0] * F / (DG * (k * y[0] + 1 / tau))))

    def y_bc(ya, yb):
        return np.array([ya[0] - y1a, yb[0]])

    rmesh = np.linspace(rD, rb - (rDi - rD), rdivs)
    y_guess = np.zeros((2, rmesh.size))
    calc_y_vs_r_at_t = solve_bvp(dydr,
                                 y_bc,
                                 rmesh,
                                 y_guess,
                                 tol=tolerance,
                                 max_nodes=max_mesh_nodes).sol
    y_vs_r_at_all_t.append(calc_y_vs_r_at_t)
    return None
Ejemplo n.º 20
0
    def no_bc_bvp(Func, r0):
        def bc(ya, yb):

            #return np.array([ya[1]-(lamH*ya[0]*(ya[0]**2-H**2)), yb[1]-(lamH*yb[0]*(yb[0]**2-V**2))])
            return np.array([ya[0] - H, yb[0] - V])

        xs = np.linspace(0, r0, round((2**10) * r0 * r0))
        y_a = np.zeros((2, xs.size))
        y_a[1] = -0.01396517
        y_b = np.zeros((2, xs.size))

        #xs2 = np.linspace(0, r0, (2**12)*r0)

        res_a = solve_bvp(Func, bc, xs, y_a, tol=1e-9)
        y0 = res_a.sol(xs)[0]
        d0 = res_a.sol(xs)[1]

        return ([xs, y0], [xs, d0])
Ejemplo n.º 21
0
        def path(t):
            """Generate parameterized function for geodesic curve.

            Parameters
            ----------
            t : array-like, shape=[n_times,]
                Times at which to compute points of the geodesics.

            Returns
            -------
            geodesic : array-like, shape=[..., n_times, dim]
                Values of the geodesic at times t.
            """
            t = gs.to_ndarray(t, to_ndim=1)
            geod = []

            def initialize(point_0, point_1):
                """Initialize the solution of the boundary value problem."""
                lin_init = gs.zeros([2 * self.dim, n_steps])
                lin_init[:self.dim, :] = gs.transpose(
                    gs.linspace(point_0, point_1, n_steps))
                lin_init[self.dim:, :-1] = n_steps * (lin_init[:self.dim, 1:] -
                                                      lin_init[:self.dim, :-1])
                lin_init[self.dim:, -1] = lin_init[self.dim:, -2]
                return lin_init

            t_int = gs.linspace(0.0, 1.0, n_steps)
            fun_jac = jac if jacobian else None

            for ip, ep in zip(initial_point, end_point):

                def bc(y0, y1, ip=ip, ep=ep):
                    return boundary_cond(y0, y1, ip, ep)

                solution = solve_bvp(bvp,
                                     bc,
                                     t_int,
                                     initialize(ip, ep),
                                     fun_jac=fun_jac)
                solution_at_t = solution.sol(t)
                geodesic = solution_at_t[:self.dim, :]
                geod.append(gs.squeeze(gs.transpose(geodesic)))

            return geod[0] if len(initial_point) == 1 else gs.stack(geod)
def diff_sol_bvp(f, bc, t0, tf, y0, yf):

    # initial mesh points
    x = np.linspace(t0, tf, 5)

    # initially choosen y'(t) in the y[1] array
    # and initial guess of y in the y[0]
    y = np.zeros((2, x.size)) + 1

    sol_bvp = solve_bvp(f, bc, x, y)

    x_plot = np.linspace(t0, tf, 100)
    y_plot = sol_bvp.sol(x_plot)[0]

    plt.plot(x_plot, y_plot, label='numerical solution')
    plt.legend()
    plt.xlabel("t", fontsize=13)
    plt.ylabel("y(t)", fontsize=13)
    plt.show()
Ejemplo n.º 23
0
def Append_y1y3_vs_r_at_t(rD):
    def dydr(r, y):
        return np.vstack(
            (y[1], -y[1] / r + k * y[0] * y[2] / DG, y[3],
             -y[3] / r + k * y[0] * y[2] / DA - F / DA + y[2] / (DA * tau)))

    def y_bc(ya, yb):
        return np.array([ya[0] - y1a, yb[0], ya[2] - y3a, yb[2] - F * tau])

    rmesh = np.linspace(rD, rb - (rDi - rD), rdivs)
    y_guess = np.zeros((4, rmesh.size))
    calc_y_vs_r_at_t = solve_bvp(dydr,
                                 y_bc,
                                 rmesh,
                                 y_guess,
                                 tol=tolerance,
                                 max_nodes=max_mesh_nodes).sol
    y_vs_r_at_all_t.append(calc_y_vs_r_at_t)
    return None
Ejemplo n.º 24
0
def tpbvp_hjb_solve_time_march(aug_dynamics: callable, bc: callable, x,
                               time_marchs, initial_tol, tol, max_nodes):
    """
    :param max_nodes: maximal number of mesh nodes
    :param bc: boundary condition
    :param x: initial guess, shape N,1
    :param aug_dynamics: the dynamics
    :param tol: tolerence in the whole BVP
    :param time_marchs: should be increasing sequence of real number; time_marchs[0,-1] = t0, T
    :param initial_tol: initial tolerance in solving one stage bvp, we half it every stage until it reach tol
    :return:
    """
    t = np.array([time_marchs[0]])
    x_guess = x.reshape(-1, 1)
    tolerance = initial_tol
    status = True
    for k in range(time_marchs.shape[0] - 1):
        if tolerance >= 2 * tol:
            tolerance /= 2.
        if k == time_marchs.shape[0] - 2:
            tolerance = tol

        t = np.concatenate((t, time_marchs[k + 1:k + 2]))
        x_guess = np.hstack(
            (x_guess, x_guess[:, -1:]))  # use current value to be next guess

        SOL = solve_bvp(aug_dynamics,
                        bc,
                        t,
                        x_guess,
                        tol=tolerance,
                        max_nodes=max_nodes,
                        verbose=0)
        if not SOL.success:
            status = False
            print(SOL.message)
            break
        t = SOL.x
        x_guess = SOL.y

    return status, t, x_guess
Ejemplo n.º 25
0
def ks_profile(s,p):
        # bvp solver for KS periodic profile equation. Here p is a structure
        # containing the parameters X=period, q=integration constant,
        # beta = parameter, epsilon = parameter, detla=paramter.
        # The parameter beta is treated as a free variable.
        # The structure s either contains a matlab ode/bvp solution structure,
        # s.sol which provides an initial guess for the bvp solver, or if it does
        # not, then an initial guess is provided which corresponds to q=6,
        # epsilon=0.2, X=6.3.

        # change defalut tolerance settings if not specified.
        if 'options' not in s:
                s.options = Struct()
                s.options.AbsTol = 10**(-6)
                s.options.RelTol = 10**(-8)

        # check if an initial guess is provided.
        if 'sol' not in s:
                #ld=load('profile_starter');
                #s.sol=ld.s.sol
                pass

        # define an anomynuous function to allow the passing of the parameter p
        # without using a global variable.
        ode = lambda x,y,delta: (periodic_ode(x,y,delta,p));

        # define anonymous functions to avoid global variables
        guess = lambda x: (interpolate(x,s.sol))

        #Define the default guess function if none is loaded.
        initialGuessFunction = lambda x: np.array([np.sin(2*np.pi/p.X*x),np.cos(2*np.pi/p.X*x)*2*np.pi/p.X,-np.sin(2*np.pi/p.X*x)*4*np.pi**2/p.X**2])

        #Create the initial space and the initial guess.
        initSpace = np.linspace(0,p.X,83)
        initialGuess = initialGuessFunction(initSpace)
        initialGuess = ks_guess() #loads from the file the guess.

        #Solve the bvp with the initial guess and return the solutions.
        sol = solve_bvp(ode,bc,initSpace,initialGuess,p=[p.delta])
        delta = sol.p
        return sol, delta
def get_bound_ions(b2_pair, mg_conc, na_conc, r, z_d = -24, reff = 1.9):

    dr               = r[1] - r[0]
    fourpirsq        = 4*np.pi*np.power(r, 2)
    idx_reff         = np.abs(r - reff).argmin()
    idx_int_limit    = np.abs(r - (reff + 0.2)).argmin()
    den_s            = 3*z_d/(4*np.pi*reff**3)
    cl_conc          = 2*mg_conc + na_conc
    b2_mg, b2_na     = b2_pair[0], b2_pair[1]

    res = integrate.solve_bvp(poisson_boltzmann_b2, bc, r, initial_y)
    phi = res.sol(r)[0]

    rho_mg, rho_na = rho(r, +2, mg_conc, phi, b2_mg)/2, rho(r, +1, na_conc, phi, b2_na)

    local_mg, local_na = rho_mg*fourpirsq, rho_na*fourpirsq

    cum_mg = [integrate.trapz(local_mg[0:i], r[0:i], dx = dr) for i in range(idx_int_limit)]
    cum_na = [integrate.trapz(local_na[0:i], r[0:i], dx = dr) for i in range(idx_int_limit)]

    return np.array([cum_mg[idx_reff], cum_na[idx_reff]])
Ejemplo n.º 27
0
def tpbvp_hjb_solve_warm_start(dynamics: callable, eval_U: callable, x, t,
                               ode_solver, bvp_guess, aug_dynamics: callable,
                               bc: callable, tol, max_nodes):
    SOL = solve_ivp(dynamics,
                    t,
                    x,
                    method=ode_solver,
                    args=(eval_U, ),
                    rtol=1e-4)
    # compute V and dV/dx at several points along (SOL.t, SOL.y). There might be more than that in t.
    V_guess, A_guess = bvp_guess(SOL.t.reshape(1, -1), SOL.y)
    X_aug_guess = np.vstack((SOL.y, A_guess, V_guess))
    SOL = solve_bvp(aug_dynamics,
                    bc,
                    SOL.t,
                    X_aug_guess,
                    verbose=0,
                    tol=tol,
                    max_nodes=max_nodes)

    return SOL.success, SOL.x, SOL.y
Ejemplo n.º 28
0
def bvp_geodesic(manifold, p0, p1):
    """
    Compute the geodesic connecting two points by solving the associated
    boundary value problem using the SciPy 'solve_bvp' function.

    Inputs:
        manifold:   the manifold over which the geodesic will be computed.
                    This object should provide a 'geodesic_system' function,
                    and should be compatible with the GeodesicODE class.
        p0:         a torch Tensor representing the starting point of the
                    requested geodesic.
        p1:         a torch Tensor representing the ending point of the
                    requested geodesic.

    Output:
        retval:     an object returned by 'solve_bvp' representing the solution
                    curve.
    """
    odefunc_obj = GeodesicODE(manifold)
    odefunc = lambda t, x: odefunc_obj.f_numpy(t, x)
    p0np = p0.numpy().reshape(-1, 1)
    p1np = p1.numpy().reshape(-1, 1)
    dim = p0np.shape[0]

    def bc(ya, yb):
        retval = np.zeros(2*dim)
        retval[:dim] = ya[:dim] - p0np.flatten()
        retval[dim:] = yb[:dim] - p1np.flatten()
        return retval

    T = 30 # initial number of grid points
    t_init = np.linspace(0, 1, T, dtype=np.float32).reshape(1, T)
    line_init = np.outer(p0np, (1.0 - t_init)) + np.outer(p1np, t_init) # (dim)xT
    deriv_init = (p1np - p0np).reshape((dim, 1)).repeat(T, axis=1) # (dim)xT
    x_init = np.concatenate((line_init, deriv_init), axis=0) # (2dim)xT

    from scipy.integrate import solve_bvp
    retval = solve_bvp(odefunc, bc, t_init.flatten(), x_init)

    return retval
def iterateGamma(g_list,
                 f,
                 alpha,
                 t_range,
                 color_list=['r', 'g', 'b', 'm', 'k', 'c'],
                 save='no'):

    t = np.linspace(t_range[0], t_range[1], t_range[2])
    ystart = np.zeros((2, t.size))

    r_t_list = []

    for i, g in enumerate(g_list):
        result = solve_bvp(lambda t, y: diff_y(t, y, alpha=alpha, f=f, g=g),
                           lambda y0, y1: bc(y0, y1, alpha=alpha, f=f, g=g), t,
                           ystart)

        lambd_t = np.array(result.y[0])
        phi_t = np.array(result.y[1])
        r_t = np.divide(np.multiply(lambd_t, np.subtract(phi_t, 1)),
                        (2 * alpha))
        r_t_list.append(r_t)
        plt.plot(t, r_t, label='gamma = ' + str(g), color=color_list[i])

        if save != 'no':
            np.savetxt('Data/Quadratic/' + save + '_' + str(g) + '_gamma.csv',
                       r_t,
                       delimiter=",")

    #plt.legend(loc='best')
    plt.xlabel('Time, $t$', fontsize=18)
    plt.ylabel('Repair rate, $r(t)$', fontsize=18)
    plt.xticks(fontsize=12)
    plt.yticks(fontsize=12)
    plt.tight_layout()
    plt.xlim(0, 101)
    plt.legend(loc='best')
    if save != 'no':
        plt.savefig('Figures/Quadratic/' + save + '_gamma.png', dpi=800)
    plt.show()
Ejemplo n.º 30
0
def solve(x0, xf, alpha, guess=None):

    # initialise dynamics
    dyn = dynamics(x0, xf, alpha)

    # time and state guess
    t, s = dyn.linear_guess(1, 50) if guess is None else guess

    # duration
    p = [1.]

    # solve tpbvp
    res = solve_bvp(dyn.fun,
                    dyn.bc,
                    t,
                    s,
                    p,
                    tol=1e-10,
                    verbose=2,
                    max_nodes=10000)

    return res
Ejemplo n.º 31
0
    def solve_equi(self, wA):
        r"""
    Solve for the equilibrium buoyancy profile, given a specified vertical
    velocity profile, and pre-set surface and bottom boundary conditions, based
    on the system of equations defined by :meth:`pymoc.modules.Column.ode`.

    Parameters
    ----------

    wA : ndarray
         Area integrated velocity profile for the equilibrium solution. Units: m\ :sup:`3`/s

    """

        self.wA = make_func(wA, self.z, 'w')
        sol_init = np.zeros((2, np.size(self.z)))
        sol_init[0, :] = self.b
        sol_init[1, :] = self.bz
        res = integrate.solve_bvp(self.ode, self.bc, self.z, sol_init)
        # interpolate solution for b and db/dz onto original grid
        self.b = res.sol(self.z)[0, :]
        self.bz = res.sol(self.z)[1, :]
    def fun(x, y):
        res = []
        for i in range(0, y.shape[1]):
            res.append(np.hstack((dXdPsi(y[2:4,i], V0), dFdX(x[i], y[0:2,i], kappa))))
        return np.transpose(np.vstack(res))

    def bc(ya, yb):
        return np.array([ya[0] - X0[0], ya[1] - X0[1], yb[2] + kT * (yb[0] - XT[0]), yb[3] + kT * (yb[1] - XT[1])])



    y = np.vstack((np.transpose(X), np.transpose(Psi))) #np.zeros((2, t.size)))) #np.ones((4, t.size))

    t = np.arange(0,1 + 1e-10,h / T)

    res = spi.solve_bvp(fun, bc, t, y, verbose=1)
    print(res.status, res.message, res.success)

    #print(res.sol(t))
    #print(t)
    #print(res.x)


    fig = plt.figure(num=None, figsize=(12, 6), dpi=300)
    gs = GridSpec(4, 3)

    ax1 = fig.add_subplot(gs[0:3, 0:3])
    ax2 = fig.add_subplot(gs[3, 0])
    ax3 = fig.add_subplot(gs[3, 1])
    ax4 = fig.add_subplot(gs[3, 2])
    
Ejemplo n.º 33
0
def kernel(ell, nu, eig, fgong):
    """Returns a dict of structural kernels.  I have tried to make this as
    notationally similar to Gough & Thompson (1991) as possible.

    Parameters
    ----------
    ell: int
        The angular degree of the mode.
    nu: float
        The cyclic frequency of the mode.
    eig: np.array, shape(N,7)
        Eigenfrequency data for the mode, as produced by ADIPLS.
    fgong: dict
        Stellar model data in a dictionary, as per load_fgong()
        above.

    Returns
    -------
    kernel: np.array, length N
        The density or sound speed structure kernel.
    """
    omega = 2.*np.pi*nu                      # convert to cyclic frequency
    G = 6.672e-8                             # gravitational constant
    L2 = ell*(ell+1)
    L = np.sqrt(L2)
    M, R = fgong['glob'][:2]                 # mass and radius from FGONG
    sigma = np.sqrt(R**3/G/M)*omega          # dimensionless frequency

    ## unpack fgong file (c.f. page 6 section 2.1.3 of above doc)
    r = fgong['var'][::-1,0]                 # radial co-ordinate
    m = M*np.exp(fgong['var'][::-1,1])       # mass co-ordinate
    P = fgong['var'][::-1,3]                 # pressure
    rho = fgong['var'][::-1,4]               # density
    Gamma1 = fgong['var'][::-1,9]            # first adiabatic index
    cs2 = Gamma1*P/rho                       # square of the sound speed
    Y = 1 - fgong['var'][::-1,5] - fgong['var'][::-1,16] # helium abundance
    
    # Gamma_1,Y = ( partial ln Gamma_1 / partial ln Y ) _ {P, rho} etc
    Gamma_1rho = fgong['var'][::-1,25]
    Gamma_1p = fgong['var'][::-1,26]
    Gamma_1Y = fgong['var'][::-1,27]
    
    ## equilibrium model (c.f. ADIPLS - The Aarhus adi. osc. pack., section 2.1)
    A = fgong['var'][::-1,14] # 1/Gamma_1 (dln p / dln r) - (dln rho / dln r)
    A1 = (m/M)/(r/R)**3                      # fractional volume
    Vg = (G*m*rho)/(Gamma1*P*r)
    drho_dr = -(Vg+A)*rho/r                  # density gradient
    
    ## unpack eigenfunction (c.f. page 7 of Notes on adi. osc. prog.)
    x = eig[:,0]                             # dimensionless radius (i.e. r/R)
    y1 = eig[:,1]                            # xi_r / R
    y2 = eig[:,2]                            # l(l+1)/R * xi_h
    y3 = eig[:,3]                            # -x * Phi' / (g * r)
  # y4 = eig[:,4]                            # x^2 * d/dx (y_3 / x)
    
    xi_r = y1*R                              # radial component of eigenfunction
    
    dxi_r_dr = np.hstack((0., np.diff(xi_r)/np.diff(r)))
    
    # chi is the "dilatation"
    if ell == 0:
        xi_h = 0.*xi_r 
      # eta = G*m/r**3/omega**2
        chi = Vg/x*(y1-sigma**2/A1/x*y2)
    elif ell > 0:
        xi_h = y2*R/L2
      # eta = L2*G*m/r**3/omega**2
        chi = Vg/x*(y1-y2*sigma**2/(A1*L2)-y3)
    else:
        raise ValueError('ell must be non-negative')
    
    # most stellar models include the central point, at which the
    # numerical value of chi and drho_dr might be buggy.
    chi[0] = 0.
    drho_dr[0] = 0.
    
    S = np.trapz((xi_r**2+L2*xi_h**2)*rho*r**2, r)
    
    
    ### Calculate c, rho pair
    # c.f. Gough & Thompson 1991 equation (60)
    K_c_rho = rho*cs2*chi**2*r**2 / (S*omega**2)
    
    # first compute the huge bracketed terms 
    # in last two lines of equation (61) 
    K_rho_c = (ell+1.)/r**ell*(xi_r-ell*xi_h) \
        *integrate((rho*chi+xi_r*drho_dr)*r**(ell+2.), r) \
        - ell*r**(ell+1.)*(xi_r+(ell+1.)*xi_h) \
        *complement((rho*chi+xi_r*drho_dr)*r**(1.-ell), r)
    # then combine it with the rest
    K_rho_c = -0.5*(xi_r**2+L2*xi_h**2)*rho*omega**2*r**2 \
        +0.5*rho*cs2*chi**2*r**2 \
        -G*m*(chi*rho+0.5*xi_r*drho_dr)*xi_r \
        -4*np.pi*G*rho*r**2*complement((chi*rho+0.5*xi_r*drho_dr)*xi_r, r) \
        +G*m*rho*xi_r*dxi_r_dr \
        +0.5*G*(m*drho_dr+4.*np.pi*r**2*rho**2)*xi_r**2 \
        -4*np.pi*G*rho/(2.*ell+1.)*K_rho_c
    K_rho_c = K_rho_c / (S*omega**2)
    
    
    ### Calculate c^2, rho pair
    # d(c^2)/c^2 = 2 * d(c)/c
    # so K_c2_rho = K_c_rho / 2
    K_c2_rho = K_c_rho / 2.
    K_rho_c2 = K_rho_c
    
    
    ### Calculate Gamma_1, rho pair
    # K_Gamma1_rho = K_c2_rho (c.f. Basu, Studying Stars 2011, eq 3.20)
    # K_rho_Gamma1 (c.f. InversionKit v. 2.2, eq. 105)
    K_rho_Gamma1 = K_rho_c2
    integrand = Gamma1*chi**2*r**2 / (2*S*omega**2)
    first_int = integrate(integrand , r)
    second_int = complement(4*np.pi*G*rho/r**2*integrate(integrand, r), r)
    K_Gamma1_rho = K_rho_c2 - K_c2_rho + G*m*rho/r**2 * \
        first_int + rho*r**2 * second_int
    
    
    ### Calculate u, Y pair
    # K_Y_u = Gamma_1,Y * K_Gamma1_rho (c.f. Basu & Chaplin 2016, eq 10.40)
    # K_u_Y = P * d(P^-1 psi)/dr + Gamma_1,p * K_Gamma1_rho
    # where psi is obtained by solving
    # d[psi(r)]/dr - 4 pi G rho r^2 int_r^R rho/(r^2 P) psi dr = -z(r)
    # z(r) = K_rho_Gamma1 + (Gamma_1,p + Gamma_1,rho) K_Gamma1_rho
    K_Y_u = Gamma_1Y * K_Gamma1_rho

    z = K_rho_Gamma1 + ( Gamma_1p + Gamma_1rho ) * K_Gamma1_rho
    
    rho_spl = UnivariateSpline(r, rho)
    P_spl = UnivariateSpline(r, P)
    z_spl = UnivariateSpline(r, z)
    
    drho = rho_spl.derivative()
    dz = z_spl.derivative()
    
    def bvp(t, psi):
        # psi'' + a(r) psi' + b(r) psi = f(r)
        # where
        # a(r) =  P/rho (r rho' - 2 rho)
        # b(r) = -P/rho [ 1 / ( 4 pi G r^2 rho ) ]
        # f(r) =  P/rho ( z r rho' - rho r z' + 2 z rho )
        # rearrange into y_1' = y_2
        #                y_2' = f(t) - a(t) y_2 - b(t) psi 
        
        # remesh onto variable x from r
        rhot = rho_spl(t) 
        Pt = P_spl(t) 
        zt = z_spl(t) 
        
        # differentiate with respect to x
        drhot = drho(t) 
        dzt = dz(t) 
        
        # calculate variables on mesh x
        #Prhot = Pt / rhot
        #at = Prhot * ( t * rhot - 2 * rhot )
        #bt = - Prhot * ( 1 / ( 4 * np.pi * G * t**2 * rhot ) )
        #ft = Prhot * ( zt * t * drhot - \
        #               rhot * x * dzt + \
        #               2 * zt * rhot )
        
        drhorho = drhot / rhot
        
        at = drhorho - 2 / t
        bt = 4 * np.pi * G * t * rhot**2 / Pt
        ft = zt * (2/t + drhorho) - dzt
        
        return np.vstack(( psi[1], 
                           ft - at * psi[1] - bt * psi[0] ))
    
    result = solve_bvp(bvp, 
        lambda ya, yb: np.array([ ya[0]-1, yb[0]-1 ]), 
        r, 
        np.array([ np.ones(len(r)), np.ones(len(r)) ]), 
        max_nodes=1000000)#, tol=1e-5)
    
    
    
    
    
    #def dpsi_dr(psi, s):
    #    return 4*np.pi*G * np.interp(s, r, rho) * s**2 \
    #        * trapz(rho[r>=s] / (r[r>=s]**2 * P[r>=s]) * psi, r[r>=s]) \
    #        - ( np.interp(s, r, K_rho_Gamma1) \
    #            + ( np.interp(s, r, Gamma_1p) + np.interp(s, r, Gamma_1rho) ) \
    #              * np.interp(s, r, K_Gamma1_rho) \
    #          )
    #psi = odeint(dpsi_dr, 1.0, r).T[0]
    #print(psi)
    
    
    
    #def dpsi_dr(r2, psi):
    #    print('r2 == r', np.all(r2 == r))
    #    psi = psi[0]
    #    print('len(psi) == len(r)', len(psi) == len(r))
    #    return np.vstack((4*np.pi*G*rho*r**2 \
    #        * complement(rho/(r**2*P)*psi, r) \
    #        + ( K_rho_Gamma1 + ( Gamma_1p + Gamma_1rho ) * K_Gamma1_rho ))).T
    
    #def dpsi_dr(r2, psi):
    #    psi = psi[0]
    #    return np.vstack((4*np.pi*G*np.interp(r2, r, rho)*r2**2 \
    #        * complement(np.interp(r2, r, rho)/(r2**2*np.interp(r2,r,P))*psi, r2) \
    #        + ( np.interp(r2, r, K_rho_Gamma1) + ( np.interp(r2, r, Gamma_1p) \
    #        + np.interp(r2, r, Gamma_1rho) ) * np.interp(r2, r, K_Gamma1_rho) ))).T
    
    ##psi = np.zeros(len(r))
    ##psi[0] = r[0] * f(0, 0)
    ##for ii in range(1, len(r)):
    ##    h = r[ii] - r[ii-1]
    ##    psi[ii] = psi[ii-1] + h * f(psi[ii-1], ii-1)
    ##print(psi)
    
    #def resid(psi):
    #    return np.gradient(psi, r) - f(psi)
    
    
    
    #result = solve_bvp(dpsi_dr, 
    #    lambda ya,yb: np.array([ (ya[0]-1)**2 + (yb[0]-1)**2 ]),
    #    r, [np.ones(len(r))], max_nodes=100000, tol=1e-9)
    
    
    # dPsi1_dr = 4 pi G r^2 rho Psi_2 + 
    #            [ K_rho_Gamma1 + ( Gamma_1P + Gamma_1rho ) * K_Gamma1_rho ]
    # dPsi2_dr = -rho/(r^2 P) Psi_1
    
    #def bvp(t, psi):
    #    rhot = rho_spl(t) 
    #    psi1 = 4 * np.pi * G * rhot * t**2 * psi[1] + z_spl(t)
    #    psi2 = - rhot / (t * P_spl(t)) * psi[0]
    #    return np.vstack(( psi1, psi2 ))
    
    #result = solve_bvp(bvp, 
    #    lambda ya, yb: np.array([ ya[0]-1, yb[0]-1 ]), 
    #    r, 
    #    np.array([ np.ones(len(r)), np.zeros(len(r)) ]), 
    #    max_nodes=100000000, tol=1e-4)
    
#    def bvp(t, psi):
#        rhot = rho_spl(t) 
#        dpsi = 4 * np.pi * G * rhot * t**2 \
#            * complement(rhot / ( t**2 * P_spl(t) ) * psi[0], t) - z_spl(t)
#        print('dpsi', dpsi)
#        return np.vstack(( dpsi )).T
    
#    result = solve_bvp(bvp, 
#        lambda ya, yb: np.array([ yb[0]-1 ]), 
#        r, 
#        np.array([ np.ones(len(x)) ]), 
#        max_nodes=100000000, tol=1e-3) 
    
    #result = solve_bvp(dPsi2_dr2, 
    #    lambda ya, yb: np.array([ (ya[0]-1)**2, (yb[0]-1)**2 ]),
    #    r, [ np.ones(len(r)), np.zeros(len(r)) ], 
    #    max_nodes=1e6)#, tol=1e-5)
    
    print(result)
    psi = result.sol(r)[0] #interp1d(result['x'], result['y'][0])(r)
    print('psi', psi)
    
    #result = least_squares(resid, np.ones(len(r)))
    #print(result)
    #psi = result['x']
    #psi = minimize(sqdiff, np.ones(len(r)), method='Nelder-Mead')['x']
    
    K_u_Y = P * UnivariateSpline(P**-1 * psi, r).derivative()(r) \
        + Gamma_1p * K_Gamma1_rho
    
    
    return { 
        ('c',      'rho'): (K_c_rho,      K_rho_c2),
        ('c2',     'rho'): (K_c2_rho,     K_rho_c2),
        ('Gamma1', 'rho'): (K_Gamma1_rho, K_rho_Gamma1),
        ('u',      'Y'):   (K_u_Y,        K_Y_u),
        ('psi', 'psi'):    (psi,          psi)
    }
Ejemplo n.º 34
0
def profile(p,s,s_old):

    #--------------------------------------------------------------------------
    # provide initial guess
    #--------------------------------------------------------------------------

    if isinstance(s_old, dict):
        if 'solver' in s_old:
            if s_old['solver'] == 'bvp':
                pre_guess = lambda x: continuation_guess(x,s_old,s)
            else:
                pre_guess = lambda x: ode_to_bvp_guess(x,s_old,s)
                s['stride'] = 3
        else:
            pre_guess = lambda x: continuation_guess(x,s_old,s)

        stride = s_old['stride']

        x_dom = s_old['sol'].x[::stride].copy() # do I need the .copy() ?

        if (len(s_old['sol'].x)-1) % stride != 0:
           x_dom[-1] = s_old['sol'].x[-1]

        s['I'] = s_old['I']
        s['L']= s_old['L']
        s['R'] = s_old['R']

    else:

        s['I'] = 1
        if 'R' not in s:
            s['R'] = 5

        s['L'] = -s['R']

        pre_guess = lambda x: guess(x,s)
        x_dom = np.linspace(0,1,30)

    #--------------------------------------------------------------------------
    # convergence to endstates tolerance
    #--------------------------------------------------------------------------

    err = s['tol'] + 1
    while err > s['tol']:
        pre_bc = lambda x,y: bc(x,y,s)
        pre_ode = lambda x,y: double_F(x,y,s,p)

        initGuess = np.array([pre_guess(x) for x in x_dom],dtype=np.complex).T

        s['sol'] = solve_bvp(pre_ode,pre_bc,x_dom,initGuess,
                             tol=s['bvp_options']['Tol'],
                             max_nodes=s['bvp_options']['Nmax'])

        err1 = np.max(np.abs(s['sol'].y[s['rarray'],-1] - s['UR']))
        err2 = np.max(np.abs(s['sol'].y[s['larray'],-1] - s['UL']))
        err  = max(err1,err2)

        if 'stats' in s:
            if s['stats'] == 'on':
                print("Profile boundary error: ",err)

        if err > s['tol']:
           s_old = s
        if err1 > s['tol']:
           s['R'] *= 1.1#*s['R']
           s['L'] = -s['R']
        if err2 > s['tol']:
           s['L'] *= 1.1#*s.L;
           s['R'] = -s['L']
        if abs(s['L']) > s['L_max']:
           raise ValueError("""Could not meet specified tolerance in profile solver
                without exceeding the maximum allowed value of negative infinity.""")
        if abs(s['R']) > s['R_max']:
           raise ValueError("""Could not meet specified tolerance in profile solver
                without exceeding the maximum allowed value of positive infinity.""")
        if err > s['tol']:
            pre_guess = lambda x: continuation_guess(x,s_old,s)
            x_dom = s_old['sol'].x

    return p,s
Ejemplo n.º 35
0
 def time_flow(self):
     x = np.linspace(0, 1, 10)
     y = np.ones((7, x.size))
     solve_bvp(self.fun_flow, self.bc_flow, x, y, p=[1], tol=self.TOL)
Ejemplo n.º 36
0
 def time_gas(self):
     x = np.linspace(0, 3, 5)
     y = np.empty((2, x.size))
     y[0] = 0.5
     y[1] = -0.5
     solve_bvp(self.fun_gas, self.bc_gas, x, y, tol=self.TOL)
Ejemplo n.º 37
0
 def time_peak(self):
     x = np.linspace(-1, 1, 5)
     y = np.zeros((2, x.size))
     solve_bvp(self.fun_peak, self.bc_peak, x, y, tol=self.TOL)