positions = np.hstack( ( x.reshape( ( -1, 1 ) ), y.reshape( ( -1, 1 ) ) ) ) limx = pos_door + 1.2 / opened_width # pon = [] for i in range( 16 ): a = 2 * np.pi * i / 16 pon.append( [ 1.5 + obstacle_radius * np.cos( a ), 0.5 + obstacle_radius * np.sin( a ), np.cos( a ), np.sin( a ) ] ) # domain domain = ConvexPolyhedraAssembly() domain.add_box( [ 0, 0 ], [ 2, 1 ] ) domain.add_box( [ pos_door, 0.5 - opened_width / 2 ], [ limx, 0.5 + opened_width / 2 ] ) if obstacle_radius: domain.add_convex_polyhedron( np.array( pon ), -1.0 ) domain.display_boundaries_vtk( directory + "/bound.vtk" ) # domain_asy = "draw((0,0)--(3,0)--(3,1)--(4,1)--(4,0)--(7,0)--(7,3)--(4,3)--(4,2)--(3,2)--(3,3)--(0,3)--cycle);\n" s = 0.5 * target_radius g = GradGrid( domain, [ [ limx - 2 * s, 0.5 ] ], s ) # iterations color_values = positions[ :, 1 ] color_values = ( color_values - np.min( color_values ) ) / np.ptp( color_values ) ot = OptimalTransport(domain, RadialFuncInBall()) ot.set_weights( np.ones( positions.shape[ 0 ] ) * target_radius ** 2 ) ot.set_masses( np.ones( positions.shape[ 0 ] ) * np.pi * target_radius ** 2 )
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))
R2 = positions[:, 0]**2 + positions[:, 1]**2 positions = positions[R2 <= 4] positions = positions[positions[:, 0] + positions[:, 1] > 1.0 / n] positions = positions[-positions[:, 0] + positions[:, 1] > 1.0 / n] N = positions.shape[0] rho0 = 1 / np.pi mass = 0.25 * rho0 * np.pi * 4 / N target_radius = (mass / np.pi)**0.5 # iterations weights = np.ones(positions.shape[0]) * target_radius**2 domain = ConvexPolyhedraAssembly() domain.add_convex_polyhedron([ [0, 0, +1, -1], [9, 9, 0, +1], [-9, 9, -1, -1], ]) domain.display_boundaries_vtk(directory + "/bounds.vtk") color_values = 0.5 * np.linalg.norm( positions, axis=1, keepdims=True, ord=2) color_values = (color_values - np.min(color_values)) / ( np.max(color_values) - np.min(color_values)) ot = OptimalTransport(domain, RadialFuncInBall()) ot.set_weights(weights) ot.set_masses(np.ones(positions.shape[0]) * mass) nb_timesteps = int(3 / target_radius) for i in range(nb_timesteps):
from pysdot.domain_types import ConvexPolyhedraAssembly from pysdot.radial_funcs import RadialFuncEntropy from pysdot import OptimalTransport import numpy as np # constants for n in [10]: directory = "results/diffusion_{}".format(n) # constants eps = n**-0.5 # domain domain = ConvexPolyhedraAssembly() domain.add_convex_polyhedron([[-1, -1, -1, 0], [-1, -1, 0, -1], [+2, -1, 1, -1], [-1, +2, 0, +1]]) domain.display_boundaries_vtk(directory + "/bounds.vtk") # positions = [] for y in np.linspace(0, 1, n): for x in np.linspace(0, 1, n): positions.append([x, y]) positions = np.array(positions) # iterations max_w = -1 min_w = 0 ot = OptimalTransport(domain, RadialFuncEntropy(eps))