Exemple #1
0
def majorant_distribution_using_DG0(e_form, r_d, r_f, A, invA, min_eig_A, beta,
                                    C_FD, mesh, dim):

    # Define the functional space used for distribution over cells
    DG0 = FunctionSpace(mesh, "DG", 0)
    w = TestFunction(DG0)

    m_d_DG0 = Function(DG0)
    m_df_DG0 = Function(DG0)
    e_DG0 = Function(DG0)

    # Define variational forms of dual component of majorant and the whole functional
    m_d_var = w * (inner(invA * r_d, r_d)) * dx(domain=mesh)
    m_df_var = w * (
        (1.0 + beta) * inner(invA * r_d, r_d) + C_FD**2 / min_eig_A *
        (1 + 1 / beta) * inner(r_f, r_f)) * dx(domain=mesh)
    e_var = w * (inner(A * Grad(e_form, dim), Grad(e_form,
                                                   dim))) * dx(domain=mesh)

    # Assemble the variation form and dumping obtained vector into function from DG0
    assemble(m_d_var, tensor=m_d_DG0.vector())
    assemble(m_df_var, tensor=m_df_DG0.vector())
    assemble(e_var, tensor=e_DG0.vector())

    # Assign distributions
    m_d_distr = m_d_DG0.vector().array()
    m_df_distr = m_df_DG0.vector().array()
    e_distr = e_DG0.vector().array()

    # Check the correctness of the localized distributions
    print "sum(maj_distr)", numpy.sum(m_df_distr)
    print "sum(m_d_distr)", numpy.sum(m_d_distr)
    print "sum(e_d_distr)", numpy.sum(e_distr)

    return e_distr, m_d_distr, m_df_distr
Exemple #2
0
def error_norm(u, ue, lmbd, A, invA, a, func_a, V, Ve, mesh, dim):
    """
    :param u: approximate solution
    :param ue: exact solution
    :param lmbd: reaction function
    :param A: diffusion operator
    :param Ve: functional space of exact solution
    :param mesh: mesh
    :param dim: dimension of the problem

    :return: error-norm between u and ue
    """
    # Interpolate exact and approximate solution to the functional space of exact solution
    u_ve = interpolate(u, Ve)
    u_exact_ve = interpolate(ue, Ve)
    e = abs(u_ve - u_exact_ve)

    # Define variational form of the error
    var_grad_e = inner(A * Grad(e, dim), Grad(e, dim))
    delta = abs(lmbd - 0.5 * Div(func_a, dim))
    var_delta_e = delta * inner(e, e)
    var_lambda_e = lmbd * inner(e, e)
    var_diva_e = (-0.5 * Div(func_a, dim)) * inner(e, e)

    var_a_e = inner(invA * a * e, a * e)

    # Assembling variational form of the error
    grad_e = assemble(var_grad_e * dx(domain=mesh))
    delta_e = assemble(var_delta_e * dx(domain=mesh))
    lambda_e = assemble(var_lambda_e * dx(domain=mesh))
    diva_e = assemble(var_diva_e * dx(domain=mesh))
    a_e = assemble(var_a_e * dx(domain=mesh))

    # Calculate L2 norm
    l2_e = assemble(inner(e, e) * dx(domain=mesh))
    # Calculate Linf norm
    #e_func = project(e, Ve, form_compiler_parameters={'quadrature_degree': 4})
    #linf_e = norm(e_func.vector(), 'linf')

    # Calculate Linf based on the nodal values
    u_exact_v = interpolate(ue, V)
    linf_e = abs(u_exact_v.vector().array() - u.vector().array()).max()

    print '%------------------------------------------------------------------------------------%'
    print '% Error '
    print '%------------------------------------------------------------------------------------%'
    print "\| grad e \|^2_A                 = %8.2e" % grad_e
    print "\| e \|^2                        = %8.2e" % l2_e
    print "\| e \|^2_inf                    = %8.2e" % linf_e
    print "\| (lmbd - 0.5 div a)^0.5 e \|^2 = %8.2e" % delta_e
    print "\| lmbd^0.5 e \|^2               = %8.2e" % lambda_e
    print "\| a e \|^2_{A^{-1}}             = %8.2e" % a_e
    '''
    print "\| grad e \|^2_A + \| (lmbd - 0.5 div a)^0.5 e \|^2          = %8.2e" \
          % (grad_e + delta_e)
    print "\| grad e \|^2_A + \| lmbd^0.5 e \|^2 + \| a e \|^2_{A^{-1}} = %8.2e" \
          % (grad_e + lambda_e + a_e)
    '''
    return grad_e, l2_e, linf_e, delta_e, lambda_e, a_e, var_grad_e, var_delta_e, var_lambda_e, var_a_e
Exemple #3
0
def get_matrices_of_optimization_problem_bar(H_div, v, f_bar, invA, mesh, dim):
    """
    :param H_div: funtional space for the flux function
    :param v: approximate solution
    :param f_bar: right-hand side function (modified RHS)
    :param A: diffusion matrix
    :param mesh: mesh
    :param dim: geometrical problem dimension
    :return DivDiv, PhiPhi, RhsDivPhi, RhsPhi: matrixes for the optimal reconstruction of the flux
    """
    # Define variational problem
    y = TrialFunction(H_div)
    q = TestFunction(H_div)

    # Define system of linear equation to find the majorant
    # Phi_i, i = 1, ..., d are vector-valued basis of H_div
    # \int_\Omega div(phi_i) div(phi_j) \dx
    DivPhiDivPhi = assemble(inner(Div(y, dim), Div(q, dim)) * dx(domain=mesh))
    #DivPhiDivPhi_sp = as_backend_type(assemble(inner(Div(y, dim), Div(q, dim)) * dx(domain=mesh))).mat()
    #DivPhiDivPhi_sparray = csr_matrix(DivPhiDivPhi_sp.getValuesCSR()[::-1], shape=DivPhiDivPhi_sp.size)

    # \int_\Omega A^{-1} phi_i \cdot phi_j \dx
    PhiPhi = assemble(inner(invA * y, q) * dx(domain=mesh))
    # Define vectors included into the RHS
    RhsDivPhi = assemble(inner(-f_bar, Div(q, dim)) * dx(domain=mesh))
    RhsPhi = assemble(inner(Grad(v, dim), q) * dx(domain=mesh))

    #print "DivDiv = ", DivPhiDivPhi.array()
    #print "PhiPhi = ", PhiPhi.array()

    #print "RhsDivPhi = ", RhsDivPhi.array()
    #print "RhsPhi = ", RhsPhi.array()

    return DivPhiDivPhi, PhiPhi, RhsDivPhi, RhsPhi
