Exemplo n.º 1
0
def arw2(gam,c):
    r"""Returns the second order IMEX additive multistep method based on the
    parametrization in Section 3.2 of Ascher, Ruuth, & Spiteri.  The parameters
    are gam and c.  Known methods are obtained with the following values:

        (1/2,0):   CNAB
        (1/2,1/8): MCNAB
        (0,1):     CNLF
        (1,0):     SBDF

    **Examples**::

        >>> from nodepy import lm
        >>> import sympy
        >>> CNLF = lm.arw2(0,sympy.Rational(1))
        >>> CNLF.order()
        2
        >>> CNLF.method1.ssp_coefficient()
        1
        >>> CNLF.method2.ssp_coefficient()
        0
        >>> print(CNLF.stiff_damping_factor()) #doctest: +ELLIPSIS
        0.999...
    """
    half = sympy.Rational(1,2)
    alpha = snp.array([gam-half,-2*gam,gam+half])
    beta  = snp.array([c/2,1-gam-c,gam+c/2]) #implicit part
    gamma = snp.array([-gam,gam+1,0]) #explicit part
    return AdditiveLinearMultistepMethod(alpha,beta,gamma,'ARW2('+str(gam)+','+str(c)+')')
Exemplo n.º 2
0
def loadLMM(which='All'):
    """
    Load a set of standard linear multistep methods for testing.

    **Examples**::

        >>> from nodepy import lm
        >>> ebdf5 = lm.loadLMM('eBDF5')
        >>> ebdf5.is_zero_stable()
        True
    """
    LM={}
    #================================================
    alpha = snp.array([-12,75,-200,300,-300,137])/sympy.Rational(137,1)
    beta = snp.array([60,-300,600,-600,300,0])/sympy.Rational(137,1)
    LM['eBDF5'] = LinearMultistepMethod(alpha,beta,'eBDF 5')
    #================================================
    theta = sympy.Rational(1,2)
    alpha = snp.array([-1,1])
    beta = snp.array([1-theta,theta])
    gamma = snp.array([1,0])
    LM['ET112'] = AdditiveLinearMultistepMethod(alpha,beta,gamma,'Euler-Theta')
    #================================================
    if which=='All':
        return LM
    else:
        return LM[which]
Exemplo n.º 3
0
def loadLMM(which='All'):
    """
    Load a set of standard linear multistep methods for testing.

    **Examples**::

        >>> from nodepy import lm
        >>> ebdf5 = lm.loadLMM('eBDF5')
        >>> ebdf5.is_zero_stable()
        True
    """
    LM = {}
    # ================================================
    alpha = snp.array([-12, 75, -200, 300, -300, 137]) / sympy.Rational(137, 1)
    beta = snp.array([60, -300, 600, -600, 300, 0]) / sympy.Rational(137, 1)
    LM['eBDF5'] = LinearMultistepMethod(alpha, beta, 'eBDF 5')
    # ================================================
    theta = sympy.Rational(1, 2)
    alpha = snp.array([-1, 1])
    beta = snp.array([1 - theta, theta])
    gamma = snp.array([1, 0])
    LM['ET112'] = AdditiveLinearMultistepMethod(alpha, beta, gamma,
                                                'Euler-Theta')
    # ================================================
    if which == 'All':
        return LM
    else:
        return LM[which]
