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
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
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
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
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
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
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
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
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
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
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
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
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
def a(u, v): return inner(A * Grad(u, dim), Grad(v, dim)) + lmbd * inner(u, v)
def J_energy_norm_error(w, grad_e, norm_grad_e, dim): return inner(Grad(w, dim), grad_e) / norm_grad_e
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
def J(w, grad_e, norm_grad_e, dim): return inner(Grad(w, dim), grad_e) / norm_grad_e
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
def b(u, v): return inner(A * Grad(u, dim), Grad( v, dim)) + lmbd * inner(u, v) + inner(inner(conv, Grad(u, dim)), v)