Exemple #4
0
def calculate_majorant_bar_mu_opt(u, y, beta, f_bar, A, invA, min_eig_A, lmbd,
                                  mesh, dim, C_FD):
    """
    :param u: approximate solution
    :param y: flux
    :param beta: parameter minimizing majorant
    :param f_bar: right-hand side function (modified RHS)
    :param A: diffusion matrix
    :param min_eig_A: minimal eigenvalue of diffusion matrix
    :param lmbd: reaction function
    :param mesh: mesh
    :param dim: geometrical problem dimension
    :param C_FD: Freidrichs constant
    :return maj: majorant value
            m_d, m_f_one_minus_mu_opt: majorant components
            beta: optimal parameter
            var_m_d, var_m_f_w_opt: variational form of the majorant (to use them later in construction of error estimators)
    """
    # Define optimal parameters
    mu_opt = (C_FD**2) * (1.0 + beta) * lmbd / (beta * min_eig_A + (C_FD**2) *
                                                (1.0 + beta) * lmbd)
    w_opt = (C_FD**2) * (1 + beta) / (beta * min_eig_A + (C_FD**2) *
                                      (1 + beta) * lmbd)

    # Define residuals
    r_d = y - A * Grad(u, dim)
    r_f = (Div(y, dim) + f_bar)

    # Define variational forms
    var_m_d = abs(inner(invA * r_d, r_d))
    var_m_f_w_opt = w_opt * abs(inner(r_f, r_f))
    var_m_f_one_minus_mu_opt = ((1 - mu_opt) *
                                (1 - mu_opt)) * abs(inner(r_f, r_f))

    # Define majorant components
    m_d = assemble(var_m_d * dx(domain=mesh))
    m_f_w_opt = assemble(var_m_f_w_opt *
                         dx(domain=mesh))  # for calculating majorant
    m_f_one_minus_mu_opt = assemble(var_m_f_one_minus_mu_opt *
                                    dx(domain=mesh))  # fo calculating beta_opt

    # Calculate majorant based on the parameter value
    if m_f_w_opt <= DOLFIN_EPS:
        maj = m_d
    else:
        if m_d <= DOLFIN_EPS:
            maj = m_f_w_opt
        else:
            maj = (1.0 + beta) * m_d + m_f_w_opt

    # Calculate the optimal value for beta parameter
    beta = C_FD * sqrt(m_f_one_minus_mu_opt / m_d / min_eig_A)

    #print "m_f_one_minus_mu_opt = ", m_f_one_minus_mu_opt
    #print "m_f_w_opt = ", m_f_w_opt

    return maj, m_d, m_f_w_opt, beta, var_m_d, var_m_f_w_opt
Exemple #5
0
def get_indicators_CG0(e_form, norm_grad_e, V, V_star, f, u0, u0_boundary, u,
                       u_e, mesh, dim):

    e_form = u_e - u
    # Contruct the solution of the adjoint problem
    z = solve_dual_problem(mesh, V_star, u0, u0_boundary, e_form, dim,
                           norm_grad_e)
    Pz = project(z, V)

    # Get parameters of the mesh
    h = mesh.hmax()
    n = FacetNormal(mesh)

    # Construct the set of
    DG0 = FunctionSpace(mesh, "DG", 0)
    w = TestFunction(DG0)

    r_h = jump(Grad(u, dim), n)
    R_h = Div(Grad(u, dim), dim) + f

    eta_var = w * (h * R_h)**2 * dx(
        domain=mesh) + avg(w) * avg(h) * r_h**2 * dS(domain=mesh)
    E_DWR_var = w * inner(R_h, z - Pz) * dx(
        domain=mesh) - 0.5 * avg(w) * inner(r_h, avg(z - Pz)) * dS(domain=mesh)
    J_e_var = w * J_energy_norm_error(e_form, Grad(e_form, dim), norm_grad_e,
                                      dim) * dx(domain=mesh)

    eta_DG0 = Function(DG0)
    E_DWR_DG0 = Function(DG0)
    J_e_DG0 = Function(DG0)

    assemble(eta_var, tensor=eta_DG0.vector())
    assemble(E_DWR_var, tensor=E_DWR_DG0.vector())
    assemble(J_e_var, tensor=J_e_DG0.vector())

    eta_distr = eta_DG0.vector().array()
    E_DWR_distr = E_DWR_DG0.vector().array()
    J_e_distr = J_e_DG0.vector().array()

    print "eta_DG0 total:", numpy.sum(eta_distr)
    print "E_DWR_DG0 total", numpy.sum(E_DWR_distr)
    print "J_e_DG0 total", numpy.sum(J_e_distr)

    return eta_distr, E_DWR_distr, J_e_distr