Exemplo n.º 4
0
def arw3(gam, theta, c):
    r"""Returns the third order IMEX additive multistep method based on the
    parametrization in Section 3.3 of Ascher, Ruuth, & Whetton.  The parameters
    are gamma, theta, and c.  Known methods are obtained with the following values:

        (1,0,0):     SBDF3

    Note that there is one sign error in the ARW paper; it is corrected here.
    """
    half = sympy.Rational(1, 2)
    third = sympy.Rational(1, 3)
    alpha = snp.array([
        -half * gam**2 + third / 2, 3 * half * gam**2 + gam - 1,
        -3 * half * gam**2 - 2 * gam + half - theta,
        half * gam**2 + gam + third + theta
    ])
    beta = snp.array([
        5 * half / 6 * theta - c,
        (gam**2 - gam) * half + 3 * c - 4 * theta * third,
        1 - gam**2 - 3 * c + 23 * theta * third / 4, (gam**2 + gam) * half + c
    ])
    gamma = snp.array([(gam**2 + gam) * half + 5 * theta * third / 4,
                       -gam**2 - 2 * gam - 4 * theta * third,
                       (gam**2 + 3 * gam) * half + 1 + 23 * theta * third / 4,
                       0])
    return AdditiveLinearMultistepMethod(
        alpha, beta, gamma,
        'ARW3(' + str(gam) + ',' + str(theta) + ',' + str(c) + ')')
Exemplo n.º 5
0
def arw2(gam, c):
    r"""Returns the second order IMEX additive multistep method based on the
    parametrization in Section 3.2 of Ascher, Ruuth, & Whetton.  The parameters
    are gam and c.  Known methods are obtained with the following values:

        (1/2,0):   CNAB
        (1/2,1/8): MCNAB
        (0,1):     CNLF
        (1,0):     SBDF

    **Examples**::

        >>> from nodepy import lm
        >>> import sympy
        >>> CNLF = lm.arw2(0,sympy.Rational(1))
        >>> CNLF.order()
        2
        >>> CNLF.method1.ssp_coefficient()
        1
        >>> CNLF.method2.ssp_coefficient()
        0
        >>> print(CNLF.stiff_damping_factor()) #doctest: +ELLIPSIS
        0.999...
    """
    half = sympy.Rational(1, 2)
    alpha = snp.array([gam - half, -2 * gam, gam + half])
    beta = snp.array([c / 2, 1 - gam - c, gam + c / 2])  # implicit part
    gamma = snp.array([-gam, gam + 1, 0])  # explicit part
    return AdditiveLinearMultistepMethod(
        alpha, beta, gamma, 'ARW2(' + str(gam) + ',' + str(c) + ')')
Exemplo n.º 6
0
    def __init__(self,
                 A=None,
                 At=None,
                 b=None,
                 bt=None,
                 alpha=None,
                 beta=None,
                 alphat=None,
                 betat=None,
                 name='downwind Runge-Kutta Method',
                 description=''):
        r"""
            Initialize a downwind Runge-Kutta method.  The representation
            uses the form and notation of [Ketcheson2010]_.

            \\begin{align*}
            y^n_i = & u^{n-1} + \\Delta t \\sum_{j=1}^{s}
            (a_{ij} f(y_j^{n-1}) + \\tilde{a}_{ij} \\tilde{f}(y_j^n)) & (1\\le j \\le s) \\\\
            \\end{align*}

        """
        A, b, alpha, beta = snp.normalize(A, b, alpha, beta)

        butchform = [x is not None for x in [A, At, b, bt]]
        SOform = [x is not None for x in [alpha, alphat, beta, betat]]
        if not ((all(butchform) and not (True in SOform)) or
                ((not (True in butchform)) and all(SOform))):
            raise Exception("""To initialize a Runge-Kutta method,
                you must provide either Butcher arrays or Shu-Osher arrays,
                but not both.""")
        if A is not None:  #Initialize with Butcher arrays
            # Check that number of stages is consistent
            m = np.size(A, 0)  # Number of stages
            if m > 1:
                if not np.all([np.size(A, 1), np.size(b)] == [m, m]):
                    raise Exception(
                        'Inconsistent dimensions of Butcher arrays')
            else:
                if not np.size(b) == 1:
                    raise Exception(
                        'Inconsistent dimensions of Butcher arrays')
        elif alpha is not None:  #Initialize with Shu-Osher arrays
            A, At, b, bt = downwind_shu_osher_to_butcher(
                alpha, alphat, beta, betat)
        # Set Butcher arrays
        if len(np.shape(A)) == 2:
            self.A = A
            self.At = At
        else:
            self.A = snp.array([A])  #Fix for 1-stage methods
            self.At = snp.array([At])
        self.b = b
        self.bt = bt
        self.c = np.sum(self.A, 1) - np.sum(self.At, 1)
        self.name = name
        self.info = description
        self.underlying_method = rk.RungeKuttaMethod(self.A - self.At,
                                                     self.b - self.bt)
