def set_fc(self,delta): """ interpolate the exact solitary wave with offset x0 + delta onto a function in Function Space V """ # Interpolate R onto the function self.setRx(self.x0+delta) self.fc.interpolate(self.R) # scale R by h_on_delta fx = self.fc.vector() fx *= self.h_on_delta #get numpy array for radial function and interpolate using sinc rmesh = fx.array(); # get numpy array phi = sincinterp_e(self.rr, self.ff - 1.0, rmesh) + 1.0 # reload phi onto function for i in range(fx.size()): fx[i] = phi[i]
def set_fc(self, delta): """ interpolate the exact solitary wave with offset x0 + delta onto a function in Function Space V """ # Interpolate R onto the function self.setRx(self.x0 + delta) self.fc.interpolate(self.R) # scale R by h_on_delta fx = self.fc.vector() fx *= self.h_on_delta #get numpy array for radial function and interpolate using sinc rmesh = fx.array() # get numpy array phi = sincinterp_e(self.rr, self.ff - 1.0, rmesh) + 1.0 # reload phi onto function for i in range(fx.size()): fx[i] = phi[i]
def ProjectSolitaryWave(V, x0, c, n, m, d, h_on_delta, N=150): """ Calculate the projection of a Solitary Wave onto a function space V x0: origin of solitary wave on domain c: wave speed n: permeability exponent m: bulk viscosity exponent d: wave dimension h_on_delta: scale length in compaction lengths N: number of collocation points for sinc method """ # initialize Solitary Wave profile rr, ff = wave_profile(c, n, m, d, N) # initialize the radial Expression function dim = V.mesh().geometry().dim() R = radial_expression(d, dim) R.x0 = x0[0] if dim >= 2: R.x1 = x0[1] if dim == 3: R.x2 = x0[2] # project r onto Function f f = project(R, V) # scale R by h_on_delta fx = f.vector() fx *= h_on_delta #get numpy array for radial function and interpolate using sinc rmesh = fx.array() # get numpy array phi = sincinterp_e(rr, ff - 1.0, rmesh) + 1.0 # reload phi onto function for i in range(fx.size()): fx[i] = phi[i] return f
def ProjectSolitaryWave(V,x0,c,n,m,d,h_on_delta,N=150): """ Calculate the projection of a Solitary Wave onto a function space V x0: origin of solitary wave on domain c: wave speed n: permeability exponent m: bulk viscosity exponent d: wave dimension h_on_delta: scale length in compaction lengths N: number of collocation points for sinc method """ # initialize Solitary Wave profile rr, ff = wave_profile(c,n,m,d,N) # initialize the radial Expression function dim = V.mesh().geometry().dim() R = radial_expression(d,dim) R.x0 = x0[0] if dim >= 2: R.x1 = x0[1] if dim == 3: R.x2 = x0[2] # project r onto Function f f = project(R,V) # scale R by h_on_delta fx = f.vector() fx *= h_on_delta #get numpy array for radial function and interpolate using sinc rmesh = fx.array(); # get numpy array phi = sincinterp_e(rr, ff - 1.0, rmesh) + 1.0 # reload phi onto function for i in range(fx.size()): fx[i] = phi[i] return f
def eval(self,r): """ use sincinterp_e to return porosity at radius r""" f = sincinterp_e(self.r, self.f - 1.0, r) + 1.0 return 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