Exemple #6
0
def get_matrices_of_optimization_problem_II(W, u, y, f, u0, T, mesh, dim,
                                            v_deg):

    # Define variational problem
    w = TrialFunction(W)
    mu = TestFunction(W)

    #w_T, T_mesh = get_2d_slice_of_3d_function_on_Oz(mesh, w, T, dim, v_deg + 1)
    #mu_T, T_mesh = get_2d_slice_of_3d_function_on_Oz(mesh, mu, T, dim, v_deg + 1)

    #mu_0, O_mesh = get_2d_slice_of_3d_function_on_Oz(mesh, mu, 0, dim, v_deg + 1)
    #u0_0, O_mesh = get_2d_slice_of_3d_function_on_Oz(mesh, interpolate(u0, W), 0, dim, v_deg + 1)

    # Define system of linear equation to find the majorant
    S = assemble(inner(Grad(w, dim), Grad(mu, dim)) * dx(domain=mesh))
    K = assemble(inner(D_t(w, dim), D_t(mu, dim)) * dx(domain=mesh))
    #F = assemble(inner(w_T, mu_T)) * dx(domain=T_mesh)

    L = assemble(
        (D_t(u, dim) * mu + inner(Grad(u, dim), Grad(mu, dim)) - f * mu) *
        dx(domain=mesh))
    z = assemble((inner(y - Grad(u, dim), Grad(mu, dim))) * dx(domain=mesh))
    g = assemble(
        (f - D_t(u, dim) + Div(y, dim)) * D_t(mu, dim) * dx(domain=mesh))
    #I = assemble(u0_0 * mu_0 * dx(domain=O_mesh))

    return S, K, L, z, g
Exemple #7
0
def update_majorant_II_components(u, w, y, f, u0, mesh, dim, v_deg, W, Ve, T):

    r_d = (y - Grad(u, dim) + Grad(w, dim))
    r_f = (Div(y, dim) + f - D_t(u, dim) - D_t(w, dim))
    L = D_t(u, dim) * w + inner(Grad(u, dim), Grad(w, dim)) - f * w
    w_T, T_mesh = get_2d_slice_of_3d_function_on_Oz(mesh, w, T, dim, v_deg + 1)
    w_0, O_mesh = get_2d_slice_of_3d_function_on_Oz(mesh, w, 0, dim, v_deg + 1)

    u0_0, O_mesh = get_2d_slice_of_3d_function_on_Oz(mesh, interpolate(u0, Ve),
                                                     0, dim, v_deg)  # varphi
    u_0, O_mesh = get_2d_slice_of_3d_function_on_Oz(mesh, interpolate(u, Ve),
                                                    0, dim, v_deg)
    r_0 = u0_0 - u_0
    l = inner(r_0, r_0) - 2 * w_0 * r_0
    w_T_form = inner(w_T, w_T)

    m_d = assemble(inner(r_d, r_d) * dx(domain=mesh))
    m_f = assemble(inner(r_f, r_f) * dx(domain=mesh))
    m_L = assemble(
        (D_t(u, dim) * w + inner(Grad(u, dim), Grad(w, dim)) - f * w) *
        dx(domain=mesh))
    m_T = assemble(w_T_form * dx(domain=T_mesh))
    m_l = assemble(l * dx(domain=O_mesh))

    return m_d, m_f, m_l, m_L, m_T
Exemple #8
0
def solve_dual_problem(V_star, f, u0, u0_boundary, u, u_e, dim):

    # Define dual variational problem
    z = TrialFunction(V_star)
    w = TestFunction(V_star)

    # Define the system
    a_star = inner(Grad(z, dim), Grad(w, dim)) * dx(domain=mesh)
    grad_e = Grad(u_e, dim) - Grad(u, dim)
    norm_grad_e = sqrt(assemble(inner(grad_e, grad_e) * dx(domain=mesh)))
    L_star = J(w, grad_e, norm_grad_e, dim)

    z = Function(V_star)
    bc_star = DirichletBC(V_star, u0, u0_boundary)
    solve(a_star == L_star, z, bc_star)

    z_exact = project((u - u_e) / norm_grad_e, V_star)
    z_error = assemble((z - z_exact)**2 * dx(domain=mesh))

    print "z error", z_error

    return z
Exemple #9
0
def majorant_distribution_DG0(mesh, f, lmbd, A, invA, u, e_form, y, beta, C_FD,
                              dim):

    # Define the functional space used for distribution over cells
    DG0 = FunctionSpace(mesh, "DG", 0)
    w = TestFunction(DG0)

    m_d_DG0 = Function(DG0)
    m_df_DG0 = Function(DG0)
    e_d_DG0 = Function(DG0)

    # Define optimal parameters
    w_opt = (C_FD**2) * (1 + beta) / (beta + (C_FD**2) * (1 + beta) * lmbd)

    # Define the residuals of the majorant
    r_d = y - A * Grad(u, dim)
    r_f = (Div(y, dim) + f - lmbd * u)

    # Define variational forms of dual component of majorant and the whole functional
    m_d_var = w * sqrt(inner(invA * r_d, r_d)) * dx(domain=mesh)
    m_df_var = w * sqrt((1.0 + beta) * inner(invA * r_d, r_d) +
                        w_opt * inner(r_f, r_f)) * dx(domain=mesh)
    e_d_var = w * sqrt(inner(A * Grad(e_form, dim), Grad(
        e_form, dim))) * dx(domain=mesh)

    # Assemble the variation form and dumping obtained vector into function from DG0
    assemble(m_d_var, tensor=m_d_DG0.vector())
    assemble(m_df_var, tensor=m_df_DG0.vector())
    assemble(e_d_var, tensor=e_d_DG0.vector())

    m_d_distr = m_d_DG0.vector().array()
    m_df_distr = m_df_DG0.vector().array()
    e_d_distr = e_d_DG0.vector().array()

    print "m_d_DG0 total", numpy.sum(m_d_distr)
    print "m_df_DG0 total", numpy.sum(m_df_distr)
    print "e_d_DG0 total", numpy.sum(e_d_distr)

    return m_d_distr, m_df_distr, e_d_distr