Exemplo n.º 7
0
    def __init__(
        self,
        A=None,
        At=None,
        b=None,
        bt=None,
        alpha=None,
        beta=None,
        alphat=None,
        betat=None,
        name="downwind Runge-Kutta Method",
        description="",
    ):
        r"""
            Initialize a downwind Runge-Kutta method.  The representation
            uses the form and notation of [Ketcheson2010]_.

            \\begin{align*}
            y^n_i = & u^{n-1} + \\Delta t \\sum_{j=1}^{s}
            (a_{ij} f(y_j^{n-1}) + \\tilde{a}_{ij} \\tilde{f}(y_j^n)) & (1\\le j \\le s) \\\\
            \\end{align*}

        """
        A, b, alpha, beta = snp.normalize(A, b, alpha, beta)

        butchform = [x is not None for x in [A, At, b, bt]]
        SOform = [x is not None for x in [alpha, alphat, beta, betat]]
        if not ((all(butchform) and not (True in SOform)) or ((not (True in butchform)) and all(SOform))):
            raise Exception(
                """To initialize a Runge-Kutta method,
                you must provide either Butcher arrays or Shu-Osher arrays,
                but not both."""
            )
        if A is not None:  # Initialize with Butcher arrays
            # Check that number of stages is consistent
            m = np.size(A, 0)  # Number of stages
            if m > 1:
                if not np.all([np.size(A, 1), np.size(b)] == [m, m]):
                    raise Exception("Inconsistent dimensions of Butcher arrays")
            else:
                if not np.size(b) == 1:
                    raise Exception("Inconsistent dimensions of Butcher arrays")
        elif alpha is not None:  # Initialize with Shu-Osher arrays
            A, At, b, bt = downwind_shu_osher_to_butcher(alpha, alphat, beta, betat)
        # Set Butcher arrays
        if len(np.shape(A)) == 2:
            self.A = A
            self.At = At
        else:
            self.A = snp.array([A])  # Fix for 1-stage methods
            self.At = snp.array([At])
        self.b = b
        self.bt = bt
        self.c = np.sum(self.A, 1) - np.sum(self.At, 1)
        self.name = name
        self.info = description
        self.underlying_method = rk.RungeKuttaMethod(self.A - self.At, self.b - self.bt)
Exemplo n.º 8
0
def arw3(gam,theta,c):
    r"""Returns the third order IMEX additive multistep method based on the
    parametrization in Section 3.3 of Ascher, Ruuth, & Whetton.  The parameters
    are gamma, theta, and c.  Known methods are obtained with the following values:

        (1,0,0):     SBDF3

    Note that there is one sign error in the ARW paper; it is corrected here.
    """
    half = sympy.Rational(1,2)
    third = sympy.Rational(1,3)
    alpha = snp.array([-half*gam**2+third/2, 3*half*gam**2+gam-1, -3*half*gam**2-2*gam+half-theta,
                       half*gam**2+gam+third+theta])
    beta  = snp.array([5*half/6*theta-c, (gam**2-gam)*half+3*c-4*theta*third, 1-gam**2-3*c+23*theta*third/4,
                       (gam**2+gam)*half+c])
    gamma = snp.array([(gam**2+gam)*half+5*theta*third/4, -gam**2-2*gam-4*theta*third,
                       (gam**2+3*gam)*half+1+23*theta*third/4,0])
    return AdditiveLinearMultistepMethod(alpha,beta,gamma,'ARW3('+str(gam)+','+str(theta)+','+str(c)+')')