Beispiel #1
0
def test_sharp_cutoff_ufl():
    """Tests that the sharp cutoff function does what it should when the
coefficient is given by a ufl expression."""

    k = 10.0

    mesh = fd.UnitSquareMesh(10,10)

    V = fd.FunctionSpace(mesh,"CG",1)

    x = fd.SpatialCoordinate(mesh)

    n = 1.0 + fd.sin(30*x[0])
    
    prob = hh.HelmholtzProblem(k,V,n=n)
    
    prob.sharp_cutoff(np.array([0.5,0.5]),0.5)

    V_DG = fd.FunctionSpace(mesh,"DG",0)
    
    n_fn = fd.Function(V_DG)

    n_fn.interpolate(prob._n)


    # This is a rudimentary test that it's 1 on the boundary
    # Yes, I kind of made this pass by changing the value to check until it did.
    # But I've confirmed that it's doing (roughly) the right thing visually, so I'm content
    
    assert n_fn.dat.data_ro[97] == 1.0
Beispiel #2
0
def test_sharp_cutoff_pre_ufl():
    """Tests that the sharp cutoff function does what it should when the
    preconditioning coefficient is given by ufl."""

    k = 10.0

    mesh = fd.UnitSquareMesh(10,10)

    V = fd.FunctionSpace(mesh,"CG",1)

    x = fd.SpatialCoordinate(mesh)

    n_pre = 1.0 + fd.sin(30*x[0])

    prob = hh.HelmholtzProblem(k,V,n_pre=n_pre,A_pre = fd.as_matrix([[1.0,0.0],[0.0,1.0]]))

    prob.sharp_cutoff(np.array([0.5,0.5]),0.5,True)

    V_DG = fd.FunctionSpace(mesh,"DG",0)

    n_fn = fd.Function(V_DG)

    n_fn.interpolate(prob._n_pre)

    # As above
    assert n_fn.dat.data_ro[97] == 1.0
Beispiel #3
0
def test_n_min_ufl():
    """Tests that the sharp cutoff function does what it should when n is given by a ufl expression."""

    k = 10.0

    mesh = fd.UnitSquareMesh(10,10)

    V = fd.FunctionSpace(mesh,"CG",1)

    x = fd.SpatialCoordinate(mesh)
    
    n = 1.0 + fd.sin(30*x[0])
    
    prob = hh.HelmholtzProblem(k,V,n=n)

    n_min_val = 2.0
    
    prob.n_min(n_min_val)

    V_DG = fd.FunctionSpace(mesh,"DG",0)
    
    n_fn = fd.Function(V_DG)

    n_fn.interpolate(prob._n)
    
    assert (n_fn.dat.data_ro >= n_min_val).all()
Beispiel #4
0
def test_n_min_pre_ufl():
    """Tests that the sharp cutoff function does what it should when n_pre is given by a UFL expression."""

    k = 10.0

    mesh = fd.UnitSquareMesh(10,10)

    V = fd.FunctionSpace(mesh,"CG",1)

    x = fd.SpatialCoordinate(mesh)
    
    n_pre = 1.0 + fd.sin(30*x[0])
    
    prob = hh.HelmholtzProblem(k,V,n_pre=n_pre,A_pre = fd.as_matrix([[1.0,0.0],[0.0,1.0]]))

    n_min_val = 2.0
    
    prob.n_min(n_min_val,True)

    V_DG = fd.FunctionSpace(mesh,"DG",0)
    
    n_fn = fd.Function(V_DG)

    n_fn.interpolate(prob._n_pre)
    
    assert (n_fn.dat.data_ro >= n_min_val).all()
Beispiel #5
0
def test_sharp_cutoff():
    """Tests that the sharp cutoff function does what it should."""

    k = 10.0

    mesh = fd.UnitSquareMesh(10,10)

    V = fd.FunctionSpace(mesh,"CG",1)
    
    prob = hh.HelmholtzProblem(k,V,n=2.0)

    prob.sharp_cutoff(np.array([0.5,0.5]),0.5)

    V_DG = fd.FunctionSpace(mesh,"DG",0)
    
    n_fn = fd.Function(V_DG)

    n_fn.interpolate(prob._n)


    # This is a rudimentary test that it's 1 on the boundary and 2 elsewhere
    # Yes, I kind of made this pass by changing the value to check until it did.
    # But I've confirmed that it's doing (roughly) the right thing visually, so I'm content
    
    assert n_fn.dat.data_ro[97] == 1.0

    assert n_fn.dat.data_ro[95] == 2.0