Exemple #10
0
def solve_dual_problem(mesh, V_star, u0, u0_boundary, e, dim, norm_grad_e):

    # Define dual variational problem
    z = TrialFunction(V_star)
    w = TestFunction(V_star)

    # Define the adjoint right-hand side
    a_star = inner(Grad(z, dim), Grad(w, dim)) * dx(domain=mesh)

    # Define the adjoint left-hand side
    L_star = J_energy_norm_error(w, Grad(e, dim), norm_grad_e,
                                 dim) * dx(domain=mesh)

    z = Function(V_star)
    bc_star = DirichletBC(V_star, u0, u0_boundary)
    solve(a_star == L_star, z, bc_star)

    z_exact = project(e / norm_grad_e, V_star)

    z_error = assemble((z - z_exact)**2 * dx(domain=mesh))
    print "z error", z_error

    return z
Exemple #11
0
def minorant(u, mesh, Vh, u0, u0_boundary, f, dim, error):

    # Define variational problem
    w = TrialFunction(Vh)
    mu = TestFunction(Vh)

    a = inner(NablaGrad(w, dim), NablaGrad(mu, dim)) * dx(domain=mesh)
    L = (f * mu - inner(NablaGrad(u, dim), Grad(mu, dim))) * dx(domain=mesh)

    w = Function(Vh)

    # Define boundary condition
    bc = DirichletBC(Vh, u0, u0_boundary)
    solve(a == L, w, bc)

    min_var = (2 * (f * w - inner(Grad(u, dim), Grad(w, dim))) -
               inner(Grad(w, dim), Grad(w, dim))) * dx(domain=mesh)
    min = assemble(min_var)

    print "error = %.4e , min = %.4e, i_eff_min = %.4e" % (error, min,
                                                           min / error)

    return min, w
Exemple #12
0
def majorant_nd(v, y, H_div, V, VV, f, A, invA, lambda_1, a, lmbd, error, mesh,
                dim, C_FD, C_Ntr, problem_params):
    """
    :param v: approximate solution
    :param y: flux
    :param H_div: funtional space for the flux function
    :param f: right-hand side function (modified RHS)
    :param A: diffusion matrix
    :param lambda_1: minimal eigenvalue of diffusion matrix
    :param a: convection function
    :param lmbd: reaction function
    :param error: error value
    :param mesh: mesh
    :param dim: geometrical problem dimension
    :param C_FD: Freidrichs constant of the computational domain
    :param MAJORANT_OPTIMIZE: test_parameter on weather to optimize majorant of not
    :return maj: majorant value
            m_d, m_f_one_minus_mu_opt: majorant components
            beta: optimal parameter
            var_m_d, var_m_f_w_opt: variational form of the majorant (to use them later in construction of error estimators)
            maj, y, beta, m_d, m_f, var_m_d, var_m_f_w_opt, majorant_reconstruction_time, majorant_minimization_time
    """

    tic()

    # Initialize value
    beta = 1.0
    #for i in range(2):
    f_bar = f - lmbd * v - inner(a, Grad(v, dim))
    #f_bar = f
    maj, m_d, m_f, beta, var_m_d, var_m_f_w_opt = calculate_majorant_bar_mu_opt(
        v, y, beta, f_bar, A, invA, lambda_1, lmbd, mesh, dim, C_FD)
    i_eff = sqrt(maj / error)
    print " "
    print '%------------------------------------------------------------------------------------%'
    print "% Majorant before optimization"
    print '%------------------------------------------------------------------------------------%'
    print " "

    output_optimization_results(0, maj, m_d, m_f, i_eff, beta, error)

    majorant_reconstruction_time = toc()

    if problem_params["MAJORANT_OPTIMIZE"]:
        #----------------------------------------------------------------------------#
        # Optimization algorithm
        #----------------------------------------------------------------------------#
        print " "
        print "%-----------------------"
        print "% optimization "
        print "%-----------------------"
        print " "

        tic()
        S, K, z, g = get_matrices_of_optimization_problem_bar(
            H_div, v, f_bar, invA, mesh, dim)

        y = Function(H_div)
        Y = y.vector()

        OPT_ITER = problem_params["majorant_optimization_iterations"]
        # Execute iterative process to optimize majorant with respect to beta and flux
        for k in range(0, problem_params["majorant_optimization_iterations"]):
            # Solve system with respect to Y
            #yMatrix = (C_FD ** 2) / lambda_1 * S + beta * K
            #yRhs = sum((C_FD ** 2) / lambda_1 * z, beta * g)
            #solve(yMatrix, Y, yRhs)

            solve((C_FD**2) / lambda_1 * S + beta * K, Y,
                  (C_FD**2) / lambda_1 * z + beta * g)

            y.vector = Y
            '''

            YtSY = assemble(inner(Div(y, dim), Div(y, dim)) * dx(domain=mesh))
            YtSz2 = assemble(2 * inner(Div(y, dim), f) * dx(domain=mesh))
            FF = assemble(inner(f, f) * dx(domain=mesh))

            print "Y^T*S*Y", YtSY
            print "2*Y^T*z", YtSz2
            print "FF", FF
            print "\| div y + f \|^2", YtSY + YtSz2 + FF

            YtY = assemble(inner(y, y) * dx(domain=mesh))
            YtSz2 = assemble(2 * inner(Grad(v, dim), y) * dx(domain=mesh))
            GradVGradV = assemble(inner(Grad(v, dim), Grad(v, dim)) * dx(domain=mesh))

            print "YtY", YtY
            print "YtSz2", YtSz2
            print "GradVGradV", GradVGradV
            print "\| y - grad v \|^2", YtY - YtSz2 + GradVGradV

            print "\| v \|", (norm(v, 'L2'))**2
            print "\| grad v \|", (norm(v, 'H1'))**2
            print "\| div y \|", (norm(project(div(y), V), 'L2'))**2
            print "\| f \|", (norm(project(f, V), 'L2'))**2
            '''
            # Calculate majorant
            maj, m_d, m_f, beta, var_m_d, var_m_f_w_opt = calculate_majorant_bar_mu_opt(
                v, y, beta, f_bar, A, invA, lambda_1, lmbd, mesh, dim, C_FD)
            i_eff = sqrt(maj / error)

            output_optimization_results(k + 1, maj, m_d, m_f, i_eff, beta,
                                        error)

        majorant_minimization_time = toc()

    else:

        majorant_minimization_time = 0.0

    return maj, y, beta, m_d, m_f, var_m_d, var_m_f_w_opt, majorant_reconstruction_time, majorant_minimization_time
