Пример #1
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
Пример #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
Пример #3
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
Пример #4
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
Пример #5
0
def get_matrices_of_optimization_problem(H_div, u, f_bar, invA, mesh, dim):

    # Define variational problem
    y = TrialFunction(H_div)
    q = TestFunction(H_div)

    # Define system of linear equation to find the majorant
    S = assemble(inner(Div(y, dim), Div(q, dim)) * dx(domain=mesh))
    K = assemble(inner(invA * y, q) * dx(domain=mesh))
    N = assemble(inner(y, q) * ds(neumann_bc_marker))

    #z = assemble(inner(- (f - c_H * D_t(u, dim)), Div(q, dim)) * dx(domain=mesh))
    z = assemble(inner(-f_bar, Div(q, dim)) * dx(domain=mesh))
    g = assemble(inner(NablaGrad(u, dim), q) * dx(domain=mesh))

    return S, K, z, g
Пример #6
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 lambda_1: 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)
    #mu_opt = 1
    w_opt = (C_FD**2) * (1.0 + beta) / (
        beta * min_eig_A + (C_FD**2) * (1.0 + beta) * lmbd
    )  # this is the function in front of inner(r_f, r_f)

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

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

    # Define variational forms
    var_m_d = inner(invA * r_d, r_d)
    var_m_f_w_opt = w_opt * inner(r_f, r_f)
    var_m_f_one_minus_mu_opt = ((1 - mu_opt)**2) * inner(
        r_f, r_f)  # only for the calculation of optimal beta

    # 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)

    return maj, m_d, m_f_one_minus_mu_opt, beta, var_m_d, var_m_f_w_opt
Пример #7
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
Пример #8
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
Пример #9
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
Пример #10
0
def error_norm(u, ue, A, lmbd, a, f, c_H, v_degree, mesh, T, dim, V, Ve):
    """
    :param u: approximate solution
    :param ue: exact solution
    :param A:
    :param lmbd:
    :param lambd:

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

    res = Div(A * NablaGrad(u, dim), dim) \
          + f \
          - c_H * D_t(u, dim) \
          - lmbd * u \
          - inner(a, NablaGrad(u, dim))

    var_e = inner(e, e)
    var_delta_e = inner((lmbd - 0.5 * Div(a, dim)) * e, e)
    var_lambda_e = lmbd * inner(e, e)
    var_grad_e = inner(A * NablaGrad(e, dim), NablaGrad(e, dim))
    var_e_t = inner(c_H * D_t(e, dim), c_H * D_t(e, dim))
    var_laplas_e = inner(Div(A * NablaGrad(e, dim), dim),
                         Div(A * NablaGrad(e, dim), dim))
    var_e_id = inner(res, res)

    val_e = assemble(var_e * dx(domain=mesh))
    val_delta_e = assemble(var_delta_e * dx(domain=mesh))
    val_lmbd_e = assemble(var_lambda_e * dx(domain=mesh))
    val_grad_e = assemble(var_grad_e * dx(domain=mesh))
    val_e_t = assemble(var_e_t * dx(domain=mesh))
    val_laplas_e = assemble(var_laplas_e * dx(domain=mesh))

    val_e_id = assemble(var_e_id * dx(domain=mesh))

    u_T, mesh_T = get_2d_slice_of_3d_function_on_Oz(mesh, u_ve, T, dim,
                                                    v_degree)
    ue_T, mesh_T = get_2d_slice_of_3d_function_on_Oz(mesh, u_exact_ve, T, dim,
                                                     v_degree)
    var_e_T = abs(ue_T - u_T)
    val_e_T = assemble(inner(var_e_T, var_e_T) * dx(domain=mesh_T))

    u_0, mesh_0 = get_2d_slice_of_3d_function_on_Oz(mesh, u_ve, 0.0, dim,
                                                    v_degree)
    ue_0, mesh_0 = get_2d_slice_of_3d_function_on_Oz(mesh, u_exact_ve, 0.0,
                                                     dim, v_degree)
    var_e_0 = abs(ue_0 - u_0)
    val_e_0 = assemble(inner(A * var_e_0, var_e_0) * dx(domain=mesh_0))

    print '%------------------------------------------------------------------------------------%'
    print '% Error '
    print '%------------------------------------------------------------------------------------%\n'
    print "\| grad_x e \|^2_A               = %8.2e" % val_grad_e
    print "\| e \|^2                        = %8.2e" % val_e
    print "\| (lmbd - 0.5 div a)^0.5 e \|^2 = %8.2e" % val_delta_e
    print "\| lmbd^0.5 e \|^2               = %8.2e\n" % val_lmbd_e

    print "\| laplas e \|^2                 = %8.2e" % val_laplas_e
    print "\| e_t \|^2                      = %8.2e" % val_e_t
    print "\| r_v \|^2                      = %8.2e" % val_e_id

    print "\| e \|^2_T                      = %8.2e" % val_e_T
    print "\| e \|^2_0                      = %8.2e\n" % val_e_0
    #print "\| grad_x e \|^2_T               = %8.2e" % val_grad_e_T
    #print "\| grad_x e \|^2_0               = %8.2e\n" % val_grad_e_0

    print '%------------------------------------------------------------------------------------%'
    print '% Error identity '
    print '%------------------------------------------------------------------------------------%\n'

    print "id = \| e \|^2_T + \| r_v \|^2               = %8.2e" % (val_e_T +
                                                                    val_e_id)
    print "\| laplas e \|^2 + \| e_t \|^2 + \| e \|^2_0 = %8.2e\n" % (
        val_e_0 + val_laplas_e + val_e_t + val_delta_e)

    return e, val_e, val_grad_e, val_delta_e, val_e_T, val_laplas_e + val_e_t, val_e_id, \
           var_e, var_delta_e, var_grad_e