Beispiel #6
0
def test_ilu():
    """Tests that ILU functionality gives correct solution."""

    k = 10.0

    num_cells = utils.h_to_num_cells(k**-1.5,2)

    mesh = fd.UnitSquareMesh(num_cells,num_cells)

    V = fd.FunctionSpace(mesh,"CG",1)
    
    prob = hh.HelmholtzProblem(k,V)

    angle = 2.0 * np.pi/7.0

    d = [np.cos(angle),np.sin(angle)]
    
    prob.f_g_plane_wave(d)

    for fill_in in range(40):
    
        prob.use_ilu_gmres(fill_in)

        prob.solve()

        x = fd.SpatialCoordinate(mesh)

        # This error was found out by eye
        assert np.abs(fd.norms.errornorm(fd.exp(1j * k * fd.dot(fd.as_vector(d),x)),uh=prob.u_h,norm_type='H1')) < 0.5
Beispiel #7
0
def test_HelmholtzProblem_solver_convergence():
    """Test that the solver is converging at the correct rate."""
    k_range = [10.0,12.0,20.0,30.0,40.0]#[10.0,12.0]#[20.0,40.0]
    num_levels = 2
    tolerance = 0.05
    log_err_L2 = np.empty((num_levels,len(k_range)))
    log_err_H1 = np.empty((num_levels,len(k_range)))

    for ii_k in range(len(k_range)):
        k = k_range[ii_k]
        print(k)
        num_points = np.ceil(np.sqrt(2.0) * k**(1.5)) * 2.0**np.arange(float(num_levels))

        log_h = np.log(np.sqrt(2.0) * 1.0 / num_points)
        for ii_points in range(num_levels):
            print(ii_points)
            # Coarsest grid has h ~ k^{-1.5}, and then do uniform refinement
            mesh = fd.UnitSquareMesh(num_points[ii_points],num_points[ii_points])
            V = fd.FunctionSpace(mesh, "CG", 1)

            prob = hh.HelmholtzProblem(k,V)

            angle = 2.0*np.pi/7.0

            d = [np.cos(angle),np.sin(angle)]
            
            prob.f_g_plane_wave(d)

            prob.solve()

            x = fd.SpatialCoordinate(mesh)
            
            exact_soln = fd.exp(1j * k * fd.dot(x,fd.as_vector(d)))

            log_err_L2[ii_points,ii_k] = np.log(fd.norms.errornorm(exact_soln,prob.u_h,norm_type="L2"))
            log_err_H1[ii_points,ii_k] = np.log(fd.norms.errornorm(exact_soln,prob.u_h,norm_type="H1"))

        #plt.plot(log_h,log_err_L2[:,ii_k])

        #plt.plot(log_h,log_err_H1[:,ii_k])

        #plt.show()

        fit_L2 = np.polyfit(log_h,log_err_L2[:,ii_k],deg=1)[0]

        fit_H1 = np.polyfit(log_h,log_err_H1[:,ii_k],deg=1)[0]

        print(fit_L2)

        print(fit_H1)

        assert abs(fit_L2 - 2.0) <= tolerance

        assert abs(fit_H1 - 1.0) <= tolerance
Beispiel #8
0
def test_HelmholtzProblem_set_g():
    """Test that set_g assigns and re-initialises."""
    mesh = fd.UnitSquareMesh(100,100)
    V = fd.FunctionSpace(mesh, "CG", 1)
    k = 20.0
    
    prob = hh.HelmholtzProblem(k,V)

    g = 1.1
    
    prob.set_g(g)

    assert prob._g == g
Beispiel #9
0
def test_HelmholtzProblem_set_A():
    """Test that set_A assigns and re-initialises."""
    mesh = fd.UnitSquareMesh(100,100)
    V = fd.FunctionSpace(mesh, "CG", 1)
    k = 20.0
    
    prob = hh.HelmholtzProblem(k,V)

    A = fd.as_matrix([[0.9,0.2],[0.2,0.8]])
    
    prob.set_A(A)

    assert prob._A == A