Exemple #13
0
def majorant_nd(v, y, H_div, f, A, invA, min_eig_A, eps, a, lmbd, error, mesh,
                dim, C_FD, C_Ntr, problem_params):
    """
    :param v: approximate solution
    :param y: flux
    :param H_div: funtional space for the flux function
    :param f: right-hand side function (modified RHS)
    :param A: diffusion matrix
    :param min_eig_A: minimal eigenvalue of diffusion matrix
    :param a: convection function
    :param lmbd: reaction function
    :param error: error value
    :param mesh: mesh
    :param dim: geometrical problem dimension
    :param C_FD: Freidrichs constant of the computational domain
    :param MAJORANT_OPTIMIZE: test_parameter on weather to optimize majorant of not
    :return maj: majorant value
            m_d, m_f_one_minus_mu_opt: majorant components
            beta: optimal parameter
            var_m_d, var_m_f_w_opt: variational form of the majorant (to use them later in construction of error estimators)
            maj, y, beta, m_d, m_f, var_m_d, var_m_f_w_opt, majorant_reconstruction_time, majorant_minimization_time
    """

    tic()

    # Initialize value
    beta = 1.0
    #for i in range(2):
    f_bar = f - lmbd * v - inner(a, Grad(v, dim))
    #f_bar = f
    maj, m_d, m_f, beta, var_m_d, var_m_f_w_opt = calculate_majorant_bar_mu_opt(
        v, y, beta, f_bar, A, invA, min_eig_A, lmbd, mesh, dim, C_FD)
    i_eff = sqrt(maj / error)
    print " "
    print '%------------------------------------------------------------------------------------%'
    print "% Majorant optimization"
    print '%------------------------------------------------------------------------------------%'
    print " "

    info(parameters, verbose=True)

    print(parameters.linear_algebra_backend)
    list_linear_solver_methods()
    list_krylov_solver_preconditioners()

    solver = KrylovSolver('gmres', 'ilu')
    prm = solver.parameters
    prm.absolute_tolerance = 1e-10
    prm.relative_tolerance = 1e-6
    prm.maximum_iterations = 1000

    output_optimization_results(0, maj, m_d, m_f, i_eff, beta, error)

    majorant_reconstruction_time = toc()

    if problem_params["MAJORANT_OPTIMIZE"]:
        #----------------------------------------------------------------------------#
        # Optimization algorithm
        #----------------------------------------------------------------------------#

        tic()
        S, K, z, g = get_matrices_of_optimization_problem_bar(
            H_div, v, f_bar, invA, mesh, dim)

        y = Function(H_div)
        Y = y.vector()

        OPT_ITER = problem_params["majorant_optimization_iterations"]
        i_eff = 1e8
        k = 1
        m_d = 1.0
        m_f = 10.0

        # Execute iterative process to optimize majorant with respect to beta and flux
        while k in range(0, OPT_ITER):  # m_d * min_eig_A /m_f <= 1: #or
            # Solve system with respect to Y
            #yMatrix = (C_FD ** 2) / min_eig_A * S + beta * K
            #yRhs = sum((C_FD ** 2) / min_eig_A * z, beta * g)
            #solve(yMatrix, Y, yRhs)

            solve((C_FD**2) / min_eig_A * S + beta * K, Y,
                  (C_FD**2) / min_eig_A * z + beta * g)

            #if len(Y) <= 1e4:
            #    solve((C_FD ** 2) / min_eig_A * S + beta * K, Y, (C_FD ** 2) / min_eig_A * z + beta * g)
            #else:
            #    solver.solve((C_FD ** 2) / min_eig_A * S + beta * K, Y, (C_FD ** 2) / min_eig_A * z + beta * g,
            #      "gmres", "ilu")

            y.vector = Y
            """
            YtSY = assemble(inner(Div(y, dim), Div(y, dim)) * dx(domain=mesh))
            YtSz2 = assemble(2 * inner(Div(y, dim), f) * dx(domain=mesh))
            FF = assemble(inner(f, f) * dx(domain=mesh))

            print "Y^T*S*Y", YtSY
            print "2*Y^T*z", YtSz2
            print "FF", FF
            print "\| div y + f \|^2", YtSY + YtSz2 + FF

            YtY = assemble(inner(y, y) * dx(domain=mesh))
            YtSz2 = assemble(2 * inner(Grad(v, dim), y) * dx(domain=mesh))
            GradVGradV = assemble(inner(Grad(v, dim), Grad(v, dim)) * dx(domain=mesh))
            """

            # Calculate majorant
            maj, m_d, m_f, beta, var_m_d, var_m_f_w_opt = calculate_majorant_bar_mu_opt(
                v, y, beta, f_bar, A, invA, min_eig_A, lmbd, mesh, dim, C_FD)
            i_eff = sqrt(maj / error)

            output_optimization_results(k, maj, m_d, m_f, i_eff, beta, error)
            k = k + 1

        majorant_minimization_time = toc()

    else:

        majorant_minimization_time = 0.0

    return maj, y, beta, m_d, m_f, var_m_d, var_m_f_w_opt, majorant_reconstruction_time, majorant_minimization_time
Exemple #14
0
 def a(u, v):
     return inner(A * Grad(u, dim), Grad(v, dim)) + lmbd * inner(u, v)
Exemple #15
0
def J_energy_norm_error(w, grad_e, norm_grad_e, dim):
    return inner(Grad(w, dim), grad_e) / norm_grad_e
