def solwave_mck(c, d, M, dist = pi / 2., xtol = 1.e-12, verbose = False): """ Compute the collocation points and values for the d-dimensional McKenzie solitary wave equation. n=3, m=0. Inputs: c - soliton parameter, d - dimension, M - No. of points, [dist = pi/2] - distance from the x axis to the nearest singularity in the complex plane, [xtol = 1.e-12] - solver tolerance, [verbose=True/False] Outputs: r, f - collocation points and the soliton """ decay = sqrt(1. - 3. / c) h = sqrt((pi * dist) / (decay * M)) r = sinc_eo.points(M, h) u0 = magma1d.solwave_mck(r, c) - 1. d0 = 1. D2 = sinc_eo.D2_e(M, h) D1 = sinc_eo.D1_eo(M, h) D1_r = sinc_eo.D1_x_e(M, h) IN1 = sinc_eo.IN1_oe(M, h) params = {'c': c, 'd': d0, 'D2': D2, 'D1':D1, 'D1_r':D1_r, 'IN': IN1} if d < 2.: params['d'] = d u = fsolve(lambda v: solwave_mck_eq(v, params), u0, fprime = lambda v:solwave_mck_eq_jac(v, params), xtol= xtol) else: # Initial value for the delta dimension value. # This can be tuned as needed delta_dim = (d - 1.)/10. # Loop will terminate if the delta dim value gets too # small, this may be tunded as needed delta_dim_min = 1.e-6 d0 = 1. while d0 < d and delta_dim > delta_dim_min: d1 = min([d0 + delta_dim, d]) params['d'] = d1 if verbose: print ' computing with d = ', d1 u1, infodict, ier, mesg = \ fsolve(lambda v:solwave_mck_eq(v,params), u0, \ fprime =lambda v:solwave_mck_eq_jac(v, params), \ xtol= xtol, full_output=1) if ier == 1 and np.max(np.abs(u1)) > 1.e-8: d0 = d1 u0 = u1 else: if verbose: if np.max(np.abs(u1)) <= 1.e-8: print " converged to the zero solution, adjusteing delta_dim" else: print " solver failed to converge, adjusting delta_dim" print " solver err = ", ier delta_dim = delta_dim / 2. if verbose: jac = solwave_mck_eq_jac(u1, params) condnum = np.linalg.cond(jac) print " condition number = ", condnum u = u0 if d0 < d: print " Failed to converge to the soliton solution, last value of d =", d0 f = 0.0 else: f = 1. + u return r, f
def solwave_m1(c, n, d, M, dist = pi / 2., xtol = 1.e-12, verbose = False): """ Compute the collocation points and values for the general d-dimensional solitary wave equation with n > 1, and m=1 Inputs: c - soliton parameter, n - first nonlinearity, d - dimension, M - No. of points, [dist = pi/2] - distance from the x axis to the nearest singularity in the complex plane, [xtol = 1.e-12] - solver tolerance, [verbose=True/False] Outputs: r, f - collocation points and the soliton """ # Iterate in soliton parameter, if neccessary, to achieve a good # guess. This may be replaced with another algorithm if a better # initial guess for the 1D soliton is available. if verbose: print " iterating in c" # Initial value for delta c. This can be tuned as needed. delta_c = .5 * n / c # Loop will terminate if the delta c value gets too small, this may be # adjusted as needed delta_c_min = 1.e-6 c0 = n d0 = 1. while c0 < c and delta_c > delta_c_min: c1 = min([c0 + delta_c, c]) decay = sqrt(1. - n / c1) h = sqrt((pi * dist) / (decay * M)) r1 = sinc_eo.points(M, h) D2 = sinc_eo.D2_e(M, h) D1 = sinc_eo.D1_eo(M, h) D1_r = sinc_eo.D1_x_e(M, h) IN1 = sinc_eo.IN1_oe(M, h) params = {'c': c1, 'n': n, 'd': d0, 'D2': D2, 'D1': D1, 'D1_r': D1_r, 'IN': IN1} try: # uguess = spline(r0, u0, r1) uguess = sinc_eo.sincinterp_e(r0,u0,r1) except: uguess = 3. * (1. - n / c1) / cosh(.5 * decay * r1)**2 if verbose: print ' computing with c = ', c1 u1, infodict, ier, mesg = \ fsolve(lambda v: solwave_m1_eq(v,params), uguess, \ # fprime = lambda v:solwave_m1_eq_jac(v, params), \ xtol= xtol, full_output=1) if ier == 1 and np.max(np.abs(u1)) > 1.e-10: c0 = c1 u0 = u1 r0 = r1 else: if verbose: if np.max(np.abs(u1)) <= 1.e-8: print " converged to the zero solution, adjusteing delta_c" else: print " solver failed to converge, adjusting delta_c" print " solver err = ", ier delta_c = delta_c / 2. u = u0 r = r0 # Iterate in dimension, if neccessary if d > 1.: if verbose: print " iterating in d" delta_dim = (n - 1.) / 10. # Loop will terminate if the delta dim value gets too # small, this can be adjusted as desired delta_dim_min = 1.e-6 d0 = 1. u0 = u while d0 < d and delta_dim > delta_dim_min: d1 = min([d0 + delta_dim, d]) params['d'] = d1 if verbose: print ' computing with d = ', d1 u1, infodict, ier, mesg = \ fsolve(lambda v: solwave_m1_eq(v, params), u0, \ # fprime = lambda v:solwave_m1_eq_jac(v, params), xtol= xtol, full_output=1) if ier == 1 and np.max(np.abs(u1)) > 1.e-8: d0 = d1 u0 = u1 else: if verbose: if np.max(np.abs(u1)) <= 1.e-8: print " converged to the zero solution, adjusteing delta_dim" else: print " solver failed to converge, adjusting delta_dim" print " solver err = ", ier delta_dim = delta_dim / 2. u = u0 if d0 < d: print " Failed to converge to the soliton solution, last value of d =", d0 f = 0.0 else: f = 1. + u return r, f