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)+')')
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]
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]
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) + ')')
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) + ')')
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)
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)
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)+')')