Exemple #16
0
def compare_error_indicators(mesh, V, V_star, f, u0, u0_boundary, u, u_e,
                             grad_u_e, y, beta, test_num, tag, dim):

    z = solve_dual_problem(V_star, f, u0, u0_boundary, u, u_e)
    Pz = project(z, V)

    norm_grad_e = sqrt(
        assemble(
            inner(grad_u_e - Grad(u, dim), grad_u_e - Grad(u, dim)) *
            dx(domain=mesh)))
    h = mesh.hmax()
    n = FacetNormal(mesh)
    DG0 = FunctionSpace(mesh, "DG", 0)
    w = TestFunction(DG0)

    r_h = jump(Grad(u, dim), n)
    R_h = div(Grad(u, dim)) + f

    cell_num = mesh.num_cells()

    e = abs(u_e - u)
    r_d = abs(Grad(u, dim) - y)
    r_f = abs(f + Div(y, dim))
    eta_var = w * (h * R_h)**2 * dx + avg(w) * avg(h) * r_h**2 * dS
    E_DWR_var = w * inner(R_h, z - Pz) * dx - 0.5 * avg(w) * inner(
        r_h, avg(z - Pz)) * dS
    J_e_var = w * J(w, e, norm_grad_e) * dx
    m_d_var = w * sqrt(inner(r_d, r_d)) * dx
    #C_FD = 1 / (sqrt(3) * DOLFIN_PI)
    height = 1
    width = 2
    length = 2
    C_FD = 1.0 / DOLFIN_PI / sqrt(1.0 / height**2 + 1.0 / width**2 +
                                  1.0 / length**2)
    m_df_var = w * sqrt((1 + beta) * inner(r_d, r_d) + C_FD**2 *
                        (1 + 1 / beta) * inner(r_f, r_f)) * dx

    #M_e = w * (u - u_exact) * dx

    eta_DG0 = Function(DG0)
    E_DWR_DG0 = Function(DG0)
    J_e_DG0 = Function(DG0)
    m_d_DG0 = Function(DG0)
    m_df_DG0 = Function(DG0)

    assemble(eta_var, tensor=eta_DG0.vector())
    assemble(E_DWR_var, tensor=E_DWR_DG0.vector())
    assemble(J_e_var, tensor=J_e_DG0.vector())
    assemble(m_d_var, tensor=m_d_DG0.vector())
    assemble(m_df_var, tensor=m_df_DG0.vector())

    eta_distr = eta_DG0.vector().array()
    E_DWR_distr = E_DWR_DG0.vector().array()
    J_e_distr = J_e_DG0.vector().array()
    m_d_distr = m_d_DG0.vector().array()
    m_df_distr = m_df_DG0.vector().array()

    eta_DG0_total = numpy.sum(eta_distr)
    E_DWR_DG0_total = numpy.sum(E_DWR_distr)
    J_e_DG0_total = numpy.sum(J_e_distr)
    m_d_DG0_total = numpy.sum(m_d_distr)
    m_df_DG0_total = numpy.sum(m_df_distr)

    print "eta_DG0 total:", eta_DG0_total
    print "E_DWR_DG0 total", E_DWR_DG0_total
    print "J_e_DG0 total", J_e_DG0_total
    print "m_d_DG0 total", m_d_DG0_total
    print "m_df_DG0 total", m_df_DG0_total
Exemple #17
0
def J(w, grad_e, norm_grad_e, dim):
    return inner(Grad(w, dim), grad_e) / norm_grad_e
