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 test_estimates(self, test_params): # Define the project path # --------------------------------------------------------------------------------------------------------------# project_path = postprocess.get_project_path() # Check if it does exist and create folder for the results # --------------------------------------------------------------------------------------------------------------# results_folder_name = postprocess.construct_result_folder_name( self.dim, test_num, test_params) postprocess.create_results_folder(results_folder_name, test_params) # --------------------------------------------------------------------------------------------------------------# # Define problem data # --------------------------------------------------------------------------------------------------------------# # Define the mesh based on the domain geometry # --------------------------------------------------------------------------------------------------------------# mesh = self.construct_mesh(test_params["nx0"], test_params["nx1"], test_params["nx2"], test_params["nt"], test_params["res"], project_path) if test_params["PLOT"] == True: # Plot and save the initial mesh file_name = project_path + results_folder_name + 'initial-mesh' if self.dim == 2: postprocess.plot_mesh(mesh, file_name) elif self.dim == 3: postprocess.plot_mesh_3d(mesh, file_name) boundary_facets, ds, dS = self.construct_boundary_faces(mesh) # Calculate the estimate for Freidrichs constant based on the domain C_FD = problem.calculate_CF_of_domain(domain, self.dim - 1) C_Ntr = problem.calculate_trace_constant(self.test_num) # Define functional spaces based on the mesh #--------------------------------------------------------------------------------------------------------------# V, VV, V_exact, VV_exact, H_div = \ problem.functional_spaces(mesh, test_params, self.dim) # Define problem data functions #--------------------------------------------------------------------------------------------------------------# f, A, invA, adjA, lmbd, a, uD, uN, u0, u_e, grad_u_e = self.convert_problem_data_to_expressions( mesh, test_params) # Majorant parameters delta = 1 # gamma = 1.5 # gamma = 2 gamma = 1 # Output to console the problem data problem.output_problem_characteristics(self.test_num, self.u_expr, self.grad_u_expr, self.f_expr, self.domain, self.dim, mesh.num_cells(), mesh.num_vertices(), test_params["v_approx_order"]) t0_problem = time.clock() self.solve_problem_nd_t(mesh, boundary_facets, ds, dS, V, VV, V_exact, VV_exact, H_div, u_e, grad_u_e, f, A, invA, adjA, self.min_eig_A, lmbd, a, u0, uD, uN, C_FD, C_Ntr, delta, gamma, project_path, results_folder_name, test_params) t1_problem = time.clock() print("time = %d s" % (t1_problem - t0_problem))
def test_estimates(self, test_params): # Define the project path # --------------------------------------------------------------------------------------------------------------# project_path = postprocess.get_project_path() # Check if it does exist and create folder for the results # --------------------------------------------------------------------------------------------------------------# results_folder_name = postprocess.construct_result_folder_name( self.dim, test_num, test_params) postprocess.create_results_folder(results_folder_name, test_params) # --------------------------------------------------------------------------------------------------------------# # Define problem data # --------------------------------------------------------------------------------------------------------------# # Define the mesh based on the domain geometry # --------------------------------------------------------------------------------------------------------------# mesh = self.construct_mesh(test_params["nx0"], test_params["nx1"], test_params["nx2"], test_params["res"], project_path) if test_params["PLOT"] == True: # Plot and save the initial mesh if self.dim == 2: postprocess.plot_mesh( mesh, project_path + results_folder_name + 'initial-mesh') elif self.dim == 3: postprocess.plot_mesh_3d( mesh, project_path + results_folder_name + 'initial-mesh') boundary_facets, ds, dS = self.construct_boundary_faces(mesh) # Calculate the estimate for Freidrichs constant based on the domain C_FD = problem.calculate_CF_of_domain(domain, self.dim) C_Ntr = self.calculate_trace_constant() # Define functional spaces based on the mesh #--------------------------------------------------------------------------------------------------------------# V, VV, V_exact, VV_exact, H_div = \ problem.functional_spaces(mesh, test_params, self.dim) # Define problem data functions eps = 1e0 # initialize the eps #--------------------------------------------------------------------------------------------------------------# f, A, invA, adjA, min_eig_A, lmbd, a, uD, uN, u_e, grad_u_e = self.convert_problem_data_to_expressions( mesh, test_params, eps) # Output to console the problem data problem.output_problem_characteristics( self.test_num, self.u_expr, self.grad_u_expr, self.f_expr, self.A_expr, self.lambda_expr, self.a_expr, self.uD_expr, self.domain, self.dim, mesh.num_cells(), mesh.num_vertices(), test_params["v_approx_order"], test_params["flux_approx_order"]) # Run the solver with a posteriori error control # --------------------------------------------------------------------------------------------------------------# t0_problem = time.clock() while eps > self.eps: mesh, V, VV, V_exact, VV_exact, H_div, boundary_facets, ds, dS \ = self.solve_problem_nd_t(mesh, boundary_facets, ds, dS, V, V_exact, VV_exact, H_div, u_e, f, A, invA, adjA, min_eig_A, lmbd, a, eps, uD, uN, C_FD, C_Ntr, project_path, results_folder_name, test_params) test_params['number_of_refinements'] = test_params[ 'number_of_refinements'] + 2 #test_params['percentage_value'] = test_params['percentage_value'] + 0.1 eps = 1e-1 * eps f, A, invA, adjA, min_eig_A, lmbd, a, uD, uN, u_e, grad_u_e = self.convert_problem_data_to_expressions( mesh, test_params, eps) print "\n\nmin_eig_A = ", min_eig_A print "\n\nupdated eps = ", eps print "\n\n" t1_problem = time.clock() print("time = %d" % (t1_problem - t0_problem))