def get_solution_at_time(self, t): p4 = self.get_post_shock_pressure_p4() u4, rho4, w = self.get_post_shock_density_and_velocity_and_shock_speed( p4) #compute values at foot of rarefaction p3 = p4 u3 = u4 rho3 = self.rho1 * (p3 / self.p1)**(1. / self.gamma) c1 = sqrt(self.gamma * self.p1 / self.rho1) c3 = sqrt(self.gamma * p3 / rho3) xi = 0.5 | length xr = 1.0 | length xl = 0.0 | length xsh = xi + w * t xcd = xi + u3 * t xft = xi + (u3 - c3) * t xhd = xi - c1 * t gm1 = self.gamma - 1.0 gp1 = self.gamma + 1.0 dx = (xr - xl) / (self.number_of_points - 1) x = xl + dx * arange(self.number_of_points) rho = VectorQuantity.zeros(self.number_of_points, density) p = VectorQuantity.zeros(self.number_of_points, mass / (length * time**2)) u = VectorQuantity.zeros(self.number_of_points, speed) for i in range(self.number_of_points): if x[i] < xhd: rho[i] = self.rho1 p[i] = self.p1 u[i] = self.u1 elif x[i] < xft: u[i] = 2. / (self.gamma + 1.0) * (c1 + (x[i] - xi) / t) fact = 1. - 0.5 * gm1 * u[i] / c1 rho[i] = self.rho1 * fact**(2. / gm1) p[i] = self.p1 * fact**(2. * self.gamma / gm1) elif x[i] < xcd: rho[i] = rho3 p[i] = p3 u[i] = u3 elif x[i] < xsh: rho[i] = rho4 p[i] = p4 u[i] = u4 else: rho[i] = self.rho5 p[i] = self.p5 u[i] = self.u5 return x, rho, p, u
def get_solution_at_time(self, t): p4 = self.get_post_shock_pressure_p4() u4, rho4, w = self.get_post_shock_density_and_velocity_and_shock_speed( p4) # compute values at foot of rarefaction p3 = p4 u3 = u4 rho3 = self.rho1 * (p3 / self.p1)**(1. / self.gamma) c1 = sqrt(self.gamma * self.p1 / self.rho1) c3 = sqrt(self.gamma * p3 / rho3) xi = 0.5 | length xr = 1.0 | length xl = 0.0 | length xsh = xi + w * t xcd = xi + u3 * t xft = xi + (u3 - c3) * t xhd = xi - c1 * t gm1 = self.gamma - 1.0 gp1 = self.gamma + 1.0 dx = (xr - xl) / (self.number_of_points - 1) x = xl + dx * arange(self.number_of_points) rho = VectorQuantity.zeros(self.number_of_points, density) p = VectorQuantity.zeros( self.number_of_points, mass / (length * time**2)) u = VectorQuantity.zeros(self.number_of_points, speed) for i in range(self.number_of_points): if x[i] < xhd: rho[i] = self.rho1 p[i] = self.p1 u[i] = self.u1 elif x[i] < xft: u[i] = 2. / (self.gamma + 1.0) * (c1 + (x[i] - xi) / t) fact = 1. - 0.5 * gm1 * u[i] / c1 rho[i] = self.rho1 * fact ** (2. / gm1) p[i] = self.p1 * fact ** (2. * self.gamma / gm1) elif x[i] < xcd: rho[i] = rho3 p[i] = p3 u[i] = u3 elif x[i] < xsh: rho[i] = rho4 p[i] = p4 u[i] = u4 else: rho[i] = self.rho5 p[i] = self.p5 u[i] = self.u5 return x, rho, p, u
def __init__(self, name, shape, unit): InMemoryAttribute.__init__(self, name) self.quantity = VectorQuantity.zeros( shape, unit, )
def particleset_potential(particles, smoothing_length_squared=zero, G=constants.G, gravity_code=None, block_size=0): """ Returns the potential at the position of each particle in the set. :argument smooting_length_squared: gravitational softening, added to every distance**2. :argument G: gravitational constant, need to be changed for particles in different units systems >>> from amuse.datamodel import Particles >>> particles = Particles(2) >>> particles.x = [0.0, 1.0] | units.m >>> particles.y = [0.0, 0.0] | units.m >>> particles.z = [0.0, 0.0] | units.m >>> particles.mass = [1.0, 1.0] | units.kg >>> particles.potential() quantity<[-6.67428e-11, -6.67428e-11] m**2 * s**-2> """ n = len(particles) if block_size == 0: max = 100000 * 100 #100m floats block_size = max // n if block_size == 0: block_size = 1 #if more than 100m particles, then do 1 by one mass = particles.mass x_vector = particles.x y_vector = particles.y z_vector = particles.z potentials = VectorQuantity.zeros(len(mass), mass.unit / x_vector.unit) inf_len = numpy.inf | x_vector.unit offset = 0 newshape = (n, 1) x_vector_r = x_vector.reshape(newshape) y_vector_r = y_vector.reshape(newshape) z_vector_r = z_vector.reshape(newshape) mass_r = mass.reshape(newshape) while offset < n: if offset + block_size > n: block_size = n - offset x = x_vector[offset:offset + block_size] y = y_vector[offset:offset + block_size] z = z_vector[offset:offset + block_size] indices = numpy.arange(block_size) dx = x_vector_r - x dy = y_vector_r - y dz = z_vector_r - z dr_squared = (dx * dx) + (dy * dy) + (dz * dz) dr = (dr_squared + smoothing_length_squared).sqrt() index = (indices + offset, indices) dr[index] = inf_len potentials += (mass[offset:offset + block_size] / dr).sum(axis=1) offset += block_size return -G * potentials
def increase_to_length(self, newlength): delta = newlength - len(self.quantity) if delta == 0: return deltashape = list(self.quantity.shape) deltashape[0] = delta zeros_for_concatenation = VectorQuantity.zeros(deltashape, self.quantity.unit) self.quantity.extend(zeros_for_concatenation)
def particleset_potential(particles, smoothing_length_squared = zero, G = constants.G, gravity_code = None, block_size = 0): """ Returns the potential at the position of each particle in the set. :argument smooting_length_squared: gravitational softening, added to every distance**2. :argument G: gravitational constant, need to be changed for particles in different units systems >>> from amuse.datamodel import Particles >>> particles = Particles(2) >>> particles.x = [0.0, 1.0] | units.m >>> particles.y = [0.0, 0.0] | units.m >>> particles.z = [0.0, 0.0] | units.m >>> particles.mass = [1.0, 1.0] | units.kg >>> particles.potential() quantity<[-6.67428e-11, -6.67428e-11] m**2 * s**-2> """ n = len(particles) if block_size == 0: max = 100000 * 100 #100m floats block_size = max // n if block_size == 0: block_size = 1 #if more than 100m particles, then do 1 by one mass = particles.mass x_vector = particles.x y_vector = particles.y z_vector = particles.z potentials = VectorQuantity.zeros(len(mass),mass.unit/x_vector.unit) inf_len = numpy.inf | x_vector.unit offset = 0 newshape =(n, 1) x_vector_r = x_vector.reshape(newshape) y_vector_r = y_vector.reshape(newshape) z_vector_r = z_vector.reshape(newshape) mass_r=mass.reshape(newshape) while offset < n: if offset + block_size > n: block_size = n - offset x = x_vector[offset:offset+block_size] y = y_vector[offset:offset+block_size] z = z_vector[offset:offset+block_size] indices = numpy.arange(block_size) dx = x_vector_r - x dy = y_vector_r - y dz = z_vector_r - z dr_squared = (dx * dx) + (dy * dy) + (dz * dz) dr = (dr_squared+smoothing_length_squared).sqrt() index = (indices + offset, indices) dr[index] = inf_len potentials += (mass[offset:offset+block_size]/dr).sum(axis=1) offset += block_size return -G * potentials
def particleset_potential(particles, smoothing_length_squared = zero, G = constants.G): """ Returns the potential at the position of each particle in the set. :argument smooting_length_squared: gravitational softening, added to every distance**2. :argument G: gravitational constant, need to be changed for particles in different units systems >>> from amuse.datamodel import Particles >>> particles = Particles(2) >>> particles.x = [0.0, 1.0] | units.m >>> particles.y = [0.0, 0.0] | units.m >>> particles.z = [0.0, 0.0] | units.m >>> particles.mass = [1.0, 1.0] | units.kg >>> particles.potential() quantity<[-6.67428e-11, -6.67428e-11] m**2 * s**-2> """ mass = particles.mass x_vector = particles.x y_vector = particles.y z_vector = particles.z potentials = VectorQuantity.zeros(len(mass),mass.unit/x_vector.unit) for i in range(len(particles) - 1): x = x_vector[i] y = y_vector[i] z = z_vector[i] dx = x - x_vector[i+1:] dy = y - y_vector[i+1:] dz = z - z_vector[i+1:] dr_squared = (dx * dx) + (dy * dy) + (dz * dz) dr = (dr_squared+smoothing_length_squared).sqrt() potentials[i]-= (mass[i+1:]/dr).sum() potentials[i+1:]-= mass[i]/dr return G * potentials