Exemple #18
0
    def solve_problem_nd_t(self, mesh, boundary_facets, ds, dS, V, V_exact,
                           VV_exact, H_div, u_e, f, A, invA, adjA, min_eig_A,
                           lmbd, a, eps_curr, uD, uN, C_FD, C_Ntr,
                           project_path, results_folder, test_params):

        # Define the number of refinements
        ref_num = test_params['number_of_refinements'] + 20

        # Define arrays with data collected on the refinement steps
        ref_num_array = postprocess.allocate_array(ref_num + 1)
        h_max_array = postprocess.allocate_array(ref_num + 1)
        h_min_array = postprocess.allocate_array(ref_num + 1)
        dofs_array = postprocess.allocate_array(ref_num + 1)
        numcells_array = postprocess.allocate_array(ref_num + 1)
        numverts_array = postprocess.allocate_array(ref_num + 1)
        e_array = postprocess.allocate_array(ref_num + 1)
        e_l2_array = postprocess.allocate_array(ref_num + 1)
        e_linf_array = postprocess.allocate_array(ref_num + 1)

        e_min_array = postprocess.allocate_array(ref_num + 1)
        maj_array = postprocess.allocate_array(ref_num + 1)
        min_array = postprocess.allocate_array(ref_num + 1)
        i_eff_maj_array = postprocess.allocate_array(ref_num + 1)
        i_eff_min_array = postprocess.allocate_array(ref_num + 1)

        # Initialize the variables before the loop
        maj = 10e8
        i = 0
        h_min = 10e8

        # TO DO: Calculate the reference solution on the refined mesh
        '''
        if test_params['solution_tag'] == "reference-solution":
            mesh_ref = self.construct_mesh(2 ** ref_num * test_params["nx0"],
                                           2 ** ref_num * test_params["nx1"],
                                           2 ** ref_num * test_params["nx2"],
                                           2 ** ref_num * test_params["res"], project_path)
            # Update functional spaces, BC, and stiffness/mass matrices
            V_ref, VV_ref, V_ref_exact, VV_ref_exact, H_ref_div = problem.functional_spaces(mesh_ref,
                                                                            test_params["v_approx_order"],
                                                                            test_params["flux_approx_order"],
                                                                            dim)
            boundary_facets_ref, ds = self.construct_boundary_faces(mesh_ref)
            u_e, delta = problem.solve_convection_reaction_diffusion(V_ref_exact, f, A, min_eig_A, lmbd,
                                                                     problem.interpolate_vector_function(a, dim, V_ref_exact, VV_ref_exact),
                                                                     self.boundary, uD, uN,
                                                                     mesh_ref, boundary_facets_ref,
                                                                     dim, test_num)
        '''

        while h_min > eps_curr:  # (i <= ref_num and maj > test_params['accuracy_level']) or

            print(" ")
            print(
                "%-----------------------------------------------------------------------------------------------------------%"
            )
            print " Refinement cycle # %d : DOFs = %d" % (
                i, len(V.dofmap().dofs()))
            print(
                "%-----------------------------------------------------------------------------------------------------------%"
            )
            print(" ")

            # Compute approximate solution u and stabilization parameter (in case of the convection dominated problem)

            u, delta = problem.solve_convection_reaction_diffusion(
                V, f, A, min_eig_A, lmbd,
                problem.interpolate_vector_function(a, dim, V_exact, VV_exact),
                self.boundary, uD, uN, mesh, boundary_facets, self.dim,
                self.test_num, test_params)

            # In case of explicitely unknown exact solution, calculate it with high order order polynomials
            if test_params['solution_tag'] == "reference-solution":
                # Compute reference solution with high order polynomials
                u_e, delta = problem.solve_convection_reaction_diffusion(
                    V_exact, f, A, min_eig_A, lmbd,
                    problem.interpolate_vector_function(
                        a, dim, V_exact,
                        VV_exact), self.boundary, uD, uN, mesh,
                    boundary_facets, self.dim, self.test_num, test_params)

            if test_params["PLOT"] == True:
                #plot(u, interactive=True)
                # Plot approximate solution
                postprocess.plot_function(
                    u, mesh, dim, project_path + results_folder + 'u-%d' % i)

            # Calculate error
            grad_e, e_l2, e_linf, delta_e, lambda_e, a_e, var_grad_e, var_lmbd_diva_e, var_lmbd_e, var_a_e = \
                estimates.error_norm(u, u_e, lmbd, A, invA,
                                     a,
                                     problem.interpolate_vector_function(a, dim, V_exact, VV_exact),
                                     V, V_exact, mesh, dim)
            # Define the error for the majorant
            error = grad_e + delta_e

            # Define the error for the minorant
            if test_params[
                    "pde_tag"] == "reaction-diffusion-pde" or test_params[
                        "pde_tag"] == "diffusion-pde":
                error_min = grad_e + delta_e
            elif test_params[
                    "pde_tag"] == "reaction-convection-diffusion-pde" or test_params[
                        "pde_tag"] == "convection-diffusion-pde":
                error_min = grad_e + lambda_e + a_e

            if test_params["error_estimates"] == True:

                # L2-projection of grad u to Hdiv space
                y = project(A * Grad(u, dim), H_div)

                # Test for the correctness of the code and the majorant for the y = A dot \grad u
                # y = interpolate(A * Grad(u, dim), H_div)
                #y = project(A * Grad(u_e, dim), H_div)

                # Contruct the majorant
                maj, y, beta, md, mf, var_m_d, var_m_f_w_opt, \
                majorant_reconstruction_time, majorant_minimization_time = \
                    estimates.majorant_nd(u, y, H_div, f, A, invA, min_eig_A, eps, a, lmbd, error, mesh, dim, C_FD, C_Ntr, test_params)

                # Output the results of upper bound reconstructions
                estimates.output_result_error_and_majorant(
                    sqrt(error), sqrt(maj), sqrt(maj / error))

                # Construct error and majorant distribution
                ed_distr, delta_e_distr, e_distr, md_distr, mf_distr, maj_distr, ed, md = \
                    estimates.error_majorant_distribution_nd(mesh, dim, V_exact,
                                                             var_grad_e, var_lmbd_diva_e, var_m_d, var_m_f_w_opt, beta)

                # Calculate the smoothness parameter
                #smoothness_distr = problem.smoothness_distribution(u, mesh, dim)
                #print "smoothness ", smoothness_distr

                #smooth_criterion = problem.SmoothnessCriterion(v=interpolate(u, V_exact), mesh=mesh,
                #                                               expression_degree=test_params["expression_degree"])

                #smoothness_vals = project(smooth_criterion, FunctionSpace(mesh, "DG", 0))
                #print "smoothness_vals:", smoothness_vals.vector().array()

                # Calculate minorant
                min, phi = estimates.minorant(u_e, u, mesh, ds, V_exact, uN,
                                              self.boundary, f, A, lmbd, a,
                                              dim, test_params)
                # Output the results of lower bound reconstructions
                estimates.output_result_minorant(sqrt(error_min), sqrt(min),
                                                 sqrt(min / error_min))

                maj_array[i] = sqrt(maj)
                i_eff_maj_array[i] = sqrt(maj / error)

                min_array[i] = sqrt(min)
                i_eff_min_array[i] = sqrt(min / error_min)

                if test_params["pde_tag"] == "reaction-convection-diffusion-pde" \
                            or test_params["pde_tag"] == "convection-diffusion-pde":
                    e_min_array[i] = sqrt(error_min)
                else:
                    e_min_array[i] = e_array[i]
                '''
                #tag = 'E-DWR-'
                #tag = 'eta-'
                #tag = 'error-'
                #tag = 'm-d-'
                #tag = 'm-df-'

                eta_distr, E_DWR_distr, J_e_distr, m_d_distr, m_df_distr  = \
                    compare_error_indicators(mesh, V, V_star, V_e, f, u_0, boundary, u,
                                             interpolate(u_e, V_e), interpolate(grad_u_e, VV_e),
                                             y, beta, test_num, tag)



                cells_num = mesh.num_cells()
                N_array[i] = cells_num
                e_array[i] = sum(J_e_distr)

                if tag == 'eta-':
                    distr = eta_distr
                elif tag == 'E-DWR-':
                    distr = E_DWR_distr
                elif tag == 'error-':
                    distr = J_e_distr
                elif tag == 'm-d-':
                    distr = m_d_distr
                elif tag == 'm-df-':
                    distr = m_df_distr

                '''
                '''
                md_CG0_distr, mdf_CG0_distr, e_CGO_distr = estimates.majorant_distribution_DG0(mesh, f, lmbd, A, invA, u, e_form, y, beta, C_FD, dim)

                residual_CG0_distr, e_DWR_CG0_distr, J_e_CG0_distr = estimates.get_indicators_CG0(mesh, V, V_exact, f, A, adjA, lmbd, u_0, boundary, u, u_e,
                                                                                                  e_form, sqrt(e_d), dim)

                # Plot histograms with obtained indicators
                postprocess.plot_histogram(mesh, J_e_CG0_distr, residual_CG0_distr,
                                           project_path + results_folder + 'je-residual-distr-hist' + results_info)
                postprocess.plot_histogram(mesh, J_e_CG0_distr, e_DWR_CG0_distr,
                                           project_path + results_folder + 'je-edwr-distr-hist' + results_info)
                # Plot histograms with obtained indicators from majorant
                postprocess.plot_histogram(mesh, J_e_CG0_distr, md_CG0_distr,
                                           project_path + results_folder + 'je-md-distr-hist' + results_info)
                postprocess.plot_histogram(mesh, J_e_CG0_distr, mdf_CG0_distr,
                                           project_path + results_folder + 'je-mdf-distr-hist' + results_info)
                '''

            # Update the arrays of data with respect to the refinement cycle
            ref_num_array[i] = i + 1
            e_array[i] = sqrt(error)
            e_l2_array[i] = e_l2
            e_linf_array[i] = e_linf
            h_max_array[i] = mesh.hmax()
            h_min_array[i] = mesh.hmin()

            h_min = mesh.hmin()
            print "hmax = ", mesh.hmax()
            print "hmin = ", mesh.hmin()

            num_cells = mesh.num_cells()
            num_vertices = mesh.num_vertices()
            num_dofs = len(V.dofmap().dofs())

            numcells_array[i] = num_cells
            numverts_array[i] = num_vertices
            dofs_array[i] = num_dofs

            # Construct the tag with problem information
            results_info = postprocess.construct_result_tag(
                test_num, i, test_params["nx0"], test_params["nx1"],
                test_params["nx2"], num_cells, num_vertices)

            # Plot histogram with the error and majorant distribution
            #postprocess.plot_histogram(mesh, ed_distr, md_distr,
            #                           project_path + results_folder + 'e-maj-distr-hist' + results_info)
            #postprocess.plot_histogram_smoothness(mesh, mf_distr, 'k',
            #                           project_path + results_folder + 'mf-distr-hist' + results_info)
            #postprocess.plot_histogram_smoothness(mesh, smoothness_distr, 'b',
            #                           project_path + results_folder + 'smoothness-distr-hist' + results_info)

            # For the refinement accept the last one change the mesh-dependent values like spaces and mesh functions
            if ref_num > 0 and i + 1 <= ref_num:

                # If the error estimates are constructed, then the mesh refinement can vary: uniform or adaptive
                if test_params["error_estimates"] == True:
                    # Refine mesh
                    mesh, mat_file_tag = self.execute_refinement_strategy(
                        test_params, mesh, e_distr, md_distr, project_path,
                        results_folder, results_info)
                    # Save the results in mat-file
                    postprocess.save_results_to_mat_file(
                        ed_distr, md_distr, e_array, maj_array,
                        i_eff_maj_array, e_min_array, min_array, mat_file_tag)

                    if i + 1 == ref_num:
                        postprocess.save_mesh_to_xml_file(
                            mesh, project_path + results_folder, results_info)

                    # If the refiniment strategy is adaptive, that plot the changes in the mesh, majorant, and the error
                    if test_params['refinement_tag'] == "adaptive":

                        if test_params["PLOT"] == True:
                            # Plot result mesh
                            if dim == 2:
                                postprocess.plot_mesh(
                                    mesh, project_path + results_folder +
                                    'mesh' + results_info)

                                # Plot 'carpets with colored elements' dependent on the error and the majorant
                                #postprocess.plot_carpet_2d(mesh, ed,
                                #                           project_path + results_folder + 'carpet-error' + results_info)
                                #postprocess.plot_carpet_2d(mesh, md,
                                #                           project_path + results_folder + 'carpet-majorant' + results_info)
                            elif dim == 3:
                                postprocess.plot_mesh_3d(
                                    mesh, project_path + results_folder +
                                    'initial-mesh')
                # If the error estimates aren't constructed, the mesh refinement is uniform
                else:
                    mesh = refine(mesh)

                # Update functional spaces, BC, and stiffness/mass matrices
                V, VV, V_exact, VV_exact, H_div = problem.functional_spaces(
                    mesh, test_params, dim)
                if test_params[
                        'material_tag'] == "material-changing":  # over the domain
                    # Define A if it is changing
                    A = problem.construct_from_mesh_functions(
                        dim, self.A_expr, mesh)

                boundary_facets, ds, dS = self.construct_boundary_faces(mesh)

                # Define the value of the maj for the loop criteria
                if test_params["error_estimates"] == True:
                    maj = maj_array[i]
                else:
                    maj = e_array[i]

            # Update the refinement number
            i += 1

        # Output the results
        decay_result_folder = postprocess.create_decay_tag(
            test_params, project_path, results_folder, results_info)

        postprocess.document_errors_decay(float(self.dim), test_params,
                                          decay_result_folder, dofs_array[0:i],
                                          h_min_array[0:i], e_array[0:i],
                                          e_l2_array[0:i], e_linf_array[0:i],
                                          e_min_array[0:i], maj_array[0:i],
                                          min_array[0:i])
        return mesh, V, VV, V_exact, VV_exact, H_div, boundary_facets, ds, dS
Exemple #19
0
 def b(u, v):
     return inner(A * Grad(u, dim), Grad(
         v, dim)) + lmbd * inner(u, v) + inner(inner(conv, Grad(u, dim)), v)