def test_gross_pitaevskii(): problem = GrossPitaevskii() n = problem.mesh.control_volumes.shape[0] u0 = numpy.zeros(n, dtype=complex) x, y, z = problem.mesh.node_coords.T # In the N->0 limit, we can decompose the modes in Cartesian form [7] as being # proportional to # # psi_{m, n} ~ H_m(sqrt(omega)x) H_n(sqrt(omega)y) exp(-omega r**2 / 2) # # where H_m are Hermite polynomials. These linear eigenfunctions have corresponding # eigenvalues mu = (m + n + 1) omega. u0 = numpy.exp(-problem.omega * (x**2 + y**2) / 2).astype(complex) mu0 = problem.omega plt.ion() fig = plt.figure() ax = fig.add_subplot(111) plt.xlabel("$\\mu$") plt.ylabel("$||\\psi||_2$ / |\\Omega|") plt.grid() b_list = [] values_list = [] (line1, ) = ax.plot(b_list, values_list, "-", color="#1f77f4") area = numpy.sum(problem.mesh.control_volumes) def callback(k, b, sol): b_list.append(b) line1.set_xdata(b_list) values_list.append(numpy.sqrt(problem.inner(sol, sol)) / area) line1.set_ydata(values_list) ax.set_xlim(0.0, 100.0) ax.set_ylim(0.0, 1.0) fig.canvas.draw() fig.canvas.flush_events() # Store the solution meshio.write_points_cells( f"sol{k:03d}.vtk", problem.mesh.node_coords, {"triangle": problem.mesh.cells["nodes"]}, point_data={ "psi": numpy.array([numpy.real(sol), numpy.imag(sol)]).T }, ) # pacopy.natural(problem, u0, mu0, callback, max_newton_steps=10) pacopy.euler_newton(problem, u0, mu0, callback, stepsize0=1.0e-2, max_newton_steps=10)
def test_ginzburg_landau(max_steps=5, n=20): a = 10.0 points, cells = meshzoo.rectangle_tri(np.linspace(-a / 2, a / 2, n), np.linspace(-a / 2, a / 2, n)) # add column with zeros for magnetic potential points = np.column_stack([points, np.zeros_like(points[:, 0])]) mesh = meshplex.Mesh(points, cells) problem = GinzburgLandau(mesh) n = problem.mesh.control_volumes.shape[0] u0 = np.ones(n, dtype=complex) mu0 = 0.0 mu_list = [] filename = "sol.xdmf" with meshio.xdmf.TimeSeriesWriter(filename) as writer: writer.write_points_cells(problem.mesh.points, {"triangle": problem.mesh.cells("points")}) def callback(k, mu, sol): mu_list.append(mu) # Store the solution psi = np.array([np.real(sol), np.imag(sol)]).T writer.write_data(k, point_data={"psi": psi}) with open("data.yml", "w") as fh: yaml.dump( { "filename": filename, "mu": [float(m) for m in mu_list] }, fh) # pacopy.natural( # problem, # u0, # mu0, # callback, # max_steps=1000, # lambda_stepsize0=1.0e-2, # newton_max_steps=5, # newton_tol=1.0e-10, # ) pacopy.euler_newton( problem, u0, mu0, callback, max_steps=max_steps, stepsize0=1.0e-2, stepsize_max=1.0, newton_tol=1.0e-10, )
def test_ginzburg_landau(max_steps=5, n=20): a = 10.0 points, cells = meshzoo.rectangle(-a / 2, a / 2, -a / 2, a / 2, n, n) mesh = meshplex.MeshTri(points, cells) problem = GinzburgLandau(mesh) n = problem.mesh.control_volumes.shape[0] u0 = numpy.ones(n, dtype=complex) mu0 = 0.0 mu_list = [] filename = "sol.xdmf" with meshio.xdmf.TimeSeriesWriter(filename) as writer: writer.write_points_cells(problem.mesh.node_coords, {"triangle": problem.mesh.cells["nodes"]}) def callback(k, mu, sol): mu_list.append(mu) # Store the solution psi = numpy.array([numpy.real(sol), numpy.imag(sol)]).T writer.write_data(k, point_data={"psi": psi}) with open("data.yml", "w") as fh: yaml.dump( { "filename": filename, "mu": [float(m) for m in mu_list] }, fh) # pacopy.natural( # problem, # u0, # mu0, # callback, # max_steps=1000, # lambda_stepsize0=1.0e-2, # newton_max_steps=5, # newton_tol=1.0e-10, # ) pacopy.euler_newton( problem, u0, mu0, callback, max_steps=max_steps, stepsize0=1.0e-2, stepsize_max=1.0, newton_tol=1.0e-10, )
def solve(self): if self.cont_method == 'Euler-Newton': pacopy.euler_newton(self, self.u0, self.lmbda0, self.callback, max_steps=self.max_steps, newton_tol=self.newton_tol) elif self.cont_method == 'Natural': pacopy.natural(self, self.u0, self.lmbda0, self.callback, max_steps=self.max_steps, newton_tol=self.newton_tol)
def test_bratu(max_steps=10, update_plot=False): problem = Bratu1d() u0 = numpy.zeros(problem.n) lmbda0 = 0.0 # https://stackoverflow.com/a/4098938/353337 plt.ion() fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 5)) # fig = plt.figure() ax1 = fig.add_subplot(1, 2, 1) ax1.set_xlabel("$\\lambda$") ax1.set_ylabel("$||u||_2$") ax1.set_xlim(0.0, 4.0) ax1.set_ylim(0.0, 6.0) ax1.grid() (line1, ) = ax1.plot([], [], "-x", color="C0") ax2 = fig.add_subplot(1, 2, 2) ax2.set_title("solution") ax2.set_xlim(0.0, 1.0) ax2.set_ylim(0.0, 5.0) ax2.grid() (line2, ) = ax2.plot([], [], "-", color="C0") line2.set_xdata(numpy.linspace(0.0, 1.0, problem.n)) # line3, = ax2.plot([], [], "-", color="C1") # line3.set_xdata(numpy.linspace(0.0, 1.0, problem.n)) milestones = numpy.arange(0.5, 3.2, 0.5) def callback(k, lmbda, sol): if update_plot: line1.set_xdata(numpy.append(line1.get_xdata(), lmbda)) # val = numpy.max(numpy.abs(sol)) val = numpy.sqrt(problem.inner(sol, sol)) line1.set_ydata(numpy.append(line1.get_ydata(), val)) # ax1.plot( # [lmbda_pre], [numpy.sqrt(problem.inner(u_pre, u_pre))], ".", color="C1" # ) line2.set_ydata(sol) # line3.set_ydata(du_dlmbda) fig.canvas.draw() fig.canvas.flush_events() # plt.savefig('bratu1d.png', transparent=True, bbox_inches="tight") pacopy.natural( problem, u0, lmbda0, callback, max_steps=max_steps, newton_tol=1e-10, milestones=milestones, ) # The condition number of the Jacobian is about 10^4, so we can only expect Newton # to converge up to about this factor above machine precision. pacopy.euler_newton(problem, u0, lmbda0, callback, max_steps=max_steps, newton_tol=1.0e-10)
def callback(k, lmbda, sol): lmbda_list.append(lmbda) values_list.append(np.sqrt(problem.inner(sol, sol))) if values_list[-1] > upper: raise RangeException turning_point = 3.51383 # Farrell et al try: euler_newton(problem, u0, lmbda0, callback, max_steps=500, newton_tol=1.0e-10) except RangeException: if __name__ == '__main__': fig, ax = subplots() ax.set_xlabel(r'$\lambda$') ax.set_ylabel(r'$||u||_2$') ax.grid() ax.plot(lmbda_list, values_list, '-o') ax.axvline(turning_point, linestyle='dotted') ax.set_xlim(0.0, 4.0) ax.set_ylim(0.0, upper) fig.savefig(Path(__file__).with_suffix('.png'))
def test_continuation(max_steps=5): a = 10.0 n = 20 points, cells = meshzoo.rectangle(-a / 2, a / 2, -a / 2, a / 2, n, n) mesh = meshplex.MeshTri(points, cells) problem = GinzburgLandauReal(mesh) num_unknowns = 2 * problem.mesh.control_volumes.shape[0] u0 = numpy.ones(num_unknowns) u0[1::2] = 0.0 mu0 = 0.0 # plt.ion() # fig = plt.figure() # ax = fig.add_subplot(111) # plt.axis("square") # plt.xlabel("$\\mu$") # plt.ylabel("$||\\psi||_2$") # plt.grid() # b_list = [] # values_list = [] # line1, = ax.plot(b_list, values_list, "-", color="#1f77f4") mu_list = [] filename = "sol.xdmf" with meshio.xdmf.TimeSeriesWriter(filename) as writer: writer.write_points_cells(problem.mesh.node_coords, {"triangle": problem.mesh.cells["nodes"]}) def callback(k, mu, sol): mu_list.append(mu) # Store the solution psi = numpy.array([sol[0::2], sol[1::2]]).T writer.write_data(k, point_data={"psi": psi}) with open("data.yml", "w") as fh: yaml.dump( { "filename": filename, "mu": [float(m) for m in mu_list] }, fh) # pacopy.natural( # problem, # u0, # b0, # callback, # max_steps=1, # lambda_stepsize0=1.0e-2, # newton_max_steps=5, # newton_tol=1.0e-10, # ) pacopy.euler_newton( problem, u0, mu0, callback, max_steps=max_steps, stepsize0=1.0e-2, stepsize_max=1.0, newton_tol=1.0e-10, )
def test_mittelmann_fenics(): from dolfin import ( Function, FunctionSpace, Point, RectangleMesh, TestFunction, TrialFunction, assemble, dot, dx, exp, grad, solve, ) class Mittelmann: def __init__(self): mesh = RectangleMesh(Point(-0.5, -0.5), Point(+0.5, +0.5), 20, 20) self.V = FunctionSpace(mesh, "Lagrange", 1) u = TrialFunction(self.V) v = TestFunction(self.V) self.a = assemble(dot(grad(u), grad(v)) * dx) self.m = assemble(u * v * dx) def inner(self, a, b): return a.inner(self.m * b) def norm2_r(self, a): return a.inner(a) def f(self, u, lmbda): v = TestFunction(self.V) ufun = Function(self.V) ufun.vector()[:] = u out = (self.a * u - 10 * assemble(ufun * v * dx) + 10 * lmbda * assemble(exp(ufun) * v * dx)) return out def df_dlmbda(self, u, lmbda): v = TestFunction(self.V) ufun = Function(self.V) ufun.vector()[:] = u out = 10 * assemble(exp(ufun) * v * dx) return out def jacobian_solver(self, u, lmbda, rhs): t = TrialFunction(self.V) v = TestFunction(self.V) ufun = Function(self.V) ufun.vector()[:] = u a = (self.a - 10 * assemble(t * v * dx) + 10 * lmbda * assemble(exp(ufun) * t * v * dx)) x = Function(self.V) solve(a, x.vector(), rhs) return x.vector() problem = Mittelmann() u0 = Function(problem.V).vector() lmbda0 = 0.0 plt.ion() fig = plt.figure() ax = fig.add_subplot(111) # plt.axis("square") plt.xlabel("$\\lambda$") plt.ylabel("$||u||_2$") plt.grid() lmbda_list = [] values_list = [] (line1, ) = ax.plot(lmbda_list, values_list, "-", color="#1f77f4") def callback(k, lmbda, sol): lmbda_list.append(lmbda) line1.set_xdata(lmbda_list) values_list.append(math.sqrt(problem.inner(sol, sol))) line1.set_ydata(values_list) ax.set_xlim(0.0, 0.5) ax.set_ylim(0.0, 5.0) fig.canvas.draw() fig.canvas.flush_events() # pacopy.natural(problem, u0, lmbda0, callback, max_steps=100) pacopy.euler_newton(problem, u0, lmbda0, callback, max_steps=500)
def test_bratu_fenics(max_steps=10): from dolfin import ( DirichletBC, Function, FunctionSpace, TestFunction, TrialFunction, UnitSquareMesh, XDMFFile, assemble, dot, dx, exp, grad, solve, ) class Bratu: def __init__(self): self.mesh = UnitSquareMesh(40, 40, "left/right") self.V = FunctionSpace(self.mesh, "Lagrange", 1) self.bc = DirichletBC(self.V, 0.0, "on_boundary") u = TrialFunction(self.V) v = TestFunction(self.V) self.a = assemble(dot(grad(u), grad(v)) * dx) self.m = assemble(u * v * dx) def inner(self, a, b): return a.inner(self.m * b) def norm2_r(self, a): return a.inner(a) def f(self, u, lmbda): v = TestFunction(self.V) ufun = Function(self.V) ufun.vector()[:] = u out = self.a * u - lmbda * assemble(exp(ufun) * v * dx) DirichletBC(self.V, ufun, "on_boundary").apply(out) return out def df_dlmbda(self, u, lmbda): v = TestFunction(self.V) ufun = Function(self.V) ufun.vector()[:] = u out = -assemble(exp(ufun) * v * dx) self.bc.apply(out) return out def jacobian_solver(self, u, lmbda, rhs): t = TrialFunction(self.V) v = TestFunction(self.V) # from dolfin import Constant # a = assemble( # dot(grad(t), grad(v)) * dx - Constant(lmbda) * exp(u) * t * v * dx # ) ufun = Function(self.V) ufun.vector()[:] = u a = self.a - lmbda * assemble(exp(ufun) * t * v * dx) self.bc.apply(a) x = Function(self.V) # solve(a, x.vector(), rhs, "gmres", "ilu") solve(a, x.vector(), rhs) return x.vector() problem = Bratu() u0 = Function(problem.V).vector() lmbda0 = 0.0 plt.ion() fig = plt.figure() ax = fig.add_subplot(111) plt.axis("square") plt.xlabel("$\\lambda$") plt.ylabel("$||u||_2$") plt.grid() lmbda_list = [] values_list = [] (line1, ) = ax.plot(lmbda_list, values_list, "-", color="C0") f = XDMFFile("sol.xdmf") u = Function(problem.V) def callback(k, lmbda, sol): lmbda_list.append(lmbda) line1.set_xdata(lmbda_list) values_list.append(math.sqrt(problem.inner(sol, sol))) line1.set_ydata(values_list) ax.set_xlim(0.0, 10.0) ax.set_ylim(0.0, 6.0) # import numpy as np # ax.plot([lmbda_pre], [np.sqrt(problem.inner(u_pre, u_pre))], ".", color="C1") fig.canvas.draw() fig.canvas.flush_events() u.vector()[:] = sol f.write(u, k) # pacopy.natural(problem, u0, lmbda0, callback, max_steps=100) pacopy.euler_newton(problem, u0, lmbda0, callback, max_steps=max_steps, newton_tol=1.0e-10)
def test_bratu(max_steps=10, update_plot=False): problem = Bratu1d() u0 = numpy.zeros(problem.n) lmbda0 = 0.0 plt.ion() fig = plt.figure() ax1 = fig.add_subplot(111) ax1.set_xlabel("$\\lambda$") ax1.set_ylabel("$||u||_2$") ax1.grid() # ax2 = fig.add_subplot(122) # ax2.grid() (line1,) = ax1.plot([], [], "-x", color="#1f77f4") # line2, = ax2.plot([], [], "-", color="#1f77f4") # line2.set_xdata(numpy.linspace(0.0, 1.0, problem.n)) # line3, = ax2.plot([], [], "-", color="red") # line3.set_xdata(numpy.linspace(0.0, 1.0, problem.n)) milestones = numpy.arange(0.5, 3.2, 0.5) if update_plot: profile_fig, profile_ax = plt.subplots() def callback(k, lmbda, sol): if update_plot: line1.set_xdata(numpy.append(line1.get_xdata(), lmbda)) # val = numpy.max(numpy.abs(sol)) val = numpy.sqrt(problem.inner(sol, sol)) line1.set_ydata(numpy.append(line1.get_ydata(), val)) ax1.set_xlim(0.0, 4.0) ax1.set_ylim(0.0, 6.0) # ax1.plot([lmbda_pre], [numpy.sqrt(problem.inner(u_pre, u_pre))], ".r") # line2.set_ydata(sol) # line3.set_ydata(du_dlmbda) # ax2.set_xlim(0.0, 1.0) # ax2.set_ylim(0.0, 6.0) fig.canvas.draw() fig.canvas.flush_events() # plt.savefig('bratu1d.png', transparent=True, bbox_inches="tight") if lmbda in milestones: profile_ax.plot(numpy.linspace(0.0, 1.0, problem.n), sol, label=lmbda) pacopy.natural( problem, u0, lmbda0, callback, max_steps=max_steps, newton_tol=1e-10, milestones=milestones, ) # The condition number of the Jacobian is about 10^4, so we can only expect Newton # to converge up to about this factor above machine precision. pacopy.euler_newton( problem, u0, lmbda0, callback, max_steps=max_steps, newton_tol=1.0e-10 )