def run(n, base_filename, l=0.5): os.system("rm {}*.vtk".format(base_filename)) # initial conditions domain = ConvexPolyhedraAssembly() domain.add_box([0, 0], [1, 1]) positions = [] velocities = [] radius = 0.5 * l / n for y in np.linspace(radius, l - radius, n): for x in np.linspace(0.5 - l / 2 + radius, 0.5 + l / 2 - radius, n): nx = x + 0 * radius * (np.random.rand() - 0.5) ny = y + 0 * radius + 0 * radius * (np.random.rand() - 0.5) if (nx - 0.5)**2 + (ny - 0.5 * l)**2 < (0.5 * l)**2: velocities.append([0, -radius / 5]) positions.append([nx, ny]) masses = np.ones(len(positions)) * l**2 / n**2 # simulation fs = FluidSystem(domain, positions, velocities, masses, base_filename) fs.coeff_centroid_force = 1e-5 fs.display() for num_iter in range(500): print("num_iter:", num_iter, "time:", fs.time) fs.make_step() fs.display()
def make_square(box=[0, 0, 1, 1]): """ Constructs a square domain with uniform measure (source measure 'rho'). To be passed to the 'newton_ot' and 'PowerDiagram' functions. Args: box (list): coordinates of the bottom-left and top-right corners Returns: domain (pysdot.domain_types): domain """ domain = ConvexPolyhedraAssembly() domain.add_box([box[0], box[1]], [box[2], box[3]]) return domain
def run(n, base_filename, l=0.5): # domain domain = ConvexPolyhedraAssembly() domain.add_box([0, 0], [1, 1]) # initial positions, weights and masses positions = [] if n == 1: radius = 0.3 mass = 3.14159 * radius**2 positions.append([0.5, radius]) else: radius = l / (2 * (n - 1)) mass = l**2 / n**2 for y in np.linspace(radius, l - radius, n): for x in np.linspace(0.5 - l / 2 + radius, 0.5 + l / 2 - radius, n): nx = x + 0.0 * radius * (np.random.rand() - 0.5) ny = y + 0.0 * radius * (np.random.rand() - 0.5) + 0.5 * radius positions.append([nx, ny]) positions = np.array(positions) nb_diracs = positions.shape[0] # dim = positions.shape[ 1 ] # OptimalTransport ot = OptimalTransport(domain, RadialFuncInBall()) ot.set_weights(np.ones(nb_diracs) * radius**2) ot.set_masses(np.ones(nb_diracs) * mass) ot.set_positions(positions) ot.max_iter = 100 ot.adjust_weights() ot.display_vtk(base_filename + "0.vtk", points=True, centroids=True) # history of centroids ce = ot.get_centroids() ce[:, 1] += radius / 10 bh = [ce] dt = 1.0 for num_iter in range(200): print("num_iter", num_iter) bh.append(ot.get_centroids()) fit_positions(ot, bh, dt) # display n1 = int(num_iter / 1) + 1 ot.display_vtk(base_filename + "{}.vtk".format(n1), points=True, centroids=True)
def run(n, base_filename, l=0.5): # domain domain = ConvexPolyhedraAssembly() domain.add_box([0, 0], [1, 1]) # initial positions, weights and masses positions = [] if n == 1: radius = 0.3 mass = 3.14159 * radius**2 positions.append([0.5, radius]) else: radius = l / (2 * (n - 1)) mass = l**2 / n**2 for y in np.linspace(radius, l - radius, n): for x in np.linspace(radius, l - radius, n): nx = x # + 0.2 * radius * (np.random.rand() - 0.5) ny = y # + 0.2 * radius * (np.random.rand() - 0.5) positions.append([nx, ny]) positions = np.array(positions) nb_diracs = positions.shape[0] dim = positions.shape[1] # OptimalTransport ot = OptimalTransport(domain, RadialFuncInBall()) ot.set_weights(np.ones(nb_diracs) * radius**2) ot.set_masses(np.ones(nb_diracs) * mass) ot.set_positions(positions) ot.adjust_weights() ot.display_vtk(base_filename + "0.vtk", points=True) g = np.zeros((nb_diracs, dim)) g[:, 1] = -0.001 bh = [ot.get_centroids()] # history of centroids for num_iter in range(50): bh.append(ot.get_centroids()) print("num_iter", num_iter) # proposition for centroids bn = 2 * bh[-1] - bh[-2] + g # find a new set of diracs parameters (position and weight) # to be as close to the new centroids as possible update_positions_to_get_centroids(ot, bn) # display n1 = num_iter + 1 ot.display_vtk(base_filename + "{}.vtk".format(n1), points=True)
def run(n, base_filename): domain = ConvexPolyhedraAssembly() domain.add_box([0, 0], [1, 1]) domain.add_box([0.2, -0.5], [0.8, 0]) positions = [] radius = 0.5 / (2 * (n - 1)) for y in np.linspace(radius, 0.5 + radius, n): for x in np.linspace(radius, 0.5 + radius, n): positions.append([x, y]) nb_diracs = len(positions) # ot = OptimalTransport(domain, RadialFuncInBall()) ot.set_masses(np.ones(nb_diracs) * 0.8 * 0.5**2 / nb_diracs) ot.set_weights(np.ones(nb_diracs) * radius**2) ot.set_positions(np.array(positions)) b_old = ot.pd.centroids() ot.adjust_weights() ot.display_vtk(base_filename + "0.vtk") nb_timesteps = int(20 / radius) v = np.zeros((nb_diracs, 2)) dt = 0.003 * radius for i in range(nb_timesteps): print(i, "/", nb_timesteps) # first trial v[:, 1] -= 1 p_old = ot.get_positions() p_tst = p_old + dt * v ot.set_positions(p_tst) ot.adjust_weights() # display d = int(n / 5) if i % d == 0: ot.display_vtk(base_filename + "{:03}.vtk".format(1 + int(i / d))) # corrections b_new = ot.pd.centroids() v = (b_new - b_old) / dt ot.set_positions(b_new) b_old = b_new
def setUp(self): rf = RadialFuncArfd( lambda r: ((1 - r * r) * (r < 1))**2.5, # value lambda w: 1 / w**0.5, # input scaling lambda w: w**2.5, # output scaling lambda r: 2.5 * ((1 - r * r) * (r < 1))**1.5, # value for the der wrt weight lambda w: 1 / w**0.5, # input scaling for the der wrt weight lambda w: w**1.5, # output scaling for the der wrt weight [1], # stops (radii values where we may have discontinuities) 1e-8 # precision ) # set up a domain, with only 1 dirac domain = ConvexPolyhedraAssembly() domain.add_box([0.0, 0.0], [2.0, 1.0]) self.pd = PowerDiagram(domain=domain, radial_func=rf)
def setUp(self): rf = RadialFuncArfd( lambda r: (1 - r * r) * (r < 1), # value lambda w: 1 / w**0.5, # input (radius) scaling lambda w: w, # output scaling lambda r: r < 1, # value for the der wrt weight lambda w: 1 / w**0.5, # input scaling for the der wrt weight lambda w: 1, # output scaling for the der wrt weight [1] # stops (radii value where we may have discontinuities) ) # should use only 2 polynomials self.assertEqual(rf.nb_polynomials(), 2) # set up a domain, with only 1 dirac domain = ConvexPolyhedraAssembly() domain.add_box([0.0, 0.0], [2.0, 1.0]) self.pd = PowerDiagram(domain=domain, radial_func=rf)
positions.append([r * np.cos(a), r * np.sin(a)]) ot.set_positions(np.array(positions)) if cpt == 0: ot.set_weights(np.array(masses) / np.pi * 0.25) ot.set_masses(np.array(masses)) ot.max_iter = 100 ot.adjust_weights(relax=0.5) ot.display_vtk("lc_{}.vtk".format(cpt)) return ot.pd.der_boundary_integral() domain = ConvexPolyhedraAssembly() domain.add_box([0, 0], [10, 10]) crb = {} for n in range(30, 31): ot = OptimalTransport(domain, RadialFuncInBall()) k = "{}".format(n) crb[k] = [] cpt = 0 for coeff_r in [0.9875]: # np.linspace( 0.9875, 0.4, 120 ): e = test_discr(ot, n, coeff_r, cpt) print(e) # crb[ k ].append( [ coeff_r, e ] ) # cpt += 1 # for key, val in crb.items():
def setUp(self): self.domain = ConvexPolyhedraAssembly() self.domain.add_box([0.0, 0.0], [10.0, 10.0]) self.solver = Scipy.Solver()
def make_square(box=[0, 0, 1, 1]): density = ConvexPolyhedraAssembly() density.add_box([box[0], box[1]], [box[2], box[3]]) return density
def run(n, base_filename, l=0.5): # domain domain = ConvexPolyhedraAssembly() # domain.add_box([0, 0], [1, 1]) domain.add_convex_polyhedron([ # x y Nx Ny (ext) [0, 0, -1, -0.2], [0, 0, -0.2, -1], [1, 1, +1, 0], [1, 1, 0, +1], ]) # initial positions, weights and masses positions = [] if n == 1: radius = 0.2 else: radius = l / (2 * (n - 1)) for y in np.linspace(radius, l - radius, n): for x in np.linspace(radius, l - radius, n): nx = x + 0.2 * radius * (np.random.rand() - 0.5) ny = y + 0.2 * radius * (np.random.rand() - 0.5) positions.append([nx, ny]) positions = np.array(positions) nb_diracs = positions.shape[0] # OptimalTransport ot = OptimalTransport(domain, RadialFuncInBall()) ot.set_weights(np.ones(nb_diracs) * radius**2) ot.set_masses(np.ones(nb_diracs) * l**2 / nb_diracs) ot.set_positions(positions) ot.adjust_weights() ot.display_vtk(base_filename + "0.vtk") ot.set_positions(ot.get_centroids()) velocity = 0.0 * positions for num_iter in range(200): print("num_iter", num_iter) # barycenters at the beginning ot.adjust_weights() b_o = ot.get_centroids() # trial for the new barycenters velocity[:, 0] -= 0.05 * radius * 0.707 velocity[:, 1] -= 0.05 * radius * 0.707 b_n = b_o + velocity # optimisation of positions to go to the target barycenters ropt = scipy.optimize.minimize(obj, b_n.flatten(), (ot, b_n), tol=1e-4, method='BFGS', options={'eps': 1e-4 * radius}) positions = ropt.x.reshape((-1, 2)) ot.set_positions(positions) ot.adjust_weights() # new barycenters, corrected (minimize have update the weights) b_n = ot.get_centroids() velocity = b_n - b_o print(positions, velocity) # display ot.pd.display_vtk_points(base_filename + "pts_{}.vtk".format(num_iter + 1)) ot.display_vtk(base_filename + "{}.vtk".format(num_iter + 1))
def setUp(self): self.domain = ConvexPolyhedraAssembly() self.domain.add_box([0, 0], [1, 1])
def test_measure(self): domain = ConvexPolyhedraAssembly() domain.add_box([0, 0], [2, 1]) self.assertAlmostEqual(domain.measure(), 2.0)
def run(n, base_filename, l=0.5): # domain domain = ConvexPolyhedraAssembly() domain.add_box([0, 0], [1, 1]) # initial positions, weights and masses positions = [] radius = l / (2 * (n - 1)) mass = l**2 / n**2 for y in np.linspace(radius, l - radius, n): for x in np.linspace(0.5 - l / 2 + radius, 0.5 + l / 2 - radius, n): nx = x + 0.0 * radius * (np.random.rand() - 0.5) ny = y + 0.0 * radius * (np.random.rand() - 0.5) positions.append([nx, ny]) positions = np.array(positions) nb_diracs = positions.shape[0] dim = positions.shape[1] # OptimalTransport ot = OptimalTransport(domain, RadialFuncInBall()) ot.set_weights(np.ones(nb_diracs) * radius**2) ot.set_masses(np.ones(nb_diracs) * mass) ot.set_positions(positions) ot.max_iter = 100 ot.adjust_weights() ot.display_vtk(base_filename + "0.vtk", points=True, centroids=True) # gravity G = np.zeros((nb_diracs, dim)) G[:, 1] = -9.81 # eps = 0.5 dt = radius * 0.1 V = np.zeros((nb_diracs, dim)) M = np.stack([ot.get_masses() for d in range(dim)]).transpose() for num_iter in range(500): print("num_iter:", num_iter, "dt:", dt) C = ot.get_centroids() X = ot.get_positions() A = G + (C - ot.get_positions()) / (M * eps**2) while True: dV = dt * A dX = dt * (V + dV) if np.max(np.linalg.norm(dX, axis=1, ord=2)) < 0.2 * radius: dt *= 1.05 V += dV X += dX break dt *= 0.5 ot.set_positions(X) ot.adjust_weights() # display n1 = int(num_iter / 1) + 1 ot.display_vtk(base_filename + "{}.vtk".format(n1), points=True, centroids=True)