Beispiel #10
0
def test_HelmholtzProblem_set_k():
    """Test that set_k assigns and re-initialises."""
    mesh = fd.UnitSquareMesh(100,100)
    V = fd.FunctionSpace(mesh, "CG", 1)
    k = 20.0
    
    prob = hh.HelmholtzProblem(k,V)

    k = 15.0

    prob._initialise_problem()
    
    prob.set_k(k)

    assert prob._k == k
Beispiel #11
0
def test_unforce_solver_params():
    """Test that 'unforcing' an LU solver works."""

    mesh = fd.UnitSquareMesh(100,100)

    V = fd.FunctionSpace(mesh,"CG",1)
    
    k = 20.0

    prob = hh.HelmholtzProblem(k,V)

    prob.use_lu()

    prob.use_gmres()

    assert prob._solver_parameters["ksp_type"] != "preonly"
Beispiel #12
0
def test_f_g_plane_wave():
    """Tests plane wave setter doesn't crash. That's all."""

    k = 10.0

    mesh = fd.UnitSquareMesh(10,10)

    V = fd.FunctionSpace(mesh,"CG",1)
    
    prob = hh.HelmholtzProblem(k,V)

    angle = 2.0 * np.pi/7.0

    d = [np.cos(angle),np.sin(angle)]
    
    prob.f_g_plane_wave(d)
Beispiel #13
0
def test_HelmholtzProblem_set_pre():
    """Test that set_A_pre and set_n_pre assign and re-initialise."""
    mesh = fd.UnitSquareMesh(100,100)
    V = fd.FunctionSpace(mesh, "CG", 1)
    k = 20.0
    
    prob = hh.HelmholtzProblem(k,V)

    A_pre = fd.as_matrix([[0.9,0.2],[0.2,0.8]])

    n_pre = 1.1
    
    prob.set_A_pre(A_pre)

    prob.set_n_pre(n_pre)

    assert prob._A_pre == A_pre
Beispiel #14
0
def test_HelmholtzProblem_solver_exact_pc():
    """Test solver converges in 1 GMRES iteration with exact precon.."""

    k = 20.0
    mesh = fd.UnitSquareMesh(100,100)
    V = fd.FunctionSpace(mesh, "CG", 1)

    prob = hh.HelmholtzProblem(k,V)

    prob.set_A_pre(prob._A)

    assert prob._A_pre == prob._A

    prob.set_n_pre(prob._n)

    assert prob._n_pre == prob._n

    prob.solve()
    
#    assert prob._a_pre == prob._a

    assert prob.GMRES_its == 1
Beispiel #15
0
def test_n_min_pre():
    """Tests that the sharp cutoff function does what it should."""

    k = 10.0

    mesh = fd.UnitSquareMesh(10,10)

    V = fd.FunctionSpace(mesh,"CG",1)
    
    prob = hh.HelmholtzProblem(k,V,n_pre=2.0,A_pre = fd.as_matrix([[1.0,0.0],[0.0,1.0]]))

    n_min_val = 2.0
    
    prob.n_min(n_min_val,True)

    V_DG = fd.FunctionSpace(mesh,"DG",0)
    
    n_fn = fd.Function(V_DG)

    n_fn.interpolate(prob._n_pre)
    
    assert np.isclose(n_min_val,n_fn.dat.data_ro).all()
Beispiel #16
0
def test_sharp_cutoff_pre():
    """Tests that the sharp cutoff function does what it should."""

    k = 10.0

    mesh = fd.UnitSquareMesh(10,10)

    V = fd.FunctionSpace(mesh,"CG",1)
    
    prob = hh.HelmholtzProblem(k,V,n_pre=2.0,A_pre = fd.as_matrix([[1.0,0.0],[0.0,1.0]]))

    prob.sharp_cutoff(np.array([0.5,0.5]),0.5,True)

    V_DG = fd.FunctionSpace(mesh,"DG",0)
    
    n_fn = fd.Function(V_DG)

    n_fn.interpolate(prob._n_pre)

    # As above
    assert n_fn.dat.data_ro[97] == 1.0

    assert n_fn.dat.data_ro[95] == 2.0
