int main() { // Create space. // Transform input data to the format used by the "Space" constructor. SpaceData *md = new SpaceData(); Space* space = new Space(md->N_macroel, md->interfaces, md->poly_orders, md->material_markers, md->subdivisions, N_GRP, N_SLN); delete md; // Enumerate basis functions, info for user. int ndof = Space::get_num_dofs(space); info("ndof: %d", ndof); // Plot the space. space->plot("space.gp"); for (int g = 0; g < N_GRP; g++) { space->set_bc_left_dirichlet(g, flux_left_surf[g]); space->set_bc_right_dirichlet(g, flux_right_surf[g]); } // Initialize the weak formulation. WeakForm wf(2); wf.add_matrix_form(0, 0, jacobian_mat1_0_0, NULL, mat1); wf.add_matrix_form(0, 0, jacobian_mat2_0_0, NULL, mat2); wf.add_matrix_form(0, 0, jacobian_mat3_0_0, NULL, mat3); wf.add_matrix_form(0, 1, jacobian_mat1_0_1, NULL, mat1); wf.add_matrix_form(0, 1, jacobian_mat2_0_1, NULL, mat2); wf.add_matrix_form(0, 1, jacobian_mat3_0_1, NULL, mat3); wf.add_matrix_form(1, 0, jacobian_mat1_1_0, NULL, mat1); wf.add_matrix_form(1, 0, jacobian_mat2_1_0, NULL, mat2); wf.add_matrix_form(1, 0, jacobian_mat3_1_0, NULL, mat3); wf.add_matrix_form(1, 1, jacobian_mat1_1_1, NULL, mat1); wf.add_matrix_form(1, 1, jacobian_mat2_1_1, NULL, mat2); wf.add_matrix_form(1, 1, jacobian_mat3_1_1, NULL, mat3); wf.add_vector_form(0, residual_mat1_0, NULL, mat1); wf.add_vector_form(0, residual_mat2_0, NULL, mat2); wf.add_vector_form(0, residual_mat3_0, NULL, mat3); wf.add_vector_form(1, residual_mat1_1, NULL, mat1); wf.add_vector_form(1, residual_mat2_1, NULL, mat2); wf.add_vector_form(1, residual_mat3_1, NULL, mat3); // Initialize the FE problem. bool is_linear = false; DiscreteProblem *dp = new DiscreteProblem(&wf, space, is_linear); // Newton's loop. // Fill vector coeff_vec using dof and coeffs arrays in elements. double *coeff_vec = new double[Space::get_num_dofs(space)]; get_coeff_vector(space, coeff_vec); // Set up the solver, matrix, and rhs according to the solver selection. SparseMatrix* matrix = create_matrix(matrix_solver); Vector* rhs = create_vector(matrix_solver); Solver* solver = create_linear_solver(matrix_solver, matrix, rhs); int it = 1; while (1) { // Obtain the number of degrees of freedom. int ndof = Space::get_num_dofs(space); // Assemble the Jacobian matrix and residual vector. dp->assemble(coeff_vec, matrix, rhs); // Calculate the l2-norm of residual vector. double res_l2_norm = get_l2_norm(rhs); // Info for user. info("---- Newton iter %d, ndof %d, res. l2 norm %g", it, Space::get_num_dofs(space), res_l2_norm); // If l2 norm of the residual vector is within tolerance, then quit. // NOTE: at least one full iteration forced // here because sometimes the initial // residual on fine mesh is too small. if(res_l2_norm < NEWTON_TOL && it > 1) break; // Multiply the residual vector with -1 since the matrix // equation reads J(Y^n) \deltaY^{n+1} = -F(Y^n). for(int i=0; i<ndof; i++) rhs->set(i, -rhs->get(i)); // Solve the linear system. if(!solver->solve()) error ("Matrix solver failed.\n"); // Add \deltaY^{n+1} to Y^n. for (int i = 0; i < ndof; i++) coeff_vec[i] += solver->get_solution()[i]; // If the maximum number of iteration has been reached, then quit. if (it >= NEWTON_MAX_ITER) error ("Newton method did not converge."); // Copy coefficients from vector y to elements. set_coeff_vector(coeff_vec, space); it++; } // Plot the solution. Linearizer l(space); l.plot_solution("solution.gp"); info("Done."); return 0; }
int main(int argc, char* argv[]) { // Time measurement. TimePeriod cpu_time; cpu_time.tick(); // Load the mesh. Mesh mesh; H2DReader mloader; mloader.load("square.mesh", &mesh); // Perform initial mesh refinements. for (int i=0; i<INIT_REF; i++) mesh.refine_all_elements(); // Create an L2 space with default shapeset. L2Space space(&mesh, bc_types, NULL, Ord2(P_H, P_V)); int ndof = Space::get_num_dofs(&space); info("ndof = %d", ndof); // Initialize the weak formulation. WeakForm wf; wf.add_matrix_form(callback(bilinear_form)); wf.add_vector_form(callback(linear_form)); wf.add_matrix_form_surf(callback(bilinear_form_boundary), H2D_DG_BOUNDARY_EDGE); wf.add_vector_form_surf(callback(linear_form_boundary), H2D_DG_BOUNDARY_EDGE); wf.add_matrix_form_surf(callback(bilinear_form_interface), H2D_DG_INNER_EDGE); // Initialize the FE problem. bool is_linear = true; DiscreteProblem dp(&wf, &space, is_linear); // Set up the solver, matrix, and rhs according to the solver selection. SparseMatrix* matrix = create_matrix(matrix_solver); Vector* rhs = create_vector(matrix_solver); Solver* solver = create_linear_solver(matrix_solver, matrix, rhs); // Initialize the preconditioner in the case of SOLVER_AZTECOO. if (matrix_solver == SOLVER_AZTECOO) { ((AztecOOSolver*) solver)->set_solver(iterative_method); ((AztecOOSolver*) solver)->set_precond(preconditioner); // Using default iteration parameters (see solver/aztecoo.h). } // Initialize the solution. Solution sln; // Assemble the stiffness matrix and right-hand side vector. info("Assembling the stiffness matrix and right-hand side vector."); dp.assemble(matrix, rhs); // Solve the linear system and if successful, obtain the solution. info("Solving the matrix problem."); if(solver->solve()) Solution::vector_to_solution(solver->get_solution(), &space, &sln); else error ("Matrix solver failed.\n"); // Time measurement. cpu_time.tick(); // Clean up. delete solver; delete matrix; delete rhs; info("ndof = %d", ndof); info("Coordinate ( 0.1, 0.1) value = %lf", sln.get_pt_value(0.1, 0.1)); info("Coordinate ( 0.3, 0.3) value = %lf", sln.get_pt_value(0.3, 0.3)); info("Coordinate ( 0.5, 0.5) value = %lf", sln.get_pt_value(0.5, 0.5)); info("Coordinate ( 0.7, 0.7) value = %lf", sln.get_pt_value(0.7, 0.7)); double coor_xy[4] = {0.1, 0.3, 0.5, 0.7}; double value[4] = {0.999885, 0.844340, 0.000000, 0.000000}; for (int i = 0; i < 4; i++) { if ((value[i] - sln.get_pt_value(coor_xy[i], coor_xy[i])) < 1E-6) { printf("Success!\n"); } else { printf("Failure!\n"); return ERR_FAILURE; } } return ERR_SUCCESS; }
// Usage: caffe_('solver_solve', hSolver) static void solver_solve(MEX_ARGS) { mxCHECK(nrhs == 1 && mxIsStruct(prhs[0]), "Usage: caffe_('solver_solve', hSolver)"); Solver<float>* solver = handle_to_ptr<Solver<float> >(prhs[0]); solver->Solve(); }
// Sets some constants, performs uniform mesh refinement // and calculates reference solution. This needs to get // done prior to adaptivity. bool ModuleBasicAdapt::prepare_for_adaptivity() { // Perform basic sanity checks, create mesh, perform // uniform refinements, create space, register weak forms. bool mesh_ok = this->create_space_and_forms(); if (!mesh_ok) return false; this->ndof_coarse = Space::get_num_dofs(this->space); if (this->ndof_coarse <= 0) return false; // Initialize refinement selector. this->ref_selector = new H1ProjBasedSelector(this->cand_list, this->conv_exp, H2DRS_DEFAULT_ORDER); this->ref_selector->set_error_weights(this->adaptivity_weight_1, this->adaptivity_weight_2, this->adaptivity_weight_3); // Construct globally refined reference mesh and setup reference space. this->space_ref = (H1Space*)construct_refined_space(this->space); this->ndof_fine = Space::get_num_dofs(this->space_ref); // Initialize the FE problem on reference mesh. bool is_linear = true; DiscreteProblem dp(this->wf, this->space_ref, is_linear); // Set up the solver, matrix, and rhs according to the solver selection. info("Initializing matrix solver, matrix, and rhs vector."); SparseMatrix* matrix = create_matrix(this->matrix_solver); Vector* rhs = create_vector(this->matrix_solver); Solver* solver = create_linear_solver(this->matrix_solver, matrix, rhs); // Begin assembly time measurement. TimePeriod cpu_time_assembly; cpu_time_assembly.tick(); // Assemble the stiffness matrix and right-hand side vector. info("Assembling matrix and vector on reference mesh."); dp.assemble(matrix, rhs); // End assembly time measurement. this->assembly_time = cpu_time_assembly.accumulated(); this->assembly_time_total += this->assembly_time; // Begin solver time measurement. TimePeriod cpu_time_solver; cpu_time_solver.tick(); // Solve the linear system and if successful, obtain the solution. info("Solving on reference mesh."); if(solver->solve()) Solution::vector_to_solution(solver->get_solution(), this->space_ref, this->sln_ref); else { info("Matrix solver failed.\n"); return false; } // End solver time measurement. cpu_time_solver.tick(); this->solver_time = cpu_time_solver.accumulated(); this->solver_time_total += this->solver_time; // Clean up. info("Deleting matrix solver, matrix and rhs vector."); delete solver; delete matrix; delete rhs; return true; }
int main() { // Time measurement. TimePeriod cpu_time; cpu_time.tick(); // Create coarse mesh, set Dirichlet BC, enumerate basis functions. Space* space = new Space(A, B, NELEM, DIR_BC_LEFT, DIR_BC_RIGHT, P_INIT, NEQ); info("N_dof = %d.", Space::get_num_dofs(space)); // Initialize the weak formulation. WeakForm wf; wf.add_matrix_form(jacobian); wf.add_vector_form(residual); // Initialize the FE problem. bool is_linear = false; DiscreteProblem *dp_coarse = new DiscreteProblem(&wf, space, is_linear); // Newton's loop on coarse mesh. // Obtain the number of degrees of freedom. int ndof = Space::get_num_dofs(space); // Fill vector coeff_vec using dof and coeffs arrays in elements. double *coeff_vec_coarse = new double[Space::get_num_dofs(space)]; solution_to_vector(space, coeff_vec_coarse); // Set up the solver, matrix, and rhs according to the solver selection. SparseMatrix* matrix_coarse = create_matrix(matrix_solver); Vector* rhs_coarse = create_vector(matrix_solver); Solver* solver_coarse = create_linear_solver(matrix_solver, matrix_coarse, rhs_coarse); int it = 1; while (1) { // Obtain the number of degrees of freedom. int ndof_coarse = Space::get_num_dofs(space); // Assemble the Jacobian matrix and residual vector. dp_coarse->assemble(matrix_coarse, rhs_coarse); // Calculate the l2-norm of residual vector. double res_norm = 0; for(int i=0; i<ndof_coarse; i++) res_norm += rhs_coarse->get(i)*rhs_coarse->get(i); res_norm = sqrt(res_norm); // Info for user. info("---- Newton iter %d, residual norm: %.15f", it, res_norm); // If l2 norm of the residual vector is within tolerance, then quit. // NOTE: at least one full iteration forced // here because sometimes the initial // residual on fine mesh is too small. if(res_norm < NEWTON_TOL_COARSE && it > 1) break; // Multiply the residual vector with -1 since the matrix // equation reads J(Y^n) \deltaY^{n+1} = -F(Y^n). for(int i=0; i<ndof_coarse; i++) rhs_coarse->set(i, -rhs_coarse->get(i)); // Solve the linear system. if(!solver_coarse->solve()) error ("Matrix solver failed.\n"); // Add \deltaY^{n+1} to Y^n. for (int i = 0; i < ndof_coarse; i++) coeff_vec_coarse[i] += solver_coarse->get_solution()[i]; // If the maximum number of iteration has been reached, then quit. if (it >= NEWTON_MAX_ITER) error ("Newton method did not converge."); // Copy coefficients from vector y to elements. vector_to_solution(coeff_vec_coarse, space); it++; } // Cleanup. delete matrix_coarse; delete rhs_coarse; delete solver_coarse; delete dp_coarse; delete [] coeff_vec_coarse; // DOF and CPU convergence graphs. SimpleGraph graph_dof_est, graph_cpu_est; SimpleGraph graph_dof_exact, graph_cpu_exact; // Main adaptivity loop. int as = 1; while(1) { info("============ Adaptivity step %d ============", as); // Construct globally refined reference mesh and setup reference space. Space* ref_space = construct_refined_space(space); // Initialize the FE problem. bool is_linear = false; DiscreteProblem* dp = new DiscreteProblem(&wf, ref_space, is_linear); // Set up the solver, matrix, and rhs according to the solver selection. SparseMatrix* matrix = create_matrix(matrix_solver); Vector* rhs = create_vector(matrix_solver); Solver* solver = create_linear_solver(matrix_solver, matrix, rhs); // Newton's loop on fine mesh. // Fill vector coeff_vec using dof and coeffs arrays in elements. double *coeff_vec = new double[Space::get_num_dofs(ref_space)]; solution_to_vector(ref_space, coeff_vec); int it = 1; while (1) { // Obtain the number of degrees of freedom. int ndof = Space::get_num_dofs(ref_space); // Assemble the Jacobian matrix and residual vector. dp->assemble(matrix, rhs); // Calculate the l2-norm of residual vector. double res_norm = 0; for(int i=0; i<ndof; i++) res_norm += rhs->get(i)*rhs->get(i); res_norm = sqrt(res_norm); // Info for user. info("---- Newton iter %d, residual norm: %.15f", it, res_norm); // If l2 norm of the residual vector is within tolerance, then quit. // NOTE: at least one full iteration forced // here because sometimes the initial // residual on fine mesh is too small. if(res_norm < NEWTON_TOL_REF && it > 1) break; // Multiply the residual vector with -1 since the matrix // equation reads J(Y^n) \deltaY^{n+1} = -F(Y^n). for(int i=0; i<ndof; i++) rhs->set(i, -rhs->get(i)); // Solve the linear system. if(!solver->solve()) error ("Matrix solver failed.\n"); // Add \deltaY^{n+1} to Y^n. for (int i = 0; i < ndof; i++) coeff_vec[i] += solver->get_solution()[i]; // If the maximum number of iteration has been reached, then quit. if (it >= NEWTON_MAX_ITER) error ("Newton method did not converge."); // Copy coefficients from vector y to elements. vector_to_solution(coeff_vec, ref_space); it++; } // Cleanup. delete matrix; delete rhs; delete solver; delete dp; delete [] coeff_vec; // Starting with second adaptivity step, obtain new coarse // space solution via Newton's method. Initial condition is // the last coarse mesh solution. if (as > 1) { //Info for user. info("Solving on coarse mesh"); // Initialize the FE problem. bool is_linear = false; DiscreteProblem* dp_coarse = new DiscreteProblem(&wf, space, is_linear); // Newton's loop on coarse mesh. // Fill vector coeff_vec using dof and coeffs arrays in elements. double *coeff_vec_coarse = new double[Space::get_num_dofs(space)]; solution_to_vector(space, coeff_vec_coarse); // Set up the solver, matrix, and rhs according to the solver selection. SparseMatrix* matrix_coarse = create_matrix(matrix_solver); Vector* rhs_coarse = create_vector(matrix_solver); Solver* solver_coarse = create_linear_solver(matrix_solver, matrix_coarse, rhs_coarse); int it = 1; while (1) { // Obtain the number of degrees of freedom. int ndof_coarse = Space::get_num_dofs(space); // Assemble the Jacobian matrix and residual vector. dp_coarse->assemble(matrix_coarse, rhs_coarse); // Calculate the l2-norm of residual vector. double res_norm = 0; for(int i=0; i<ndof_coarse; i++) res_norm += rhs_coarse->get(i)*rhs_coarse->get(i); res_norm = sqrt(res_norm); // Info for user. info("---- Newton iter %d, residual norm: %.15f", it, res_norm); // If l2 norm of the residual vector is within tolerance, then quit. // NOTE: at least one full iteration forced // here because sometimes the initial // residual on fine mesh is too small. if(res_norm < NEWTON_TOL_COARSE && it > 1) break; // Multiply the residual vector with -1 since the matrix // equation reads J(Y^n) \deltaY^{n+1} = -F(Y^n). for(int i=0; i<ndof_coarse; i++) rhs_coarse->set(i, -rhs_coarse->get(i)); // Solve the linear system. if(!solver_coarse->solve()) error ("Matrix solver failed.\n"); // Add \deltaY^{n+1} to Y^n. for (int i = 0; i < ndof_coarse; i++) coeff_vec_coarse[i] += solver_coarse->get_solution()[i]; // If the maximum number of iteration has been reached, then quit. if (it >= NEWTON_MAX_ITER) error ("Newton method did not converge."); // Copy coefficients from vector y to elements. vector_to_solution(coeff_vec_coarse, space); it++; } // Cleanup. delete matrix_coarse; delete rhs_coarse; delete solver_coarse; delete dp_coarse; delete [] coeff_vec_coarse; } // In the next step, estimate element errors based on // the difference between the fine mesh and coarse mesh solutions. double err_est_array[MAX_ELEM_NUM]; double err_est_rel = calc_err_est(NORM, space, ref_space, err_est_array) * 100; // Info for user. info("Relative error (est) = %g %%", err_est_rel); // Time measurement. cpu_time.tick(); // If exact solution available, also calculate exact error. if (EXACT_SOL_PROVIDED) { // Calculate element errors wrt. exact solution. double err_exact_rel = calc_err_exact(NORM, space, exact_sol, NEQ, A, B) * 100; // Info for user. info("Relative error (exact) = %g %%", err_exact_rel); // Add entry to DOF and CPU convergence graphs. graph_dof_exact.add_values(Space::get_num_dofs(space), err_exact_rel); graph_cpu_exact.add_values(cpu_time.accumulated(), err_exact_rel); } // Add entry to DOF and CPU convergence graphs. graph_dof_est.add_values(Space::get_num_dofs(space), err_est_rel); graph_cpu_est.add_values(cpu_time.accumulated(), err_est_rel); // Decide whether the relative error is sufficiently small. if(err_est_rel < TOL_ERR_REL) break; // Returns updated coarse and fine meshes, with the last // coarse and fine mesh solutions on them, respectively. // The coefficient vectors and numbers of degrees of freedom // on both meshes are also updated. adapt(NORM, ADAPT_TYPE, THRESHOLD, err_est_array, space, ref_space); as++; // Plot meshes, results, and errors. adapt_plotting(space, ref_space, NORM, EXACT_SOL_PROVIDED, exact_sol); // Cleanup. delete ref_space; } // Save convergence graphs. graph_dof_est.save("conv_dof_est.dat"); graph_cpu_est.save("conv_cpu_est.dat"); graph_dof_exact.save("conv_dof_exact.dat"); graph_cpu_exact.save("conv_cpu_exact.dat"); int success_test = 1; info("N_dof = %d.", Space::get_num_dofs(space)); if (Space::get_num_dofs(space) > 40) success_test = 0; if (success_test) { info("Success!"); return ERROR_SUCCESS; } else { info("Failure!"); return ERROR_FAILURE; } }
int main() { // Create space. // Transform input data to the format used by the "Space" constructor. SpaceData *md = new SpaceData(verbose); Space* space = new Space(md->N_macroel, md->interfaces, md->poly_orders, md->material_markers, md->subdivisions, N_GRP, N_SLN); delete md; // Enumerate basis functions, info for user. info("N_dof = %d", Space::get_num_dofs(space)); // Plot the space. space->plot("space.gp"); // Initial approximation of the dominant eigenvalue. double K_EFF = 1.0; // Initial approximation of the dominant eigenvector. double init_val = 1.0; for (int g = 0; g < N_GRP; g++) { set_vertex_dofs_constant(space, init_val, g); space->set_bc_right_dirichlet(g, flux_right_surf[g]); } // Initialize the weak formulation. WeakForm wf(2); wf.add_matrix_form(0, 0, jacobian_fuel_0_0, NULL, fuel); wf.add_matrix_form(0, 0, jacobian_water_0_0, NULL, water); wf.add_matrix_form(0, 1, jacobian_fuel_0_1, NULL, fuel); wf.add_matrix_form(0, 1, jacobian_water_0_1, NULL, water); wf.add_matrix_form(1, 0, jacobian_fuel_1_0, NULL, fuel); wf.add_matrix_form(1, 0, jacobian_water_1_0, NULL, water); wf.add_matrix_form(1, 1, jacobian_fuel_1_1, NULL, fuel); wf.add_matrix_form(1, 1, jacobian_water_1_1, NULL, water); wf.add_vector_form(0, residual_fuel_0, NULL, fuel); wf.add_vector_form(0, residual_water_0, NULL, water); wf.add_vector_form(1, residual_fuel_1, NULL, fuel); wf.add_vector_form(1, residual_water_1, NULL, water); wf.add_vector_form_surf(0, residual_surf_left_0, BOUNDARY_LEFT); wf.add_vector_form_surf(1, residual_surf_left_1, BOUNDARY_LEFT); // Initialize the FE problem. bool is_linear = false; DiscreteProblem *dp = new DiscreteProblem(&wf, space, is_linear); Linearizer l(space); char solution_file[32]; // Source iteration int i; int current_solution = 0, previous_solution = 1; double K_EFF_old; for (i = 0; i < Max_SI; i++) { // Plot the critical (i.e. steady-state) flux in the actual iteration. sprintf(solution_file, "solution_%d.gp", i); l.plot_solution(solution_file); // Store the previous solution (used at the right-hand side). for (int g = 0; g < N_GRP; g++) copy_dofs(current_solution, previous_solution, space, g); // Obtain the number of degrees of freedom. int ndof = Space::get_num_dofs(space); // Fill vector coeff_vec using dof and coeffs arrays in elements. double *coeff_vec = new double[Space::get_num_dofs(space)]; get_coeff_vector(space, coeff_vec); // Set up the solver, matrix, and rhs according to the solver selection. SparseMatrix* matrix = create_matrix(matrix_solver); Vector* rhs = create_vector(matrix_solver); Solver* solver = create_linear_solver(matrix_solver, matrix, rhs); int it = 1; while (1) { // Obtain the number of degrees of freedom. int ndof = Space::get_num_dofs(space); // Assemble the Jacobian matrix and residual vector. dp->assemble(matrix, rhs); // Calculate the l2-norm of residual vector. double res_l2_norm = get_l2_norm(rhs); // Info for user. info("---- Newton iter %d, ndof %d, res. l2 norm %g", it, Space::get_num_dofs(space), res_l2_norm); // If l2 norm of the residual vector is within tolerance, then quit. // NOTE: at least one full iteration forced // here because sometimes the initial // residual on fine mesh is too small. if(res_l2_norm < NEWTON_TOL && it > 1) break; // Multiply the residual vector with -1 since the matrix // equation reads J(Y^n) \deltaY^{n+1} = -F(Y^n). for(int i=0; i<ndof; i++) rhs->set(i, -rhs->get(i)); // Solve the linear system. if(!solver->solve()) error ("Matrix solver failed.\n"); // Add \deltaY^{n+1} to Y^n. for (int i = 0; i < ndof; i++) coeff_vec[i] += solver->get_solution()[i]; // If the maximum number of iteration has been reached, then quit. if (it >= NEWTON_MAX_ITER) error ("Newton method did not converge."); // Copy coefficients from vector y to elements. set_coeff_vector(coeff_vec, space); it++; } // Cleanup. delete matrix; delete rhs; delete solver; delete [] coeff_vec; // Update the eigenvalue. K_EFF_old = K_EFF; K_EFF = calc_total_reaction_rate(space, nSf, 0., 40.); // Convergence test. if (fabs(K_EFF - K_EFF_old)/K_EFF < TOL_SI) break; // Normalize total neutron flux to one fission neutron. multiply_dofs_with_constant(space, 1./K_EFF, current_solution); if (verbose) info("K_EFF_%d = %.8f", i+1, K_EFF); } // Print the converged eigenvalue. info("K_EFF = %.8f, err= %.8f%%", K_EFF, 100*(K_EFF-1)); // Plot the converged critical neutron flux. sprintf(solution_file, "solution.gp"); l.plot_solution(solution_file); // Comparison with analytical results (see the reference above). double flux[N_GRP], J[N_GRP], R; get_solution_at_point(space, 0.0, flux, J); R = flux[0]/flux[1]; info("phi_fast/phi_therm at x=0 : %.4f, err = %.2f%%", R, 100*(R-2.5332)/2.5332); get_solution_at_point(space, 40.0, flux, J); R = flux[0]/flux[1]; info("phi_fast/phi_therm at x=40 : %.4f, err = %.2f%%", R, 100*(R-1.5162)/1.5162); info("Done."); return 0; }
int main(int argc, char* argv[]) { // Time measurement TimePeriod cpu_time; cpu_time.tick(); // Load the mesh. Mesh mesh; H2DReader mloader; mloader.load("lshape3q.mesh", &mesh); // quadrilaterals //mloader.load("lshape3t.mesh", &mesh); // triangles // Perform initial mesh refinemets. for (int i=0; i < INIT_REF_NUM; i++) mesh.refine_all_elements(); // Enter boundary markers. BCTypes bc_types; bc_types.add_bc_dirichlet(Hermes::vector<int>(BDY_1, BDY_6)); bc_types.add_bc_newton(Hermes::vector<int>(BDY_2, BDY_3, BDY_4, BDY_5)); // Enter Dirichlet boundary values. BCValues bc_values; bc_values.add_zero(Hermes::vector<int>(BDY_1, BDY_6)); // Create an Hcurl space with default shapeset. HcurlSpace space(&mesh, &bc_types, &bc_values, P_INIT); // Initialize the weak formulation. WeakForm wf; wf.add_matrix_form(callback(bilinear_form), HERMES_SYM); wf.add_matrix_form_surf(callback(bilinear_form_surf)); wf.add_vector_form_surf(linear_form_surf, linear_form_surf_ord); // Initialize coarse and reference mesh solutions. Solution sln, ref_sln; // Initialize exact solution. ExactSolution sln_exact(&mesh, exact); // Initialize refinement selector. HcurlProjBasedSelector selector(CAND_LIST, CONV_EXP, H2DRS_DEFAULT_ORDER); // Initialize views. VectorView v_view("Solution (magnitude)", new WinGeom(0, 0, 460, 350)); v_view.set_min_max_range(0, 1.5); OrderView o_view("Polynomial orders", new WinGeom(470, 0, 400, 350)); // DOF and CPU convergence graphs. SimpleGraph graph_dof_est, graph_cpu_est, graph_dof_exact, graph_cpu_exact; // Adaptivity loop: int as = 1; bool done = false; do { info("---- Adaptivity step %d:", as); // Construct globally refined reference mesh and setup reference space. Space* ref_space = construct_refined_space(&space); // Initialize matrix solver. SparseMatrix* matrix = create_matrix(matrix_solver); Vector* rhs = create_vector(matrix_solver); Solver* solver = create_linear_solver(matrix_solver, matrix, rhs); // Assemble the reference problem. info("Solving on reference mesh."); bool is_linear = true; DiscreteProblem* dp = new DiscreteProblem(&wf, ref_space, is_linear); dp->assemble(matrix, rhs); // Time measurement. cpu_time.tick(); // Solve the linear system of the reference problem. If successful, obtain the solution. if(solver->solve()) Solution::vector_to_solution(solver->get_solution(), ref_space, &ref_sln); else error ("Matrix solver failed.\n"); // Time measurement. cpu_time.tick(); // Project the fine mesh solution onto the coarse mesh. info("Projecting reference solution on coarse mesh."); OGProjection::project_global(&space, &ref_sln, &sln, matrix_solver); // View the coarse mesh solution and polynomial orders. v_view.show(&sln); o_view.show(&space); // Calculate element errors and total error estimate. info("Calculating error estimate and exact error."); Adapt* adaptivity = new Adapt(&space); double err_est_rel = adaptivity->calc_err_est(&sln, &ref_sln) * 100; // Calculate exact error, bool solutions_for_adapt = false; double err_exact_rel = adaptivity->calc_err_exact(&sln, &sln_exact, solutions_for_adapt) * 100; // Report results. info("ndof_coarse: %d, ndof_fine: %d", Space::get_num_dofs(&space), Space::get_num_dofs(ref_space)); info("err_est_rel: %g%%, err_exact_rel: %g%%", err_est_rel, err_exact_rel); // Time measurement. cpu_time.tick(); // Add entry to DOF and CPU convergence graphs. graph_dof_est.add_values(Space::get_num_dofs(&space), err_est_rel); graph_dof_est.save("conv_dof_est.dat"); graph_cpu_est.add_values(cpu_time.accumulated(), err_est_rel); graph_cpu_est.save("conv_cpu_est.dat"); graph_dof_exact.add_values(Space::get_num_dofs(&space), err_exact_rel); graph_dof_exact.save("conv_dof_exact.dat"); graph_cpu_exact.add_values(cpu_time.accumulated(), err_exact_rel); graph_cpu_exact.save("conv_cpu_exact.dat"); // If err_est_rel too large, adapt the mesh. if (err_est_rel < ERR_STOP) done = true; else { info("Adapting coarse mesh."); done = adaptivity->adapt(&selector, THRESHOLD, STRATEGY, MESH_REGULARITY); // Increase the counter of performed adaptivity steps. if (done == false) as++; } if (Space::get_num_dofs(&space) >= NDOF_STOP) done = true; // Clean up. delete solver; delete matrix; delete rhs; delete adaptivity; if(done == false) delete ref_space->get_mesh(); delete ref_space; delete dp; } while (done == false); verbose("Total running time: %g s", cpu_time.accumulated()); // Show the reference solution - the final result. v_view.set_title("Fine mesh solution (magnitude)"); v_view.show(&ref_sln); // Wait for all views to be closed. View::wait(); return 0; }
int main(int argc, char* argv[]) { // Instantiate a class with global functions. Hermes2D hermes2d; // Load the mesh. Mesh mesh; H2DReader mloader; mloader.load("../square_quad.mesh", &mesh); // Perform initial mesh refinement. for (int i=0; i < INIT_REF_NUM; i++) mesh.refine_all_elements(); // Set exact solution. CustomExactSolution exact(&mesh, ALPHA); // Define right-hand side. CustomRightHandSide rhs(ALPHA); // Initialize the weak formulation. CustomWeakForm wf(&rhs); // Initialize boundary conditions DefaultEssentialBCNonConst bc(BDY_DIRICHLET, &exact); EssentialBCs bcs(&bc); // Create an H1 space with default shapeset. H1Space space(&mesh, &bcs, P_INIT); // Initialize refinement selector. H1ProjBasedSelector selector(CAND_LIST, CONV_EXP, H2DRS_DEFAULT_ORDER); // DOF and CPU convergence graphs. SimpleGraph graph_dof, graph_cpu, graph_dof_exact, graph_cpu_exact; // Time measurement. TimePeriod cpu_time; cpu_time.tick(); // Adaptivity loop: int as = 1; bool done = false; do { info("---- Adaptivity step %d:", as); // Construct globally refined reference mesh and setup reference space. Space* ref_space = Space::construct_refined_space(&space); SparseMatrix* matrix = create_matrix(matrix_solver); Vector* rhs = create_vector(matrix_solver); Solver* solver = create_linear_solver(matrix_solver, matrix, rhs); // Assemble the reference problem. info("Solving on reference mesh."); DiscreteProblem* dp = new DiscreteProblem(&wf, ref_space); dp->assemble(matrix, rhs); // Time measurement. cpu_time.tick(); // Solve the linear system of the reference problem. If successful, obtain the solution. Solution ref_sln; if(solver->solve()) Solution::vector_to_solution(solver->get_solution(), ref_space, &ref_sln); else error ("Matrix solver failed.\n"); // Time measurement. cpu_time.tick(); // Project the fine mesh solution onto the coarse mesh. Solution sln; info("Projecting reference solution on coarse mesh."); OGProjection::project_global(&space, &ref_sln, &sln, matrix_solver); // Calculate element errors and total error estimate. info("Calculating error estimate and exact error."); Adapt* adaptivity = new Adapt(&space); double err_est_rel = adaptivity->calc_err_est(&sln, &ref_sln) * 100; // Calculate exact error. double err_exact_rel = hermes2d.calc_rel_error(&sln, &exact, HERMES_H1_NORM) * 100; // Report results. info("ndof_coarse: %d, ndof_fine: %d", Space::get_num_dofs(&space), Space::get_num_dofs(ref_space)); info("err_est_rel: %g%%, err_exact_rel: %g%%", err_est_rel, err_exact_rel); // Time measurement. cpu_time.tick(); // Add entry to DOF and CPU convergence graphs. graph_dof.add_values(Space::get_num_dofs(&space), err_est_rel); graph_dof.save("conv_dof_est.dat"); graph_cpu.add_values(cpu_time.accumulated(), err_est_rel); graph_cpu.save("conv_cpu_est.dat"); graph_dof_exact.add_values(Space::get_num_dofs(&space), err_exact_rel); graph_dof_exact.save("conv_dof_exact.dat"); graph_cpu_exact.add_values(cpu_time.accumulated(), err_exact_rel); graph_cpu_exact.save("conv_cpu_exact.dat"); // If err_est too large, adapt the mesh. if (err_est_rel < ERR_STOP) done = true; else { info("Adapting coarse mesh."); done = adaptivity->adapt(&selector, THRESHOLD, STRATEGY, MESH_REGULARITY); // Increase the counter of performed adaptivity steps. if (done == false) as++; } if (Space::get_num_dofs(&space) >= NDOF_STOP) done = true; // Clean up. delete solver; delete matrix; delete rhs; delete adaptivity; if(done == false) delete ref_space->get_mesh(); delete ref_space; delete dp; } while (done == false); verbose("Total running time: %g s", cpu_time.accumulated()); int ndof = Space::get_num_dofs(&space); int n_dof_allowed = 270; printf("n_dof_actual = %d\n", ndof); printf("n_dof_allowed = %d\n", n_dof_allowed); if (ndof <= n_dof_allowed) { printf("Success!\n"); return ERR_SUCCESS; } else { printf("Failure!\n"); return ERR_FAILURE; } }
int main(int argc, char* argv[]) { // Load the mesh. Mesh u_mesh, v_mesh; H2DReader mloader; mloader.load("crack.mesh", &u_mesh); // Perform initial uniform mesh refinement. for (int i=0; i < INIT_REF_NUM; i++) u_mesh.refine_all_elements(); // Create initial mesh for the vertical displacement component. // This also initializes the multimesh hp-FEM. v_mesh.copy(&u_mesh); // Create H1 spaces with default shapesets. H1Space u_space(&u_mesh, bc_types_xy, essential_bc_values, P_INIT); H1Space v_space(MULTI ? &v_mesh : &u_mesh, bc_types_xy, essential_bc_values, P_INIT); // Initialize the weak formulation. WeakForm wf(2); wf.add_matrix_form(0, 0, callback(bilinear_form_0_0), HERMES_SYM); wf.add_matrix_form(0, 1, callback(bilinear_form_0_1), HERMES_SYM); wf.add_matrix_form(1, 1, callback(bilinear_form_1_1), HERMES_SYM); wf.add_vector_form_surf(1, linear_form_surf_1, linear_form_surf_1_ord, BDY_TOP); // Initialize coarse and reference mesh solutions. Solution u_sln, v_sln, u_ref_sln, v_ref_sln; // Initialize refinement selector. H1ProjBasedSelector selector(CAND_LIST, CONV_EXP, H2DRS_DEFAULT_ORDER); // DOF and CPU convergence graphs. SimpleGraph graph_dof_est, graph_cpu_est; // Time measurement. TimePeriod cpu_time; cpu_time.tick(); // Adaptivity loop: int as = 1; bool done = false; do { info("---- Adaptivity step %d:", as); // Construct globally refined reference mesh and setup reference space. Tuple<Space *>* ref_spaces = construct_refined_spaces(Tuple<Space *>(&u_space, &v_space)); // Assemble the reference problem. info("Solving on reference mesh."); bool is_linear = true; DiscreteProblem* dp = new DiscreteProblem(&wf, *ref_spaces, is_linear); SparseMatrix* matrix = create_matrix(matrix_solver); Vector* rhs = create_vector(matrix_solver); Solver* solver = create_linear_solver(matrix_solver, matrix, rhs); dp->assemble(matrix, rhs); // Time measurement. cpu_time.tick(); // Solve the linear system of the reference problem. If successful, obtain the solutions. if(solver->solve()) Solution::vector_to_solutions(solver->get_solution(), *ref_spaces, Tuple<Solution *>(&u_ref_sln, &v_ref_sln)); else error ("Matrix solver failed.\n"); // Time measurement. cpu_time.tick(); // Project the fine mesh solution onto the coarse mesh. info("Projecting reference solution on coarse mesh."); OGProjection::project_global(Tuple<Space *>(&u_space, &v_space), Tuple<Solution *>(&u_ref_sln, &v_ref_sln), Tuple<Solution *>(&u_sln, &v_sln), matrix_solver); // Calculate element errors. info("Calculating error estimate and exact error."); Adapt* adaptivity = new Adapt(Tuple<Space *>(&u_space, &v_space), Tuple<ProjNormType>(HERMES_H1_NORM, HERMES_H1_NORM)); adaptivity->set_error_form(0, 0, bilinear_form_0_0<scalar, scalar>, bilinear_form_0_0<Ord, Ord>); adaptivity->set_error_form(0, 1, bilinear_form_0_1<scalar, scalar>, bilinear_form_0_1<Ord, Ord>); adaptivity->set_error_form(1, 0, bilinear_form_1_0<scalar, scalar>, bilinear_form_1_0<Ord, Ord>); adaptivity->set_error_form(1, 1, bilinear_form_1_1<scalar, scalar>, bilinear_form_1_1<Ord, Ord>); // Calculate error estimate for each solution component and the total error estimate. Tuple<double> err_est_rel; bool solutions_for_adapt = true; double err_est_rel_total = adaptivity->calc_err_est(Tuple<Solution *>(&u_sln, &v_sln), Tuple<Solution *>(&u_ref_sln, &v_ref_sln), solutions_for_adapt, HERMES_TOTAL_ERROR_REL | HERMES_ELEMENT_ERROR_ABS, &err_est_rel) * 100; // Time measurement. cpu_time.tick(); // Report results. info("ndof_coarse[0]: %d, ndof_fine[0]: %d, err_est_rel[0]: %g%%", u_space.Space::get_num_dofs(), (*ref_spaces)[0]->Space::get_num_dofs(), err_est_rel[0]*100); info("ndof_coarse[1]: %d, ndof_fine[1]: %d, err_est_rel[1]: %g%%", v_space.Space::get_num_dofs(), (*ref_spaces)[1]->Space::get_num_dofs(), err_est_rel[1]*100); info("ndof_coarse_total: %d, ndof_fine_total: %d, err_est_rel_total: %g%%", Space::get_num_dofs(Tuple<Space *>(&u_space, &v_space)), Space::get_num_dofs(*ref_spaces), err_est_rel_total); // Add entry to DOF and CPU convergence graphs. graph_dof_est.add_values(Space::get_num_dofs(Tuple<Space *>(&u_space, &v_space)), err_est_rel_total); graph_dof_est.save("conv_dof_est.dat"); graph_cpu_est.add_values(cpu_time.accumulated(), err_est_rel_total); graph_cpu_est.save("conv_cpu_est.dat"); // If err_est too large, adapt the mesh. if (err_est_rel_total < ERR_STOP) done = true; else { info("Adapting coarse mesh."); done = adaptivity->adapt(Tuple<RefinementSelectors::Selector *>(&selector, &selector), MULTI ? THRESHOLD_MULTI:THRESHOLD_SINGLE, STRATEGY, MESH_REGULARITY); } if (Space::get_num_dofs(Tuple<Space *>(&u_space, &v_space)) >= NDOF_STOP) done = true; // Clean up. delete solver; delete matrix; delete rhs; delete adaptivity; if(done == false) for(int i = 0; i < ref_spaces->size(); i++) delete (*ref_spaces)[i]->get_mesh(); delete ref_spaces; delete dp; // Increase counter. as++; } while (done == false); verbose("Total running time: %g s", cpu_time.accumulated()); int ndof = Space::get_num_dofs(Tuple<Space *>(&u_space, &v_space)); int ndof_allowed = 920; printf("ndof actual = %d\n", ndof); printf("ndof allowed = %d\n", ndof_allowed); if (ndof <= ndof_allowed) { // ndofs was 908 at the time this test was created printf("Success!\n"); return ERR_SUCCESS; } else { printf("Failure!\n"); return ERR_FAILURE; } }
int main(int argc, char* argv[]) { // Load the mesh. Mesh mesh; H2DReader mloader; mloader.load("square_quad.mesh", &mesh); // Perform initial mesh refinement. for (int i = 0; i < INIT_REF_NUM; i++) mesh.refine_all_elements(); // Enter boundary markers. BCTypes bc_types; bc_types.add_bc_dirichlet(BDY_DIRICHLET); bc_types.add_bc_neumann(BDY_NEUMANN_LEFT); // Enter Dirichlet boudnary values. BCValues bc_values; bc_values.add_function(BDY_DIRICHLET, essential_bc_values); // Create an H1 space with default shapeset. H1Space space(&mesh, &bc_types, &bc_values, P_INIT); // Initialize the weak formulation. WeakForm wf; wf.add_matrix_form(callback(bilinear_form), HERMES_SYM); wf.add_vector_form(linear_form, linear_form_ord); // Initialize refinement selector. H1ProjBasedSelector selector(CAND_LIST, CONV_EXP, H2DRS_DEFAULT_ORDER); // Set exact solution. ExactSolution exact(&mesh, fndd); // Initialize views. ScalarView sview("Solution", new WinGeom(0, 0, 440, 350)); sview.show_mesh(false); OrderView oview("Polynomial orders", new WinGeom(450, 0, 420, 350)); // DOF and CPU convergence graphs. SimpleGraph graph_dof, graph_cpu, graph_dof_exact, graph_cpu_exact; // Time measurement. TimePeriod cpu_time; cpu_time.tick(); // Adaptivity loop: int as = 1; bool done = false; do { info("---- Adaptivity step %d:", as); // Construct globally refined reference mesh and setup reference space. Space* ref_space = construct_refined_space(&space); // Assemble the reference problem. info("Solving on reference mesh."); bool is_linear = true; DiscreteProblem* dp = new DiscreteProblem(&wf, ref_space, is_linear); SparseMatrix* matrix = create_matrix(matrix_solver); Vector* rhs = create_vector(matrix_solver); Solver* solver = create_linear_solver(matrix_solver, matrix, rhs); dp->assemble(matrix, rhs); // Time measurement. cpu_time.tick(); // Solve the linear system of the reference problem. If successful, obtain the solution. Solution ref_sln; if(solver->solve()) Solution::vector_to_solution(solver->get_solution(), ref_space, &ref_sln); else error ("Matrix solver failed.\n"); // Time measurement. cpu_time.tick(); // Project the fine mesh solution onto the coarse mesh. Solution sln; info("Projecting reference solution on coarse mesh."); OGProjection::project_global(&space, &ref_sln, &sln, matrix_solver); // View the coarse mesh solution and polynomial orders. sview.show(&sln); oview.show(&space); // Calculate element errors and total error estimate. info("Calculating error estimate and exact error."); Adapt* adaptivity = new Adapt(&space, HERMES_H1_NORM); bool solutions_for_adapt = true; double err_est_rel = adaptivity->calc_err_est(&sln, &ref_sln, solutions_for_adapt, HERMES_TOTAL_ERROR_REL | HERMES_ELEMENT_ERROR_REL) * 100; // Calculate exact error for each solution component. solutions_for_adapt = false; double err_exact_rel = adaptivity->calc_err_exact(&sln, &exact, solutions_for_adapt, HERMES_TOTAL_ERROR_REL | HERMES_ELEMENT_ERROR_REL) * 100; // Report results. info("ndof_coarse: %d, ndof_fine: %d", Space::get_num_dofs(&space), Space::get_num_dofs(ref_space)); info("err_est_rel: %g%%, err_exact_rel: %g%%", err_est_rel, err_exact_rel); // Time measurement. cpu_time.tick(); // Add entry to DOF and CPU convergence graphs. graph_dof.add_values(Space::get_num_dofs(&space), err_est_rel); graph_dof.save("conv_dof_est.dat"); graph_cpu.add_values(cpu_time.accumulated(), err_est_rel); graph_cpu.save("conv_cpu_est.dat"); graph_dof_exact.add_values(Space::get_num_dofs(&space), err_exact_rel); graph_dof_exact.save("conv_dof_exact.dat"); graph_cpu_exact.add_values(cpu_time.accumulated(), err_exact_rel); graph_cpu_exact.save("conv_cpu_exact.dat"); // If err_est too large, adapt the mesh. if (err_est_rel < ERR_STOP) done = true; else { info("Adapting coarse mesh."); done = adaptivity->adapt(&selector, THRESHOLD, STRATEGY, MESH_REGULARITY); // Increase the counter of performed adaptivity steps. if (done == false) as++; } if (Space::get_num_dofs(&space) >= NDOF_STOP) done = true; // Clean up. delete solver; delete matrix; delete rhs; delete adaptivity; if(done == false) delete ref_space->get_mesh(); delete ref_space; delete dp; } while (done == false); verbose("Total running time: %g s", cpu_time.accumulated()); // Wait for all views to be closed. View::wait(); return 0; }
int main(int argc, char* argv[]) { // Load the mesh. Mesh mesh, basemesh; H2DReader mloader; mloader.load("GAMM-channel.mesh", &basemesh); // Perform initial mesh refinements. for (int i = 0; i < INIT_REF_NUM; i++) basemesh.refine_all_elements(); basemesh.refine_by_criterion(criterion, 4); mesh.copy(&basemesh); // Enter boundary markers. BCTypes bc_types; bc_types.add_bc_neumann(Hermes::Tuple<int>(BDY_SOLID_WALL, BDY_INLET_OUTLET)); // Create L2 spaces with default shapesets. L2Space space_rho(&mesh, &bc_types, P_INIT); L2Space space_rho_v_x(&mesh, &bc_types, P_INIT); L2Space space_rho_v_y(&mesh, &bc_types, P_INIT); L2Space space_e(&mesh, &bc_types, P_INIT); // Initialize solutions, set initial conditions. Solution sln_rho, sln_rho_v_x, sln_rho_v_y, sln_e, prev_rho, prev_rho_v_x, prev_rho_v_y, prev_e; Solution rsln_rho, rsln_rho_v_x, rsln_rho_v_y, rsln_e; sln_rho.set_exact(&mesh, ic_density); sln_rho_v_x.set_exact(&mesh, ic_density_vel_x); sln_rho_v_y.set_exact(&mesh, ic_density_vel_y); sln_e.set_exact(&mesh, ic_energy); prev_rho.set_exact(&mesh, ic_density); prev_rho_v_x.set_exact(&mesh, ic_density_vel_x); prev_rho_v_y.set_exact(&mesh, ic_density_vel_y); prev_e.set_exact(&mesh, ic_energy); // Initialize weak formulation. WeakForm wf(4); // Bilinear forms coming from time discretization by explicit Euler's method. wf.add_matrix_form(0,0,callback(bilinear_form_0_0_time)); wf.add_matrix_form(1,1,callback(bilinear_form_1_1_time)); wf.add_matrix_form(2,2,callback(bilinear_form_2_2_time)); wf.add_matrix_form(3,3,callback(bilinear_form_3_3_time)); // Volumetric linear forms. // Linear forms coming from the linearization by taking the Eulerian fluxes' Jacobian matrices from the previous time step. // First flux. /* wf.add_vector_form(0,callback(linear_form_0_1), HERMES_ANY, Hermes::Tuple<MeshFunction*>(&prev_rho_v_x)); wf.add_vector_form(1, callback(linear_form_1_0_first_flux), HERMES_ANY, Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y)); wf.add_vector_form(1, callback(linear_form_1_1_first_flux), HERMES_ANY, Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y)); wf.add_vector_form(1, callback(linear_form_1_2_first_flux), HERMES_ANY, Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y)); wf.add_vector_form(1, callback(linear_form_1_3_first_flux), HERMES_ANY, Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e)); wf.add_vector_form(2, callback(linear_form_2_0_first_flux), HERMES_ANY, Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y)); wf.add_vector_form(2, callback(linear_form_2_1_first_flux), HERMES_ANY, Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y)); wf.add_vector_form(2, callback(linear_form_2_2_first_flux), HERMES_ANY, Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y)); wf.add_vector_form(2, callback(linear_form_2_3_first_flux), HERMES_ANY, Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e)); wf.add_vector_form(3, callback(linear_form_3_0_first_flux), HERMES_ANY, Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e)); wf.add_vector_form(3, callback(linear_form_3_1_first_flux), HERMES_ANY, Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e)); wf.add_vector_form(3, callback(linear_form_3_2_first_flux), HERMES_ANY, Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e)); wf.add_vector_form(3, callback(linear_form_3_3_first_flux), HERMES_ANY, Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e)); // Second flux. wf.add_vector_form(0,callback(linear_form_0_2),HERMES_ANY, Hermes::Tuple<MeshFunction*>(&prev_rho_v_y)); wf.add_vector_form(1, callback(linear_form_1_0_second_flux), HERMES_ANY, Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y)); wf.add_vector_form(1, callback(linear_form_1_1_second_flux), HERMES_ANY, Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y)); wf.add_vector_form(1, callback(linear_form_1_2_second_flux), HERMES_ANY, Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y)); wf.add_vector_form(1, callback(linear_form_1_3_second_flux), HERMES_ANY, Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e)); wf.add_vector_form(2, callback(linear_form_2_0_second_flux), HERMES_ANY, Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y)); wf.add_vector_form(2, callback(linear_form_2_1_second_flux), HERMES_ANY, Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y)); wf.add_vector_form(2, callback(linear_form_2_2_second_flux), HERMES_ANY, Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y)); wf.add_vector_form(2, callback(linear_form_2_3_second_flux), HERMES_ANY, Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e)); wf.add_vector_form(3, callback(linear_form_3_0_second_flux), HERMES_ANY, Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e)); wf.add_vector_form(3, callback(linear_form_3_1_second_flux), HERMES_ANY, Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e)); wf.add_vector_form(3, callback(linear_form_3_2_second_flux), HERMES_ANY, Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e)); wf.add_vector_form(3, callback(linear_form_3_3_second_flux), HERMES_ANY, Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e)); */ // Volumetric linear forms coming from the time discretization. #ifdef HERMES_USE_VECTOR_VALUED_FORMS wf.add_vector_form(0, linear_form_vector, linear_form_order, HERMES_ANY, Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e)); wf.add_vector_form(1, linear_form_vector, linear_form_order, HERMES_ANY, Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e)); wf.add_vector_form(2, linear_form_vector, linear_form_order, HERMES_ANY, Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e)); wf.add_vector_form(3, linear_form_vector, linear_form_order, HERMES_ANY, Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e)); #else wf.add_vector_form(0,linear_form, linear_form_order, HERMES_ANY, &prev_rho); wf.add_vector_form(1,linear_form, linear_form_order, HERMES_ANY, &prev_rho_v_x); wf.add_vector_form(2,linear_form, linear_form_order, HERMES_ANY, &prev_rho_v_y); wf.add_vector_form(3,linear_form, linear_form_order, HERMES_ANY, &prev_e); #endif // Surface linear forms - inner edges coming from the DG formulation. #ifdef HERMES_USE_VECTOR_VALUED_FORMS wf.add_vector_form_surf(0, linear_form_interface_vector, linear_form_order, H2D_DG_INNER_EDGE, Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e)); wf.add_vector_form_surf(1, linear_form_interface_vector, linear_form_order, H2D_DG_INNER_EDGE, Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e)); wf.add_vector_form_surf(2, linear_form_interface_vector, linear_form_order, H2D_DG_INNER_EDGE, Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e)); wf.add_vector_form_surf(3, linear_form_interface_vector, linear_form_order, H2D_DG_INNER_EDGE, Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e)); #else wf.add_vector_form_surf(0, linear_form_interface_0, linear_form_order, H2D_DG_INNER_EDGE, Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e)); wf.add_vector_form_surf(1, linear_form_interface_1, linear_form_order, H2D_DG_INNER_EDGE, Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e)); wf.add_vector_form_surf(2, linear_form_interface_2, linear_form_order, H2D_DG_INNER_EDGE, Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e)); wf.add_vector_form_surf(3, linear_form_interface_3, linear_form_order, H2D_DG_INNER_EDGE, Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e)); #endif // Surface linear forms - inlet / outlet edges. #ifdef HERMES_USE_VECTOR_VALUED_FORMS wf.add_vector_form_surf(0, bdy_flux_inlet_outlet_comp_vector, linear_form_order, BDY_INLET_OUTLET, Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e)); wf.add_vector_form_surf(1, bdy_flux_inlet_outlet_comp_vector, linear_form_order, BDY_INLET_OUTLET, Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e)); wf.add_vector_form_surf(2, bdy_flux_inlet_outlet_comp_vector, linear_form_order, BDY_INLET_OUTLET, Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e)); wf.add_vector_form_surf(3, bdy_flux_inlet_outlet_comp_vector, linear_form_order, BDY_INLET_OUTLET, Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e)); #else wf.add_vector_form_surf(0, bdy_flux_inlet_outlet_comp_0, linear_form_order, BDY_INLET_OUTLET, Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e)); wf.add_vector_form_surf(1, bdy_flux_inlet_outlet_comp_1, linear_form_order, BDY_INLET_OUTLET, Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e)); wf.add_vector_form_surf(2, bdy_flux_inlet_outlet_comp_2, linear_form_order, BDY_INLET_OUTLET, Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e)); wf.add_vector_form_surf(3, bdy_flux_inlet_outlet_comp_3, linear_form_order, BDY_INLET_OUTLET, Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e)); #endif // Surface linear forms - Solid wall edges. #ifdef HERMES_USE_VECTOR_VALUED_FORMS wf.add_vector_form_surf(0, bdy_flux_solid_wall_comp_vector, linear_form_order, BDY_SOLID_WALL, Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e)); wf.add_vector_form_surf(1, bdy_flux_solid_wall_comp_vector, linear_form_order, BDY_SOLID_WALL, Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e)); wf.add_vector_form_surf(2, bdy_flux_solid_wall_comp_vector, linear_form_order, BDY_SOLID_WALL, Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e)); wf.add_vector_form_surf(3, bdy_flux_solid_wall_comp_vector, linear_form_order, BDY_SOLID_WALL, Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e)); #else wf.add_vector_form_surf(0, bdy_flux_solid_wall_comp_0, linear_form_order, BDY_SOLID_WALL, Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e)); wf.add_vector_form_surf(1, bdy_flux_solid_wall_comp_1, linear_form_order, BDY_SOLID_WALL, Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e)); wf.add_vector_form_surf(2, bdy_flux_solid_wall_comp_2, linear_form_order, BDY_SOLID_WALL, Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e)); wf.add_vector_form_surf(3, bdy_flux_solid_wall_comp_3, linear_form_order, BDY_SOLID_WALL, Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e)); #endif // Filters for visualization of pressure and the two components of velocity. SimpleFilter pressure(calc_pressure_func, Hermes::Tuple<MeshFunction*>(&sln_rho, &sln_rho_v_x, &sln_rho_v_y, &sln_e)); SimpleFilter u(calc_u_func, Hermes::Tuple<MeshFunction*>(&sln_rho, &sln_rho_v_x, &sln_rho_v_y, &sln_e)); SimpleFilter w(calc_w_func, Hermes::Tuple<MeshFunction*>(&sln_rho, &sln_rho_v_x, &sln_rho_v_y, &sln_e)); // Initialize refinement selector. L2ProjBasedSelector selector(CAND_LIST, CONV_EXP, H2DRS_DEFAULT_ORDER); // Disable weighting of refinement candidates. selector.set_error_weights(1, 1, 1); //VectorView vview("Velocity", new WinGeom(0, 0, 600, 300)); //ScalarView sview("Pressure", new WinGeom(700, 0, 600, 300)); ScalarView s1("w1", new WinGeom(0, 0, 620, 300)); s1.fix_scale_width(80); ScalarView s2("w2", new WinGeom(625, 0, 600, 300)); s2.fix_scale_width(50); ScalarView s3("w3", new WinGeom(0, 350, 620, 300)); s3.fix_scale_width(80); ScalarView s4("w4", new WinGeom(625, 350, 600, 300)); s4.fix_scale_width(50); // Iteration number. int iteration = 0; // For calculation of the time derivative of the norm of the solution approximation. // Not used yet in the adaptive version. double difference; double *difference_values = new double[Space::get_num_dofs(Hermes::Tuple<Space *>(&space_rho, &space_rho_v_x, &space_rho_v_y, &space_e))]; double *last_values = new double[Space::get_num_dofs(Hermes::Tuple<Space *>(&space_rho, &space_rho_v_x, &space_rho_v_y, &space_e))]; for(int i = 0; i < Space::get_num_dofs(Hermes::Tuple<Space *>(&space_rho, &space_rho_v_x, &space_rho_v_y, &space_e)); i++) last_values[i] = 0.; // Output of the approximate time derivative. // Not used yet in the adaptive version. std::ofstream time_der_out("time_der"); for(t = 0.0; t < 10; t += TAU) { info("---- Time step %d, time %3.5f.", iteration, t); iteration++; // Periodic global derefinements. if (iteration > 1 && iteration % UNREF_FREQ == 0 && REFINEMENT_COUNT > 0) { REFINEMENT_COUNT = 0; info("Global mesh derefinement."); mesh.unrefine_all_elements(); space_rho.set_uniform_order(P_INIT); space_rho_v_x.set_uniform_order(P_INIT); space_rho_v_y.set_uniform_order(P_INIT); space_e.set_uniform_order(P_INIT); } // Adaptivity loop: int as = 1; bool done = false; do { info("---- Adaptivity step %d:", as); // Construct globally refined reference mesh and setup reference space. // Global polynomial order increase = 0; int order_increase = 0; Hermes::Tuple<Space *>* ref_spaces = construct_refined_spaces(Hermes::Tuple<Space *>(&space_rho, &space_rho_v_x, &space_rho_v_y, &space_e), order_increase); // Project the previous time level solution onto the new fine mesh. info("Projecting the previous time level solution onto the new fine mesh."); OGProjection::project_global(*ref_spaces, Hermes::Tuple<Solution *>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e), Hermes::Tuple<Solution *>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e), matrix_solver, Hermes::Tuple<ProjNormType>(HERMES_L2_NORM, HERMES_L2_NORM, HERMES_L2_NORM, HERMES_L2_NORM)); if(as > 1) { delete rsln_rho.get_mesh(); delete rsln_rho_v_x.get_mesh(); delete rsln_rho_v_y.get_mesh(); delete rsln_e.get_mesh(); } // Assemble the reference problem. info("Solving on reference mesh."); bool is_linear = true; DiscreteProblem* dp = new DiscreteProblem(&wf, *ref_spaces, is_linear); SparseMatrix* matrix = create_matrix(matrix_solver); Vector* rhs = create_vector(matrix_solver); Solver* solver = create_linear_solver(matrix_solver, matrix, rhs); // The FE problem is in fact a FV problem. dp->set_fvm(); #ifdef HERMES_USE_VECTOR_VALUED_FORMS dp->use_vector_valued_forms(); #endif dp->assemble(matrix, rhs); // Solve the linear system of the reference problem. If successful, obtain the solutions. if(solver->solve()) Solution::vector_to_solutions(solver->get_solution(), *ref_spaces, Hermes::Tuple<Solution *>(&rsln_rho, &rsln_rho_v_x, &rsln_rho_v_y, &rsln_e)); else error ("Matrix solver failed.\n"); // Project the fine mesh solution onto the coarse mesh. info("Projecting reference solution on coarse mesh."); OGProjection::project_global(Hermes::Tuple<Space *>(&space_rho, &space_rho_v_x, &space_rho_v_y, &space_e), Hermes::Tuple<Solution *>(&rsln_rho, &rsln_rho_v_x, &rsln_rho_v_y, &rsln_e), Hermes::Tuple<Solution *>(&sln_rho, &sln_rho_v_x, &sln_rho_v_y, &sln_e), matrix_solver, Hermes::Tuple<ProjNormType>(HERMES_L2_NORM, HERMES_L2_NORM, HERMES_L2_NORM, HERMES_L2_NORM)); // Calculate element errors and total error estimate. info("Calculating error estimate."); Adapt* adaptivity = new Adapt(Hermes::Tuple<Space *>(&space_rho, &space_rho_v_x, &space_rho_v_y, &space_e), Hermes::Tuple<ProjNormType>(HERMES_L2_NORM, HERMES_L2_NORM, HERMES_L2_NORM, HERMES_L2_NORM)); bool solutions_for_adapt = true; // Error components. Hermes::Tuple<double> *error_components = new Hermes::Tuple<double>(4); double err_est_rel_total = adaptivity->calc_err_est(Hermes::Tuple<Solution *>(&sln_rho, &sln_rho_v_x, &sln_rho_v_y, &sln_e), Hermes::Tuple<Solution *>(&rsln_rho, &rsln_rho_v_x, &rsln_rho_v_y, &rsln_e), solutions_for_adapt, HERMES_TOTAL_ERROR_REL | HERMES_ELEMENT_ERROR_ABS, error_components) * 100; // Report results. info("ndof_coarse: %d, ndof_fine: %d, err_est_rel: %g%%", Space::get_num_dofs(Hermes::Tuple<Space *>(&space_rho, &space_rho_v_x, &space_rho_v_y, &space_e)), Space::get_num_dofs(*ref_spaces), err_est_rel_total); // Determine the time step. double *solution_vector = new double[Space::get_num_dofs(Hermes::Tuple<Space *>(&space_rho, &space_rho_v_x, &space_rho_v_y, &space_e))]; OGProjection::project_global(Hermes::Tuple<Space *>(&space_rho, &space_rho_v_x, &space_rho_v_y, &space_e), Hermes::Tuple<MeshFunction *>(&sln_rho, &sln_rho_v_x, &sln_rho_v_y, &sln_e), solution_vector, matrix_solver, Hermes::Tuple<ProjNormType>(HERMES_L2_NORM, HERMES_L2_NORM, HERMES_L2_NORM, HERMES_L2_NORM)); double min_condition = 0; Element *e; for (int _id = 0, _max = mesh.get_max_element_id(); _id < _max; _id++) \ if (((e) = mesh.get_element_fast(_id))->used) \ if ((e)->active) { AsmList al; space_rho.get_element_assembly_list(e, &al); double rho = solution_vector[al.dof[0]]; space_rho_v_x.get_element_assembly_list(e, &al); double v1 = solution_vector[al.dof[0]] / rho; space_rho_v_y.get_element_assembly_list(e, &al); double v2 = solution_vector[al.dof[0]] / rho; space_e.get_element_assembly_list(e, &al); double energy = solution_vector[al.dof[0]]; double condition = e->get_area() / (std::sqrt(v1*v1 + v2*v2) + calc_sound_speed(rho, rho*v1, rho*v2, energy)); if(condition < min_condition || min_condition == 0.) min_condition = condition; } if(TAU > min_condition) TAU = min_condition; if(TAU < min_condition * 0.9) TAU = min_condition; delete [] solution_vector; // Visualization. s1.show(&sln_rho); s2.show(&sln_rho_v_x); s3.show(&sln_rho_v_y); s4.show(&sln_e); // If err_est too large, adapt the mesh. if (err_est_rel_total < ERR_STOP && (*error_components)[1] * 100 < ERR_STOP_VEL_X) done = true; else { info("Adapting coarse mesh."); done = adaptivity->adapt(Hermes::Tuple<RefinementSelectors::Selector *>(&selector, &selector, &selector, &selector), THRESHOLD, STRATEGY, MESH_REGULARITY); REFINEMENT_COUNT++; if (Space::get_num_dofs(Hermes::Tuple<Space *>(&space_rho, &space_rho_v_x, &space_rho_v_y, &space_e)) >= NDOF_STOP) done = true; else // Increase the counter of performed adaptivity steps. as++; } // We have to empty the cache of NeighborSearch class instances. NeighborSearch::empty_main_caches(); // If used, we need to clean the vector valued form caches. #ifdef HERMES_USE_VECTOR_VALUED_FORMS DiscreteProblem::empty_form_caches(); #endif // Clean up. delete solver; delete matrix; delete rhs; delete adaptivity; for(unsigned int i = 0; i < ref_spaces->size(); i++) delete (*ref_spaces)[i]; delete dp; } while (done == false); // Debugging. /* std::ofstream out("matrix"); for(int i = 0; i < matrix->get_size(); i++) for(int j = 0; j < matrix->get_size(); j++) if(std::abs(matrix->get(i,j)) != 0) out << '(' << i << ',' << j << ')' << ':' << matrix->get(i,j) << std::endl; out.close(); out.open("rhs"); for(int j = 0; j < matrix->get_size(); j++) if(std::abs(rhs->get(j)) != 0) out << '(' << j << ')' << ':' << rhs->get(j) << std::endl; out.close(); out.open("sol"); for(int j = 0; j < matrix->get_size(); j++) out << '(' << j << ')' << ':' << solver->get_solution()[j] << std::endl; out.close(); */ // Copy the solutions into the previous time level ones. prev_rho.copy(&rsln_rho); prev_rho_v_x.copy(&rsln_rho_v_x); prev_rho_v_y.copy(&rsln_rho_v_y); prev_e.copy(&rsln_e); delete rsln_rho.get_mesh(); delete rsln_rho_v_x.get_mesh(); delete rsln_rho_v_y.get_mesh(); delete rsln_e.get_mesh(); // Visualization. /* pressure.reinit(); u.reinit(); w.reinit(); sview.show(&pressure); vview.show(&u,&w); */ } time_der_out.close(); return 0; }
int main() { // Time measurement. TimePeriod cpu_time; cpu_time.tick(); // Create space, set Dirichlet BC, enumerate basis functions. Space* space = new Space(A, B, NELEM, DIR_BC_LEFT, DIR_BC_RIGHT, P_INIT, NEQ, NEQ); // Enumerate basis functions, info for user. int ndof = Space::get_num_dofs(space); info("ndof: %d", ndof); // Initialize the weak formulation. WeakForm wf(2); wf.add_matrix_form(0, 0, jacobian_0_0); wf.add_matrix_form(0, 1, jacobian_0_1); wf.add_matrix_form(1, 0, jacobian_1_0); wf.add_matrix_form(1, 1, jacobian_1_1); wf.add_vector_form(0, residual_0); wf.add_vector_form(1, residual_1); // Initialize the FE problem. bool is_linear = false; DiscreteProblem *dp = new DiscreteProblem(&wf, space, is_linear); // Newton's loop. // Fill vector coeff_vec using dof and coeffs arrays in elements. double *coeff_vec = new double[Space::get_num_dofs(space)]; get_coeff_vector(space, coeff_vec); // Set up the solver, matrix, and rhs according to the solver selection. SparseMatrix* matrix = create_matrix(matrix_solver); Vector* rhs = create_vector(matrix_solver); Solver* solver = create_linear_solver(matrix_solver, matrix, rhs); int it = 1; bool success = false; while (1) { // Obtain the number of degrees of freedom. int ndof = Space::get_num_dofs(space); // Assemble the Jacobian matrix and residual vector. dp->assemble(coeff_vec, matrix, rhs); // Calculate the l2-norm of residual vector. double res_l2_norm = get_l2_norm(rhs); // Info for user. info("---- Newton iter %d, ndof %d, res. l2 norm %g", it, Space::get_num_dofs(space), res_l2_norm); // If l2 norm of the residual vector is within tolerance, then quit. // NOTE: at least one full iteration forced // here because sometimes the initial // residual on fine mesh is too small. if(res_l2_norm < NEWTON_TOL && it > 1) break; // Multiply the residual vector with -1 since the matrix // equation reads J(Y^n) \deltaY^{n+1} = -F(Y^n). for(int i=0; i<ndof; i++) rhs->set(i, -rhs->get(i)); // Solve the linear system. if(!(success = solver->solve())) error ("Matrix solver failed.\n"); // Add \deltaY^{n+1} to Y^n. for (int i = 0; i < ndof; i++) coeff_vec[i] += solver->get_solution()[i]; // If the maximum number of iteration has been reached, then quit. if (it >= NEWTON_MAX_ITER) error ("Newton method did not converge."); // Copy coefficients from vector y to elements. set_coeff_vector(coeff_vec, space); it++; } info("Total running time: %g s", cpu_time.accumulated()); // Test variable. info("ndof = %d.", Space::get_num_dofs(space)); // Cleanup. for(unsigned i = 0; i < DIR_BC_LEFT.size(); i++) delete DIR_BC_LEFT[i]; DIR_BC_LEFT.clear(); for(unsigned i = 0; i < DIR_BC_RIGHT.size(); i++) delete DIR_BC_RIGHT[i]; DIR_BC_RIGHT.clear(); delete matrix; delete rhs; delete solver; delete[] coeff_vec; delete dp; delete space; if (success) { info("Success!"); return ERROR_SUCCESS; } else { info("Failure!"); return ERROR_FAILURE; } }
/* Vertical guess at the given location to the given depth */ void Solver::makeVLineGuess(int i, int j, int depth) { assert(0 <= i && i < grid_->getHeight() && 0 <= j && j < grid_->getWidth()+1); assert(depth >= 0); if (grid_->getVLine(i, j) == EMPTY) { /* there is only one case where the grid * will not be updated, which is handled * at the end of this iteration. */ grid_->setUpdated(true); Grid lineGuess; grid_->copy(lineGuess); /* make a LINE guess */ lineGuess.setVLine(i, j, LINE); Solver lineSolver = Solver(lineGuess, rules_, contradictions_, selectedRules_, selectLength_, depth, epq_); ruleCounts_ = ruleCounts_ + lineSolver.ruleCounts_; /* If this guess happens to solve the puzzle we need to make sure that * the opposite guess leads to a contradiction, otherwise we know that * there might be multiple solutions */ if (lineGuess.isSolved()) { Grid nLineGuess; grid_->copy(nLineGuess); nLineGuess.setVLine(i, j, NLINE); Solver nLineSolver = Solver(nLineGuess, rules_, contradictions_, selectedRules_, selectLength_, MAX_DEPTH, epq_); ruleCounts_ = ruleCounts_ + nLineSolver.ruleCounts_; if (nLineSolver.testContradictions()) { /* The opposite guess leads to a contradiction * so the previous found solution is the only one */ lineGuess.copy(*grid_); } else if (nLineGuess.isSolved() || nLineSolver.hasMultipleSolutions()) { /* The opposite guess also led to a solution * so there are multiple solutions */ multipleSolutions_ = true; } else { /* The opposite guess led to neither a solution or * a contradiction, which can only happen if the subPuzzle * is unsolvable for our maximum depth. We can learn nothing * from this result. */ grid_->setUpdated(false); } return; } /* test for contradictions; if we encounter one we set the opposite line */ else if (lineSolver.testContradictions()) { grid_->setVLine(i, j, NLINE); return; } else { Grid nLineGuess; grid_->copy(nLineGuess); /* make an NLINE guess */ nLineGuess.setVLine(i, j, NLINE); Solver nLineSolver = Solver(nLineGuess, rules_, contradictions_, selectedRules_, selectLength_, depth, epq_); ruleCounts_ = ruleCounts_ + nLineSolver.ruleCounts_; /* if both guesses led to multiple solutions, we know this puzzle * must also lead to another solution */ if (nLineSolver.hasMultipleSolutions() || lineSolver.hasMultipleSolutions()) { multipleSolutions_ = true; return; } /* again check if solved. In this case we already know that we can't * get to a solution or contradiction with the opposite guess, so * we know we can't conclude whether this is the single solution */ else if (nLineGuess.isSolved()) { lineSolver = Solver(lineGuess, rules_, contradictions_, selectedRules_, selectLength_, MAX_DEPTH, epq_); ruleCounts_ = ruleCounts_ + lineSolver.ruleCounts_; if (lineSolver.testContradictions()) { /* The opposite guess leads to a contradiction * so the previous found solution is the only one */ nLineGuess.copy(*grid_); } else if (lineGuess.isSolved() || lineSolver.hasMultipleSolutions()) { /* The opposite guess also led to a solution * so there are multiple solutions */ multipleSolutions_ = true; } else { /* The opposite guess led to neither a solution or * a contradiction, which can only happen if the subPuzzle * is unsolvable for our maximum depth. We can learn nothing * from this result. */ grid_->setUpdated(false); } return; } /* again check for contradictions */ else if (nLineSolver.testContradictions()) { grid_->setVLine(i, j, LINE); return; } else { grid_->setUpdated(false); /* check for things that happen when we make both * guesses; if we find any, we know they must happen */ intersectGrids(lineGuess, nLineGuess); if (grid_->getUpdated()) { return; } } } } }
int main() { // Time measurement. TimePeriod cpu_time; cpu_time.tick(); // Create coarse mesh, set Dirichlet BC, enumerate basis functions. Space* space = new Space(A, B, NELEM, DIR_BC_LEFT, DIR_BC_RIGHT, P_INIT, NEQ); // Enumerate basis functions, info for user. int ndof = Space::get_num_dofs(space); info("ndof: %d", ndof); // Initialize the weak formulation. WeakForm wf; wf.add_matrix_form(jacobian); wf.add_vector_form(residual); // Initialize the FE problem. bool is_linear = false; DiscreteProblem *dp_coarse = new DiscreteProblem(&wf, space, is_linear); // Newton's loop on coarse mesh. // Fill vector coeff_vec using dof and coeffs arrays in elements. double *coeff_vec_coarse = new double[Space::get_num_dofs(space)]; get_coeff_vector(space, coeff_vec_coarse); // Set up the solver, matrix, and rhs according to the solver selection. SparseMatrix* matrix_coarse = create_matrix(matrix_solver); Vector* rhs_coarse = create_vector(matrix_solver); Solver* solver_coarse = create_linear_solver(matrix_solver, matrix_coarse, rhs_coarse); int it = 1; while (1) { // Obtain the number of degrees of freedom. int ndof_coarse = Space::get_num_dofs(space); // Assemble the Jacobian matrix and residual vector. dp_coarse->assemble(coeff_vec_coarse, matrix_coarse, rhs_coarse); // Calculate the l2-norm of residual vector. double res_l2_norm = get_l2_norm(rhs_coarse); // Info for user. info("---- Newton iter %d, ndof %d, res. l2 norm %g", it, Space::get_num_dofs(space), res_l2_norm); // If l2 norm of the residual vector is within tolerance, then quit. // NOTE: at least one full iteration forced // here because sometimes the initial // residual on fine mesh is too small. if(res_l2_norm < NEWTON_TOL_COARSE && it > 1) break; // Multiply the residual vector with -1 since the matrix // equation reads J(Y^n) \deltaY^{n+1} = -F(Y^n). for(int i=0; i < ndof_coarse; i++) rhs_coarse->set(i, -rhs_coarse->get(i)); // Solve the linear system. if(!solver_coarse->solve()) error ("Matrix solver failed.\n"); // Add \deltaY^{n+1} to Y^n. for (int i = 0; i < ndof_coarse; i++) coeff_vec_coarse[i] += solver_coarse->get_solution()[i]; // If the maximum number of iteration has been reached, then quit. if (it >= NEWTON_MAX_ITER) error ("Newton method did not converge."); // Copy coefficients from vector y to elements. set_coeff_vector(coeff_vec_coarse, space); it++; } // Cleanup. delete matrix_coarse; delete rhs_coarse; delete solver_coarse; delete [] coeff_vec_coarse; delete dp_coarse; // DOF and CPU convergence graphs. SimpleGraph graph_dof_est, graph_cpu_est; SimpleGraph graph_dof_exact, graph_cpu_exact; // Adaptivity loop: int as = 1; bool done = false; do { info("---- Adaptivity step %d:", as); // Construct globally refined reference mesh and setup reference space. Space* ref_space = construct_refined_space(space); // Initialize the FE problem. bool is_linear = false; DiscreteProblem* dp = new DiscreteProblem(&wf, ref_space, is_linear); // Set up the solver, matrix, and rhs according to the solver selection. SparseMatrix* matrix = create_matrix(matrix_solver); Vector* rhs = create_vector(matrix_solver); Solver* solver = create_linear_solver(matrix_solver, matrix, rhs); // Newton's loop on the fine mesh. info("Solving on fine mesh:"); // Fill vector coeff_vec using dof and coeffs arrays in elements. double *coeff_vec = new double[Space::get_num_dofs(ref_space)]; get_coeff_vector(ref_space, coeff_vec); int it = 1; while (1) { // Obtain the number of degrees of freedom. int ndof = Space::get_num_dofs(ref_space); // Assemble the Jacobian matrix and residual vector. dp->assemble(coeff_vec, matrix, rhs); // Calculate the l2-norm of residual vector. double res_l2_norm = get_l2_norm(rhs); // Info for user. info("---- Newton iter %d, ndof %d, res. l2 norm %g", it, Space::get_num_dofs(ref_space), res_l2_norm); // If l2 norm of the residual vector is within tolerance, then quit. // NOTE: at least one full iteration forced // here because sometimes the initial // residual on fine mesh is too small. if(res_l2_norm < NEWTON_TOL_REF && it > 1) break; // Multiply the residual vector with -1 since the matrix // equation reads J(Y^n) \deltaY^{n+1} = -F(Y^n). for(int i = 0; i < ndof; i++) rhs->set(i, -rhs->get(i)); // Solve the linear system. if(!solver->solve()) error ("Matrix solver failed.\n"); // Add \deltaY^{n+1} to Y^n. for (int i = 0; i < ndof; i++) coeff_vec[i] += solver->get_solution()[i]; // If the maximum number of iteration has been reached, then quit. if (it >= NEWTON_MAX_ITER) error ("Newton method did not converge."); // Copy coefficients from vector y to elements. set_coeff_vector(coeff_vec, ref_space); it++; } // Starting with second adaptivity step, obtain new coarse // mesh solution via projecting the fine mesh solution. if(as > 1) { info("Projecting the fine mesh solution onto the coarse mesh."); // Project the fine mesh solution (defined on space_ref) onto the coarse mesh (defined on space). OGProjection::project_global(space, ref_space, matrix_solver); } // Calculate element errors and total error estimate. info("Calculating error estimate."); double err_est_array[MAX_ELEM_NUM]; double err_est_rel = calc_err_est(NORM, space, ref_space, err_est_array) * 100; // Report results. info("ndof_coarse: %d, ndof_fine: %d, err_est_rel: %g%%", Space::get_num_dofs(space), Space::get_num_dofs(ref_space), err_est_rel); // Time measurement. cpu_time.tick(); // If exact solution available, also calculate exact error. if (EXACT_SOL_PROVIDED) { // Calculate element errors wrt. exact solution. double err_exact_rel = calc_err_exact(NORM, space, exact_sol, NEQ, A, B) * 100; // Info for user. info("Relative error (exact) = %g %%", err_exact_rel); // Add entry to DOF and CPU convergence graphs. graph_dof_exact.add_values(Space::get_num_dofs(space), err_exact_rel); graph_cpu_exact.add_values(cpu_time.accumulated(), err_exact_rel); } // Add entry to DOF and CPU convergence graphs. graph_dof_est.add_values(Space::get_num_dofs(space), err_est_rel); graph_cpu_est.add_values(cpu_time.accumulated(), err_est_rel); // If err_est_rel too large, adapt the mesh. if (err_est_rel < NEWTON_TOL_REF) done = true; else { info("Adapting the coarse mesh."); adapt(NORM, ADAPT_TYPE, THRESHOLD, err_est_array, space, ref_space); } as++; // Plot meshes, results, and errors. adapt_plotting(space, ref_space, NORM, EXACT_SOL_PROVIDED, exact_sol); // Cleanup. delete solver; delete matrix; delete rhs; delete ref_space; delete dp; delete [] coeff_vec; } while (done == false); info("Total running time: %g s", cpu_time.accumulated()); // Save convergence graphs. graph_dof_est.save("conv_dof_est.dat"); graph_cpu_est.save("conv_cpu_est.dat"); graph_dof_exact.save("conv_dof_exact.dat"); graph_cpu_exact.save("conv_cpu_exact.dat"); return 0; }
int main(int argc, char* argv[]) { // Load the mesh. Mesh mesh; H2DReader mloader; mloader.load("sample.mesh", &mesh); // Perform uniform mesh refinement. mesh.refine_all_elements(); // Create x- and y- displacement space using the default H1 shapeset. H1Space u_space(&mesh, bc_types, essential_bc_values, P_INIT); H1Space v_space(&mesh, bc_types, essential_bc_values, P_INIT); info("ndof = %d.", Space::get_num_dofs(Tuple<Space *>(&u_space, &v_space))); // Initialize the weak formulation. WeakForm wf(2); wf.add_matrix_form(0, 0, callback(bilinear_form_0_0), HERMES_SYM); // Note that only one symmetric part is wf.add_matrix_form(0, 1, callback(bilinear_form_0_1), HERMES_SYM); // added in the case of symmetric bilinear wf.add_matrix_form(1, 1, callback(bilinear_form_1_1), HERMES_SYM); // forms. wf.add_vector_form_surf(0, callback(linear_form_surf_0), GAMMA_3_BDY); wf.add_vector_form_surf(1, callback(linear_form_surf_1), GAMMA_3_BDY); // Initialize the FE problem. bool is_linear = true; DiscreteProblem dp(&wf, Tuple<Space *>(&u_space, &v_space), is_linear); // Set up the solver, matrix, and rhs according to the solver selection. SparseMatrix* matrix = create_matrix(matrix_solver); Vector* rhs = create_vector(matrix_solver); Solver* solver = create_linear_solver(matrix_solver, matrix, rhs); // Initialize the solutions. Solution u_sln, v_sln; // Assemble the stiffness matrix and right-hand side vector. info("Assembling the stiffness matrix and right-hand side vector."); dp.assemble(matrix, rhs); // Solve the linear system and if successful, obtain the solutions. info("Solving the matrix problem."); if(solver->solve()) Solution::vector_to_solutions(solver->get_solution(), Tuple<Space *>(&u_space, &v_space), Tuple<Solution *>(&u_sln, &v_sln)); else error ("Matrix solver failed.\n"); // Visualize the solution. ScalarView view("Von Mises stress [Pa]", new WinGeom(0, 0, 800, 400)); VonMisesFilter stress(Tuple<MeshFunction *>(&u_sln, &v_sln), lambda, mu); view.show_mesh(false); view.show(&stress, HERMES_EPS_HIGH, H2D_FN_VAL_0, &u_sln, &v_sln, 1.5e5); // Wait for the view to be closed. View::wait(); // Clean up. delete solver; delete matrix; delete rhs; return 0; }
// returns true if bit is a useful condition for testing as sufficient // (no loop-modified terms, preserves reachability of assert, etc.) // regardless of whether it is actually sufficient. bool TestBit(Bit *bit) { Vector<Bit*> &tested_list = propagate->m_sufficient_tested_list; Vector<Bit*> &possible_list = propagate->m_sufficient_possible_list; Vector<Bit*> &sufficient_list = propagate->m_sufficient_list; Solver *solver = state->GetSolver(); if (tested_list.Contains(bit)) { if (possible_list.Contains(bit)) return true; return false; } if (verbose) logout << "SUFFICIENT: " << frame << ": Testing " << bit << " [" << bit->Hash() << "]" << endl; tested_list.PushBack(bit); // don't test for sufficient conditions if a timeout has occurred. if (TimerAlarm::ActiveExpired()) { if (verbose) logout << "SUFFICIENT: " << frame << ": Alarm expired" << endl; return false; } // check that the sufficient condition does not render the point // of the assertion unreachable: the solver is still satisfiable after // asserting the sufficient condition. this also takes care of // unsatisfiable sufficient conditions. state->PushContext(); // ignore bits we can't do any propagation from. CheckerPropagate *test_propagate = new CheckerPropagate(frame, propagate->m_point, propagate->m_allow_point); test_propagate->SetTest(bit); // propagations can trigger new solver side conditions. TODO: should figure // out what's going on here. if (!solver->IsSatisfiable()) { state->PopContext(); return false; } if (test_propagate->m_where->IsNone()) { if (verbose) logout << "SUFFICIENT: " << frame << ": Failed propagate: " << test_propagate->m_where << endl; state->PopContext(); delete test_propagate; return false; } // assert the tested sufficient holds in the frame. frame->AddAssert(bit); if (!solver->IsSatisfiable()) { // the sufficient condition rendered the assertion point unreachable. if (verbose) logout << "SUFFICIENT: " << frame << ": Renders point unreachable" << endl; state->PopContext(); delete test_propagate; return false; } // this is a good potential sufficient condition, remember it. possible_list.PushBack(bit); // check whether the bit is actually a sufficient condition. // just assert the original negated safe bit, and if it is unsatisfiable // it cannot occur under this sufficient condition. state->AssertBaseBits(); bool satisfiable = solver->IsSatisfiable(); if (verbose) { if (satisfiable) { logout << "SUFFICIENT: " << frame << ": Not a sufficient condition:" << endl; solver->PinAssign(); solver->PrintRawAssignment(); solver->UnpinAssign(); } else { logout << "SUFFICIENT: " << frame << ": Success!" << endl; } } if (!satisfiable) { sufficient_list.PushBack(bit); propagate_list->PushBack(test_propagate); } else { delete test_propagate; } state->PopContext(); return true; }
int OoqpInterface:: eval(const double** arg, double** res, casadi_int* iw, double* w, void* mem) const { return_status_ = -1; success_ = false; if (inputs_check_) { check_inputs(arg[CONIC_LBX], arg[CONIC_UBX], arg[CONIC_LBA], arg[CONIC_UBA]); } // Get problem data double* g=w; w += nx_; casadi_copy(arg[CONIC_G], nx_, g); double* lbx=w; w += nx_; casadi_copy(arg[CONIC_LBX], nx_, lbx); double* ubx=w; w += nx_; casadi_copy(arg[CONIC_UBX], nx_, ubx); double* lba=w; w += na_; casadi_copy(arg[CONIC_LBA], na_, lba); double* uba=w; w += na_; casadi_copy(arg[CONIC_UBA], na_, uba); double* H=w; w += nnz_in(CONIC_H); casadi_copy(arg[CONIC_H], nnz_in(CONIC_H), H); double* A=w; w += nnz_in(CONIC_A); casadi_copy(arg[CONIC_A], nnz_in(CONIC_A), A); // Temporary memory double* c_ = w; w += nx_; double* bA_ = w; w += na_; double* xlow_ = w; w += nx_; double* xupp_ = w; w += nx_; double* clow_ = w; w += na_; double* cupp_ = w; w += na_; double* x_ = w; w += nx_; double* gamma_ = w; w += nx_; double* phi_ = w; w += nx_; double* y_ = w; w += na_; double* z_ = w; w += na_; double* lambda_ = w; w += na_; double* pi_ = w; w += na_; char* ixlow_ = reinterpret_cast<char*>(iw); iw += nx_; char* ixupp_ = reinterpret_cast<char*>(iw); iw += nx_; char* iclow_ = reinterpret_cast<char*>(iw); iw += na_; char* icupp_ = reinterpret_cast<char*>(iw); iw += na_; double* dQ_ = w; w += nQ_; double* dA_ = w; w += nA_; double* dC_ = w; w += nA_; int* irowQ_ = reinterpret_cast<int*>(iw); iw += nQ_; int* jcolQ_ = reinterpret_cast<int*>(iw); iw += nQ_; int* irowA_ = reinterpret_cast<int*>(iw); iw += nA_; int* jcolA_ = reinterpret_cast<int*>(iw); iw += nA_; int* irowC_ = reinterpret_cast<int*>(iw); iw += nA_; int* jcolC_ = reinterpret_cast<int*>(iw); iw += nA_; int* x_index_ = reinterpret_cast<int*>(iw); iw += nx_; int* c_index_ = reinterpret_cast<int*>(iw); iw += na_; double* p_ = w; w += nx_; double* AT = w; w += nA_; // Parameter contribution to the objective double objParam = 0; // Get the number of free variables and their types casadi_int nx = 0, np=0; for (casadi_int i=0; i<nx_; ++i) { if (lbx[i]==ubx[i]) { // Save parameter p_[np] = lbx[i]; // Add contribution to objective objParam += g[i]*p_[np]; // Save index x_index_[i] = -1-np++; } else { // True free variable if (lbx[i]==-numeric_limits<double>::infinity()) { xlow_[nx] = 0; ixlow_[nx] = 0; } else { xlow_[nx] = lbx[i]; ixlow_[nx] = 1; } if (ubx[i]==numeric_limits<double>::infinity()) { xupp_[nx] = 0; ixupp_[nx] = 0; } else { xupp_[nx] = ubx[i]; ixupp_[nx] = 1; } c_[nx] = g[i]; x_index_[i] = nx++; } } // Get quadratic term const casadi_int* H_colind = H_.colind(); const casadi_int* H_row = H_.row(); casadi_int nnzQ = 0; // Loop over the columns of the quadratic term for (casadi_int cc=0; cc<nx_; ++cc) { // Loop over nonzero elements of the column for (casadi_int el=H_colind[cc]; el<H_colind[cc+1]; ++el) { // Only upper triangular part casadi_int rr=H_row[el]; if (rr>cc) break; // Get variable types casadi_int icc=x_index_[cc]; casadi_int irr=x_index_[rr]; if (icc<0) { if (irr<0) { // Add contribution to objective objParam += icc==irr ? H[el]*sq(p_[-1-icc])/2 : H[el]*p_[-1-irr]*p_[-1-icc]; } else { // Add contribution to gradient term c_[irr] += H[el]*p_[-1-icc]; } } else { if (irr<0) { // Add contribution to gradient term c_[icc] += H[el]*p_[-1-irr]; } else { // Add to sparsity pattern irowQ_[nnzQ] = icc; // row-major --> indices swapped jcolQ_[nnzQ] = irr; // row-major --> indices swapped dQ_[nnzQ++] = H[el]; } } } } // Get the transpose of the sparsity pattern to be able to loop over the constraints casadi_trans(A, A_, AT, spAT_, iw); // Loop over constraints const casadi_int* A_colind = A_.colind(); const casadi_int* A_row = A_.row(); const casadi_int* AT_colind = spAT_.colind(); const casadi_int* AT_row = spAT_.row(); casadi_int nA=0, nC=0, /*mz=0, */ nnzA=0, nnzC=0; for (casadi_int j=0; j<na_; ++j) { if (lba[j] == -numeric_limits<double>::infinity() && uba[j] == numeric_limits<double>::infinity()) { // Redundant constraint c_index_[j] = 0; } else if (lba[j]==uba[j]) { // Equality constraint bA_[nA] = lba[j]; // Add to A for (casadi_int el=AT_colind[j]; el<AT_colind[j+1]; ++el) { casadi_int i=AT_row[el]; if (x_index_[i]<0) { // Parameter bA_[nA] -= AT[el]*p_[-x_index_[i]-1]; } else { // Free variable irowA_[nnzA] = nA; jcolA_[nnzA] = x_index_[i]; dA_[nnzA++] = AT[el]; } } c_index_[j] = -1-nA++; } else { // Inequality constraint if (lba[j]==-numeric_limits<double>::infinity()) { clow_[nC] = 0; iclow_[nC] = 0; } else { clow_[nC] = lba[j]; iclow_[nC] = 1; } if (uba[j]==numeric_limits<double>::infinity()) { cupp_[nC] = 0; icupp_[nC] = 0; } else { cupp_[nC] = uba[j]; icupp_[nC] = 1; } // Add to C for (casadi_int el=AT_colind[j]; el<AT_colind[j+1]; ++el) { casadi_int i=AT_row[el]; if (x_index_[i]<0) { // Parameter if (iclow_[nC]==1) clow_[nC] -= AT[el]*p_[-x_index_[i]-1]; if (icupp_[nC]==1) cupp_[nC] -= AT[el]*p_[-x_index_[i]-1]; } else { // Free variable irowC_[nnzC] = nC; jcolC_[nnzC] = x_index_[i]; dC_[nnzC++] = AT[el]; } } c_index_[j] = 1+nC++; } } // Reset the solution casadi_fill(x_, nx_, 0.); casadi_fill(gamma_, nx_, 0.); casadi_fill(phi_, nx_, 0.); casadi_fill(y_, na_, 0.); casadi_fill(z_, na_, 0.); casadi_fill(lambda_, na_, 0.); casadi_fill(pi_, na_, 0.); // Solve the QP double objectiveValue; int ierr; if (false) { // Use C interface // TODO(jgillis): Change to conicvehb, see OOQP users guide qpsolvesp(c_, nx, irowQ_, nnzQ, jcolQ_, dQ_, xlow_, ixlow_, xupp_, ixupp_, irowA_, nnzA, jcolA_, dA_, bA_, nA, irowC_, nnzC, jcolC_, dC_, clow_, nC, iclow_, cupp_, icupp_, x_, gamma_, phi_, y_, z_, lambda_, pi_, &objectiveValue, print_level_, &ierr); } else { // Use C++ interface ierr=0; // All OOQP related allocations in evaluate std::vector<int> krowQ(nx+1); std::vector<int> krowA(nA+1); std::vector<int> krowC(nC+1); //casadi_int status_code = 0; makehb(irowQ_, nnzQ, get_ptr(krowQ), nx, &ierr); if (ierr == 0) makehb(irowA_, nnzA, get_ptr(krowA), nA, &ierr); if (ierr == 0) makehb(irowC_, nnzC, get_ptr(krowC), nC, &ierr); if (ierr == 0) { QpGenContext ctx; QpGenHbGondzioSetup(c_, nx, get_ptr(krowQ), jcolQ_, dQ_, xlow_, ixlow_, xupp_, ixupp_, get_ptr(krowA), nA, jcolA_, dA_, bA_, get_ptr(krowC), nC, jcolC_, dC_, clow_, iclow_, cupp_, icupp_, &ctx, &ierr); if (ierr == 0) { Solver* solver = static_cast<Solver *>(ctx.solver); gOoqpPrintLevel = print_level_; solver->monitorSelf(); solver->setMuTol(mutol_); solver->setMuTol(mutol_); QpGenFinish(&ctx, x_, gamma_, phi_, y_, z_, lambda_, pi_, &objectiveValue, &ierr); } QpGenCleanup(&ctx); } } return_status_ = ierr; success_ = ierr==SUCCESSFUL_TERMINATION; if (ierr>0) { casadi_warning("Unable to solve problem: " + str(errFlag(ierr))); } else if (ierr<0) { casadi_error("Fatal error: " + str(errFlag(ierr))); } // Retrieve eliminated decision variables for (casadi_int i=nx_-1; i>=0; --i) { casadi_int ii = x_index_[i]; if (ii<0) { x_[i] = p_[-1-ii]; } else { x_[i] = x_[ii]; } } // Retreive eliminated dual variables (linear bounds) for (casadi_int j=na_-1; j>=0; --j) { casadi_int jj = c_index_[j]; if (jj==0) { lambda_[j] = 0; } else if (jj<0) { lambda_[j] = -y_[-1-jj]; } else { lambda_[j] = pi_[-1+jj]-lambda_[-1+jj]; } } // Retreive eliminated dual variables (simple bounds) for (casadi_int i=nx_-1; i>=0; --i) { casadi_int ii = x_index_[i]; if (ii<0) { // The dual solution for the fixed parameters follows from the KKT conditions gamma_[i] = -g[i]; for (casadi_int el=H_colind[i]; el<H_colind[i+1]; ++el) { casadi_int j=H_row[el]; gamma_[i] -= H[el]*x_[j]; } for (casadi_int el=A_colind[i]; el<A_colind[i+1]; ++el) { casadi_int j=A_row[el]; gamma_[i] -= A[el]*lambda_[j]; } } else { gamma_[i] = phi_[ii]-gamma_[ii]; } } // Save optimal cost if (res[CONIC_COST]) *res[CONIC_COST] = objectiveValue + objParam; // Save primal solution casadi_copy(x_, nx_, res[CONIC_X]); // Save dual solution (linear bounds) casadi_copy(lambda_, na_, res[CONIC_LAM_A]); // Save dual solution (simple bounds) casadi_copy(gamma_, nx_, res[CONIC_LAM_X]); return 0; }
int main(int argc, char** argv) { PetscInitialize (&argc, &argv, NULL, NULL); PetscMPIInt rank, n_procs; MPI_Comm world = PETSC_COMM_WORLD; MPI_Comm_rank (world, &rank); MPI_Comm_size (world, &n_procs); Watch watchSteady; Watch watchOscAirfoil; Watch watchAFT; Watch watchPre; Watch watchIblank; //watchPre.start(); double prestart = MPI_Wtime(); string mainDir = createOutputDir(); // background grid Grid bg (mainDir, 1); bg.read_grid(); bg.set_grid(); // airfoil grid Grid ag (mainDir, 0); ag.read_grid(); ag.set_grid(); // initialize grids OscInit oscInit; oscInit.read(); oscInit.init (ag); oscInit.init (bg); // push grids to vector vector<Grid> grs; grs.push_back(move(bg)); grs.push_back(move(ag)); // set wall distances grs[0].setWallDistance(3); grs[1].setWallDistance(2); grs[0].cellADT.build (grs[0]); grs[1].cellADT.build (grs[1]); //watchPre.stop(); double preend = MPI_Wtime(); cout << "pre = " << preend - prestart << endl; //log (mainDir, watchPre.elapsedTime, "elapsedTimePre", watchPre.unit); //watchIblank.start(); double iblankstart = MPI_Wtime(); /*Iblank iBlank; iBlank.identify (grs[0], grs[1]); iBlank.identify (grs[1], grs[0]);*/ // hole cutting Iblank iblank; iblank.identify (grs[0], grs[1]); iblank.identify (grs[1], grs[0]); iblank.treatFieldIslands (grs[0]); iblank.treatFieldIslands (grs[1]); iblank.treatFringeIslands (grs[0]); iblank.treatFringeIslands (grs[1]); iblank.treatVoidAreas (grs[0]); iblank.treatVoidAreas (grs[1]); //watchIblank.stop(); //log (mainDir, watchIblank.elapsedTime, "elapsedTimeIblank", watchIblank.unit); double iblankend = MPI_Wtime(); cout << "iblank = " << iblankend - iblankstart << endl; for (int g=0; g<grs.size(); ++g) { for (int c=0; c<grs[g].cell.size(); ++c) { if (grs[g].cell[c].iBlank == iBlank_t::UNDEFINED) { cout << "undefined iblank" << endl; cout << "g = " << g << endl; cout << "c = " << c << endl; cout << "d = " << grs[g].n_bou_elm << endl; cout << "d = " << grs[g].cell.size() << endl; exit(-2); } } } grs[0].outAllVTK (0); grs[1].outAllVTK (0); Grid finalGrid (mainDir, 3); //watchAFT.start(); double aftstart = MPI_Wtime(); AFT::aft (grs, finalGrid); //cout << "out of AFT" << endl; //watchAFT.stop(); double aftend = MPI_Wtime(); cout << "aft = " << aftend - aftstart << endl; //cout << "stopped aft watch" << endl; //log (mainDir, watchAFT.elapsedTime, "elapsedTimeAFT", watchAFT.unit); //cout << "logged AFT" << endl; finalGrid.outAllVTK (0); //cout << "output final grid" << endl; exit(-2); finalGrid.readInput(); //cout << "read final grid" << endl; //finalGrid.leastSquaresCoeffs(); finalGrid.cellADT.build (finalGrid); //cout << "built final grid" << endl; oscInit.init (finalGrid); //cout << "osc init" << endl; Solver solSteady (finalGrid, "SOLVER-STEADY", finalGrid.n_in_elm); //cout << "made solSteady" << endl; solSteady.read ("Solver/solSteady.dat"); //cout << "read solSteady" << endl; // solve steady state SMAirfoil sma (solSteady.dt); OscAirfoil oa (1.); // 1 is time step sma.read ("MovingGrid/smAirfoil.dat"); oa.read ("MovingGrid/oscAirfoil.dat"); //cout << "ma read" << endl; //Coeffs coeffs (finalGrid, oscInit.rhoInf, oscInit.pInf, oscInit.Mach, oa.MachAirfoil); sma.getAllFaceVelocities (finalGrid); //cout << "sma read" << endl; watchSteady.start(); (solSteady.implicit) ? solSteady.impl(finalGrid) : solSteady.expl(finalGrid); solSteady.petsc.finalize(); watchSteady.stop(); //finalGrid.outAllVTK (0); exit(-2); // solve osc airfoil //Grid oldGrid (mainDir, 4); //Grid oldGrid = move(finalGrid); int countr = 0; watchOscAirfoil.start(); for (double time=0.; time<50.; time+=1.) // 1 is dt { cout << "time = " << time << endl; grs[0].cellADT.build (grs[0]); grs[1].cellADT.build (grs[1]); grs[0].identifyIBlank (grs[1]); grs[1].identifyIBlank (grs[0]); grs[0].outAllVTK (countr); grs[1].outAllVTK (countr); Grid finalGrid (mainDir, 3); AFT::aft (grs, finalGrid); finalGrid.cellADT.build (finalGrid); finalGrid.readInput(); //finalGrid.leastSquaresCoeffs(); if (time == 0.) { /*oa.delAlpha = 0.; oscInit.init (finalGrid); oa.interFromOldTS (finalGrid, oldGrid);*/ //finalGrid = move(oldGrid); } else { /*oscInit.init (finalGrid); oa.interFromOldTS (finalGrid, oldGrid);*/ //finalGrid.set_BCs(); //finalGrid.apply_BCs(); } Solver solOscAirfoil (finalGrid, "SOLVER-OSC-AIRFOIL", finalGrid.n_in_elm); solOscAirfoil.read ("Solver/solOscAirfoil.dat"); solOscAirfoil.time = time; oa.setAngles (time); /*oa.getAllFaceVelocities (finalGrid); (solOscAirfoil.implicit) ? solOscAirfoil.impl(finalGrid) : solOscAirfoil.expl(finalGrid); coeffs.getCoeffs (finalGrid); outLiftCoef (coeffs, oa.alpha, solOscAirfoil.time); coeffs.outPresCoef (countr);*/ finalGrid.outAllVTK (countr); oa.moveGrid (grs[1]); //oldGrid = move(finalGrid); ++countr; } watchOscAirfoil.stop(); /*if (rank == MASTER_RANK) { //gr.outAllTecplot(); finalGrid.outAllVTK (0); //coeffs.out.close(); log (mainDir, watchSteady.elapsedTime, "elapsedTimeSteady", watchSteady.unit); //log (mainDir, watchOscAirfoil.elapsedTime, "elapsedTimeOscAirfoil", watchOscAirfoil.unit); solSteady.log (finalGrid.logDir); //solOscAirfoil.log (gr.logDir); sma.log (finalGrid.logDir); //oa.log (gr.logDir); }*/ PetscFinalize(); return 0; }
int main(int argc, char* argv[]) { // Time measurement. TimePeriod cpu_time; cpu_time.tick(); // Load the mesh. Mesh mesh; H2DReader mloader; mloader.load("square.mesh", &mesh); // Perform initial mesh refinements. for (int i=0; i < INIT_REF_NUM; i++) mesh.refine_all_elements(); // Enter boundary markers. BCTypes bc_types; bc_types.add_bc_dirichlet(Hermes::Tuple<int>(BDY_BOTTOM, BDY_RIGHT, BDY_TOP, BDY_LEFT)); // Enter Dirichlet boundary values. BCValues bc_values; bc_values.add_zero(Hermes::Tuple<int>(BDY_BOTTOM, BDY_RIGHT, BDY_TOP, BDY_LEFT)); // Create an H1 space with default shapeset. H1Space space(&mesh, &bc_types, &bc_values, P_INIT); int ndof = Space::get_num_dofs(&space); info("ndof: %d", ndof); info("Assembling by DiscreteProblem, solving by Umfpack:"); // Time measurement. cpu_time.tick(HERMES_SKIP); // Initialize weak formulation, WeakForm wf1; wf1.add_matrix_form(callback(jacobian_form_hermes), HERMES_NONSYM, HERMES_ANY); wf1.add_vector_form(callback(residual_form_hermes), HERMES_ANY); // Initialize the discrete problem. bool is_linear = false; DiscreteProblem dp1(&wf1, &space, is_linear); // Set up the solver, matrix, and rhs for the coarse mesh according to the solver selection. SparseMatrix* matrix = create_matrix(matrix_solver); Vector* rhs = create_vector(matrix_solver); Solver* solver = create_linear_solver(matrix_solver, matrix, rhs); // Initialize the solution. Solution sln1; if (matrix_solver == SOLVER_AZTECOO) { ((AztecOOSolver*) solver)->set_solver(iterative_method); ((AztecOOSolver*) solver)->set_precond(preconditioner); // Using default iteration parameters (see solver/aztecoo.h). } // Project the initial condition on the FE space to obtain initial // coefficient vector for the Newton's method. info("Projecting to obtain initial vector for the Newton's method."); scalar* coeff_vec = new scalar[Space::get_num_dofs(&space)] ; Solution* sln_tmp = new Solution(&mesh, init_cond); OGProjection::project_global(&space, sln_tmp, coeff_vec, matrix_solver); delete sln_tmp; // Perform Newton's iteration. int it = 1; while (1) { // Obtain the number of degrees of freedom. int ndof = Space::get_num_dofs(&space); // Assemble the Jacobian matrix and residual vector. dp1.assemble(coeff_vec, matrix, rhs, false); // Multiply the residual vector with -1 since the matrix // equation reads J(Y^n) \deltaY^{n+1} = -F(Y^n). rhs->change_sign(); // Calculate the l2-norm of residual vector. double res_l2_norm = get_l2_norm(rhs); // Info for user. info("---- Newton iter %d, ndof %d, res. l2 norm %g", it, Space::get_num_dofs(&space), res_l2_norm); // If l2 norm of the residual vector is within tolerance, or the maximum number // of iteration has been reached, then quit. if (res_l2_norm < NEWTON_TOL || it > NEWTON_MAX_ITER) break; // Solve the linear system. if(!solver->solve()) error ("Matrix solver failed.\n"); // Add \deltaY^{n+1} to Y^n. for (int i = 0; i < ndof; i++) coeff_vec[i] += solver->get_solution()[i]; if (it >= NEWTON_MAX_ITER) error ("Newton method did not converge."); it++; } // Translate the resulting coefficient vector into the Solution sln1. Solution::vector_to_solution(coeff_vec, &space, &sln1); // Cleanup. delete(matrix); delete(rhs); delete(solver); // CPU time needed by UMFpack double time1 = cpu_time.tick().last(); // Time measurement. cpu_time.tick(HERMES_SKIP); // TRILINOS PART: // Project the initial condition on the FE space. info("Projecting initial condition on the FE space."); sln_tmp = new Solution(&mesh, init_cond); OGProjection::project_global(&space, sln_tmp, coeff_vec, matrix_solver); delete sln_tmp; // Measure the projection time. double proj_time = cpu_time.tick().last(); // Initialize the weak formulation for Trilinos. WeakForm wf2(1, JFNK ? true : false); if (!JFNK || (JFNK && PRECOND == 1)) wf2.add_matrix_form(callback(jacobian_form_nox), HERMES_SYM); if (JFNK && PRECOND == 2) wf2.add_matrix_form(callback(precond_form_nox), HERMES_SYM); wf2.add_vector_form(callback(residual_form_nox)); // Initialize DiscreteProblem. DiscreteProblem dp2(&wf2, &space); // Initialize the NOX solver with the vector "coeff_vec". info("Initializing NOX."); NoxSolver nox_solver(&dp2); nox_solver.set_init_sln(coeff_vec); // Choose preconditioning. RCP<Precond> pc = rcp(new MlPrecond("sa")); if (PRECOND) { if (JFNK) nox_solver.set_precond(pc); else nox_solver.set_precond("ML"); } // Solve the nonlinear problem using NOX. info("Assembling by DiscreteProblem, solving by NOX."); Solution sln2; if (nox_solver.solve()) { Solution::vector_to_solution(nox_solver.get_solution(), &space, &sln2); info("Number of nonlin iterations: %d (norm of residual: %g)", nox_solver.get_num_iters(), nox_solver.get_residual()); info("Total number of iterations in linsolver: %d (achieved tolerance in the last step: %g)", nox_solver.get_num_lin_iters(), nox_solver.get_achieved_tol()); } else error("NOX failed."); // CPU time needed by NOX. double time2 = cpu_time.tick().last(); // Calculate errors. Solution ex; ex.set_exact(&mesh, &exact); double rel_err_1 = calc_rel_error(&sln1, &ex, HERMES_H1_NORM) * 100; info("Solution 1 (%s): exact H1 error: %g (time %g s)", MatrixSolverNames[matrix_solver].c_str(), rel_err_1, time1); double rel_err_2 = calc_rel_error(&sln2, &ex, HERMES_H1_NORM) * 100; info("Solution 2 (NOX): exact H1 error: %g (time %g + %g = %g [s])", rel_err_2, proj_time, time2, proj_time+time2); // Show both solutions. ScalarView view1("Solution 1", new WinGeom(0, 0, 500, 400)); view1.show(&sln1); ScalarView view2("Solution 2", new WinGeom(510, 0, 500, 400)); view2.show(&sln2); // Wait for all views to be closed. View::wait(); return 0; }
int main(int argc, char* argv[]) { // Load the mesh. Mesh mesh; H2DReader mloader; mloader.load("lshape.mesh", &mesh); // quadrilaterals // Perform initial mesh refinements. for (int i=0; i<INIT_REF_NUM; i++) mesh.refine_all_elements(); // Create an H1 space with default shapeset. H1Space space(&mesh, bc_types, essential_bc_values, P_INIT); // Initialize the weak formulation. WeakForm wf; wf.add_matrix_form(callback(bilinear_form), HERMES_SYM); wf.add_vector_form(callback(linear_form)); // Initialize refinement selector. H1ProjBasedSelector selector(CAND_LIST, CONV_EXP, H2DRS_DEFAULT_ORDER); // Set exact solution. ExactSolution exact(&mesh, fndd); // DOF and CPU convergence graphs. SimpleGraph graph_dof, graph_cpu, graph_dof_exact, graph_cpu_exact; // Time measurement. TimePeriod cpu_time; cpu_time.tick(); // Adaptivity loop: int as = 1; bool done = false; do { info("---- Adaptivity step %d:", as); // Construct globally refined reference mesh and setup reference space. Space* ref_space = construct_refined_space(&space); // Assemble the reference problem. info("Solving on reference mesh."); bool is_linear = true; DiscreteProblem* dp = new DiscreteProblem(&wf, ref_space, is_linear); SparseMatrix* matrix = create_matrix(matrix_solver); Vector* rhs = create_vector(matrix_solver); Solver* solver = create_linear_solver(matrix_solver, matrix, rhs); dp->assemble(matrix, rhs); // Time measurement. cpu_time.tick(); // Solve the linear system of the reference problem. If successful, obtain the solution. Solution ref_sln; if(solver->solve()) Solution::vector_to_solution(solver->get_solution(), ref_space, &ref_sln); else error ("Matrix solver failed.\n"); // Time measurement. cpu_time.tick(); // Project the fine mesh solution onto the coarse mesh. Solution sln; info("Projecting reference solution on coarse mesh."); OGProjection::project_global(&space, &ref_sln, &sln, matrix_solver); // Calculate element errors and total error estimate. info("Calculating error estimate and exact error."); Adapt* adaptivity = new Adapt(&space, HERMES_H1_NORM); bool solutions_for_adapt = true; double err_est_rel = adaptivity->calc_err_est(&sln, &ref_sln, solutions_for_adapt, HERMES_TOTAL_ERROR_REL | HERMES_ELEMENT_ERROR_REL) * 100; // Calculate exact error for each solution component. solutions_for_adapt = false; double err_exact_rel = adaptivity->calc_err_exact(&sln, &exact, solutions_for_adapt, HERMES_TOTAL_ERROR_REL | HERMES_ELEMENT_ERROR_REL) * 100; // Report results. info("ndof_coarse: %d, ndof_fine: %d", Space::get_num_dofs(&space), Space::get_num_dofs(ref_space)); info("err_est_rel: %g%%, err_exact_rel: %g%%", err_est_rel, err_exact_rel); // Time measurement. cpu_time.tick(); // Add entry to DOF and CPU convergence graphs. graph_dof.add_values(Space::get_num_dofs(&space), err_est_rel); graph_dof.save("conv_dof_est.dat"); graph_cpu.add_values(cpu_time.accumulated(), err_est_rel); graph_cpu.save("conv_cpu_est.dat"); graph_dof_exact.add_values(Space::get_num_dofs(&space), err_exact_rel); graph_dof_exact.save("conv_dof_exact.dat"); graph_cpu_exact.add_values(cpu_time.accumulated(), err_exact_rel); graph_cpu_exact.save("conv_cpu_exact.dat"); // If err_est too large, adapt the mesh. if (err_est_rel < ERR_STOP) done = true; else { info("Adapting coarse mesh."); done = adaptivity->adapt(&selector, THRESHOLD, STRATEGY, MESH_REGULARITY); // Increase the counter of performed adaptivity steps. if (done == false) as++; } if (Space::get_num_dofs(&space) >= NDOF_STOP) done = true; // Clean up. delete solver; delete matrix; delete rhs; delete adaptivity; if(done == false) delete ref_space->get_mesh(); delete ref_space; delete dp; } while (done == false); verbose("Total running time: %g s", cpu_time.accumulated()); int ndof = Space::get_num_dofs(&space); #define ERROR_SUCCESS 0 #define ERROR_FAILURE -1 int n_dof_allowed = 660; printf("n_dof_actual = %d\n", ndof); printf("n_dof_allowed = %d\n", n_dof_allowed); if (ndof <= n_dof_allowed) { printf("Success!\n"); return ERROR_SUCCESS; } else { printf("Failure!\n"); return ERROR_FAILURE; } }
bool Configuration::addPost(Solver& s) const { if (s.sharedContext() && s.sharedContext()->sccGraph.get() && !s.getPost(PostPropagator::priority_reserved_ufs)) { return s.addPost(new DefaultUnfoundedCheck()); } return true; }
int main() { // Create space, set Dirichlet BC, enumerate basis functions. Space* space = new Space(A, B, NELEM, DIR_BC_LEFT, DIR_BC_RIGHT, P_INIT, NEQ); info("N_dof = %d.", Space::get_num_dofs(space)); // Initialize the weak formulation. WeakForm wf(4); wf.add_matrix_form(0, 0, jacobian_1_1); wf.add_matrix_form(0, 1, jacobian_1_2); wf.add_matrix_form(1, 0, jacobian_2_1); wf.add_matrix_form(1, 1, jacobian_2_2); wf.add_matrix_form(1, 2, jacobian_2_3); wf.add_matrix_form(2, 1, jacobian_3_2); wf.add_matrix_form(2, 2, jacobian_3_3); wf.add_matrix_form(2, 3, jacobian_3_4); wf.add_matrix_form(3, 2, jacobian_4_3); wf.add_matrix_form(3, 3, jacobian_4_4); wf.add_vector_form(0, residual_1); wf.add_vector_form(1, residual_2); wf.add_vector_form(2, residual_3); wf.add_vector_form(3, residual_4); // Initialize the FE problem. bool is_linear = false; DiscreteProblem *dp = new DiscreteProblem(&wf, space, is_linear); // Newton's loop. // Fill vector coeff_vec using dof and coeffs arrays in elements. double *coeff_vec = new double[Space::get_num_dofs(space)]; get_coeff_vector(space, coeff_vec); // Set up the solver, matrix, and rhs according to the solver selection. SparseMatrix* matrix = create_matrix(matrix_solver); Vector* rhs = create_vector(matrix_solver); Solver* solver = create_linear_solver(matrix_solver, matrix, rhs); int it = 1; while (1) { // Obtain the number of degrees of freedom. int ndof = Space::get_num_dofs(space); // Assemble the Jacobian matrix and residual vector. dp->assemble(matrix, rhs); // Calculate the l2-norm of residual vector. double res_l2_norm = get_l2_norm(rhs); // Info for user. info("---- Newton iter %d, ndof %d, res. l2 norm %g", it, Space::get_num_dofs(space), res_l2_norm); // If l2 norm of the residual vector is within tolerance, then quit. // NOTE: at least one full iteration forced // here because sometimes the initial // residual on fine mesh is too small. if(res_l2_norm < NEWTON_TOL && it > 1) break; // Multiply the residual vector with -1 since the matrix // equation reads J(Y^n) \deltaY^{n+1} = -F(Y^n). for(int i=0; i<ndof; i++) rhs->set(i, -rhs->get(i)); // Solve the linear system. if(!solver->solve()) error ("Matrix solver failed.\n"); // Add \deltaY^{n+1} to Y^n. for (int i = 0; i < ndof; i++) coeff_vec[i] += solver->get_solution()[i]; // If the maximum number of iteration has been reached, then quit. if (it >= NEWTON_MAX_ITER) error ("Newton method did not converge."); // Copy coefficients from vector y to elements. set_coeff_vector(coeff_vec, space); it++; } // Plot the solution. Linearizer l(space); l.plot_solution("solution.gp"); // Plot the resulting space. space->plot("space.gp"); info("Done."); return 0; }
int main(int argc, char* argv[]) { // Time measurement. TimePeriod cpu_time; cpu_time.tick(); // Load the mesh. Mesh mesh; H2DReader mloader; mloader.load("domain.mesh", &mesh); // Perform initial mesh refinements. mesh.refine_all_elements(); // Enter boundary markers. BCTypes bc_types; bc_types.add_bc_dirichlet(BDY_HORIZONTAL); bc_types.add_bc_neumann(BDY_VERTICAL); // Enter Dirichlet boundary values. BCValues bc_values; bc_values.add_function(BDY_HORIZONTAL, essential_bc_values); // Create an H1 space with default shapeset. H1Space space(&mesh, &bc_types, &bc_values, P_INIT); // Initialize the weak formulation. WeakForm wf; wf.add_matrix_form(bilinear_form, bilinear_form_ord, HERMES_SYM); wf.add_vector_form(linear_form, linear_form_ord); wf.add_vector_form_surf(linear_form_surf, linear_form_surf_ord, BDY_VERTICAL); // Initialize coarse and reference mesh solution. Solution sln, ref_sln; // Initialize refinement selector. H1ProjBasedSelector selector(CAND_LIST, CONV_EXP, H2DRS_DEFAULT_ORDER); // DOF and CPU convergence graphs initialization. SimpleGraph graph_dof, graph_cpu; // Adaptivity loop: int as = 1; bool done = false; do { info("---- Adaptivity step %d:", as); // Construct globally refined reference mesh and setup reference space. Space* ref_space = construct_refined_space(&space); // Assemble the reference problem. info("Solving on reference mesh."); bool is_linear = true; DiscreteProblem* dp = new DiscreteProblem(&wf, ref_space, is_linear); SparseMatrix* matrix = create_matrix(matrix_solver); Vector* rhs = create_vector(matrix_solver); Solver* solver = create_linear_solver(matrix_solver, matrix, rhs); dp->assemble(matrix, rhs); // Time measurement. cpu_time.tick(); // Solve the linear system of the reference problem. If successful, obtain the solution. if(solver->solve()) Solution::vector_to_solution(solver->get_solution(), ref_space, &ref_sln); else error ("Matrix solver failed.\n"); // Time measurement. cpu_time.tick(); // Project the fine mesh solution onto the coarse mesh. info("Projecting reference solution on coarse mesh."); OGProjection::project_global(&space, &ref_sln, &sln, matrix_solver); // Calculate element errors and total error estimate. info("Calculating error estimate."); Adapt* adaptivity = new Adapt(&space); double err_est_rel = adaptivity->calc_err_est(&sln, &ref_sln) * 100; // Report results. info("ndof_coarse: %d, ndof_fine: %d, err_est_rel: %g%%", Space::get_num_dofs(&space), Space::get_num_dofs(ref_space), err_est_rel); // Time measurement. cpu_time.tick(); // Add entry to DOF and CPU convergence graphs. graph_dof.add_values(Space::get_num_dofs(&space), err_est_rel); graph_dof.save("conv_dof_est.dat"); graph_cpu.add_values(cpu_time.accumulated(), err_est_rel); graph_cpu.save("conv_cpu_est.dat"); // If err_est_rel too large, adapt the mesh. if (err_est_rel < ERR_STOP) done = true; else { info("Adapting coarse mesh."); done = adaptivity->adapt(&selector, THRESHOLD, STRATEGY, MESH_REGULARITY); } if (Space::get_num_dofs(&space) >= NDOF_STOP) done = true; // Clean up. delete solver; delete matrix; delete rhs; delete adaptivity; if (done == false) delete ref_space->get_mesh(); delete ref_space; delete dp; // Increase counter. as++; } while (done == false); verbose("Total running time: %g s", cpu_time.accumulated()); int ndof = Space::get_num_dofs(&space); printf("ndof allowed = %d\n", 430); printf("ndof actual = %d\n", ndof); if (ndof < 430) { // ndofs was 414 at the time this test was created printf("Success!\n"); return ERR_SUCCESS; } else { printf("Failure!\n"); return ERR_FAILURE; } }
int main(int argc, char **args) { int res = ERR_SUCCESS; #ifdef WITH_PETSC PetscInitialize(&argc, &args, (char *) PETSC_NULL, PETSC_NULL); #endif if (argc < 2) error("Not enough parameters."); printf("* Loading mesh '%s'\n", args[1]); Mesh mesh1; H3DReader mesh_loader; if (!mesh_loader.load(args[1], &mesh1)) error("Loading mesh file '%s'\n", args[1]); #if defined RHS2 Ord3 order(P_INIT_X, P_INIT_Y, P_INIT_Z); printf(" - Setting uniform order to (%d, %d, %d)\n", order.x, order.y, order.z); // Create an H1 space with default shapeset. printf("* Setting the space up\n"); H1Space space(&mesh1, bc_types, essential_bc_values, order); int ndofs = space.assign_dofs(); printf(" - Number of DOFs: %d\n", ndofs); printf("* Calculating a solution\n"); // duplicate the mesh Mesh mesh2; mesh2.copy(mesh1); // do some changes mesh2.refine_all_elements(H3D_H3D_H3D_REFT_HEX_XYZ); mesh2.refine_all_elements(H3D_H3D_H3D_REFT_HEX_XYZ); Solution fsln(&mesh2); fsln.set_const(-6.0); #else // duplicate the mesh Mesh mesh2; mesh2.copy(mesh1); Mesh mesh3; mesh3.copy(mesh1); // change meshes mesh1.refine_all_elements(H3D_REFT_HEX_X); mesh2.refine_all_elements(H3D_REFT_HEX_Y); mesh3.refine_all_elements(H3D_REFT_HEX_Z); printf("* Setup spaces\n"); Ord3 o1(2, 2, 2); printf(" - Setting uniform order to (%d, %d, %d)\n", o1.x, o1.y, o1.z); H1Space space1(&mesh1, bc_types_1, essential_bc_values_1, o1); Ord3 o2(2, 2, 2); printf(" - Setting uniform order to (%d, %d, %d)\n", o2.x, o2.y, o2.z); H1Space space2(&mesh2, bc_types_2, essential_bc_values_2, o2); Ord3 o3(1, 1, 1); printf(" - Setting uniform order to (%d, %d, %d)\n", o3.x, o3.y, o3.z); H1Space space3(&mesh3, bc_types_3, essential_bc_values_3, o3); int ndofs = 0; ndofs += space1.assign_dofs(); ndofs += space2.assign_dofs(ndofs); ndofs += space3.assign_dofs(ndofs); printf(" - Number of DOFs: %d\n", ndofs); #endif #if defined WITH_UMFPACK MatrixSolverType matrix_solver = SOLVER_UMFPACK; #elif defined WITH_PARDISO MatrixSolverType matrix_solver = SOLVER_PARDISO; #elif defined WITH_PETSC MatrixSolverType matrix_solver = SOLVER_PETSC; #elif defined WITH_MUMPS MatrixSolverType matrix_solver = SOLVER_MUMPS; #endif #ifdef RHS2 WeakForm wf; wf.add_matrix_form(bilinear_form<double, scalar>, bilinear_form<Ord, Ord>, HERMES_SYM); wf.add_vector_form(linear_form<double, scalar>, linear_form<Ord, Ord>, HERMES_ANY, &fsln); // Initialize discrete problem. bool is_linear = true; DiscreteProblem dp(&wf, &space, is_linear); #elif defined SYS3 WeakForm wf(3); wf.add_matrix_form(0, 0, biform_1_1<double, scalar>, biform_1_1<Ord, Ord>, HERMES_SYM); wf.add_matrix_form(0, 1, biform_1_2<double, scalar>, biform_1_2<Ord, Ord>, HERMES_NONSYM); wf.add_vector_form(0, liform_1<double, scalar>, liform_1<Ord, Ord>); wf.add_matrix_form(1, 1, biform_2_2<double, scalar>, biform_2_2<Ord, Ord>, HERMES_SYM); wf.add_matrix_form(1, 2, biform_2_3<double, scalar>, biform_2_3<Ord, Ord>, HERMES_NONSYM); wf.add_vector_form(1, liform_2<double, scalar>, liform_2<Ord, Ord>); wf.add_matrix_form(2, 2, biform_3_3<double, scalar>, biform_3_3<Ord, Ord>, HERMES_SYM); // Initialize discrete problem. bool is_linear = true; DiscreteProblem dp(&wf, Hermes::vector<Space *>(&space1, &space2, &space3), is_linear); #endif // Time measurement. TimePeriod cpu_time; cpu_time.tick(); // Set up the solver, matrix, and rhs according to the solver selection. SparseMatrix* matrix = create_matrix(matrix_solver); Vector* rhs = create_vector(matrix_solver); Solver* solver = create_linear_solver(matrix_solver, matrix, rhs); // Initialize the preconditioner in the case of SOLVER_AZTECOO. if (matrix_solver == SOLVER_AZTECOO) { ((AztecOOSolver*) solver)->set_solver(iterative_method); ((AztecOOSolver*) solver)->set_precond(preconditioner); // Using default iteration parameters (see solver/aztecoo.h). } // Assemble stiffness matrix and load vector. dp.assemble(matrix, rhs); // Solve the linear system. If successful, obtain the solution. info("Solving the linear problem."); bool solved = solver->solve(); // Time measurement. cpu_time.tick(); // Print timing information. info("Solution and mesh with polynomial orders saved. Total running time: %g s", cpu_time.accumulated()); // Time measurement. TimePeriod sln_time; sln_time.tick(); if (solved) { #ifdef RHS2 // Solve the linear system. If successful, obtain the solution. info("Solving the linear problem."); Solution sln(&mesh1); Solution::vector_to_solution(solver->get_solution(), &space, &sln); // Set exact solution. ExactSolution ex_sln(&mesh1, exact_solution); // Norm. double h1_sln_norm = h1_norm(&sln); double h1_err_norm = h1_error(&sln, &ex_sln); printf(" - H1 solution norm: % le\n", h1_sln_norm); printf(" - H1 error norm: % le\n", h1_err_norm); double l2_sln_norm = l2_norm(&sln); double l2_err_norm = l2_error(&sln, &ex_sln); printf(" - L2 solution norm: % le\n", l2_sln_norm); printf(" - L2 error norm: % le\n", l2_err_norm); if (h1_err_norm > EPS || l2_err_norm > EPS) { // Calculated solution is not enough precise. res = ERR_FAILURE; } #elif defined SYS3 // Solution 1. Solution sln1(&mesh1); Solution sln2(&mesh2); Solution sln3(&mesh3); Solution::vector_to_solution(solver->get_solution(), &space1, &sln1); Solution::vector_to_solution(solver->get_solution(), &space2, &sln2); Solution::vector_to_solution(solver->get_solution(), &space3, &sln3); ExactSolution esln1(&mesh1, exact_sln_fn_1); ExactSolution esln2(&mesh2, exact_sln_fn_2); ExactSolution esln3(&mesh3, exact_sln_fn_3); // Norm. double h1_err_norm1 = h1_error(&sln1, &esln1); double h1_err_norm2 = h1_error(&sln2, &esln2); double h1_err_norm3 = h1_error(&sln3, &esln3); double l2_err_norm1 = l2_error(&sln1, &esln1); double l2_err_norm2 = l2_error(&sln2, &esln2); double l2_err_norm3 = l2_error(&sln3, &esln3); printf(" - H1 error norm: % le\n", h1_err_norm1); printf(" - L2 error norm: % le\n", l2_err_norm1); if (h1_err_norm1 > EPS || l2_err_norm1 > EPS) { // Calculated solution is not enough precise. res = ERR_FAILURE; } printf(" - H1 error norm: % le\n", h1_err_norm2); printf(" - L2 error norm: % le\n", l2_err_norm2); if (h1_err_norm2 > EPS || l2_err_norm2 > EPS) { // Calculated solution is not enough precise. res = ERR_FAILURE; } printf(" - H1 error norm: % le\n", h1_err_norm3); printf(" - L2 error norm: % le\n", l2_err_norm3); if (h1_err_norm3 > EPS || l2_err_norm3 > EPS) { // Calculated solution is not enough precise. res = ERR_FAILURE; } #endif #ifdef RHS2 out_fn_vtk(&sln, "solution"); #elif defined SYS3 out_fn_vtk(&sln1, "sln1"); out_fn_vtk(&sln2, "sln2"); out_fn_vtk(&sln3, "sln3"); #endif } else res = ERR_FAILURE; // Print timing information. info("Solution and mesh with polynomial orders saved. Total running time: %g s", sln_time.accumulated()); // Clean up. delete matrix; delete rhs; delete solver; return res; }
int main(int argc, char* argv[]) { // Load the mesh. Mesh mesh; H2DReader mloader; mloader.load("domain.mesh", &mesh); // Perform initial mesh refinements. mesh.refine_towards_vertex(3, CORNER_REF_LEVEL); // Enter boundary markers. BCTypes bc_types; bc_types.add_bc_dirichlet(BDY_INNER); bc_types.add_bc_neumann(Hermes::Tuple<int>(BDY_BOTTOM, BDY_OUTER, BDY_LEFT)); // Enter Dirichlet boudnary values. BCValues bc_values; bc_values.add_zero(BDY_INNER); // Create an H1 space with default shapeset. H1Space space(&mesh, &bc_types, &bc_values, P_INIT); int ndof = Space::get_num_dofs(&space); info("ndof = %d", ndof); // Initialize the weak formulation. WeakForm wf; wf.add_matrix_form(callback(bilinear_form)); wf.add_vector_form(callback(linear_form)); wf.add_vector_form_surf(callback(linear_form_surf_bottom), BDY_BOTTOM); wf.add_vector_form_surf(callback(linear_form_surf_outer), BDY_OUTER); wf.add_vector_form_surf(callback(linear_form_surf_left), BDY_LEFT); // Initialize the FE problem. bool is_linear = true; DiscreteProblem dp(&wf, &space, is_linear); // Set up the solver, matrix, and rhs according to the solver selection. SparseMatrix* matrix = create_matrix(matrix_solver); Vector* rhs = create_vector(matrix_solver); Solver* solver = create_linear_solver(matrix_solver, matrix, rhs); // Initialize the solution. Solution sln; // Assemble the stiffness matrix and right-hand side vector. info("Assembling the stiffness matrix and right-hand side vector."); dp.assemble(matrix, rhs); // Solve the linear system and if successful, obtain the solution. info("Solving the matrix problem."); if(solver->solve()) Solution::vector_to_solution(solver->get_solution(), &space, &sln); else error ("Matrix solver failed.\n"); // Visualize the approximation. ScalarView view("Solution", new WinGeom(0, 0, 440, 350)); view.show(&sln); // Compute and show gradient magnitude. // (Note that the gradient at the re-entrant // corner needs to be truncated for visualization purposes.) ScalarView gradview("Gradient", new WinGeom(450, 0, 400, 350)); MagFilter grad(Hermes::Tuple<MeshFunction *>(&sln, &sln), Hermes::Tuple<int>(H2D_FN_DX, H2D_FN_DY)); gradview.show(&grad); // Wait for the views to be closed. View::wait(); // Clean up. delete solver; delete matrix; delete rhs; return 0; }
int main(int argc, char* argv[]) { // Time measurement. TimePeriod cpu_time; cpu_time.tick(); // Load the mesh. Mesh mesh, basemesh; H2DReader mloader; mloader.load("domain.mesh", &basemesh); // Perform initial mesh refinements. mesh.copy(&basemesh); for(int i = 0; i < INIT_REF_NUM; i++) mesh.refine_all_elements(); mesh.refine_towards_boundary(3, INIT_REF_NUM_BDY); // Create an H1 space with default shapeset. H1Space space(&mesh, bc_types, essential_bc_values, P_INIT); int ndof = Space::get_num_dofs(&space); info("ndof = %d.", ndof); // Create a selector which will select optimal candidate. H1ProjBasedSelector selector(CAND_LIST, CONV_EXP, H2DRS_DEFAULT_ORDER); // Solutions for the time stepping and the Newton's method. Solution sln, ref_sln, sln_prev_time; // Adapt mesh to represent initial condition with given accuracy. info("Mesh adaptivity to an exact function:"); int as = 1; bool done = false; do { // Setup space for the reference solution. Space *rspace = construct_refined_space(&space); // Assign the function f() to the fine mesh. ref_sln.set_exact(rspace->get_mesh(), init_cond); // Project the function f() on the coarse mesh. OGProjection::project_global(&space, &ref_sln, &sln_prev_time, matrix_solver); // Calculate element errors and total error estimate. Adapt adaptivity(&space, HERMES_H1_NORM); bool solutions_for_adapt = true; double err_est_rel = adaptivity.calc_err_est(&sln_prev_time, &ref_sln, solutions_for_adapt, HERMES_TOTAL_ERROR_REL | HERMES_ELEMENT_ERROR_REL) * 100; info("Step %d, ndof %d, proj_error %g%%", as, Space::get_num_dofs(&space), err_est_rel); // If err_est_rel too large, adapt the mesh. if (err_est_rel < ERR_STOP) done = true; else { double to_be_processed = 0; done = adaptivity.adapt(&selector, THRESHOLD, STRATEGY, MESH_REGULARITY, to_be_processed); if (Space::get_num_dofs(&space) >= NDOF_STOP) done = true; } as++; } while (done == false); // Project the initial condition on the FE space // to obtain initial coefficient vector for the Newton's method. info("Projecting initial condition to obtain coefficient vector for Newton on coarse mesh."); scalar* coeff_vec_coarse = new scalar[Space::get_num_dofs(&space)]; OGProjection::project_global(&space, init_cond, coeff_vec_coarse, matrix_solver); OGProjection::project_global(&space, &sln_prev_time, &sln, matrix_solver); // Initialize the weak formulation. WeakForm wf; if (TIME_INTEGRATION == 1) { wf.add_matrix_form(jac_form_vol_euler, jac_form_vol_ord, HERMES_UNSYM, HERMES_ANY, &sln_prev_time); wf.add_matrix_form_surf(jac_form_surf_1_euler, jac_form_surf_1_ord, BDY_1); wf.add_matrix_form_surf(jac_form_surf_4_euler, jac_form_surf_4_ord, BDY_4); wf.add_matrix_form_surf(jac_form_surf_6_euler, jac_form_surf_6_ord, BDY_6); wf.add_vector_form(res_form_vol_euler, res_form_vol_ord, HERMES_ANY, &sln_prev_time); wf.add_vector_form_surf(res_form_surf_1_euler, res_form_surf_1_ord, BDY_1); wf.add_vector_form_surf(res_form_surf_4_euler, res_form_surf_4_ord, BDY_4); wf.add_vector_form_surf(res_form_surf_6_euler, res_form_surf_6_ord, BDY_6); } else { wf.add_matrix_form(jac_form_vol_cranic, jac_form_vol_ord, HERMES_UNSYM, HERMES_ANY, &sln_prev_time); wf.add_matrix_form_surf(jac_form_surf_1_cranic, jac_form_surf_1_ord, BDY_1); wf.add_matrix_form_surf(jac_form_surf_4_cranic, jac_form_surf_4_ord, BDY_4); wf.add_matrix_form_surf(jac_form_surf_6_cranic, jac_form_surf_6_ord, BDY_6); wf.add_vector_form(res_form_vol_cranic, res_form_vol_ord, HERMES_ANY, &sln_prev_time); wf.add_vector_form_surf(res_form_surf_1_cranic, res_form_surf_1_ord, BDY_1, &sln_prev_time); wf.add_vector_form_surf(res_form_surf_4_cranic, res_form_surf_4_ord, BDY_4, &sln_prev_time); wf.add_vector_form_surf(res_form_surf_6_cranic, res_form_surf_6_ord, BDY_6, &sln_prev_time); } // Error estimate and discrete problem size as a function of physical time. SimpleGraph graph_time_err_est, graph_time_err_exact, graph_time_dof, graph_time_cpu; // Time stepping loop. int num_time_steps = (int)(T_FINAL/TAU + 0.5); for(int ts = 1; ts <= num_time_steps; ts++) { // Time measurement. cpu_time.tick(); // Updating current time. TIME = ts*TAU; info("---- Time step %d:", ts); // Periodic global derefinements. if (ts > 1 && ts % UNREF_FREQ == 0) { info("Global mesh derefinement."); mesh.copy(&basemesh); space.set_uniform_order(P_INIT); // Project fine mesh solution on the globally derefined mesh. info("Projecting fine mesh solution on globally derefined mesh."); OGProjection::project_global(&space, &ref_sln, &sln, matrix_solver); } // Adaptivity loop (in space): bool done = false; int as = 1; do { info("---- Time step %d, adaptivity step %d:", ts, as); // Construct globally refined reference mesh // and setup reference space. Space* ref_space = construct_refined_space(&space); scalar* coeff_vec = new scalar[Space::get_num_dofs(ref_space)]; // Calculate initial coefficient vector for Newton on the fine mesh. if (as == 1 && ts == 1) { info("Projecting coarse mesh solution to obtain initial vector on new fine mesh."); OGProjection::project_global(ref_space, &sln, coeff_vec, matrix_solver); } else { info("Projecting previous fine mesh solution to obtain initial vector on new fine mesh."); OGProjection::project_global(ref_space, &ref_sln, coeff_vec, matrix_solver); } // Initialize the FE problem. bool is_linear = false; DiscreteProblem dp(&wf, ref_space, is_linear); // Set up the solver, matrix, and rhs according to the solver selection. SparseMatrix* matrix = create_matrix(matrix_solver); Vector* rhs = create_vector(matrix_solver); Solver* solver = create_linear_solver(matrix_solver, matrix, rhs); // Perform Newton's iteration. int it = 1; while (1) { // Obtain the number of degrees of freedom. int ndof = Space::get_num_dofs(ref_space); // Assemble the Jacobian matrix and residual vector. dp.assemble(coeff_vec, matrix, rhs, false); // Multiply the residual vector with -1 since the matrix // equation reads J(Y^n) \deltaY^{n+1} = -F(Y^n). for (int i = 0; i < ndof; i++) rhs->set(i, -rhs->get(i)); // Calculate the l2-norm of residual vector. double res_l2_norm = get_l2_norm(rhs); // Info for user. info("---- Newton iter %d, ndof %d, res. l2 norm %g", it, Space::get_num_dofs(ref_space), res_l2_norm); // If l2 norm of the residual vector is within tolerance, or the maximum number // of iteration has been reached, then quit. if (res_l2_norm < NEWTON_TOL_FINE || it > NEWTON_MAX_ITER) break; // Solve the linear system. if(!solver->solve()) error ("Matrix solver failed.\n"); // Add \deltaY^{n+1} to Y^n. for (int i = 0; i < ndof; i++) coeff_vec[i] += solver->get_solution()[i]; if (it >= NEWTON_MAX_ITER) error ("Newton method did not converge."); it++; } // Translate the resulting coefficient vector into the actual solutions. Solution::vector_to_solutions(coeff_vec, ref_space, &ref_sln); // Project the fine mesh solution on the coarse mesh. info("Projecting fine mesh solution on coarse mesh for error calculation."); OGProjection::project_global(&space, &ref_sln, &sln, matrix_solver); // Calculate element errors. info("Calculating error estimate."); Adapt* adaptivity = new Adapt(&space, HERMES_H1_NORM); bool solutions_for_adapt = true; // Calculate error estimate wrt. fine mesh solution. double err_est_rel = adaptivity->calc_err_est(&sln, &ref_sln, solutions_for_adapt, HERMES_TOTAL_ERROR_REL | HERMES_ELEMENT_ERROR_ABS) * 100; // Report results. info("ndof_coarse: %d, ndof_fine: %d, space_err_est_rel: %g%%", Space::get_num_dofs(&space), Space::get_num_dofs(ref_space), err_est_rel); // Add entries to convergence graphs. graph_time_err_est.add_values(ts*TAU, err_est_rel); graph_time_err_est.save("time_error_est.dat"); graph_time_dof.add_values(ts*TAU, Space::get_num_dofs(&space)); graph_time_dof.save("time_dof.dat"); graph_time_cpu.add_values(ts*TAU, cpu_time.accumulated()); graph_time_cpu.save("time_cpu.dat"); // If space_err_est too large, adapt the mesh. if (err_est_rel < ERR_STOP) done = true; else { info("Adapting coarse mesh."); done = adaptivity->adapt(&selector, THRESHOLD, STRATEGY, MESH_REGULARITY); if (Space::get_num_dofs(&space) >= NDOF_STOP) { done = true; break; } as++; } // Cleanup. delete [] coeff_vec; delete solver; delete matrix; delete rhs; delete adaptivity; delete ref_space->get_mesh(); delete ref_space; } while (!done); // Copy new time level solution into sln_prev_time. sln_prev_time.copy(&ref_sln); } info("Coordinate ( 2, -2.0) value = %lf", sln_prev_time.get_pt_value( 2, -2.0)); info("Coordinate ( 2, -4.0) value = %lf", sln_prev_time.get_pt_value( 2, -4.0)); info("Coordinate ( 6, -2.0) value = %lf", sln_prev_time.get_pt_value( 6, -2.0)); info("Coordinate ( 6, -4.0) value = %lf", sln_prev_time.get_pt_value( 6, -4.0)); info("Coordinate ( 4, -3.0) value = %lf", sln_prev_time.get_pt_value( 4, -3.0)); #define ERROR_SUCCESS 0 #define ERROR_FAILURE -1 double coor_x[5] = {2.0, 2.0, 6.0, 6.0, 4.0}; double coor_y[5] = {-2.0, -4.0, -2.0, -4.0, -3.0}; double value[5] = {-4.821844, -2.462673, -4.000754, -1.705534, -3.257146}; for (int i = 0; i < 5; i++) { if ((value[i] - sln_prev_time.get_pt_value(coor_x[i], coor_y[i])) < 1E-6) { } else { printf("Failure!\n"); return ERROR_FAILURE; } } printf("Success!\n"); return ERROR_SUCCESS; }
// Usage: caffe_('solver_get_iter', hSolver) static void solver_get_iter(MEX_ARGS) { mxCHECK(nrhs == 1 && mxIsStruct(prhs[0]), "Usage: caffe_('solver_get_iter', hSolver)"); Solver<float>* solver = handle_to_ptr<Solver<float> >(prhs[0]); plhs[0] = mxCreateDoubleScalar(solver->iter()); }
int main(int argc, char **args) { // Test variable. int success_test = 1; if (argc < 5) error("Not enough parameters."); // Load the mesh. Mesh mesh; H3DReader mloader; if (!mloader.load(args[1], &mesh)) error("Loading mesh file '%s'.", args[1]); // Initialize the space according to the // command-line parameters passed. sscanf(args[2], "%d", &m); sscanf(args[3], "%d", &n); sscanf(args[4], "%d", &o); int mx = maxn(4, m, n, o, 4); Ord3 order(mx, mx, mx); H1Space space(&mesh, bc_types, NULL, order); // Initialize the weak formulation. WeakForm wf; wf.add_matrix_form(bilinear_form<double, scalar>, bilinear_form<Ord, Ord>, HERMES_SYM); wf.add_vector_form(linear_form<double, scalar>, linear_form<Ord, Ord>); wf.add_vector_form_surf(linear_form_surf<double, scalar>, linear_form_surf<Ord, Ord>); // Initialize the FE problem. bool is_linear = true; DiscreteProblem dp(&wf, &space, is_linear); // Initialize the solver in the case of SOLVER_PETSC or SOLVER_MUMPS. initialize_solution_environment(matrix_solver, argc, args); // Set up the solver, matrix, and rhs according to the solver selection. SparseMatrix* matrix = create_matrix(matrix_solver); Vector* rhs = create_vector(matrix_solver); Solver* solver = create_linear_solver(matrix_solver, matrix, rhs); // Initialize the preconditioner in the case of SOLVER_AZTECOO. if (matrix_solver == SOLVER_AZTECOO) { ((AztecOOSolver*) solver)->set_solver(iterative_method); ((AztecOOSolver*) solver)->set_precond(preconditioner); // Using default iteration parameters (see solver/aztecoo.h). } // Assemble the linear problem. info("Assembling (ndof: %d).", Space::get_num_dofs(&space)); dp.assemble(matrix, rhs); // Solve the linear system. If successful, obtain the solution. info("Solving."); Solution sln(&mesh); if(solver->solve()) Solution::vector_to_solution(solver->get_solution(), &space, &sln); else error ("Matrix solver failed.\n"); ExactSolution ex_sln(&mesh, exact_solution); // Calculate exact error. info("Calculating exact error."); Adapt *adaptivity = new Adapt(&space, HERMES_H1_NORM); bool solutions_for_adapt = false; double err_exact = adaptivity->calc_err_exact(&sln, &ex_sln, solutions_for_adapt, HERMES_TOTAL_ERROR_ABS); if (err_exact > EPS) // Calculated solution is not precise enough. success_test = 0; // Clean up. delete matrix; delete rhs; delete solver; delete adaptivity; // Properly terminate the solver in the case of SOLVER_PETSC or SOLVER_MUMPS. finalize_solution_environment(matrix_solver); if (success_test) { info("Success!"); return ERR_SUCCESS; } else { info("Failure!"); return ERR_FAILURE; } }
void addHeuristic( Solver& s ) { if( Heu == "dom" ) { MinDomain h(abs(rdz)); s.add( h ); } if( Heu == "lex" ) { Lexicographic h; s.add( h ); } else if( Heu == "deg") { MaxDegree h(abs(rdz)); s.add( h ); } else if( Heu == "rand") { Random h; s.add( h ); } else if( Heu == "dom+deg") { MinDomMaxDeg h(abs(rdz)); s.add( h ); } else if( Heu == "dom/deg") { DomOverDeg h(abs(rdz)); s.add( h ); } else if( Heu == "dom/wldeg") { DomOverWLDeg h(abs(rdz)); s.add( h ); } else if( Heu == "dom/wdeg") { DomOverWDeg h(abs(rdz)); s.add( h ); } else if( Heu == "neighbor") { Neighbor h(abs(rdz)); s.add( h ); } else if( Heu == "impact") { Impact h(abs(rdz)); s.add( h ); } else if( Heu == "impact/deg") { ImpactOverDeg h(abs(rdz)); s.add( h ); } else if( Heu == "impact/wdeg") { ImpactOverWDeg h(abs(rdz)); s.add( h ); } else if( Heu == "impact/wldeg") { ImpactOverWLDeg h(abs(rdz)); s.add( h ); } else { NoOrder h; s.add( h ); } }
int main(int argc, char* argv[]) { // Load the mesh. Mesh mesh; H2DReader mloader; mloader.load("square_quad.mesh", &mesh); // quadrilaterals // mloader.load("square_tri.mesh", &mesh); // triangles // Perform initial mesh refinement. for (int i=0; i<INIT_REF_NUM; i++) mesh.refine_all_elements(); mesh.refine_towards_boundary(BDY_LAYER, INIT_REF_NUM_BDY); // Enter boundary markers. BCTypes bc_types; bc_types.add_bc_dirichlet(Hermes::Tuple<int>(BDY_LAYER, BDY_REST)); // Enter Dirichlet boundary values. BCValues bc_values; bc_values.add_function(BDY_LAYER, essential_bc_values); bc_values.add_const(BDY_REST, 1.0); // Create an H1 space with default shapeset. H1Space space(&mesh, &bc_types, &bc_values, P_INIT); // Initialize the weak formulation. WeakForm wf; wf.add_matrix_form(callback(bilinear_form)); if (STABILIZATION_ON == true) { wf.add_matrix_form(callback(bilinear_form_stabilization)); } if (SHOCK_CAPTURING_ON == true) { wf.add_matrix_form(callback(bilinear_form_shock_capturing)); } // Initialize coarse and reference mesh solution. Solution sln, ref_sln; // Initialize refinement selector. H1ProjBasedSelector selector(CAND_LIST, CONV_EXP, H2DRS_DEFAULT_ORDER); // DOF and CPU convergence graphs initialization. SimpleGraph graph_dof, graph_cpu; // Time measurement. TimePeriod cpu_time; cpu_time.tick(); // Adaptivity loop: int as = 1; bool done = false; do { info("---- Adaptivity step %d:", as); // Construct globally refined reference mesh and setup reference space. Space* ref_space = construct_refined_space(&space); // Assemble the reference problem. info("Solving on reference mesh."); bool is_linear = true; DiscreteProblem* dp = new DiscreteProblem(&wf, ref_space, is_linear); SparseMatrix* matrix = create_matrix(matrix_solver); Vector* rhs = create_vector(matrix_solver); Solver* solver = create_linear_solver(matrix_solver, matrix, rhs); dp->assemble(matrix, rhs); // Time measurement. cpu_time.tick(); // Solve the linear system of the reference problem. // If successful, obtain the solution. if(solver->solve()) Solution::vector_to_solution(solver->get_solution(), ref_space, &ref_sln); else error ("Matrix solver failed.\n"); // Project the fine mesh solution onto the coarse mesh. info("Projecting reference solution on coarse mesh."); OGProjection::project_global(&space, &ref_sln, &sln, matrix_solver); // Calculate element errors and total error estimate. info("Calculating error estimate."); Adapt* adaptivity = new Adapt(&space, HERMES_H1_NORM); bool solutions_for_adapt = true; double err_est_rel = adaptivity->calc_err_est(&sln, &ref_sln, solutions_for_adapt, HERMES_TOTAL_ERROR_REL | HERMES_ELEMENT_ERROR_REL) * 100; // Report results. info("ndof_coarse: %d, ndof_fine: %d, err_est_rel: %g%%", Space::get_num_dofs(&space), Space::get_num_dofs(ref_space), err_est_rel); // Time measurement. cpu_time.tick(); // Add entry to DOF and CPU convergence graphs. graph_dof.add_values(Space::get_num_dofs(&space), err_est_rel); graph_dof.save("conv_dof_est.dat"); graph_cpu.add_values(cpu_time.accumulated(), err_est_rel); graph_cpu.save("conv_cpu_est.dat"); // If err_est too large, adapt the mesh. if (err_est_rel < ERR_STOP) done = true; else { info("Adapting coarse mesh."); done = adaptivity->adapt(&selector, THRESHOLD, STRATEGY, MESH_REGULARITY); // Increase the counter of performed adaptivity steps. if (done == false) as++; } if (Space::get_num_dofs(&space) >= NDOF_STOP) done = true; // Clean up. delete solver; delete matrix; delete rhs; delete adaptivity; if(done == false) delete ref_space->get_mesh(); delete ref_space; delete dp; } while (done == false); verbose("Total running time: %g s", cpu_time.accumulated()); int ndof = Space::get_num_dofs(&space); int n_dof_allowed = 570; printf("n_dof_actual = %d\n", ndof); printf("n_dof_allowed = %d\n", n_dof_allowed);// ndofs was 558 at the time this test was created if (ndof <= n_dof_allowed) { printf("Success!\n"); return ERR_SUCCESS; } else { printf("Failure!\n"); return ERR_FAILURE; } }