def u_init(self): """ Routine to compute the starting values for the particles Returns: particle set filled with initial data """ u0 = self.u0 N = self.nparts u = particles(N) if u0[2][0] is not 1 or u0[3][0] is not 1: print('Error: so far only q = m = 1 is implemented (I think)') exit() # set first particle to u0 u.pos.values[0] = u0[0][0] u.pos.values[1] = u0[0][1] u.pos.values[2] = u0[0][2] u.vel.values[0] = u0[1][0] u.vel.values[1] = u0[1][1] u.vel.values[2] = u0[1][2] u.q[0] = u0[2][0] u.m[0] = u0[3][0] # initialize random seed np.random.seed(N) comx = u.pos.values[0] comy = u.pos.values[1] comz = u.pos.values[2] for n in range(1,N): # draw 3 random variables in [-1,1] to shift positions r = 2*np.random.random_sample(3)-1 u.pos.values[3*n ] = r[0]+u0[0][0] u.pos.values[3*n+1] = r[1]+u0[0][1] u.pos.values[3*n+2] = r[2]+u0[0][2] # draw 3 random variables in [-5,5] to shift velocities r = 10*np.random.random_sample(3)-5 u.vel.values[3*n ] = r[0]+u0[1][0] u.vel.values[3*n+1] = r[1]+u0[1][1] u.vel.values[3*n+2] = r[2]+u0[1][2] u.q[n] = u0[2][0] u.m[n] = u0[3][0] # gather positions to check center comx += u.pos.values[3*n ] comy += u.pos.values[3*n+1] comz += u.pos.values[3*n+2] print('Center of positions:',comx/N,comy/N,comz/N) return u
def u_init(self): """ Routine to compute the starting values for the particles Returns: particle set filled with initial data """ u0 = self.u0 N = self.nparts u = particles(N) if u0[2][0] is not 1 or u0[3][0] is not 1: print('Error: so far only q = m = 1 is implemented (I think)') exit() # set first particle to u0 u.pos.values[0] = u0[0][0] u.pos.values[1] = u0[0][1] u.pos.values[2] = u0[0][2] u.vel.values[0] = u0[1][0] u.vel.values[1] = u0[1][1] u.vel.values[2] = u0[1][2] u.q[0] = u0[2][0] u.m[0] = u0[3][0] # initialize random seed np.random.seed(N) comx = u.pos.values[0] comy = u.pos.values[1] comz = u.pos.values[2] for n in range(1, N): # draw 3 random variables in [-1,1] to shift positions r = 2 * np.random.random_sample(3) - 1 u.pos.values[3 * n] = r[0] + u0[0][0] u.pos.values[3 * n + 1] = r[1] + u0[0][1] u.pos.values[3 * n + 2] = r[2] + u0[0][2] # draw 3 random variables in [-5,5] to shift velocities r = 10 * np.random.random_sample(3) - 5 u.vel.values[3 * n] = r[0] + u0[1][0] u.vel.values[3 * n + 1] = r[1] + u0[1][1] u.vel.values[3 * n + 2] = r[2] + u0[1][2] u.q[n] = u0[2][0] u.m[n] = u0[3][0] # gather positions to check center comx += u.pos.values[3 * n] comy += u.pos.values[3 * n + 1] comz += u.pos.values[3 * n + 2] print('Center of positions:', comx / N, comy / N, comz / N) return u
def u_exact(self, t): """ Routine to compute the exact trajectory at time t (only for single-particle setup) Args: t: current time Returns: particle type containing the exact position and velocity """ # some abbreviations wE = self.omega_E wB = self.omega_B N = self.nparts u0 = self.u0 assert N == 1 u = particles(1) wbar = np.sqrt(2) * wE # position and velocity in z direction is easy to compute u.pos.values[2] = u0[0][2] * np.cos( wbar * t) + u0[1][2] / wbar * np.sin(wbar * t) u.vel.values[2] = -u0[0][2] * wbar * np.sin( wbar * t) + u0[1][2] * np.cos(wbar * t) # define temp. variables to compute complex position Op = 1 / 2 * (wB + np.sqrt(wB**2 - 4 * wE**2)) Om = 1 / 2 * (wB - np.sqrt(wB**2 - 4 * wE**2)) Rm = (Op * u0[0][0] + u0[1][1]) / (Op - Om) Rp = u0[0][0] - Rm Im = (Op * u0[0][1] - u0[1][0]) / (Op - Om) Ip = u0[0][1] - Im # compute position in complex notation w = np.complex(Rp, Ip) * np.exp(-np.complex(0, Op * t)) + np.complex( Rm, Im) * np.exp(-np.complex(0, Om * t)) # compute velocity as time derivative of the position dw = -1j * Op * np.complex( Rp, Ip) * np.exp(-np.complex(0, Op * t)) - 1j * Om * np.complex( Rm, Im) * np.exp(-np.complex(0, Om * t)) # get the appropriate real and imaginary parts u.pos.values[0] = w.real u.vel.values[0] = dw.real u.pos.values[1] = w.imag u.vel.values[1] = dw.imag return u
def u_exact(self,t): """ Routine to compute the exact trajectory at time t Args: t: current time Returns: particle type containing the exact position and velocity """ u0 = self.u0 # some abbreviations u = particles(1) # # we need a Newton iteration to get x, the rest will follow... # x1 = 0 # # Fx = x1 - 1/4*self.a0**2*(t-x1 + 1/2*(2*self.delta**2-1)*np.sin(2*t-2*x1)) # dFx = 1 + 1/4*self.a0**2*(1 + (2*self.delta**2-1)*np.cos(2*t-2*x1)) # # res = abs(Fx) # while res > 1E-12: # print(res) # x1 -= Fx/dFx # Fx = x1 - 1/4*self.a0**2*(t-x1 + 1/2*(2*self.delta**2-1)*np.sin(2*t-2*x1)) # dFx = 1 + 1/4*self.a0**2*(1 + (2*self.delta**2-1)*np.cos(2*t-2*x1)) # res = abs(Fx) # # Phi = t-x1 # # u.pos.values[0] = 1/4*self.a0**2*(Phi + 1/2*(2*self.delta**2-1)*np.sin(2*Phi)) # u.pos.values[1] = self.delta*self.a0*np.sin(Phi) # u.pos.values[2] = -(1-self.delta**2)**(1/2)*self.a0*np.cos(Phi) # # u.vel.values[0] = 0 # u.vel.values[1] = 0 # u.vel.values[2] = 0 u.pos.values[0] = u0[0][0] u.pos.values[1] = u0[0][1] u.pos.values[2] = u0[0][2] u.vel.values[0] = u0[1][0] u.vel.values[1] = u0[1][1] u.vel.values[2] = u0[1][2] u.q[:] = u0[2][0] u.m[:] = u0[3][0] return u
def u_exact(self, t): """ Routine to compute the exact trajectory at time t Args: t: current time Returns: particle type containing the exact position and velocity """ u0 = self.u0 # some abbreviations u = particles(1) # # we need a Newton iteration to get x, the rest will follow... # x1 = 0 # # Fx = x1 - 1/4*self.a0**2*(t-x1 + 1/2*(2*self.delta**2-1)*np.sin(2*t-2*x1)) # dFx = 1 + 1/4*self.a0**2*(1 + (2*self.delta**2-1)*np.cos(2*t-2*x1)) # # res = abs(Fx) # while res > 1E-12: # print(res) # x1 -= Fx/dFx # Fx = x1 - 1/4*self.a0**2*(t-x1 + 1/2*(2*self.delta**2-1)*np.sin(2*t-2*x1)) # dFx = 1 + 1/4*self.a0**2*(1 + (2*self.delta**2-1)*np.cos(2*t-2*x1)) # res = abs(Fx) # # Phi = t-x1 # # u.pos.values[0] = 1/4*self.a0**2*(Phi + 1/2*(2*self.delta**2-1)*np.sin(2*Phi)) # u.pos.values[1] = self.delta*self.a0*np.sin(Phi) # u.pos.values[2] = -(1-self.delta**2)**(1/2)*self.a0*np.cos(Phi) # # u.vel.values[0] = 0 # u.vel.values[1] = 0 # u.vel.values[2] = 0 u.pos.values[0] = u0[0][0] u.pos.values[1] = u0[0][1] u.pos.values[2] = u0[0][2] u.vel.values[0] = u0[1][0] u.vel.values[1] = u0[1][1] u.vel.values[2] = u0[1][2] u.q[:] = u0[2][0] u.m[:] = u0[3][0] return u
def prolong_space(self, G): """ Dummy prolongation routine Args: G: the coarse level data (easier to access than via the coarse attribute) """ if isinstance(G, particles): F = particles(G) elif isinstance(G, fields): F = fields(G) else: print('Transfer error') exit() return F
def prolong_space(self,G): """ Dummy prolongation routine Args: G: the coarse level data (easier to access than via the coarse attribute) """ if isinstance(G,particles): F = particles(G) elif isinstance(G,fields): F = fields(G) else: print('Transfer error') exit() return F
def restrict_space(self, F): """ Dummy restriction routine Args: F: the fine level data (easier to access than via the fine attribute) """ if isinstance(F, particles): G = particles(F) elif isinstance(F, fields): G = fields(F) else: print('Transfer error') exit() return G
def restrict_space(self,F): """ Dummy restriction routine Args: F: the fine level data (easier to access than via the fine attribute) """ if isinstance(F,particles): G = particles(F) elif isinstance(F,fields): G = fields(F) else: print('Transfer error') exit() return G
def u_exact(self,t): """ Routine to compute the exact trajectory at time t (only for single-particle setup) Args: t: current time Returns: particle type containing the exact position and velocity """ # some abbreviations wE = self.omega_E wB = self.omega_B N = self.nparts u0 = self.u0 assert N == 1 u = particles(1) wbar = np.sqrt(2)*wE # position and velocity in z direction is easy to compute u.pos.values[2] = u0[0][2]*np.cos(wbar*t) + u0[1][2]/wbar*np.sin(wbar*t) u.vel.values[2] = -u0[0][2]*wbar*np.sin(wbar*t) + u0[1][2]*np.cos(wbar*t) # define temp. variables to compute complex position Op = 1/2*(wB + np.sqrt(wB**2-4*wE**2)) Om = 1/2*(wB - np.sqrt(wB**2-4*wE**2)) Rm = (Op*u0[0][0]+u0[1][1])/(Op-Om) Rp = u0[0][0] - Rm Im = (Op*u0[0][1]-u0[1][0])/(Op-Om) Ip = u0[0][1] - Im # compute position in complex notation w = np.complex(Rp,Ip)*np.exp(-np.complex(0,Op*t)) + np.complex(Rm,Im)*np.exp(-np.complex(0,Om*t)) # compute velocity as time derivative of the position dw = -1j*Op*np.complex(Rp,Ip)*np.exp(-np.complex(0,Op*t)) - 1j*Om*np.complex(Rm,Im)*np.exp(-np.complex(0,Om*t)) # get the appropriate real and imaginary parts u.pos.values[0] = w.real u.vel.values[0] = dw.real u.pos.values[1] = w.imag u.vel.values[1] = dw.imag return u
def check_datatypes_particles(init): from pySDC.datatype_classes.particles import particles from pySDC.datatype_classes.particles import acceleration p1 = particles(init) p2 = particles(p1) p5 = particles(init) p1.pos.values[:] = 1.0 p2.pos.values[:] = 2.0 p1.vel.values[:] = 10.0 p2.vel.values[:] = 20.0 p3 = p1 + p2 p4 = p1 - p2 p5.pos = 0.1*p1.vel p6 = p1 p7 = abs(p1) a1 = acceleration(init) a2 = acceleration(a1) p8 = particles(p1) a1.values[:] = 100.0 a2.values[:] = 200.0 a3 = a1 + a2 p8.vel = 0.1*a1 p8.pos = 0.1*(0.1*a1) assert isinstance(p3,type(p1)) assert isinstance(p4,type(p1)) assert isinstance(p5.pos,type(p1.pos)) assert isinstance(p6,type(p1)) assert isinstance(p7,float) assert isinstance(a2,type(a1)) assert isinstance(p8.pos,type(p1.pos)) assert isinstance(p8.vel,type(p1.vel)) assert isinstance(0.1*0.1*a1,type(p1.vel)) assert p2 is not p1 assert p3 is not p1 assert p4 is not p1 assert p5 is not p1 assert p6 is p1 assert a2 is not a1 assert a3 is not a1 assert np.shape(p3.pos.values) == np.shape(p1.pos.values) assert np.shape(p4.pos.values) == np.shape(p1.pos.values) assert np.shape(p3.vel.values) == np.shape(p1.vel.values) assert np.shape(p4.vel.values) == np.shape(p1.vel.values) assert np.shape(a2.values) == np.shape(a1.values) assert np.all(p3.pos.values==3.0) assert np.all(p4.pos.values==-1.0) assert np.all(p3.vel.values==30.0) assert np.all(p4.vel.values==-10.0) assert np.all(p5.pos.values==1.0) assert p7 >= 0 assert np.all(p8.pos.values==1.0) assert np.all(p8.vel.values==10.0) assert np.all(a3.values==300.0)