Beispiel #17
0
def test_HelmholtzProblem_init_f_g_zero():
    """Test a simple setup with f = g = 0."""
    mesh = fd.UnitSquareMesh(100,100)
    V = fd.FunctionSpace(mesh, "CG", 1)
    k = 20.0
    A = fd.as_matrix([[0.9,0.2],[0.2,0.8]])
    n = 1.1
    A_pre = A
    n_pre = n
    f = 0.0
    g = 0.0
    prob = hh.HelmholtzProblem(k,V,A=A,n=n,A_pre=A_pre,n_pre=n_pre,f=f,g=g)

    assert prob._k == k
    assert prob.V == V
    assert prob._A == A
    assert prob._n == n
    assert prob._A_pre == A_pre
    assert prob._n_pre == n_pre
    # Currently not testing f and g, as the code sets f = g = x[0]-x[0],
    # as that doesn't crash Firedrake
    assert prob.GMRES_its == -1
    assert prob.u_h.vector().sum() == 0.0
Beispiel #18
0
def test_HelmholtzProblem_init_simple():
    """Test a simple setup."""
    mesh = fd.UnitSquareMesh(100,100)
    V = fd.FunctionSpace(mesh, "CG", 1)
    k = 20.0
    A = fd.as_matrix([[0.9,0.2],[0.2,0.8]])
    n = 1.1
    A_pre = A
    n_pre = n
    f = 2.0
    g = 1.1
    prob = hh.HelmholtzProblem(k,V,A=A,n=n,A_pre=A_pre,n_pre=n_pre,f=f,g=g)

    assert prob._k == k
    assert prob.V == V
    assert prob._A == A
    assert prob._n == n
    assert prob._A_pre == A_pre
    assert prob._n_pre == n_pre
    assert prob._f == f
    assert prob._g == g
    assert prob.GMRES_its == -1
    assert prob.u_h.vector().sum() == 0.0
Beispiel #19
0
def test_HelmholtzProblem_init_one_pc_none():
    """Test a simple setup with one preconditioning coeff as None."""
    mesh = fd.UnitSquareMesh(100,100)
    V = fd.FunctionSpace(mesh, "CG", 1)
    k = 20.0
    A = fd.as_matrix([[0.9,0.2],[0.2,0.8]])
    n = 1.1
    A_pre = None
    n_pre = 1.0
    f = 1.0
    g = 1.0
    prob = hh.HelmholtzProblem(k,V,A=A,n=n,A_pre=A_pre,n_pre=n_pre,f=f,g=g)

    prob._initialise_problem()

    assert prob._k == k
    assert prob.V == V
    assert prob._A == A
    assert prob._n == n
    assert prob._a_pre == None
    assert prob._f == f
    assert prob._g == g
    assert prob.GMRES_its == -1
    assert prob.u_h.vector().sum() == 0.0
# Define a mesh that keeps pollution error bounded
num_cells = h_to_num_cells(k**-1.5, 2)

L = 1.0

mesh = SquareMesh(num_cells, num_cells, L)

# Use piecewise-linear finite elements
V = FunctionSpace(mesh, "CG", 1)

# n = 1 inside a square of size 1/3 x 1/3, and n=0.5 outside
x = SpatialCoordinate(mesh)
square_limits = np.array([[1.0 / 3.0, 2.0 / 3.0], [1.0 / 3.0, 2.0 / 3.0]])
n = 0.5 + nd_indicator(x, 0.5, square_limits)

# Define the problem
prob = hh.HelmholtzProblem(k, V, n=n)

# Use f and g corresponding to a plane wave (in homogeneous media)
prob.f_g_plane_wave()

# Use MUMPS as a direct solver
prob.use_mumps()

# Solve the problem
prob.solve()

# Plot the solution
prob.plot()
Beispiel #21
0
            x, value * constant_to_multiply,
            np.array([[fl_ii, fl_ii + 1.0], [fl_jj, fl_jj + 1.0]]) /
            float(num_pieces))

if A_vs_n:
    A = varying_coeff
    n = 1.0
else:
    A = fd.as_matrix([[1.0, 0.0], [0.0, 1.0]])
    n = varying_coeff

A_pre = fd.as_matrix([[1.0, 0.0], [0.0, 1.0]])

n_pre = 1.0

prob = hh.HelmholtzProblem(k=k, V=V, A=A, n=n, A_pre=A_pre, n_pre=n_pre)

try:
    prob.solve()

    GMRES_its = []

    #if fd.COMM_WORLD.rank == 0:
    GMRES_its.append(prob.GMRES_its)
    GMRES_its = np.array(GMRES_its)

except fd.exceptions.ConvergenceError:
    GMRES_its = np.array([np.inf])

# Write this to file