def eval_legendre_fenchel(mu, Y, psi): """ This function returns centers of laguerre cells Z, the delaunay triangulation of these points and u_Z, the Legendre-Fenchel transform of psi defined on Z. Parameters ---------- mu : Density_2 object Density of X ensemble Y : 2D array Points on the Y ensemble psi : 1D array Kantorovich potential values at Y Returns ------- Z : 2D array Laguerre cells centers coordinates T : delaunay_2 object Weighted Delaunay triangulation of Z u_Z : 1D array Legendre-Fenchel transform of psi """ # We find the center of each Laguerre cell # or their projection on the boundary for the cells that # intersect the boundary X = mu.vertices hull = ConvexHull(X) points = X[hull.vertices] Z = ma.ma.conforming_lloyd_2(mu,Y,psi,points)[0] # By definition, psi^*(z) = min_{y\in Y} |y - z|^2 - psi_y # Correspond to the c-transform of psi. # As Z[i] is in the Laguerre cell of Y[i], the formula can be simplified: psi_star = np.square(Y[:,0] - Z[:,0]) + np.square(Y[:,1] - Z[:,1]) - psi T = ma.delaunay_2(Z, psi_star) # We remove parasite triangles by checking the determinant det = np.zeros(len(T)) i = 0 T_tmp = [] for triangle in T: A = Z[triangle[0]] B = Z[triangle[1]] C = Z[triangle[2]] AB = B-A BC = C-B det[i] = AB[0]*BC[1] - AB[1]*BC[0] if det[i] > 1e-10: T_tmp.append(triangle) i += 1 T = np.array(T_tmp) # Modification to get a convex function u(z) such # that \grad u(z) = y if z \in Lag_Y^\psi(y) u_Z = (np.square(Z[:,0]) + np.square(Z[:,1]))/2 - psi_star/2 return Z,T,u_Z
def eady_OT(Y, bbox, dens, verbose = False, w = np.array([])): H = bbox[3] #initialise discrete target density, uniform over #N points nx = Y[:,0].size nu = np.ones(nx) nu = (dens.mass() / np.sum(nu)) * nu if len(w)>0: print('trying guess') [f,m,g,Hs] = dens.kantorovich(Y, nu, w) eps0 = np.min(m) if eps0 < 1e-10: w = np.array([]) if len(w)==0: print(w,'making standard guess') #initalise weights to ensure positive cell mass w = 0.*Y[:,0] Z = Y[:,1] mask = np.where(Z>0.9999*H) w[mask] = (Z[mask] - 0.9999*H)**2 mask = np.where(Z<0.0001*H) w[mask] = (Z[mask] - 0.0001*H)**2 print(w) w = ma.optimal_transport_2(dens,Y,nu, w0=w, eps_g = 1.e-7,verbose=True) return w
def frontogenesis_timestep(N, days, tstepsize, Heun=None): tf = 60 * 60 * 24 * days #final time #initialise parameters from SG Eady model H = 1.e4 L = 1.e6 g = 10. f = 1.e-4 theta0 = 300. #create new directory to store results if Heun: newdir = "/scratchcomp04/cvr12/Results_" + str(days) + "D_" + str( N) + "N_" + str(int(tstepsize)) + "_heun" else: newdir = "/scratchcomp04/cvr12/Results_" + str(days) + "D_" + str( N) + "N_" + str(int(tstepsize)) + "_euler" os.mkdir(newdir) #initialise source density with periodic BCs in x bbox = np.array([-L, 0., L, H]) Xdens = pdx.sample_rectangle(bbox) f0 = np.ones(4) / (2 * H * L) rho = np.zeros(Xdens.shape[0]) T = ma.delaunay_2(Xdens, rho) dens = pdx.Periodic_density_in_x(Xdens, f0, T, bbox) #initialise points in geostrophic space [Y, thetap] = initialise_points(N, bbox, RegularMesh=True) Y = dens.to_fundamental_domain(Y) if Heun: #timestep using Heun's Method [Y, w, t] = heun_sg(Y, dens, tf, bbox, newdir, h=tstepsize, add_data=True) t.tofile(newdir + '/time.txt', sep=" ", format="%s") else: #timestep using forward euler scheme [Y, w, t] = forward_euler_sg(Y, dens, tf, bbox, newdir, h=tstepsize, add_data=True) t.tofile(newdir + '/time.txt', sep=" ", format="%s") return ('complete results ' + str(days) + 'D_' + str(N) + 'N_' + str(int(tstepsize)))
def periodic_laguerre_diagram_to_image(dens, Y, w, C, bbox, ww, hh): N = Y.shape[0] Y0 = dens.to_fundamental_domain(Y) x0 = dens.u[0] v = np.array([[0, 0], [x0, 0], [-x0, 0]]) Yf = np.zeros((3 * N, 2)) wf = np.hstack((w, w, w)) Cf = np.vstack((C, C, C)) for i in xrange(0, 3): Nb = N * i Ne = N * (i + 1) Yf[Nb:Ne, :] = Y0 + np.tile(v[i, :], (N, 1)) img = ma.laguerre_diagram_to_image(dens, Yf, wf, Cf, bbox, ww, hh) return (img)
def eady_OT(Y, bbox, dens, verbose=False): H = bbox[3] #initialise discrete target density, uniform over #N points nx = Y[:, 0].size nu = np.ones(nx) nu = (dens.mass() / np.sum(nu)) * nu #initalise weights to ensure positive cell mass w = 0. * Y[:, 0] Z = Y[:, 1] mask = Z > 0.9 * H w[mask] = (Z[mask] - 0.9 * H)**2 mask = Z < 0.1 * H w[mask] = (Z[mask] - 0.1 * H)**2 w = ma.optimal_transport_2(dens, Y, nu, w0=w, eps_g=1.e-5, verbose=False) return w
def euler_solve_lbfgs(shape, X, Y, p, k=2, nsmooth=4, sigma=0): N = X.shape[0] T = np.power(2, k) + 1 h = 1.0 / np.sqrt(N) # 1/h^2 = N S0 = np.zeros((2, N, 2)) S0[0] = X S0[1] = Y for j in xrange(k): T0 = S0.shape[0] T = 2 * T0 - 1 S = np.zeros((T, N, 2)) print "\nADDING TIMESTEPS (T=%d)" % T for i in xrange(T0 - 1): S[2 * i] = S0[i] mean = (S0[i] + S0[i + 1]) / 2 # when adding the first intermediate timestep, it might be # necessary to perturb the mean of the two point clouds # (this happens for the disk inversion, because in this # case mean == 0) if T0 == 2: mean = mean + sigma * np.random.randn(N, 2) # initial guess for the inserted timesteps S[2 * i + 1] = project_on_incompressible(ma.Density_2(shape), mean, verbose=True) S[T - 1] = S0[T0 - 1] S0 = S print "\nLBFGS OPTIMIZATION (T=%d)" % T lbda = 1 / np.power(h, p) S0 = euler_solve_lbfgs_step(shape, S0, X, Y, lbda) return S0
days) + "D_" + str(N) + "N_" + str(int(tstepsize)) + "_euler" imgdir = resultsdir + '/laguerre_diagrams_vgrescale' #os.mkdir(imgdir) #create triangulation with random vertices - fix for miscolouring #of pixels on diagonal as suggested by Q.MERIGOT Tdomain = np.array([[-L, 0.], [-L, H], [L, H], [L, 0.]]) Tpoints = np.random.rand(20, 2) Tpoints[:, 0] = Tpoints[:, 0] * 2 * L - L Tpoints[:, 1] = Tpoints[:, 1] * H Tri = np.vstack((Tdomain, Tpoints)) #initialise periodic density bbox = np.array([-L, 0., L, H]) T = ma.delaunay_2(Tri) f0 = np.ones(24) / 2 / L / H dens = pdx.Periodic_density_in_x(Tri, f0, T, bbox) M = int(np.ceil((60 * 60 * 24 * days) / tstepsize)) n = 0 count = 0 while n <= M: #retrieve results from file and reshape,points Y = np.fromfile(resultsdir + '/points_results_' + str(int(tstepsize)) + '/points_' + str(int(n)) + '.txt', sep=" ") l = int(Y.size / 2) Y = Y.reshape((l, 2)) #weights
def project_on_incompressible(dens,Z): N = Z.shape[0] nu = np.ones(N) * dens.mass()/N; w = ma.optimal_transport_2(dens, Z, nu, verbose=True) return dens.lloyd(Z,w)[0];
# the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. import sys sys.path.append('..'); import MongeAmpere as ma import numpy as np import scipy as sp import matplotlib.pyplot as plt import matplotlib.tri as tri N = 1000; X = np.random.rand(N,2); w = np.zeros(N); T = ma.delaunay_2(X,w); triang = tri.Triangulation(X[:,0], X[:,1], T); plt.figure() plt.gca().set_aspect('equal') plt.triplot(triang, 'bo-') plt.title('triplot of Delaunay triangulation') plt.show(); #print(T);
# along with this program. If not, see <http://www.gnu.org/licenses/>. import sys sys.path.append('..'); import MongeAmpere as ma import numpy as np import scipy as sp import scipy.optimize as opt import matplotlib.pyplot as plt import matplotlib.tri as tri X = np.array([[0,0],[1,0],[1,1],[0,1]], dtype=float); mu = np.ones(4); dens = ma.Density_2(X,mu); # target is a random set of points N = 100; Y = np.random.rand(N,2); w = np.zeros(N); for i in xrange(1,50): [Z,m] = dens.lloyd(Y, w); Y=Z; plt.cla(); T = ma.delaunay_2(Y,w); triang = tri.Triangulation(Y[:,0], Y[:,1], T); plt.gca().set_aspect('equal') plt.triplot(triang, 'bo-') plt.pause(.01)
def project_on_incompressible2(dens, Z, verbose=False): N = Z.shape[0] nu = np.ones(N) * dens.mass() / N w = ma.optimal_transport_2(dens, Z, nu, verbose=verbose) return dens.lloyd(Z, w)[0], w
from builtins import range import sys sys.path.append('..'); import MongeAmpere as ma import numpy as np import scipy as sp import scipy.optimize as opt import matplotlib.pyplot as plt import matplotlib.tri as tri X = np.array([[0,0],[1,0],[1,1],[0,1]], dtype=float); mu = np.ones(4); dens = ma.Density_2(X,mu); # target is a random set of points N = 100; Y = np.random.rand(N,2); w = np.zeros(N); for i in range(1,50): [Z,m] = dens.lloyd(Y, w); Y=Z; plt.cla(); T = ma.delaunay_2(Y,w); triang = tri.Triangulation(Y[:,0], Y[:,1], T); plt.gca().set_aspect('equal') plt.triplot(triang, 'bo-') plt.pause(.01)
E = dens.restricted_laguerre_edges(Y,w) nan = float('nan') N = E.shape[0] x = np.zeros(3*N) y = np.zeros(3*N) a = np.array(range(0,N)) x[3*a] = E[:,0] x[3*a+1] = E[:,2] x[3*a+2] = nan y[3*a] = E[:,1] y[3*a+1] = E[:,3] y[3*a+2] = nan plt.plot(Y[:,0],Y[:,1],'.') plt.plot(x,y,color=[1,0,0],linewidth=1,aa=True) dens = ma.Density_2(np.array([[0.,0.],[1.,0.],[1.,1.],[0.,1.]])) N = 400 s = np.arange(0.,1.,0.01) x,y = np.meshgrid(s,s) nx = x.size x = np.reshape(x,(nx,)) y = np.reshape(y,(nx,)) Y = np.array([x,y]).T Y[:,1] += -(0.5-Y[:,1])*((Y[:,0]-0.5)**2 - 3./8.) #plt.plot(Y[:,0],Y[:,1],'.') nu = np.ones(nx) nu = (dens.mass() / np.sum(nu)) * nu; w = 0.*Y[:,0] w = ma.optimal_transport_2(dens,Y,nu, verbose=True) draw_laguerre_cells(dens,Y,w) plt.show()
# but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. import sys sys.path.append('..') import MongeAmpere as ma import numpy as np # source: uniform measure on the square with sidelength 2 X = np.array([[-1, -1], [1, -1], [1, 1], [-1, 1]], dtype=float) T = ma.delaunay_2(X, np.zeros(4)) print T mu = np.ones(4) / 4 dens = ma.Density_2(X, mu, T) print "mass=%g" % dens.mass() # target is a random set of points, with random weights N = 1000 Y = np.random.rand(N, 2) / 2 nu = 10 + np.random.rand(N) nu = (dens.mass() / np.sum(nu)) * nu # print "mass(nu) = %f" % sum(nu) # print "mass(mu) = %f" % dens.mass() #
def initialise_points(N, bbox, RegularMesh = None): '''Function to initialise a mesh over the domain [-L,L]x[0,H] and transform to geostrophic coordinates args: N: number of grid points in z direct, total number of points will be 2*N*N RegularMesh: controls whether the mesh is regular or an optimised sample of random points in the domain returns: A numpy array of coordinates of points in geostrophic space ''' H = bbox[3] L = bbox[2] #set up regular mesh or optimised sample of random points if RegularMesh: npts = N dx = 1./npts s = np.arange(dx*0.5,1.,dx) s1 = np.arange(-1. + dx*0.5,1.,dx) x,z = np.meshgrid(s1*L,s*H) nx = x.size x = np.reshape(x,(nx,)) z = np.reshape(z,(nx,)) y = np.array([x,z]).T else: npts = 2*N*N bbox = np.array([0., -0.5, 2., 0.5]) Xdens = sample_rectangle(bbox); f0 = np.ones(4)/2; w = np.zeros(Xdens.shape[0]); T = ma.delaunay_2(Xdens,w); Sdens = Periodic_density_in_x(Xdens,f0,T,bbox) X = ma.optimized_sampling_2(Sdens,npts,niter=5) X = Sdens.to_fundamental_domain(X) x = X[:,0]*L - L z = (X[:,1]+0.5)*H y = np.array([x,z]).T #define thetap from CULLEN 2006 g = 10. f = 1.e-4 theta0 = 300. C = 3e-6 CP = 0.1 Nsq = 40/H*g/theta0 buoyancy_stratification = (z-H/2)*Nsq # b = g*theta/theta_0 thetap = buoyancy_stratification/g*theta0 + CP*np.sin(np.pi*(x/L + z/H)) X = x Z = g*thetap/theta0/f/f Y = np.array([X,Z]).T return Y, thetap
def projection_on_incompressible_moments(dens, Z): N = Z.shape[0] nu = np.ones(N) * dens.mass()/N w0= estimate_dual_variable(dens, Z) w = ma.optimal_transport_2(dens, Z, nu, w0=w0, verbose=False) return dens.moments(Z,w)
N = E.shape[0] x = np.zeros(3 * N) y = np.zeros(3 * N) a = np.array(range(0, N)) x[3 * a] = E[:, 0] x[3 * a + 1] = E[:, 2] x[3 * a + 2] = nan y[3 * a] = E[:, 1] y[3 * a + 1] = E[:, 3] y[3 * a + 2] = nan #plt.plot(x,y,color=[1,0,0],linewidth=1,aa=True) return x, y #initialise source continuous density dens = ma.Density_2(np.array([[0., 0.], [1., 0.], [1., 1.], [0., 1.]])) #initialise periodic density in x bbox = np.array([0., 0., 1., 1.]) Xdens = pdx.sample_rectangle(bbox) f0 = np.ones(4) rho = np.zeros(Xdens.shape[0]) T = ma.delaunay_2(Xdens, rho) pdens = pdx.Periodic_density_in_x(Xdens, f0, T, bbox) #initialise points N = 20 Y = np.random.rand(N, 2) #initialise discrete target density nu = np.ones(N)
def validity_analysis_results(N, days, tstepsize, t0 = 0., Heun = None): #initialise parameters H = 1.e4 L = 1.e6 g = 10. f = 1.e-4 theta0 = 300 C = 3e-6 if Heun: print('heun') datadir = "Results_"+str(days)+"D_"+str(N)+"N_"+str(int(tstepsize))+"_heun/data" resultdir = "Results_"+str(days)+"D_"+str(N)+"N_"+str(int(tstepsize))+"_heun" plotsdir = "Results_"+str(days)+"D_"+str(N)+"N_"+str(int(tstepsize))+"_heun/plots" else: print('euler') datadir = "Results_"+str(days)+"D_"+str(N)+"N_"+str(int(tstepsize))+"_euler/data" resultdir = "Results_"+str(days)+"D_"+str(N)+"N_"+str(int(tstepsize))+"_euler" plotsdir = "Results_"+str(days)+"D_"+str(N)+"N_"+str(int(tstepsize))+"_euler/plots" os.mkdir(datadir) os.mkdir(plotsdir) #set up uniform density for domain Gamma bbox = np.array([-L, 0., L, H]) Xdens = pdx.sample_rectangle(bbox) f0 = np.ones(4)/2/L/H rho = np.zeros(Xdens.shape[0]) T = ma.delaunay_2(Xdens,rho) dens = pdx.Periodic_density_in_x(Xdens,f0,T,bbox) #set up plotting uniform density for domain Gamma bbox = np.array([-L, 0., L, H]) Xdens = pdx.sample_rectangle(bbox) npts = 100 Xrnd = 2*L*(np.random.rand(npts)-0.5) Zrnd = H*np.random.rand(npts) Xdens = np.concatenate((Xdens, np.array((Xrnd, Zrnd)).T)) f0 = np.ones(npts+4)/2/L/H rho = np.zeros(Xdens.shape[0]) T = ma.delaunay_2(Xdens,rho) pdens = pdx.Periodic_density_in_x(Xdens,f0,T,bbox) #set final time(t), step size (h) and total number of time steps(N) tf = 60*60*24*days h = tstepsize N = int(np.ceil((tf-t0)/h)) #initialise arrays to store data values KEmean = np.zeros(N+1) energy = np.zeros(N+1) vgmax = np.zeros(N+1) PE = np.zeros(N+1) KE = np.zeros(N+1) rmsv = np.zeros(N+1) w = np.fromfile(resultdir+'/weights_results_'+str(int(h))+'/weights_0.txt', sep = " ") ke = np.zeros((int(w.size),2)) vg = np.zeros((int(w.size),2)) t = np.array([t0 + n*h for n in range(N+1)]) Ndump = 100 for n in range(0,N+1, Ndump): print(n,N) try: Y = np.fromfile(resultdir+'/points_results_'+str(int(h))+'/points_'+str(n)+'.txt', sep = " ") w = np.fromfile(resultdir+'/weights_results_'+str(int(h))+'/weights_'+str(n)+'.txt', sep = " ") l = int(w.size) Y = Y.reshape((l,2)) except IOError: break #Plots C = Y[:,1].reshape((l,1)) print(C.shape, w.shape) img = periodic_laguerre_diagram_to_image(pdens,Y,w,C,bbox,100,100) plt.pcolor(img) plt.savefig(plotsdir+'/c_'+str(n)+'.jpg') plt.clf() plt.plot(Y[:,0], Y[:,1], '.') plt.savefig(plotsdir+'/Y_'+str(n)+'.jpg') plt.clf() #calculate centroids and mass of cells [Yc, m] = dens.lloyd(Y, w) mtile = np.tile(m,(2,1)).T #calculate second moments to find KE and maximum of vg [m1, I] = dens.moments(Y, w) #find kinetic energy, maximum value of vg and total energy ke[:,0] = 0.5*f*f*(m*Y[:,0]**2 - 2*Y[:,0]*m1[:,0] + I[:,0]) vg[:,0] = f*(Y[:,0] - Yc[:,0]) #map back to fundamental domain ke = dens.to_fundamental_domain(ke) vg = dens.to_fundamental_domain(vg) E = ke[:,0] - f*f*Y[:,1]*m1[:,1] + 0.5*f*f*H*Y[:,1]*m pe = - f*f*Y[:,1]*m1[:,1] + 0.5*f*f*H*Y[:,1]*m energy[n] = np.sum(E) KE[n] = np.sum(ke[:,0]) KEmean[n] = np.sum(ke[:,0])*float(l) rmsv[n] = np.sqrt(KEmean[n]) PE[n] = np.sum(pe) vgmax[n] = np.amax(vg[:,0]) energy.tofile(datadir+'/energy.txt',sep = " ",format = "%s") KEmean.tofile(datadir+'/KEmean.txt',sep = " ",format = "%s") vgmax.tofile(datadir+'/vgmax.txt',sep = " ",format = "%s") t.tofile(datadir+'/time.txt',sep = " ",format = "%s") PE.tofile(datadir+'/PE.txt',sep = " ",format = "%s") KE.tofile(datadir+'/KE.txt',sep = " ",format = "%s") rmsv.tofile(datadir+'/rmsv.txt',sep = " ",format = "%s") return('complete results '+str(days)+'D_'+str(N)+'N_'+str(int(tstepsize)))
# (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. import sys sys.path.append('..') import MongeAmpere as ma import numpy as np import scipy as sp import matplotlib.pyplot as plt import matplotlib.tri as tri N = 1000 X = np.random.rand(N, 2) w = np.zeros(N) T = ma.delaunay_2(X, w) triang = tri.Triangulation(X[:, 0], X[:, 1], T) plt.figure() plt.gca().set_aspect('equal') plt.triplot(triang, 'bo-') plt.title('triplot of Delaunay triangulation') plt.show() #print(T);
##### Source and target processing ##### mu, P, nu = input_preprocessing(param) comm.Bcast([P, mpi.DOUBLE],0) comm.Bcast([nu, mpi.DOUBLE],0) p,q = geo.planar_to_gradient(P[:,0], P[:,1], target_base) Y = np.vstack([p,q]).T ##### Optimal Transport problem resolution ##### psi = np.empty(len(p)) if rank == 0: print('Number of diracs: ', len(nu)) t = time.clock() - debut print ("Inputs processing:", t, "s") psi0 = ma.optimal_transport_presolve_2(Y, mu.vertices, Y_w=nu, X_w=mu.values) psi = ma.optimal_transport_2(mu, Y, nu, w0=psi0, verbose=True) t = time.clock() - t print ("OT resolution:", t, "s") comm.Bcast([psi, mpi.DOUBLE],0) Z,T_Z,u_Z = misc.eval_legendre_fenchel(mu, Y, psi) interpol = misc.make_cubic_interpolator(Z,T_Z,u_Z,grad=Y) source_box = [np.min(Z[:,0]), np.max(Z[:,0]), np.min(Z[:,1]), np.max(Z[:,1])] target_box = [np.min(P[:,0]), np.max(P[:,0]), np.min(P[:,1]), np.max(P[:,1])] ##### Ray tracing #####
import sys import os sys.path.append('..') import MongeAmpere as ma import numpy as np import matplotlib.pyplot as plt def draw_laguerre_cells(dens, Y, w): E = dens.restricted_laguerre_edges(Y, w) nan = float('nan') N = E.shape[0] x = np.zeros(3 * N) y = np.zeros(3 * N) a = np.array(range(0, N)) x[3 * a] = E[:, 0] x[3 * a + 1] = E[:, 2] x[3 * a + 2] = nan y[3 * a] = E[:, 1] y[3 * a + 1] = E[:, 3] y[3 * a + 2] = nan plt.plot(x, y, color=[1, 0, 0], linewidth=1, aa=True) dens = ma.Density_2(np.array([[0., 0.], [2., 0.], [2., 2.], [0., 2.]])) N = 40 draw_laguerre_cells(dens, np.random.rand(N, 2), np.zeros(N)) plt.show()
# generate density def sample_rectangle(bbox): x0 = bbox[0] y0 = bbox[1] x1 = bbox[2] y1 = bbox[3] x = [x0, x1, x1, x0] y = [y0, y0, y1, y1] X = np.vstack((x, y)).T return X Xdens = sample_rectangle(bbox) f = np.ones(4) w = np.zeros(Xdens.shape[0]) T = ma.delaunay_2(Xdens, w) dens = Periodic_density_in_x(Xdens, f, T, bbox) def project_on_incompressible2(dens, Z, verbose=False): N = Z.shape[0] nu = np.ones(N) * dens.mass() / N w = ma.optimal_transport_2(dens, Z, nu, verbose=verbose) return dens.lloyd(Z, w)[0], w X = ma.optimized_sampling_2(dens, N, niter=2) # tracers ii = np.nonzero(X[:, 1] <= 0) jj = np.nonzero(X[:, 1] > 0)
Y = Z # Set image to full window ww=10 plt.figure(figsize=(ww,ww),facecolor="white") ax = plt.Axes(plt.gcf(),[0,0,1,1],yticks=[],xticks=[],frame_on=False) plt.gcf().delaxes(plt.gca()) plt.gcf().add_axes(ax) # Compute surface area of each dot, so that the total amount of gray # is coherent with the gray level of the picture # # N*s/surf = dens.mass(), where surf is the area of the image in points surf=(ww*72)*(ww*72); # 72 points per inch avg_gray = dens.mass()/255; S = (surf/N)*avg_gray for i in range(1,5): w = ma.optimal_transport_2(dens,Y,nu,verbose=True); [Z,m] = dens.lloyd(Y, w); Y = Z plt.cla(); plt.gca().set_aspect('equal') plt.scatter(Y[:,0], Y[:,1], s=S); plt.axis([0,1,0,1]) plt.axis('off') plt.pause(.01) plt.pause(10) np.savetxt(cloudname, Y, fmt='%g')
def plot_timestep(X, w, colors, bbox, fname): img = ma.laguerre_diagram_to_image(dens, X, w, colors, bbox, 1000, 500) img.save(fname)
def input_preprocessing(parameters): """ Generates proper inputs according to parameters. A density for the source and a diracs sum for the target. Parameters ---------- parameters : dictionnary Contains all the parameters Returns ------- mu : Density_2 object Y : 2D array nu : 1D array """ source_name = parameters['source'][0] source_geom = parameters['source'][1:] target_name = parameters['target'][0] target_geom = parameters['target'][1:] #### Source processing #### if source_name == 'default': x = np.array([-0.5,-0.5,0.5,0.5]) y = np.array([-0.5,0.5,-0.5,0.5]) X = np.array([x,y]).T mu = ma.Density_2(X) else: extension_source = os.path.splitext(source_name)[1] if extension_source == ".txt": X, X_w = read_data(source_name, source_geom) mu = ma.Density_2(X, X_w) else: X, mu = read_image(source_name, source_geom) # Null pixels are removed zero = np.zeros(len(mu)) J = np.greater(mu,zero) mu = mu[J] X = X[J] mu = ma.Density_2(X,mu) #### Target processing #### if target_name == 'default': # Number of diracs for the default shape Ndiracs = 10000 # Triangle x = np.array([0.5,-0.25,-0.25]) y = np.array([0.,0.433,-0.433]) # Square #x = np.array([-0.5,-0.5,0.5,0.5]) #y = np.array([-0.5,0.5,-0.5,0.5]) #Pentagon #x = np.array([0.,-1.,-0.75, 0.75, 1.]) #y = np.array([1.5,0.25,-0.5, -0.5, 0.25]) tri = np.array([x,y]).T dens_target = ma.Density_2(tri) P = ma.optimized_sampling_2(dens_target,Ndiracs) nu = np.ones(Ndiracs) * (mu.mass() / Ndiracs) else: extension_target = os.path.splitext(target_name)[1] if extension_target == ".txt": P, nu = read_data(target_name, target_geom) nu = nu * (mu.mass() / sum(nu)) else: # For a picture, number of dirac equals # number of pixels (set in read_image()) P, nu = read_image(target_name, target_geom) # Null pixels are removed zero = np.zeros(len(nu)) J = np.greater(nu,zero) P = P[J] nu = nu[J] # Mass equalization nu = nu * (mu.mass()/sum(nu)) return mu, P, nu
def projection_on_incompressible_moments(dens, Z): N = Z.shape[0] nu = np.ones(N) * dens.mass() / N w0 = estimate_dual_variable(dens, Z) w = ma.optimal_transport_2(dens, Z, nu, w0=w0, verbose=False) return dens.moments(Z, w)
def initialise_points(N, bbox, RegularMesh=None): '''Function to initialise a mesh over the domain [-L,L]x[0,H] and transform to geostrophic coordinates args: N: number of grid points in z direct, total number of points will be 2*N*N RegularMesh: controls whether the mesh is regular or an optimised sample of random points in the domain returns: A numpy array of coordinates of points in geostrophic space ''' H = bbox[3] L = bbox[2] #set up regular mesh or optimised sample of random points if RegularMesh: npts = N dx = 1. / npts s = np.arange(dx * 0.5, 1., dx) s1 = np.arange(-1. + dx * 0.5, 1., dx) x, z = np.meshgrid(s1 * L, s * H) nx = x.size x = np.reshape(x, (nx, )) z = np.reshape(z, (nx, )) y = np.array([x, z]).T else: npts = 2 * N * N bbox = np.array([0., -0.5, 2., 0.5]) Xdens = sample_rectangle(bbox) f0 = np.ones(4) / 2 w = np.zeros(Xdens.shape[0]) T = ma.delaunay_2(Xdens, w) Sdens = Periodic_density_in_x(Xdens, f0, T, bbox) X = ma.optimized_sampling_2(Sdens, npts, niter=5) x = X[:, 0] * L - L z = (X[:, 1] + 0.5) * H y = np.array([x, z]).T #define thetap from CULLEN 2006 Nsq = 2.5e-5 g = 10. f = 1.e-4 theta0 = 300. C = 3e-6 B = 0.25 thetap = Nsq * theta0 * z / g + B * np.sin(np.pi * (x / L + z / H)) vg = B * g * H / L / f / theta0 * np.sin( np.pi * (x / L + z / H)) - 2 * B * g * H / np.pi / L / f / theta0 * np.cos( np.pi * x / L) X = vg / f + x Z = g * thetap / f / f / theta0 Y = np.array([X, Z]).T thetap = f * f * theta0 * Z / g return Y, thetap
import sys sys.path.append('..'); import os import MongeAmpere as ma import numpy as np import scipy as sp import scipy.optimize as opt import matplotlib.pyplot as plt import matplotlib.tri as tri # generate uniform points in the disk, and then a Gaussian density Nx = 30; t = np.linspace(0,2*np.pi,Nx+1); t = t[0:Nx] disk = np.vstack([np.cos(t),np.sin(t)]).T; X = ma.optimized_sampling_2(ma.Density_2(disk), 1000, verbose=True); sigma = 7; mu = np.exp(-sigma*(np.power(X[:,0],2) + np.power(X[:,1],2))); dens = ma.Density_2(X,mu); N = 5000; Y = dens.random_sampling(N); nu = np.ones(N); nu = (dens.mass() / np.sum(nu)) * nu; w = np.zeros(N); for i in range(1,5): [Z,m] = dens.lloyd(Y, w); Y = Z; plt.figure(figsize=(10,10),facecolor="white")
def validity_analysis_results(N, days, tstepsize, t0=0., Heun=None): #initialise parameters H = 1.e4 L = 1.e6 g = 10. f = 1.e-4 theta0 = 300 C = 3e-6 if Heun: print('heun') datadir = "/scratchcomp04/cvr12/Results_" + str(days) + "D_" + str( N) + "N_" + str(int(tstepsize)) + "_heun/data" resultdir = "/scratchcomp04/cvr12/Results_" + str(days) + "D_" + str( N) + "N_" + str(int(tstepsize)) + "_heun" else: print('euler') datadir = "/scratchcomp04/cvr12/Results_" + str(days) + "D_" + str( N) + "N_" + str(int(tstepsize)) + "_euler/data" resultdir = "/scratchcomp04/cvr12/Results_" + str(days) + "D_" + str( N) + "N_" + str(int(tstepsize)) + "_euler" os.mkdir(datadir) #set up uniform density for domain Gamma bbox = np.array([-L, 0., L, H]) Xdens = pdx.sample_rectangle(bbox) f0 = np.ones(4) / 2 / L / H rho = np.zeros(Xdens.shape[0]) T = ma.delaunay_2(Xdens, rho) dens = pdx.Periodic_density_in_x(Xdens, f0, T, bbox) #set final time(t), step size (h) and total number of time steps(N) tf = 60 * 60 * 24 * days h = tstepsize N = int(np.ceil((tf - t0) / h)) #initialise arrays to store data values KEmean = np.zeros(N + 1) energy = np.zeros(N + 1) vgmax = np.zeros(N + 1) PE = np.zeros(N + 1) KE = np.zeros(N + 1) rmsv = np.zeros(N + 1) w = np.fromfile(resultdir + '/weights_results_' + str(int(h)) + '/weights_0.txt', sep=" ") ke = np.zeros((int(w.size), 2)) vg = np.zeros((int(w.size), 2)) t = np.array([t0 + n * h for n in range(N + 1)]) for n in range(0, N + 1): Y = np.fromfile(resultdir + '/points_results_' + str(int(h)) + '/points_' + str(n) + '.txt', sep=" ") w = np.fromfile(resultdir + '/weights_results_' + str(int(h)) + '/weights_' + str(n) + '.txt', sep=" ") l = int(w.size) Y = Y.reshape((l, 2)) #calculate centroids and mass of cells [Yc, m] = dens.lloyd(Y, w) mtile = np.tile(m, (2, 1)).T #calculate second moments to find KE and maximum of vg [m1, I] = dens.moments(Y, w) #find kinetic energy, maximum value of vg and total energy ke[:, 0] = 0.5 * f * f * (m * Y[:, 0]**2 - 2 * Y[:, 0] * m1[:, 0] + I[:, 0]) vg[:, 0] = f * (Y[:, 0] - Yc[:, 0]) #map back to fundamental domain ke = dens.to_fundamental_domain(ke) vg = dens.to_fundamental_domain(vg) E = ke[:, 0] - f * f * Y[:, 1] * m1[:, 1] + 0.5 * f * f * H * Y[:, 1] * m pe = -f * f * Y[:, 1] * m1[:, 1] + 0.5 * f * f * H * Y[:, 1] * m energy[n] = np.sum(E) KE[n] = np.sum(ke[:, 0]) KEmean[n] = np.sum(ke[:, 0]) * float(l) rmsv[n] = np.sqrt(KEmean[n]) PE[n] = np.sum(pe) vgmax[n] = np.amax(vg[:, 0]) energy.tofile(datadir + '/energy.txt', sep=" ", format="%s") KEmean.tofile(datadir + '/KEmean.txt', sep=" ", format="%s") vgmax.tofile(datadir + '/vgmax.txt', sep=" ", format="%s") t.tofile(datadir + '/time.txt', sep=" ", format="%s") PE.tofile(datadir + '/PE.txt', sep=" ", format="%s") KE.tofile(datadir + '/KE.txt', sep=" ", format="%s") rmsv.tofile(datadir + '/rmsv.txt', sep=" ", format="%s") return ('complete results ' + str(days) + 'D_' + str(N) + 'N_' + str(int(tstepsize)))
from builtins import range import sys sys.path.append('..'); import MongeAmpere as ma import numpy as np import scipy as sp import scipy.optimize as opt import matplotlib.pyplot as plt import matplotlib.tri as tri bbox = [0.,0.,1.,1.]; dens = ma.Periodic_density_2(bbox); N = 10000; Z = dens.random_sampling(N) nu = np.ones(N)/N; dt = 0.2 t = dt for i in range(1,50): print("ITERATION %d" % i) w = ma.optimal_transport_2(dens, Z, nu, verbose=True) C = dens.lloyd(Z, w)[0] Z = dens.to_fundamental_domain(Z+(dt/t)*(Z-C)) t = t+dt plt.cla() plt.scatter(Z[:,0], Z[:,1], color='blue', s=1); plt.axis([0,1,0,1]) plt.pause(.5);
# GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. import sys sys.path.append('..'); import MongeAmpere as ma import numpy as np # source: uniform measure on the square with sidelength 2 X = np.array([[-1,-1], [1, -1], [1, 1], [-1,1]], dtype=float); T = ma.delaunay_2(X,np.zeros(4)); print T mu = np.ones(4)/4; dens = ma.Density_2(X,mu,T); print "mass=%g"%dens.mass() # target is a random set of points, with random weights N = 1000; Y = np.random.rand(N,2)/2; nu = 10+np.random.rand(N); nu = (dens.mass() / np.sum(nu)) * nu; # print "mass(nu) = %f" % sum(nu) # print "mass(mu) = %f" % dens.mass() #
def sq_dist_to_incompressible(args): shape, s = args E, g = squared_distance_to_incompressible(ma.Density_2(shape), s) return E, g
import numpy as np import periodic_densities as pdx import MongeAmpere as ma import matplotlib.pyplot as plt import matplotlib.tri as tri from PIL import Image N = 10000 L = 1.e6 H = 1.e4 bbox = np.array([-L, 0., L, H]) Xdens = pdx.sample_rectangle(bbox) f0 = np.ones(4) / (2 * L * H) rho = np.zeros(Xdens.shape[0]) T = ma.delaunay_2(Xdens, rho) dens = pdx.Periodic_density_in_x(Xdens, f0, T, bbox) Y = np.random.rand(N, 2) xY[:, 0] = Y[:, 0] * 2 * L - L Y[:, 1] *= H #print(Y) print(Y.shape) nu = np.ones(Y[:, 0].size) nu = (dens.mass() / np.sum(nu)) * nu w = ma.optimal_transport_2(dens, Y, nu, verbose=True) #C = Y[:,1].reshape((N,1)) #print(C)
import matplotlib matplotlib.use('Agg') import numpy as np from periodic_densities import Periodic_density_in_x, sample_rectangle, periodicinx_draw_laguerre_cells_2 import MongeAmpere as ma import matplotlib.pyplot as plt import matplotlib.tri as tri # source: uniform measure on the square with sidelength 1 bbox = [0., 0., 1., 1.] Xdens = sample_rectangle(bbox) f0 = np.ones(4) rho = np.zeros(Xdens.shape[0]) T = ma.delaunay_2(Xdens, rho) dens = Periodic_density_in_x(Xdens, f0, T, bbox) print "mass=%g" % dens.mass() # target is a random set of points, with random weights N = 6 Y = np.random.rand(N, 2) nu = np.ones(N) nu = (dens.mass() / np.sum(nu)) * nu print "mass(nu) = %f" % sum(nu) print "mass(mu) = %f" % dens.mass() w = ma.optimal_transport_2(dens, Y, nu) #x,y = periodicinx_draw_laguerre_cells_2(dens,Y,w)
tstepsize = 1800 Heun = True #initialise parameters from SG Eady model H = 1.e4 L = 1.e6 g = 10. f = 1.e-4 theta0 = 300. #initialise source density with periodic BCs in x bbox = np.array([-L, 0., L, H]) Xdens = pdx.sample_rectangle(bbox) f0 = np.ones(4) / (2 * H * L) rho = np.zeros(Xdens.shape[0]) T = ma.delaunay_2(Xdens, rho) dens = pdx.Periodic_density_in_x(Xdens, f0, T, bbox) #initialise points in geostrophic space [Y, thetap] = initialise_points(N, bbox, RegularMesh=True) Y = dens.to_fundamental_domain(Y) if Heun: #timestep using Heun's Method print('Heun ' + str(N) + 'N') pr.enable() [Y, w, t] = heun_sg(Y, dens, tf, bbox, h=tstepsize) pr.disable() else: #timestep using forward euler scheme print('Euler ' + str(N) + 'N')