############################################################################### # This file is part of SWIFT. # Copyright (c) 2016 Matthieu Schaller (schaller@strw.leidenuniv.nl) # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published # by the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . # ############################################################################## import matplotlib matplotlib.use("Agg") from pylab import * from scipy import integrate from scipy.optimize import curve_fit from scipy.optimize import fsolve from matplotlib.font_manager import FontProperties import numpy params = { "axes.labelsize": 9, "axes.titlesize": 10, "font.size": 12, "legend.fontsize": 12, "xtick.labelsize": 9, "ytick.labelsize": 9, "text.usetex": True, "figure.figsize": (3.15, 3.15), "figure.subplot.left": 0.17, "figure.subplot.right": 0.99, "figure.subplot.bottom": 0.08, "figure.subplot.top": 0.99, "figure.subplot.wspace": 0.0, "figure.subplot.hspace": 0.0, "lines.markersize": 6, "lines.linewidth": 3.0, } rcParams.update(params) # params = { # 'axes.labelsize': 10, # 'axes.titlesize': 8, # 'font.size': 10, # 'legend.fontsize': 9, # 'xtick.labelsize': 10, # 'ytick.labelsize': 10, # 'xtick.major.pad': 2.5, # 'ytick.major.pad': 2.5, # 'text.usetex': True, # 'figure.figsize' : (4.15,4.15), # 'figure.subplot.left' : 0.14, # 'figure.subplot.right' : 0.99, # 'figure.subplot.bottom' : 0.06, # 'figure.subplot.top' : 0.99, # 'figure.subplot.wspace' : 0. , # 'figure.subplot.hspace' : 0. , # 'lines.markersize' : 6, # 'lines.linewidth' : 1.5, # } # rcParams.update(params) # rc('font',**{'family':'sans-serif','sans-serif':['Times']}) # Parameters eta = 1.2348422195325 # Resolution (Gives 48 neighbours for a cubic spline kernel) dx = 1.5 # 4 #2.7162 # Mean inter-particle separation # Constants PI = math.pi # Compute expected moothing length h = eta * dx # Get kernel support (Dehnen & Aly 2012, table 1) for 3D kernels H_cubic = 1.825742 * h H_quartic = 2.018932 * h H_quintic = 2.195775 * h H_WendlandC2 = 1.936492 * h H_WendlandC4 = 2.207940 * h H_WendlandC6 = 2.449490 * h # Get the number of neighbours within kernel support: N_H_cubic = 4.0 / 3.0 * PI * H_cubic ** 3 / (dx) ** 3 N_H_quartic = 4.0 / 3.0 * PI * H_quartic ** 3 / (dx) ** 3 N_H_quintic = 4.0 / 3.0 * PI * H_quintic ** 3 / (dx) ** 3 N_H_WendlandC2 = 4.0 / 3.0 * PI * H_WendlandC2 ** 3 / (dx) ** 3 N_H_WendlandC4 = 4.0 / 3.0 * PI * H_WendlandC4 ** 3 / (dx) ** 3 N_H_WendlandC6 = 4.0 / 3.0 * PI * H_WendlandC6 ** 3 / (dx) ** 3 print( "Smoothing length: h =", h, "Cubic spline kernel support size: H =", H_cubic, "Number of neighbours N_H =", N_H_cubic, ) print( "Smoothing length: h =", h, "Quartic spline kernel support size: H =", H_quartic, "Number of neighbours N_H =", N_H_quartic, ) print( "Smoothing length: h =", h, "Quintic spline kernel support size: H =", H_quintic, "Number of neighbours N_H =", N_H_quintic, ) print( "Smoothing length: h =", h, "Wendland C2 kernel support size: H =", H_WendlandC2, "Number of neighbours N_H =", N_H_WendlandC2, ) print( "Smoothing length: h =", h, "Wendland C4 kernel support size: H =", H_WendlandC4, "Number of neighbours N_H =", N_H_WendlandC4, ) print( "Smoothing length: h =", h, "Wendland C6 kernel support size: H =", H_WendlandC6, "Number of neighbours N_H =", N_H_WendlandC6, ) # Get kernel constants (Dehen & Aly 2012, table 1) for 3D kernel C_cubic = 16.0 / PI C_quartic = 5 ** 6 / (512 * PI) C_quintic = 3 ** 7 / (40 * PI) C_WendlandC2 = 21.0 / (2 * PI) C_WendlandC4 = 495.0 / (32 * PI) C_WendlandC6 = 1365.0 / (64 * PI) # Get the reduced kernel definitions (Dehen & Aly 2012, table 1) for 3D kernel # def plus(u) : return maximum(0., u) def cubic_spline(r): return where( r > 1.0, 0.0, where( r < 0.5, 3.0 * r ** 3 - 3.0 * r ** 2 + 0.5, -r ** 3 + 3.0 * r ** 2 - 3.0 * r + 1.0, ), ) # return plus(1. - r)**3 - 4.*plus(1./2. - r)**3 def quartic_spline(r): return where( r > 1.0, 0.0, where( r < 0.2, 6.0 * r ** 4 - 2.4 * r ** 2 + 46.0 / 125.0, where( r < 0.6, -4.0 * r ** 4 + 8.0 * r ** 3 - (24.0 / 5.0) * r ** 2 + (8.0 / 25.0) * r + 44.0 / 125.0, 1.0 * r ** 4 - 4.0 * r ** 3 + 6.0 * r ** 2 - 4.0 * r + 1.0, ), ), ) # return plus(1. - r)**4 - 5.*plus(3./5. - r)**4 + 10.*plus(1./5. - r)**4 def quintic_spline(r): return where( r > 1.0, 0.0, where( r < 1.0 / 3.0, -10.0 * r ** 5 + 10.0 * r ** 4 - (20.0 / 9.0) * r ** 2 + (22.0 / 81.0), where( r < 2.0 / 3.0, 5.0 * r ** 5 - 15.0 * r ** 4 + (50.0 / 3.0) * r ** 3 - (70.0 / 9.0) * r ** 2 + (25.0 / 27.0) * r + (17.0 / 81.0), -1.0 * r ** 5 + 5.0 * r ** 4 - 10.0 * r ** 3 + 10.0 * r ** 2 - 5.0 * r + 1.0, ), ), ) # return plus(1. - r)**5 - 6.*plus(2./3. - r)**5 + 15.*plus(1./3. - r)**5 def wendlandC2(r): return where( r > 1.0, 0.0, 4.0 * r ** 5 - 15.0 * r ** 4 + 20.0 * r ** 3 - 10 * r ** 2 + 1.0 ) def wendlandC4(r): return where( r > 1.0, 0.0, (35.0 / 3.0) * r ** 8 - 64.0 * r ** 7 + 140.0 * r ** 6 - (448.0 / 3.0) * r ** 5 + 70.0 * r ** 4 - (28.0 / 3.0) * r ** 2 + 1.0, ) def wendlandC6(r): return where( r > 1.0, 0.0, 32.0 * r ** 11 - 231.0 * r ** 10 + 704.0 * r ** 9 - 1155.0 * r ** 8 + 1056.0 * r ** 7 - 462.0 * r ** 6 + 66.0 * r ** 4 - 11.0 * r ** 2 + 1.0, ) def Gaussian(r, h): return (1.0 / (0.5 * pi * h ** 2) ** (3.0 / 2.0)) * exp(-2.0 * r ** 2 / (h ** 2)) # Kernel definitions (3D) def W_cubic_spline(r): return C_cubic * cubic_spline(r / H_cubic) / H_cubic ** 3 def W_quartic_spline(r): return C_quartic * quartic_spline(r / H_quartic) / H_quartic ** 3 def W_quintic_spline(r): return C_quintic * quintic_spline(r / H_quintic) / H_quintic ** 3 def W_WendlandC2(r): return C_WendlandC2 * wendlandC2(r / H_WendlandC2) / H_WendlandC2 ** 3 def W_WendlandC4(r): return C_WendlandC4 * wendlandC4(r / H_WendlandC4) / H_WendlandC4 ** 3 def W_WendlandC6(r): return C_WendlandC6 * wendlandC6(r / H_WendlandC6) / H_WendlandC6 ** 3 # PLOT STUFF figure() subplot(211) xx = linspace(0.0, 5 * h, 100) maxY = 1.2 * Gaussian(0, h) # Plot the kernels plot( xx, Gaussian(xx, h), "k-", linewidth=0.7, label="${\\rm %14s~ H=\\infty}$" % ("Gaussian~~~~~~"), ) plot( xx, W_cubic_spline(xx), "b-", label="${\\rm %14s~ H=%4.3f}$" % ("Cubic~spline~~", H_cubic), lw=1.5, ) plot( xx, W_quartic_spline(xx), "c-", label="${\\rm %14s~ H=%4.3f}$" % ("Quartic~spline", H_quartic), lw=1.5, ) plot( xx, W_quintic_spline(xx), "g-", label="${\\rm %14s~ H=%4.3f}$" % ("Quintic~spline", H_quintic), lw=1.5, ) plot( xx, W_WendlandC2(xx), "r-", label="${\\rm %14s~ H=%4.3f}$" % ("Wendland~C2~", H_WendlandC2), lw=1.5, ) plot( xx, W_WendlandC4(xx), "m-", label="${\\rm %14s~ H=%4.3f}$" % ("Wendland~C4~", H_WendlandC4), lw=1.5, ) plot( xx, W_WendlandC6(xx), "y-", label="${\\rm %14s~ H=%4.3f}$" % ("Wendland~C6~", H_WendlandC6), lw=1.5, ) # Indicate the position of H arrow( H_cubic, 0.12 * maxY, 0.0, -0.12 * maxY * 0.9, fc="b", ec="b", length_includes_head=True, head_width=0.03, head_length=0.12 * maxY * 0.3, ) arrow( H_quartic, 0.12 * maxY, 0.0, -0.12 * maxY * 0.9, fc="c", ec="c", length_includes_head=True, head_width=0.03, head_length=0.12 * maxY * 0.3, ) arrow( H_quintic, 0.12 * maxY, 0.0, -0.12 * maxY * 0.9, fc="g", ec="g", length_includes_head=True, head_width=0.03, head_length=0.12 * maxY * 0.3, ) arrow( H_WendlandC2, 0.12 * maxY, 0.0, -0.12 * maxY * 0.9, fc="r", ec="r", length_includes_head=True, head_width=0.03, head_length=0.12 * maxY * 0.3, ) arrow( H_WendlandC4, 0.12 * maxY, 0.0, -0.12 * maxY * 0.9, fc="m", ec="m", length_includes_head=True, head_width=0.03, head_length=0.12 * maxY * 0.3, ) arrow( H_WendlandC6, 0.12 * maxY, 0.0, -0.12 * maxY * 0.9, fc="y", ec="y", length_includes_head=True, head_width=0.03, head_length=0.12 * maxY * 0.3, ) # Show h plot([h, h], [0.0, 0.63 * maxY], "k:", linewidth=0.5) text( h, maxY * 0.65, "$h\\equiv\\eta\\langle x\\rangle$", rotation=90, ha="center", va="bottom", fontsize=9, ) # Show sigma plot([h / 2, h / 2], [0.0, 0.63 * maxY], "k:", linewidth=0.5) text( h / 2, maxY * 0.65, "$\\sigma\\equiv h/2$", rotation=90, ha="center", va="bottom", fontsize=9, ) # Show plot([dx, dx], [0.0, 0.63 * maxY], "k:", linewidth=0.5) text( dx, maxY * 0.65, "$\\langle x\\rangle = %.1f$" % dx, rotation=90, ha="center", va="bottom", fontsize=9, ) xlim(0.0, 2.5 * h) ylim(0.0, maxY) gca().xaxis.set_ticklabels([]) ylabel("$W(r,h)$", labelpad=1.5) legend( loc="upper right", frameon=False, handletextpad=0.1, handlelength=1.2, fontsize=8 ) # Same but now in log space subplot(212, yscale="log") plot(xx, Gaussian(xx, h), "k-", linewidth=0.7, label="${\\rm Gaussian}$") plot(xx, W_cubic_spline(xx), "b-", label="${\\rm Cubic~spline}$", lw=1.5) plot(xx, W_quartic_spline(xx), "c-", label="${\\rm Quartic~spline}$", lw=1.5) plot(xx, W_quintic_spline(xx), "g-", label="${\\rm Quintic~spline}$", lw=1.5) plot(xx, W_WendlandC2(xx), "r-", label="${\\rm Wendland~C2}$", lw=1.5) plot(xx, W_WendlandC4(xx), "m-", label="${\\rm Wendland~C4}$", lw=1.5) plot(xx, W_WendlandC6(xx), "y-", label="${\\rm Wendland~C6}$", lw=1.5) # Show h plot([h, h], [0.0, 1.0], "k:", linewidth=0.5) # Show sigma plot([h / 2, h / 2], [0.0, 1.0], "k:", linewidth=0.5) # Show plot([dx, dx], [0.0, 1.0], "k:", linewidth=0.5) # Show plot properties text( h / 5.0, 2e-3, "$\\langle x \\rangle = %3.1f$" % (dx), va="top", backgroundcolor="w", fontsize=9, ) text( h / 5.0 + 0.06, 4e-4, "$\\eta = %5.4f$" % (eta), va="top", backgroundcolor="w", fontsize=9, ) text( h / 5.0 + 0.06, 8e-5, "$h = \\eta\\langle x \\rangle = %5.4f$" % (h), va="top", backgroundcolor="w", fontsize=9, ) # Show number of neighbours text(1.75 * h, 2e-1 / 2.9 ** 0, "$N_{\\rm ngb}=\\infty$", fontsize=10) text( 1.75 * h, 2e-1 / 2.9 ** 1, "$N_{\\rm ngb}=%3.1f$" % (N_H_cubic), color="b", fontsize=9, ) text( 1.75 * h, 2e-1 / 2.9 ** 2, "$N_{\\rm ngb}=%3.1f$" % (N_H_quartic), color="c", fontsize=9, ) text( 1.75 * h, 2e-1 / 2.9 ** 3, "$N_{\\rm ngb}=%3.1f$" % (N_H_quintic), color="g", fontsize=9, ) text( 1.75 * h, 2e-1 / 2.9 ** 4, "$N_{\\rm ngb}=%3.1f$" % (N_H_WendlandC2), color="r", fontsize=9, ) text( 1.75 * h, 2e-1 / 2.9 ** 5, "$N_{\\rm ngb}=%3.1f$" % (N_H_WendlandC4), color="m", fontsize=9, ) text( 1.75 * h, 2e-1 / 2.9 ** 6, "$N_{\\rm ngb}=%3.0f$" % (N_H_WendlandC6), color="y", fontsize=9, ) xlim(0.0, 2.5 * h) ylim(1e-5, 0.7) xlabel("$r$", labelpad=-1) ylabel("$W(r,h)$", labelpad=0.5) savefig("kernels.pdf") ################################ # Now, let's work on derivatives ################################ # Get the derivative of the reduced kernel definitions for 3D kernels def d_cubic_spline(r): return where( r > 1.0, 0.0, where(r < 0.5, 9.0 * r ** 2 - 6.0 * r, -3.0 * r ** 2 + 6.0 * r - 3.0), ) def d_quartic_spline(r): return where( r > 1.0, 0.0, where( r < 0.2, 24.0 * r ** 3 - 4.8 * r, where( r < 0.6, -16.0 * r ** 3 + 24.0 * r ** 2 - (48.0 / 5.0) * r + (8.0 / 25.0), 4.0 * r ** 3 - 12.0 * r ** 2 + 12.0 * r - 4.0, ), ), ) def d_quintic_spline(r): return where( r > 1.0, 0.0, where( r < 1.0 / 3.0, -50.0 * r ** 4 + 40.0 * r ** 3 - (40.0 / 9.0) * r, where( r < 2.0 / 3.0, 25.0 * r ** 4 - 60.0 * r ** 3 + 50.0 * r ** 2 - (140.0 / 9.0) * r + (25.0 / 27.0), -5.0 * r ** 4 + 20.0 * r ** 3 - 30.0 * r ** 2 + 20.0 * r - 5.0, ), ), ) def d_wendlandC2(r): return where(r > 1.0, 0.0, 20.0 * r ** 4 - 60.0 * r ** 3 + 60.0 * r ** 2 - 20.0 * r) def d_wendlandC4(r): return where( r > 1.0, 0.0, 93.3333 * r ** 7 - 448.0 * r ** 6 + 840.0 * r ** 5 - 746.667 * r ** 4 + 280.0 * r ** 3 - 18.6667 * r, ) def d_wendlandC6(r): return where( r > 1.0, 0.0, 352.0 * r ** 10 - 2310.0 * r ** 9 + 6336.0 * r ** 8 - 9240.0 * r ** 7 + 7392.0 * r ** 6 - 2772.0 * r ** 5 + 264.0 * r ** 3 - 22.0 * r, ) def d_Gaussian(r, h): return ( (-8.0 * sqrt(2.0) / (PI ** (3.0 / 2.0) * h ** 5)) * r * exp(-2.0 * r ** 2 / (h ** 2)) ) def dh_Gaussian(r, h): return -(3 * Gaussian(r, h) + (r / h) * d_Gaussian(r, h)) # Get the second derivative of the reduced kernel definitions for 3D kernels # def d2_cubic_spline(r): return where(r > 1., 0., where(r < 0.5, # 18.*r - 6., # -6.*r + 6.) ) # def d2_quartic_spline(r): return where(r > 1., 0., where(r < 0.2, # 72.*r**2 - 4.8, # where(r < 0.6, # -48.*r**2 + 48.*r - (48./5.), # 12.*r**2 - 24.*r + 12.))) # def d2_quintic_spline(r): return where(r > 1., 0., where(r < 1./3., # -200.*r**3 + 120.*r**2 - (40./9.), # where(r < 2./3., # 100.*r**3 - 180.*r**2 + 100.*r - (140./9.), # -20.*r**3 + 60.*r**2 - 60.*r + 20))) # def d2_wendlandC2(r): return where(r > 1., 0., 80.*r**3 - 180.*r**2 + 120.*r - 20.) # def d2_wendlandC4(r): return where(r > 1., 0., 653.3333*r**6 - 2688.*r**5 + 4200.*r**4 - 2986.667*r**3 + 840.*r**2 - 18.6667) # def d2_wendlandC6(r): return where(r > 1., 0., 3520.*r**9 - 20790.*r**8 + 50688.*r**7 - 64680.*r**6 + 44352.*r**5 - 13860.*r**4 + 792.*r**2 - 22) # def d2_Gaussian(r,h): return (32*sqrt(2)/(PI**(3./2.)*h**7)) * r**2 * exp(-2.*r**2 / (h**2)) - 8.*sqrt(2.)/(PI**(3./2.) * h**5) * exp(- 2.*r**2 / (h**2)) # Derivative of kernel definitions (3D) def dWdx_cubic_spline(r): return C_cubic * d_cubic_spline(r / H_cubic) / H_cubic ** 4 def dWdx_quartic_spline(r): return C_quartic * d_quartic_spline(r / H_quartic) / H_quartic ** 4 def dWdx_quintic_spline(r): return C_quintic * d_quintic_spline(r / H_quintic) / H_quintic ** 4 def dWdx_WendlandC2(r): return C_WendlandC2 * d_wendlandC2(r / H_WendlandC2) / H_WendlandC2 ** 4 def dWdx_WendlandC4(r): return C_WendlandC4 * d_wendlandC4(r / H_WendlandC4) / H_WendlandC4 ** 4 def dWdx_WendlandC6(r): return C_WendlandC6 * d_wendlandC6(r / H_WendlandC6) / H_WendlandC6 ** 4 # Derivative of kernel definitions (3D) def dWdh_cubic_spline(r): return ( 3.0 * cubic_spline(r / H_cubic) + (r / H_cubic) * d_cubic_spline(r / H_cubic) ) * (-C_cubic / H_cubic ** 4) def dWdh_quartic_spline(r): return ( 3.0 * quartic_spline(r / H_quartic) + (r / H_quartic) * d_quartic_spline(r / H_quartic) ) * (-C_quartic / H_quartic ** 4) def dWdh_quintic_spline(r): return ( 3.0 * quintic_spline(r / H_quintic) + (r / H_quintic) * d_quintic_spline(r / H_quintic) ) * (-C_quintic / H_quintic ** 4) def dWdh_WendlandC2(r): return ( 3.0 * wendlandC2(r / H_WendlandC2) + (r / H_WendlandC2) * d_wendlandC2(r / H_WendlandC2) ) * (-C_WendlandC2 / H_WendlandC2 ** 4) def dWdh_WendlandC4(r): return ( 3.0 * wendlandC4(r / H_WendlandC4) + (r / H_WendlandC4) * d_wendlandC4(r / H_WendlandC4) ) * (-C_WendlandC4 / H_WendlandC4 ** 4) def dWdh_WendlandC6(r): return ( 3.0 * wendlandC6(r / H_WendlandC6) + (r / H_WendlandC6) * d_wendlandC6(r / H_WendlandC6) ) * (-C_WendlandC6 / H_WendlandC6 ** 4) # Second derivative of kernel definitions (3D) # def d2W_cubic_spline(r): return C_cubic * d2_cubic_spline(r / H_cubic) / H_cubic**5 # def d2W_quartic_spline(r): return C_quartic * d2_quartic_spline(r / H_quartic) / H_quartic**5 # def d2W_quintic_spline(r): return C_quintic * d2_quintic_spline(r / H_quintic) / H_quintic**5 # def d2W_WendlandC2(r): return C_WendlandC2 * d2_wendlandC2(r / H_WendlandC2) / H_WendlandC2**5 # def d2W_WendlandC4(r): return C_WendlandC4 * d2_wendlandC4(r / H_WendlandC4) / H_WendlandC4**5 # def d2W_WendlandC6(r): return C_WendlandC6 * d2_wendlandC6(r / H_WendlandC6) / H_WendlandC6**5 figure() subplot(211) plot([0, 2.5 * h], [0.0, 0.0], "k--", linewidth=0.7) plot(xx, d_Gaussian(xx, h), "k-", linewidth=0.7, label="${\\rm Gaussian}$") plot(xx, dWdx_cubic_spline(xx), "b-", label="${\\rm Cubic~spline}$", lw=1.5) plot(xx, dWdx_quartic_spline(xx), "c-", label="${\\rm Quartic~spline}$", lw=1.5) plot(xx, dWdx_quintic_spline(xx), "g-", label="${\\rm Quintic~spline}$", lw=1.5) plot(xx, dWdx_WendlandC2(xx), "r-", label="${\\rm Wendland~C2}$", lw=1.5) plot(xx, dWdx_WendlandC4(xx), "m-", label="${\\rm Wendland~C4}$", lw=1.5) plot(xx, dWdx_WendlandC6(xx), "y-", label="${\\rm Wendland~C6}$", lw=1.5) maxY = d_Gaussian(h / 2, h) # Show h plot([h, h], [2 * maxY, 0.1], "k:", linewidth=0.5) # Show sigma plot([h / 2, h / 2], [2 * maxY, 0.1], "k:", linewidth=0.5) # Show plot([dx, dx], [2 * maxY, 0.1], "k:", linewidth=0.5) xlim(0.0, 2.5 * h) gca().xaxis.set_ticklabels([]) ylim(1.3 * maxY, -0.1 * maxY) xlabel("$r$", labelpad=0) ylabel("$\\partial W(r,h)/\\partial r$", labelpad=0.5) legend( loc="lower right", frameon=False, handletextpad=0.1, handlelength=1.2, fontsize=8 ) subplot(212) plot([h / 2, h / 2], [0.77 * maxY, -0.15 * maxY], "k:", linewidth=0.5) plot([h, h], [0.77 * maxY, -0.15 * maxY], "k:", linewidth=0.5) plot([dx, dx], [0.77 * maxY, -0.15 * maxY], "k:", linewidth=0.5) text( h / 2, 1.25 * maxY, "$\\sigma\\equiv h/2$", rotation=90, ha="center", va="bottom", fontsize=9, ) text( h, 1.25 * maxY, "$h\\equiv\\eta\\langle x\\rangle$", rotation=90, ha="center", va="bottom", fontsize=9, ) text( dx, 1.25 * maxY, "$\\langle x\\rangle = %.1f$" % dx, rotation=90, ha="center", va="bottom", fontsize=9, ) plot([0, 2.5 * h], [0.0, 0.0], "k--", linewidth=0.7) # plot(xx, dh_Gaussian(xx, h), 'k-', linewidth=0.7, label="${\\rm Gaussian}$") plot(xx, dWdh_cubic_spline(xx), "b-", label="${\\rm Cubic~spline}$", lw=1.5) plot(xx, dWdh_quartic_spline(xx), "c-", label="${\\rm Quartic~spline}$", lw=1.5) plot(xx, dWdh_quintic_spline(xx), "g-", label="${\\rm Quintic~spline}$", lw=1.5) plot(xx, dWdh_WendlandC2(xx), "r-", label="${\\rm Wendland~C2}$", lw=1.5) plot(xx, dWdh_WendlandC4(xx), "m-", label="${\\rm Wendland~C4}$", lw=1.5) plot(xx, dWdh_WendlandC6(xx), "y-", label="${\\rm Wendland~C6}$", lw=1.5) xlim(0.0, 2.5 * h) ylim(1.3 * maxY, -0.15 * maxY) xlabel("$r$", labelpad=-1) ylabel("$\\partial W(r,h)/\\partial h$", labelpad=0.5) savefig("kernel_derivatives.pdf")