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); if(JFNK == 0) { // 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; } else jfnk_cg(dp_coarse, space, MATRIX_SOLVER_TOL, MATRIX_SOLVER_MAXITER, JFNK_EPSILON, NEWTON_TOL_COARSE, NEWTON_MAX_ITER, matrix_solver); // Cleanup. 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; double ftr_errors[MAX_ELEM_NUM]; // This array decides what // elements will be refined. 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); if(JFNK == 0) { // 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++; } // Cleanup. delete matrix; delete rhs; delete solver; delete [] coeff_vec; } else jfnk_cg(dp, ref_space, MATRIX_SOLVER_TOL, MATRIX_SOLVER_MAXITER, JFNK_EPSILON, NEWTON_TOL_COARSE, NEWTON_MAX_ITER, matrix_solver); // Cleanup. delete dp; // 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); } double max_qoi_err_est = 0; for (int i=0; i < space->get_n_active_elem(); i++) { if (GOAL_ORIENTED == 1) { // Use quantity of interest. double qoi_est = quantity_of_interest(space, X_QOI); double qoi_ref_est = quantity_of_interest(ref_space, X_QOI); ftr_errors[i] = fabs(qoi_ref_est - qoi_est); } else { // Use global norm double err_est_array[MAX_ELEM_NUM]; ftr_errors[i] = calc_err_est(NORM, space, ref_space, err_est_array); } // Info for user. info("Elem [%d]: absolute error (est) = %g%%", i, ftr_errors[i]); // Time measurement. cpu_time.tick(); // Calculating maximum of QOI FTR error for plotting purposes if (GOAL_ORIENTED == 1) { if (ftr_errors[i] > max_qoi_err_est) max_qoi_err_est = ftr_errors[i]; } else { double qoi_est = quantity_of_interest(space, X_QOI); double qoi_ref_est = quantity_of_interest(ref_space, X_QOI); double err_est = fabs(qoi_ref_est - qoi_est); if (err_est > max_qoi_err_est) max_qoi_err_est = err_est; } } // Add entries to convergence graphs. if (EXACT_SOL_PROVIDED) { double qoi_est = quantity_of_interest(space, X_QOI); double u[MAX_EQN_NUM], dudx[MAX_EQN_NUM]; exact_sol(X_QOI, u, dudx); double err_qoi_exact = fabs(u[0] - qoi_est); // Info for user. info("Relative error (exact) = %g %%", err_qoi_exact); // Add entry to DOF and CPU convergence graphs. graph_dof_exact.add_values(Space::get_num_dofs(space), err_qoi_exact); graph_cpu_exact.add_values(cpu_time.accumulated(), err_qoi_exact); } // Add entry to DOF and CPU convergence graphs. graph_dof_est.add_values(Space::get_num_dofs(space), max_qoi_err_est); graph_cpu_est.add_values(cpu_time.accumulated(), max_qoi_err_est); // Decide whether the max. FTR error in the quantity of interest // is sufficiently small. if(max_qoi_err_est < TOL_ERR_QOI) 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, ftr_errors, space, ref_space); as++; // Plot meshes, results, and errors. adapt_plotting(space, ref_space, NORM, EXACT_SOL_PROVIDED, exact_sol); // Cleanup. delete ref_space; } 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"); // Test variable. bool success = true; info("ndof = %d.", Space::get_num_dofs(space)); if (Space::get_num_dofs(space) > 150) success = false; if (success) { info("Success!"); return ERROR_SUCCESS; } else { info("Failure!"); return ERROR_FAILURE; } }
int main(int argc, char* argv[]) { Hermes2D hermes_2D; // Load the mesh. Mesh mesh; H2DReader mloader; mloader.load("domain-excentric.mesh", &mesh); //mloader.load("domain-concentric.mesh", &mesh); // Initial mesh refinements. for (int i=0; i < INIT_REF_NUM; i++) mesh.refine_all_elements(); mesh.refine_towards_boundary("Inner", INIT_BDY_REF_NUM_INNER, false); // true for anisotropic refinements mesh.refine_towards_boundary("Outer", INIT_BDY_REF_NUM_OUTER, false); // false for isotropic refinements // Initialize boundary conditions. EssentialBCNonConstX bc_inner_vel_x(std::string("Inner"), VEL, STARTUP_TIME); EssentialBCNonConstY bc_inner_vel_y(std::string("Inner"), VEL, STARTUP_TIME); DefaultEssentialBCConst bc_outer_vel(std::string("Outer"), 0.0); EssentialBCs bcs_vel_x(Hermes::vector<EssentialBoundaryCondition *>(&bc_inner_vel_x, &bc_outer_vel)); EssentialBCs bcs_vel_y(Hermes::vector<EssentialBoundaryCondition *>(&bc_inner_vel_y, &bc_outer_vel)); EssentialBCs bcs_pressure; // Spaces for velocity components and pressure. H1Space xvel_space(&mesh, &bcs_vel_x, P_INIT_VEL); H1Space yvel_space(&mesh, &bcs_vel_y, P_INIT_VEL); #ifdef PRESSURE_IN_L2 L2Space p_space(&mesh, &bcs_pressure, P_INIT_PRESSURE); #else H1Space p_space(&mesh, &bcs_pressure, P_INIT_PRESSURE); #endif Hermes::vector<Space *> spaces = Hermes::vector<Space *>(&xvel_space, &yvel_space, &p_space); // Calculate and report the number of degrees of freedom. int ndof = Space::get_num_dofs(spaces); info("ndof = %d.", ndof); // Define projection norms. ProjNormType vel_proj_norm = HERMES_H1_NORM; #ifdef PRESSURE_IN_L2 ProjNormType p_proj_norm = HERMES_L2_NORM; #else ProjNormType p_proj_norm = HERMES_H1_NORM; #endif // Solutions for the Newton's iteration and time stepping. info("Setting initial conditions."); Solution xvel_prev_time, yvel_prev_time, p_prev_time; xvel_prev_time.set_zero(&mesh); yvel_prev_time.set_zero(&mesh); p_prev_time.set_zero(&mesh); Hermes::vector<Solution*> slns = Hermes::vector<Solution*>(&xvel_prev_time, &yvel_prev_time, &p_prev_time); // Initialize weak formulation. WeakForm* wf = new WeakFormNSNewton(STOKES, RE, TAU, &xvel_prev_time, &yvel_prev_time); // Initialize the FE problem. DiscreteProblem dp(wf, spaces); // 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 views. VectorView vview("velocity [m/s]", new WinGeom(0, 0, 600, 500)); ScalarView pview("pressure [Pa]", new WinGeom(610, 0, 600, 500)); //vview.set_min_max_range(0, 1.6); vview.fix_scale_width(80); //pview.set_min_max_range(-0.9, 1.0); pview.fix_scale_width(80); pview.show_mesh(true); // Project the initial condition on the FE space to obtain initial // coefficient vector for the Newton's method. scalar* coeff_vec = new scalar[Space::get_num_dofs(spaces)]; // Newton's vector is set to zero (no OG projection needed). memset(coeff_vec, 0, ndof * sizeof(double)); /* // This can be used for more complicated initial conditions. info("Projecting initial condition to obtain initial vector for the Newton's method."); OGProjection::project_global(spaces, slns, coeff_vec, matrix_solver, Hermes::vector<ProjNormType>(vel_proj_norm, vel_proj_norm, p_proj_norm)); */ // Time-stepping loop: char title[100]; int num_time_steps = T_FINAL / TAU; for (int ts = 1; ts <= num_time_steps; ts++) { current_time += TAU; info("---- Time step %d, time = %g:", ts, current_time); // Update time-dependent essential BCs. info("Updating time-dependent essential BC."); Space::update_essential_bc_values(Hermes::vector<Space *>(&xvel_space, &yvel_space, &p_space), current_time); // Perform Newton's iteration. info("Solving nonlinear problem:"); bool verbose = true; bool jacobian_changed = true; if (!hermes_2D.solve_newton(coeff_vec, &dp, solver, matrix, rhs, jacobian_changed, NEWTON_TOL, NEWTON_MAX_ITER, verbose)) error("Newton's iteration failed."); // Update previous time level solutions. Solution::vector_to_solutions(coeff_vec, spaces, slns); // Show the solution at the end of time step. sprintf(title, "Velocity, time %g", current_time); vview.set_title(title); vview.show(&xvel_prev_time, &yvel_prev_time); sprintf(title, "Pressure, time %g", current_time); pview.set_title(title); pview.show(&p_prev_time); } // Clean up. delete [] coeff_vec; delete matrix; delete rhs; delete solver; // Wait for all views to be closed. View::wait(); return 0; }
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); double elem_errors[MAX_ELEM_NUM]; // This array decides what // elements will be refined. ElemPtr2 ref_elem_pairs[MAX_ELEM_NUM]; // To store element pairs from the // FTR solution. Decides how // elements will be hp-refined. for (int i=0; i < MAX_ELEM_NUM; i++) { ref_elem_pairs[i][0] = new Element(); ref_elem_pairs[i][1] = new Element(); } // DOF and CPU convergence graphs. SimpleGraph graph_dof_exact, graph_cpu_exact; // Adaptivity loop: int as = 1; bool done = false; do { info("---- Adaptivity step %d:", as); // 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; // For every element perform its fast trial refinement (FTR), // calculate the norm of the difference between the FTR // solution and the coarse space solution, and store the // error in the elem_errors[] array. int n_elem = space->get_n_active_elem(); for (int i=0; i < n_elem; i++) { info("=== Starting FTR of Elem [%d].", i); // Replicate coarse space including solution. Space *space_ref_local = space->replicate(); // Perform FTR of element 'i' space_ref_local->reference_refinement(i, 1); info("Elem [%d]: fine space created (%d DOF).", i, space_ref_local->assign_dofs()); // Initialize the FE problem. bool is_linear = false; DiscreteProblem* dp = new DiscreteProblem(&wf, space_ref_local, 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 FTR space. // Fill vector coeff_vec using dof and coeffs arrays in elements. double *coeff_vec = new double[Space::get_num_dofs(space_ref_local)]; get_coeff_vector(space_ref_local, coeff_vec); memset(coeff_vec, 0, Space::get_num_dofs(space_ref_local)*sizeof(double)); int it = 1; while (1) { // Obtain the number of degrees of freedom. int ndof = Space::get_num_dofs(space_ref_local); // 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_ref_local), 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, space_ref_local); it++; } // Cleanup. delete matrix; delete rhs; delete solver; delete dp; delete [] coeff_vec; // Print FTR solution (enumerated). Linearizer *lxx = new Linearizer(space_ref_local); char out_filename[255]; sprintf(out_filename, "solution_ref_%d.gp", i); lxx->plot_solution(out_filename); delete lxx; // Calculate norm of the difference between the coarse space // and FTR solutions. // NOTE: later we want to look at the difference in some quantity // of interest rather than error in global norm. double err_est_array[MAX_ELEM_NUM]; elem_errors[i] = calc_err_est(NORM, space, space_ref_local, err_est_array) * 100; info("Elem [%d]: absolute error (est) = %g%%", i, elem_errors[i]); // Copy the reference element pair for element 'i'. // into the ref_elem_pairs[i][] array Iterator *I = new Iterator(space); Iterator *I_ref = new Iterator(space_ref_local); Element *e, *e_ref; while (1) { e = I->next_active_element(); e_ref = I_ref->next_active_element(); if (e->id == i) { e_ref->copy_into(ref_elem_pairs[e->id][0]); // coarse element 'e' was split in space. if (e->level != e_ref->level) { e_ref = I_ref->next_active_element(); e_ref->copy_into(ref_elem_pairs[e->id][1]); } break; } } delete I; delete I_ref; delete space_ref_local; } // 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); } // Calculate max FTR error. double max_ftr_error = 0; for (int i=0; i < space->get_n_active_elem(); i++) { if (elem_errors[i] > max_ftr_error) max_ftr_error = elem_errors[i]; } info("Max FTR error = %g%%.", max_ftr_error); // Decide whether the max. FTR error is sufficiently small. if(max_ftr_error < TOL_ERR_FTR) break; // debug //if (as == 4) break; // Returns updated coarse space with the last solution on it. adapt(NORM, ADAPT_TYPE, THRESHOLD, elem_errors, space, ref_elem_pairs); // Plot spaces, results, and errors. adapt_plotting(space, ref_elem_pairs, NORM, EXACT_SOL_PROVIDED, exact_sol); as++; } while (done == false); info("Total running time: %g s", cpu_time.accumulated()); // Save convergence graphs. graph_dof_exact.save("conv_dof_exact.dat"); graph_cpu_exact.save("conv_cpu_exact.dat"); return 0; }
int main(int argc, char **args) { // Load the mesh. Mesh mesh; H3DReader mloader; mloader.load("fichera-corner.mesh3d", &mesh); // Perform initial mesh refinement. for (int i=0; i < INIT_REF_NUM; i++) mesh.refine_all_elements(H3D_H3D_H3D_REFT_HEX_XYZ); // Create an H1 space with default shapeset. H1Space space(&mesh, bc_types, essential_bc_values, Ord3(P_INIT_X, P_INIT_Y, P_INIT_Z)); // Initialize weak formulation. WeakForm wf; wf.add_matrix_form(bilinear_form<double, double>, bilinear_form<Ord, Ord>, HERMES_SYM, HERMES_ANY); wf.add_vector_form(linear_form<double, double>, linear_form<Ord, Ord>, HERMES_ANY); // Set exact solution. ExactSolution exact(&mesh, fndd); // DOF and CPU convergence graphs. SimpleGraph graph_dof_est, graph_cpu_est, 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, 1); // Initialize discrete problem. bool is_linear = true; 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); // 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 reference problem. info("Assembling on reference mesh (ndof: %d).", Space::get_num_dofs(ref_space)); dp.assemble(matrix, rhs); // Time measurement. cpu_time.tick(); // Solve the linear system on reference mesh. If successful, obtain the solution. info("Solving on reference mesh."); Solution ref_sln(ref_space->get_mesh()); 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 reference solution on the coarse mesh. Solution sln(space.get_mesh()); info("Projecting reference solution on coarse mesh."); OGProjection::project_global(&space, &ref_sln, &sln, matrix_solver); // Time measurement. cpu_time.tick(); // Output solution and mesh with polynomial orders. if (solution_output) { out_fn_vtk(&sln, "sln", as); out_orders_vtk(&space, "order", as); } // Skip the visualization time. cpu_time.tick(HERMES_SKIP); // 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) * 100; // Calculate exact error. solutions_for_adapt = false; double err_exact_rel = adaptivity->calc_err_exact(&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); // 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 is too large, adapt the mesh. if (err_est_rel < ERR_STOP) done = true; else { info("Adapting coarse mesh."); adaptivity->adapt(THRESHOLD); } if (Space::get_num_dofs(&space) >= NDOF_STOP) done = true; // Clean up. delete ref_space->get_mesh(); delete ref_space; delete matrix; delete rhs; delete solver; delete adaptivity; // Increase the counter of performed adaptivity steps. as++; } while (!done); return 0; }
int main(int argc, char* argv[]) { // Load the mesh. Mesh mesh; H2DReader mloader; mloader.load("GAMM-channel.mesh", &mesh); // Perform initial mesh refinements. for (int i = 0; i < INIT_REF_NUM; i++) mesh.refine_all_elements(0); //mesh.refine_towards_boundary(BDY_SOLID_WALL_BOTTOM, 2); // Initialize boundary condition types and spaces with default shapesets. L2Space space_rho(&mesh, P_INIT); L2Space space_rho_v_x(&mesh, P_INIT); L2Space space_rho_v_y(&mesh, P_INIT); L2Space space_e(&mesh, P_INIT); int ndof = Space::get_num_dofs(Hermes::vector<Space*>(&space_rho, &space_rho_v_x, &space_rho_v_y, &space_e)); info("ndof: %d", ndof); // Initialize solutions, set initial conditions. InitialSolutionEulerDensity prev_rho(&mesh, RHO_EXT); InitialSolutionEulerDensityVelX prev_rho_v_x(&mesh, RHO_EXT * V1_EXT); InitialSolutionEulerDensityVelY prev_rho_v_y(&mesh, RHO_EXT * V2_EXT); InitialSolutionEulerDensityEnergy prev_e(&mesh, QuantityCalculator::calc_energy(RHO_EXT, RHO_EXT * V1_EXT, RHO_EXT * V2_EXT, P_EXT, KAPPA)); // Numerical flux. OsherSolomonNumericalFlux num_flux(KAPPA); // Initialize weak formulation. EulerEquationsWeakFormSemiImplicitMultiComponent wf(&num_flux, KAPPA, RHO_EXT, V1_EXT, V2_EXT, P_EXT, BDY_SOLID_WALL_BOTTOM, BDY_SOLID_WALL_TOP, BDY_INLET, BDY_OUTLET, &prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e, (P_INIT == 0)); // Initialize the FE problem. bool is_linear = true; DiscreteProblem dp(&wf, Hermes::vector<Space*>(&space_rho, &space_rho_v_x, &space_rho_v_y, &space_e), is_linear); // If the FE problem is in fact a FV problem. if(P_INIT == 0) dp.set_fvm(); // Filters for visualization of Mach number, pressure and entropy. MachNumberFilter Mach_number(Hermes::vector<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e), KAPPA); PressureFilter pressure(Hermes::vector<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e), KAPPA); EntropyFilter entropy(Hermes::vector<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e), KAPPA, RHO_EXT, P_EXT); ScalarView pressure_view("Pressure", new WinGeom(0, 0, 600, 300)); ScalarView Mach_number_view("Mach number", new WinGeom(700, 0, 600, 300)); ScalarView entropy_production_view("Entropy estimate", new WinGeom(0, 400, 600, 300)); ScalarView s1("1", new WinGeom(0, 0, 600, 300)); ScalarView s2("2", new WinGeom(700, 0, 600, 300)); ScalarView s3("3", new WinGeom(0, 400, 600, 300)); ScalarView s4("4", new WinGeom(700, 400, 600, 300)); // 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); // Set up CFL calculation class. CFLCalculation CFL(CFL_NUMBER, KAPPA); int iteration = 0; double t = 0; for(t = 0.0; t < 3.0; t += time_step) { info("---- Time step %d, time %3.5f.", iteration++, t); // Set the current time step. wf.set_time_step(time_step); // Assemble the stiffness matrix and rhs. info("Assembling the stiffness matrix and right-hand side vector."); dp.assemble(matrix, rhs); // Solve the matrix problem. info("Solving the matrix problem."); scalar* solution_vector = NULL; if(solver->solve()) { solution_vector = solver->get_solution(); Solution::vector_to_solutions(solution_vector, Hermes::vector<Space *>(&space_rho, &space_rho_v_x, &space_rho_v_y, &space_e), Hermes::vector<Solution *>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e)); } else error ("Matrix solver failed.\n"); if(SHOCK_CAPTURING) { DiscontinuityDetector discontinuity_detector(Hermes::vector<Space *>(&space_rho, &space_rho_v_x, &space_rho_v_y, &space_e), Hermes::vector<Solution *>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e)); std::set<int> discontinuous_elements = discontinuity_detector.get_discontinuous_element_ids(DISCONTINUITY_DETECTOR_PARAM); FluxLimiter flux_limiter(solution_vector, Hermes::vector<Space *>(&space_rho, &space_rho_v_x, &space_rho_v_y, &space_e), Hermes::vector<Solution *>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e)); flux_limiter.limit_according_to_detector(discontinuous_elements); } CFL.calculate_semi_implicit(Hermes::vector<Solution *>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e), &mesh, time_step); // Visualization. Mach_number.reinit(); pressure.reinit(); entropy.reinit(); pressure_view.show(&pressure); entropy_production_view.show(&entropy); Mach_number_view.show(&Mach_number); /* s1.show(&prev_rho); s2.show(&prev_rho_v_x); s3.show(&prev_rho_v_y); s4.show(&prev_e); */ //View::wait(); } pressure_view.close(); entropy_production_view.close(); Mach_number_view.close(); s1.close(); s2.close(); s3.close(); s4.close(); return 0; }
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_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_INT, &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[]) { // Time measurement. TimePeriod cpu_time; cpu_time.tick(); info("TIME_MAX_ITER = %d", TIME_MAX_ITER); // Load the mesh file. Mesh mesh; H2DReader mloader; mloader.load("domain.mesh", &mesh); // Perform initial mesh refinements. for (int i=0; i < INIT_GLOB_REF_NUM; i++) mesh.refine_all_elements(); mesh.refine_towards_boundary(1, INIT_BDY_REF_NUM); // Initialize boundary conditions. BCTypes bc_types; bc_types.add_bc_dirichlet(BDY_DIRICHLET); // Enter Dirichlet boudnary values. BCValues bc_values; bc_values.add_zero(BDY_DIRICHLET); // Create H1 spaces with default shapesets. H1Space space_T(&mesh, &bc_types, &bc_values, P_INIT); H1Space space_phi(&mesh, &bc_types, &bc_values, P_INIT); Hermes::vector<Space*> spaces(&space_T, &space_phi); // Exact solutions for error evaluation. ExactSolution T_exact_solution(&mesh, T_exact), phi_exact_solution(&mesh, phi_exact); // Initialize solution views (their titles will be2 updated in each time step). ScalarView sview_T("", new WinGeom(0, 0, 500, 400)); sview_T.fix_scale_width(50); ScalarView sview_phi("", new WinGeom(0, 500, 500, 400)); sview_phi.fix_scale_width(50); ScalarView sview_T_exact("", new WinGeom(550, 0, 500, 400)); sview_T_exact.fix_scale_width(50); ScalarView sview_phi_exact("", new WinGeom(550, 500, 500, 400)); sview_phi_exact.fix_scale_width(50); char title[100]; // Character array to store the title for an actual view and time step. // Solutions in the previous time step. Solution T_prev_time, phi_prev_time; Hermes::vector<MeshFunction*> time_iterates(&T_prev_time, &phi_prev_time); // Solutions in the previous Newton's iteration. Solution T_prev_newton, phi_prev_newton; Hermes::vector<Solution*> newton_iterates(&T_prev_newton, &phi_prev_newton); // Initialize the weak formulation. WeakForm wf(2); wf.add_matrix_form(0, 0, jac_TT, jac_TT_ord); wf.add_matrix_form(0, 1, jac_Tphi, jac_Tphi_ord); wf.add_vector_form(0, res_T, res_T_ord, HERMES_ANY, &T_prev_time); wf.add_matrix_form(1, 0, jac_phiT, jac_phiT_ord); wf.add_matrix_form(1, 1, jac_phiphi, jac_phiphi_ord); wf.add_vector_form(1, res_phi, res_phi_ord, HERMES_ANY, &phi_prev_time); // Set initial conditions. T_prev_time.set_exact(&mesh, T_exact); phi_prev_time.set_exact(&mesh, phi_exact); // 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); solver->set_factorization_scheme(HERMES_REUSE_MATRIX_REORDERING); // Time stepping. int t_step = 1; do { TIME += TAU; info("---- Time step %d, t = %g s:", t_step, TIME); t_step++; info("Projecting to obtain initial vector for the Newton's method."); scalar* coeff_vec = new scalar[Space::get_num_dofs(spaces)]; OGProjection::project_global(spaces, time_iterates, coeff_vec, matrix_solver); Solution::vector_to_solutions(coeff_vec, Hermes::vector<Space*>(&space_T, &space_phi), Hermes::vector<Solution*>(&T_prev_newton, &phi_prev_newton)); // Initialize the FE problem. bool is_linear = false; DiscreteProblem dp(&wf, spaces, is_linear); // Perform Newton's iteration. info("Newton's iteration..."); bool verbose = true; if(!solve_newton(coeff_vec, &dp, solver, matrix, rhs, NEWTON_TOL, NEWTON_MAX_ITER, verbose)) error("Newton's iteration failed."); // Translate the resulting coefficient vector into the Solution sln. Solution::vector_to_solutions(coeff_vec, spaces, newton_iterates); delete [] coeff_vec; // Show the new time level solution. sprintf(title, "Approx. solution for T, t = %g s", TIME); sview_T.set_title(title); sview_T.show(&T_prev_newton); sprintf(title, "Approx. solution for phi, t = %g s", TIME); sview_phi.set_title(title); sview_phi.show(&phi_prev_newton); // Exact solution for comparison with computational results. T_exact_solution.update(&mesh, T_exact); phi_exact_solution.update(&mesh, phi_exact); // Show exact solution. sview_T_exact.show(&T_exact_solution); sprintf(title, "Exact solution for T, t = %g s", TIME); sview_T_exact.set_title(title); sview_phi_exact.show(&phi_exact_solution); sprintf(title, "Exact solution for phi, t = %g s", TIME); sview_phi_exact.set_title(title); // Calculate exact error. info("Calculating error (exact)."); Hermes::vector<double> exact_errors; Adapt adaptivity_exact(spaces, Hermes::vector<ProjNormType>(HERMES_H1_NORM, HERMES_H1_NORM)); bool solutions_for_adapt = false; adaptivity_exact.calc_err_exact(Hermes::vector<Solution *>(&T_prev_newton, &phi_prev_newton), Hermes::vector<Solution *>(&T_exact_solution, &phi_exact_solution), &exact_errors, solutions_for_adapt); double maxerr = std::max(exact_errors[0], exact_errors[1])*100; info("Exact solution error for T (H1 norm): %g %%", exact_errors[0]*100); info("Exact solution error for phi (H1 norm): %g %%", exact_errors[1]*100); info("Exact solution error (maximum): %g %%", maxerr); // Prepare previous time level solution for the next time step. T_prev_time.copy(&T_prev_newton); phi_prev_time.copy(&phi_prev_newton); } while (t_step <= TIME_MAX_ITER); // Cleanup. delete matrix; delete rhs; delete solver; // Wait for all views to be closed. View::wait(); return 0; }
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, 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; // Test variable. int success_test = 1; // 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); if (as == 2) if (err_exact_rel > 1e-10) success_test = 0; } // 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) done = true; // Extra code for this test. if (as == 30) { if (err_est_rel > 1e-10) success_test = 0; if (space->get_n_active_elem() != 2) success_test = 0; Element *e = space->first_active_element(); if (e->p != 2) success_test = 0; e = space->last_active_element(); if (e->p != 2) success_test = 0; 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 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"); if (success_test) { info("Success!"); return ERROR_SUCCESS; } else { info("Failure!"); return ERROR_FAILURE; } }
int main(int argc, char **args) { // Test variable. int success_test = 1; // Check the number of command-line parameters. if (argc < 2) { info("Use x, y, z, xy, xz, yz, or xyz as a command-line parameter."); error("Not enough command-line parameters."); } // Determine anisotropy type from the command-line parameter. ANISO_TYPE = parse_aniso_type(args[1]); // Load the mesh. Mesh mesh; H3DReader mesh_loader; mesh_loader.load("hex-0-1.mesh3d", &mesh); // Assign the lowest possible directional polynomial degrees so that the problem's NDOF >= 1. assign_poly_degrees(); // Create an H1 space with default shapeset. info("Setting directional polynomial degrees %d, %d, %d.", P_INIT_X, P_INIT_Y, P_INIT_Z); H1Space space(&mesh, bc_types, essential_bc_values, Ord3(P_INIT_X, P_INIT_Y, P_INIT_Z)); // Initialize weak formulation. WeakForm wf; wf.add_matrix_form(bilinear_form<double, scalar>, bilinear_form<Ord, Ord>, HERMES_SYM, HERMES_ANY); wf.add_vector_form(linear_form<double, scalar>, linear_form<Ord, Ord>, HERMES_ANY); // Set exact solution. ExactSolution exact(&mesh, fndd); // 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, 1); // Initialize discrete problem. bool is_linear = true; 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); // 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 reference problem. info("Assembling on reference mesh (ndof: %d).", Space::get_num_dofs(ref_space)); dp.assemble(matrix, rhs); // Time measurement. cpu_time.tick(); // Solve the linear system on reference mesh. If successful, obtain the solution. info("Solving on reference mesh."); Solution ref_sln(ref_space->get_mesh()); if(solver->solve()) Solution::vector_to_solution(solver->get_solution(), ref_space, &ref_sln); else { error ("Matrix solver failed.\n"); success_test = 0; } // Time measurement. cpu_time.tick(); // Project the reference solution on the coarse mesh. Solution sln(space.get_mesh()); info("Projecting reference solution on coarse mesh."); OGProjection::project_global(&space, &ref_sln, &sln, matrix_solver); // Time measurement. cpu_time.tick(); // Output solution and mesh with polynomial orders. if (solution_output) { out_fn_vtk(&sln, "sln", as); out_orders_vtk(&space, "order", as); } // Skip the visualization time. cpu_time.tick(HERMES_SKIP); // 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) * 100; // Calculate exact error. solutions_for_adapt = false; double err_exact_rel = adaptivity->calc_err_exact(&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); // If err_est_rel is too large, adapt the mesh. if (err_est_rel < ERR_STOP) done = true; else { info("Adapting coarse mesh."); adaptivity->adapt(THRESHOLD); } if (Space::get_num_dofs(&space) >= NDOF_STOP) done = true; // Clean up. delete ref_space->get_mesh(); delete ref_space; delete matrix; delete rhs; delete solver; delete adaptivity; // Increase the counter of performed adaptivity steps. as++; } while (!done); // This is the actual test. #define ERROR_SUCCESS 0 #define ERROR_FAILURE -1 int ndof_allowed; switch (ANISO_TYPE) { case ANISO_X: ndof_allowed = 28; break; case ANISO_Y: ndof_allowed = 28; break; case ANISO_Z: ndof_allowed = 28; break; case ANISO_X | ANISO_Y: ndof_allowed = 98; break; case ANISO_X | ANISO_Z: ndof_allowed = 98; break; case ANISO_Y | ANISO_Z: ndof_allowed = 98; break; case ANISO_X | ANISO_Y | ANISO_Z: ndof_allowed = 343; break; default: error("Admissible command-line options are x, y, x, xy, xz, yz, xyz."); } int ndof = Space::get_num_dofs(&space); info("ndof_actual = %d", ndof); info("ndof_allowed = %d", ndof_allowed); if (ndof > ndof_allowed) success_test = 0; if (success_test) { info("Success!"); return ERR_SUCCESS; } else { info("Failure!"); return ERR_FAILURE; } }
adjMatrix() { matrix=NULL; create_matrix(10); }
adjMatrix(int size) {matrix=NULL; create_matrix(size);}
int main(int argc, char *argv[]) { int rows = 8; int columns = 7; //4; char *matrix = create_matrix(rows, columns); /* set_element(matrix, rows, columns, 0, 0, 1); set_element(matrix, rows, columns, 0, 1, 0); set_element(matrix, rows, columns, 0, 2, 0); set_element(matrix, rows, columns, 0, 3, 0); set_element(matrix, rows, columns, 1, 0, 0); set_element(matrix, rows, columns, 1, 1, 0); set_element(matrix, rows, columns, 1, 2, 0); set_element(matrix, rows, columns, 1, 3, 0); set_element(matrix, rows, columns, 2, 0, 0); set_element(matrix, rows, columns, 2, 1, 0); set_element(matrix, rows, columns, 2, 2, 2); set_element(matrix, rows, columns, 2, 3, 3); */ set_element(matrix, rows, columns, 0, 0, 1); set_element(matrix, rows, columns, 0, 1, 0); set_element(matrix, rows, columns, 0, 2, 0); set_element(matrix, rows, columns, 0, 3, 0); set_element(matrix, rows, columns, 0, 4, 0); set_element(matrix, rows, columns, 0, 5, 0); set_element(matrix, rows, columns, 0, 6, 0); set_element(matrix, rows, columns, 1, 0, 0); set_element(matrix, rows, columns, 1, 1, 0); set_element(matrix, rows, columns, 1, 2, 0); set_element(matrix, rows, columns, 1, 3, 0); set_element(matrix, rows, columns, 1, 4, 0); set_element(matrix, rows, columns, 1, 5, 0); set_element(matrix, rows, columns, 1, 6, 0); set_element(matrix, rows, columns, 2, 0, 0); set_element(matrix, rows, columns, 2, 1, 0); set_element(matrix, rows, columns, 2, 2, 0); set_element(matrix, rows, columns, 2, 3, 0); set_element(matrix, rows, columns, 2, 4, 0); set_element(matrix, rows, columns, 2, 5, 0); set_element(matrix, rows, columns, 2, 6, 0); set_element(matrix, rows, columns, 3, 0, 0); set_element(matrix, rows, columns, 3, 1, 0); set_element(matrix, rows, columns, 3, 2, 0); set_element(matrix, rows, columns, 3, 3, 0); set_element(matrix, rows, columns, 3, 4, 0); set_element(matrix, rows, columns, 3, 5, 0); set_element(matrix, rows, columns, 3, 6, 0); set_element(matrix, rows, columns, 4, 0, 0); set_element(matrix, rows, columns, 4, 1, 0); set_element(matrix, rows, columns, 4, 2, 0); set_element(matrix, rows, columns, 4, 3, 0); set_element(matrix, rows, columns, 4, 4, 0); set_element(matrix, rows, columns, 4, 5, 0); set_element(matrix, rows, columns, 4, 6, 0); set_element(matrix, rows, columns, 5, 0, 0); set_element(matrix, rows, columns, 5, 1, 0); set_element(matrix, rows, columns, 5, 2, 0); set_element(matrix, rows, columns, 5, 3, 0); set_element(matrix, rows, columns, 5, 4, 0); set_element(matrix, rows, columns, 5, 5, 0); set_element(matrix, rows, columns, 5, 6, 0); set_element(matrix, rows, columns, 6, 0, 0); set_element(matrix, rows, columns, 6, 1, 0); set_element(matrix, rows, columns, 6, 2, 0); set_element(matrix, rows, columns, 6, 3, 0); set_element(matrix, rows, columns, 6, 4, 0); set_element(matrix, rows, columns, 6, 5, 0); set_element(matrix, rows, columns, 6, 6, 0); set_element(matrix, rows, columns, 7, 0, 2); set_element(matrix, rows, columns, 7, 1, 0); set_element(matrix, rows, columns, 7, 2, 0); set_element(matrix, rows, columns, 7, 3, 0); set_element(matrix, rows, columns, 7, 4, 0); set_element(matrix, rows, columns, 7, 5, 3); set_element(matrix, rows, columns, 7, 6, 3); print_matrix(matrix, rows, columns); printf("%d\n", search(matrix, rows, columns, 0, 0)); return 0; }
int main(int argc, char* argv[]) { // Instantiate a class with global functions. Hermes2D hermes2d; // Load the mesh. Mesh mesh, mesh1; H2DReader mloader; mloader.load("domain.mesh", &mesh); // Perform uniform mesh refinement. mesh.refine_all_elements(); // Initialize boundary conditions. DefaultEssentialBCConst zero_disp("Bottom", 0.0); EssentialBCs bcs(&zero_disp); // Create x- and y- displacement space using the default H1 shapeset. H1Space u1_space(&mesh, &bcs, P_INIT); H1Space u2_space(&mesh, &bcs, P_INIT); int ndof = Space::get_num_dofs(Hermes::vector<Space *>(&u1_space, &u2_space)); info("ndof = %d", ndof); // Initialize the weak formulation. CustomWeakFormLinearElasticity wf(E, nu, rho*g1, "Top", f0, f1); // Initialize the FE problem. DiscreteProblem dp(&wf, Hermes::vector<Space *>(&u1_space, &u2_space)); // 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); // Initial coefficient vector for the Newton's method. scalar* coeff_vec = new scalar[ndof]; memset(coeff_vec, 0, ndof*sizeof(scalar)); // Perform Newton's iteration. bool verbose = true; bool jacobian_changed = true; if (!hermes2d.solve_newton(coeff_vec, &dp, solver, matrix, rhs, jacobian_changed, NEWTON_TOL, NEWTON_MAX_ITER, verbose)) error("Newton's iteration failed."); // Translate the resulting coefficient vector into the Solution sln. Solution u1_sln, u2_sln; Solution::vector_to_solutions(coeff_vec, Hermes::vector<Space *>(&u1_space, &u2_space), Hermes::vector<Solution *>(&u1_sln, &u2_sln)); // Visualize the solution. ScalarView view("Von Mises stress [Pa]", new WinGeom(0, 0, 800, 400)); double lambda = (E * nu) / ((1 + nu) * (1 - 2*nu)); // First Lame constant. double mu = E / (2*(1 + nu)); // Second Lame constant. VonMisesFilter stress(Hermes::vector<MeshFunction *>(&u1_sln, &u2_sln), lambda, mu); view.show_mesh(false); view.show(&stress, HERMES_EPS_HIGH, H2D_FN_VAL_0, &u1_sln, &u2_sln, 1.5e5); // Wait for the view to be closed. View::wait(); // Clean up. delete [] coeff_vec; delete solver; delete matrix; delete rhs; return 0; }
int main(void) { clock_t begin, end; double time_spent; begin = clock(); matrix* a = create_matrix(4, 4); value temp_a[16] = { 18, 60, 57, 96, 41, 24, 99, 58, 14, 30, 97, 66, 51, 13, 19, 85 }; insert_array(temp_a, a); matrix* b = create_matrix(4, 4); assert(insert_array(temp_a, b)); //tests check_boundaries assert(check_boundaries(1,1,a)); assert(check_boundaries(4,4,a)); assert(!check_boundaries(4,5,a)); assert(!check_boundaries(5,4,a)); assert(!check_boundaries(0,1,a)); assert(!check_boundaries(1,0,a)); assert(!check_boundaries(-1,1,a)); assert(!check_boundaries(1,-1,a)); //tests compare_matrices,insert_value and get_value assert(compare_matrices(a,b)); assert(insert_value(10,1,1,b)); assert(!compare_matrices(a,b)); assert(get_value(1,1,b)==10); assert(insert_value(18,1,1,b)); assert(compare_matrices(a,b)); //tests is_matrix matrix* c=a; assert(compare_matrices(a,c)); assert(!is_matrix(a,b)); assert(is_matrix(a,c)); //tests insert_value by trying to go outside the matrix assert(insert_value(1,1,1,c)); assert(insert_value(2,2,2,c)); assert(insert_value(3,3,3,c)); assert(insert_value(4,4,4,c)); assert(!insert_value(5,5,5,c)); assert(!insert_value(-1,-1,-1,c)); assert(!insert_value(-1,-1,1,c)); assert(!insert_value(-1,1,-1,c)); //test get_value assert(get_value(1,1,c)==1); assert(get_value(2,2,c)==2); assert(get_value(3,3,c)==3); assert(get_value(4,4,c)==4); assert(get_value(0,0,c)==0); assert(get_value(1,-1,c)==0); assert(get_value(-1,1,c)==0); assert(get_value(5,5,c)==0); //tests insert and get without boundary checks insert_value_without_check(4,1,1,c); insert_value_without_check(3,2,2,c); insert_value_without_check(2,3,3,c); insert_value_without_check(1,4,4,c); assert(get_value_without_check(1,1,c)==4); assert(get_value_without_check(2,2,c)==3); assert(get_value_without_check(3,3,c)==2); assert(get_value_without_check(4,4,c)==1); //tests add_matrices value temp_b[16]={ 36,120,114,192, 82,48,198,116, 28, 60, 194,132, 102,26,38,170}; assert(insert_array(temp_b,a)); matrix* d = create_matrix(4, 4); assert(add_matrices(b,b,d)); assert(compare_matrices(d,a)); //tests subtract_matrices value temp_c[16]={ 0,0,0,0, 0,0,0,0, 0, 0, 0,0, 0,0,0,0}; assert(insert_array(temp_c,a)); assert(subtract_matrices(b,b,d)); assert(compare_matrices(d,a)); //tests sum_of_row assert(insert_array(temp_a,a)); assert(sum_of_row(1,a)==231); assert(sum_of_row(4,a)==168); assert(sum_of_row(0,a)==0); assert(sum_of_row(5,a)==0); //tests sum_of_column assert(sum_of_column(1,a)==124); assert(sum_of_column(4,a)==305); assert(sum_of_column(0,a)==0); assert(sum_of_column(5,a)==0); //tests get_row_vector matrix* e = create_matrix(1, 4); value temp_d[4] = { 18, 60, 57, 96}; assert(insert_array(temp_d,e)); matrix* f = create_matrix(1, 4); assert(!get_row_vector(0,a,f)); assert(!get_row_vector(5,a,f)); assert(get_row_vector(1,a,f)); assert(compare_matrices(e,f)); //tests get_column_vector matrix* g = create_matrix(4, 1); assert(insert_array(temp_d,e)); matrix* h = create_matrix(1, 4); assert(!get_row_vector(0,a,h)); assert(!get_row_vector(5,a,h)); assert(get_row_vector(1,a,h)); assert(compare_matrices(e,h)); //tests mulitply_matrices assert(multiply_matrices(a,a,b)); value temp_f[16]={8478,5478,14319,17130, 6066,6760,15418,16792, 6206,5328,14431,15096, 6052,5047,7652,14129.00}; assert(insert_array(temp_f,d)); assert(compare_matrices(b,d)); assert(!multiply_matrices(a,h,b)); assert(!multiply_matrices(a,a,h)); //tests transpose_matrix value temp_g[16]={18,41,14,51, 60,24,30,13, 57,99,97,19, 96,58,66,85}; assert(insert_array(temp_g,d)); assert(transpose_matrix(a,b)); assert(compare_matrices(b,d)); assert(!transpose_matrix(e,b)); assert(!transpose_matrix(a,e)); //tests multiply_matrix_with_scalar value temp_h[16] = { 36, 120, 114, 192, 82, 48, 198, 116, 28, 60, 194, 132, 102, 26, 38, 170 }; assert(insert_array(temp_h,b)); multiply_matrix_with_scalar(2,a); assert(compare_matrices(a,b)); //test get_sub_matrix matrix* i=create_matrix(2,2); assert(insert_array(temp_a,a)); assert(get_sub_matrix(1,2,1,2,a,i)); matrix* j=create_matrix(2,2); value temp_i[4] = { 18, 60, 41, 24}; assert(insert_array(temp_i,j)); assert(compare_matrices(j,i)); value temp_j[4] = { 97, 66, 19, 85}; assert(insert_array(temp_j,j)); assert(get_sub_matrix(3,4,3,4,a,i)); assert(compare_matrices(j,i)); assert(!get_sub_matrix(2,4,3,4,a,i)); assert(!get_sub_matrix(3,4,2,4,a,i)); assert(!get_sub_matrix(4,5,4,5,a,i)); assert(!get_sub_matrix(0,1,0,1,a,i)); //test insert_row_vector assert(insert_array(temp_a,a)); value temp_k[16] = { 18, 60, 57, 96, 18, 60, 57, 96, 14, 30, 97, 66, 51, 13, 19, 85 }; assert(insert_array(temp_k,b)); assert(insert_array(temp_d,e)); assert(insert_row_vector(2,e,a)); assert(compare_matrices(a,b)); end = clock(); time_spent = (double)(end - begin) / CLOCKS_PER_SEC; printf("time taken was: %f \n",time_spent); free_matrix(a); free_matrix(b); free_matrix(d); free_matrix(e); free_matrix(f); free_matrix(g); free_matrix(h); free_matrix(i); free_matrix(j); return 0; }
int main(int argc, char* argv[]) { info("Desired number of eigenvalues: %d.", NUMBER_OF_EIGENVALUES); // Load the mesh. info("Loading and refining mesh..."); Mesh mesh; H3DReader mloader; mloader.load("hexahedron.mesh3d", &mesh); // Perform initial mesh refinements (optional). for (int i = 0; i < INIT_REF_NUM; i++) mesh.refine_all_elements(H3D_H3D_H3D_REFT_HEX_XYZ); // Create an H1 space with default shapeset. H1Space space(&mesh, bc_types, essential_bc_values, Ord3(P_INIT_X, P_INIT_Y, P_INIT_Z)); int ndof = Space::get_num_dofs(&space); info("ndof: %d.", ndof); // Initialize the weak formulation for the left hand side, i.e., H. info("Initializing weak form..."); WeakForm wf_left, wf_right; wf_left.add_matrix_form(bilinear_form_left, bilinear_form_left_ord, HERMES_SYM, HERMES_ANY ); wf_right.add_matrix_form(callback(bilinear_form_right), HERMES_SYM, HERMES_ANY ); // Initialize matrices and matrix solver. SparseMatrix* matrix_left = create_matrix(matrix_solver); SparseMatrix* matrix_right = create_matrix(matrix_solver); Solver* solver = create_linear_solver(matrix_solver, matrix_left); // Assemble the matrices. info("Assembling matrices..."); bool is_linear = true; DiscreteProblem dp_left(&wf_left, &space, is_linear); dp_left.assemble(matrix_left); DiscreteProblem dp_right(&wf_right, &space, is_linear); dp_right.assemble(matrix_right); // Write matrix_left in MatrixMarket format. write_matrix_mm("mat_left.mtx", matrix_left); // Write matrix_right in MatrixMarket format. write_matrix_mm("mat_right.mtx", matrix_right); // Calling Python eigensolver. Solution will be written to "eivecs.dat". info("Using eigensolver..."); char call_cmd[255]; sprintf(call_cmd, "python solveGenEigenFromMtx.py mat_left.mtx mat_right.mtx %g %d %g %d", TARGET_VALUE, NUMBER_OF_EIGENVALUES, TOL, MAX_ITER); system(call_cmd); // Initializing solution vector, solution and ScalarView. info("Initializing solution vector..."); double* coeff_vec = new double[ndof]; Solution sln(space.get_mesh()); // Reading solution vectors from file and visualizing. info("Reading solution vectors from file and saving as solutions in paraview format..."); FILE *file = fopen("eivecs.dat", "r"); char line [64]; // Maximum line size. fgets(line, sizeof line, file); // ndof int n = atoi(line); if (n != ndof) error("Mismatched ndof in the eigensolver output file."); fgets(line, sizeof line, file); // Number of eigenvectors in the file. int neig = atoi(line); if (neig != NUMBER_OF_EIGENVALUES) error("Mismatched number of eigenvectors in the eigensolver output file."); for (int ieig = 0; ieig < neig; ieig++) { // Get next eigenvector from the file. for (int i = 0; i < ndof; i++) { fgets(line, sizeof line, file); coeff_vec[i] = atof(line); } // Convert coefficient vector into a Solution. Solution::vector_to_solution(coeff_vec, &space, &sln); out_fn_vtk(&sln, "sln", ieig ); } fclose(file); delete [] coeff_vec; return 0; };
int main(int argc, char **args) { // Test variable. int success_test = 1; if (argc < 2) error("Not enough parameters"); // Load the mesh. Mesh mesh; H3DReader mloader; if (!mloader.load(args[1], &mesh)) error("Loading mesh file '%s'\n", args[1]); // Initialize the space 1. Ord3 o1(2, 2, 2); H1Space space1(&mesh, bc_types, essential_bc_values, o1); // Initialize the space 2. Ord3 o2(4, 4, 4); H1Space space2(&mesh, bc_types, essential_bc_values, o2); // Initialize the weak formulation. WeakForm wf(2); wf.add_matrix_form(0, 0, bilinear_form_1<double, scalar>, bilinear_form_1<Ord, Ord>, HERMES_SYM); wf.add_vector_form(0, linear_form_1<double, scalar>, linear_form_1<Ord, Ord>); wf.add_matrix_form(1, 1, bilinear_form_2<double, scalar>, bilinear_form_2<Ord, Ord>, HERMES_SYM); wf.add_vector_form(1, linear_form_2<double, scalar>, linear_form_2<Ord, Ord>); // Initialize the FE problem. bool is_linear = true; DiscreteProblem dp(&wf, Tuple<Space *>(&space1, &space2), 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(Tuple<Space *>(&space1, &space2))); dp.assemble(matrix, rhs); // Solve the linear system. If successful, obtain the solution. info("Solving."); Solution sln1(&mesh); Solution sln2(&mesh); if(solver->solve()) Solution::vector_to_solutions(solver->get_solution(), Tuple<Space *>(&space1, &space2), Tuple<Solution *>(&sln1, &sln2)); else error ("Matrix solver failed.\n"); ExactSolution ex_sln1(&mesh, exact_sln_fn_1); ExactSolution ex_sln2(&mesh, exact_sln_fn_2); // Calculate exact error. info("Calculating exact error."); Adapt *adaptivity = new Adapt(Tuple<Space *>(&space1, &space2), Tuple<ProjNormType>(HERMES_H1_NORM, HERMES_H1_NORM)); bool solutions_for_adapt = false; double err_exact = adaptivity->calc_err_exact(Tuple<Solution *>(&sln1, &sln2), Tuple<Solution *>(&ex_sln1, &ex_sln2), 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; } }
int main(int argc, char **args) { // Test variable. int success_test = 1; if (argc < 3) 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. int o; sscanf(args[2], "%d", &o); Ord3 order(o, o, o); HcurlSpace space(&mesh, bc_types, NULL, order); // Initialize the weak formulation. WeakForm wf; wf.add_matrix_form(callback(bilinear_form), HERMES_SYM); wf.add_vector_form(callback(linear_form)); // 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). } // 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_HCURL_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; if (success_test) { info("Success!"); return ERR_SUCCESS; } else { info("Failure!"); return ERR_FAILURE; } }
int main(int argc, char* argv[]) { // Instantiate a class with global functions. Hermes2D hermes2d; // Time measurement. TimePeriod cpu_time; cpu_time.tick(); // Load the mesh. Mesh mesh; H2DReader mloader; mloader.load("domain.mesh", &mesh); // Perform initial mesh refinements. for (int i=0; i < INIT_REF_NUM; i++) mesh.refine_all_elements(); // Initialize boundary conditions CustomEssentialBCNonConst bc_essential("Boundary horizontal"); EssentialBCs bcs(&bc_essential); // Create an H1 space with default shapeset. H1Space space(&mesh, &bcs, P_INIT); int ndof = space.get_num_dofs(); info("ndof = %d", ndof); // Initialize the weak formulation. CustomWeakFormGeneral wf("Boundary horizontal"); // Initialize the FE problem. DiscreteProblem dp(&wf, &space); SparseMatrix* matrix = create_matrix(matrix_solver); Vector* rhs = create_vector(matrix_solver); Solver* solver = create_linear_solver(matrix_solver, matrix, rhs); if (matrix_solver == SOLVER_AZTECOO) { ((AztecOOSolver*) solver)->set_solver(iterative_method); ((AztecOOSolver*) solver)->set_precond(preconditioner); // Using default iteration parameters (see solver/aztecoo.h). } // Initial coefficient vector for the Newton's method. scalar* coeff_vec = new scalar[ndof]; memset(coeff_vec, 0, ndof*sizeof(scalar)); // Perform Newton's iteration. if (!hermes2d.solve_newton(coeff_vec, &dp, solver, matrix, rhs)) error("Newton's iteration failed."); // Translate the resulting coefficient vector into the Solution sln. Solution sln; Solution::vector_to_solution(coeff_vec, &space, &sln); // Time measurement. cpu_time.tick(); // Clean up. delete solver; delete matrix; delete rhs; delete [] coeff_vec; // View the solution and mesh. ScalarView sview("Solution", new WinGeom(0, 0, 440, 350)); sview.show(&sln); OrderView oview("Polynomial orders", new WinGeom(450, 0, 400, 350)); oview.show(&space); // Skip visualization time. cpu_time.tick(HERMES_SKIP); // Print timing information. 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 **args) { // Time measurement. TimePeriod cpu_time; cpu_time.tick(); // Load the mesh. Mesh mesh; ExodusIIReader mloader; mloader.load("brick_with_holes_tet.e", &mesh); // Create H1 space with default shapeset for x-displacement component. H1Space xdisp(&mesh, bc_types_x, essential_bc_values, Ord3(P_INIT)); // Create H1 space with default shapeset for y-displacement component. H1Space ydisp(&mesh, bc_types_y, essential_bc_values, Ord3(P_INIT)); // Create H1 space with default shapeset for z-displacement component. H1Space zdisp(&mesh, bc_types_z, essential_bc_values, Ord3(P_INIT)); // Initialize weak formulation. WeakForm wf(3); 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(0, 2, callback(bilinear_form_0_2), HERMES_SYM); wf.add_vector_form_surf(0, callback(surf_linear_form_x), bdy_force); wf.add_matrix_form(1, 1, callback(bilinear_form_1_1), HERMES_SYM); wf.add_matrix_form(1, 2, callback(bilinear_form_1_2), HERMES_SYM); wf.add_vector_form_surf(1, callback(surf_linear_form_y), bdy_force); wf.add_matrix_form(2, 2, callback(bilinear_form_2_2), HERMES_SYM); wf.add_vector_form_surf(2, callback(surf_linear_form_z), bdy_force); // Initialize discrete problem. bool is_linear = true; DiscreteProblem dp(&wf, Hermes::vector<Space *>(&xdisp, &ydisp, &zdisp), 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). } // Assemble stiffness matrix and load vector. info("Assembling the linear problem (ndof: %d).", Space::get_num_dofs(Hermes::vector<Space *>(&xdisp, &ydisp, &zdisp))); dp.assemble(matrix, rhs); // Solve the linear system. If successful, obtain the solution. info("Solving the linear problem."); Solution xsln(xdisp.get_mesh()); Solution ysln(ydisp.get_mesh()); Solution zsln(zdisp.get_mesh()); if(solver->solve()) Solution::vector_to_solutions(solver->get_solution(), Hermes::vector<Space *>(&xdisp, &ydisp, &zdisp), Hermes::vector<Solution *>(&xsln, &ysln, &zsln)); else error ("Matrix solver failed.\n"); // Output all components of the solution. if (solution_output) out_fn_vtk(&xsln, &ysln, &zsln, "sln"); // Time measurement. cpu_time.tick(); // Print timing information. info("Solutions saved. Total running time: %g s.", cpu_time.accumulated()); // Clean up. delete matrix; delete rhs; delete solver; return 0; }
int main(int argc, char **args) { // Time measurement. TimePeriod cpu_time; cpu_time.tick(); // Load the mesh. Mesh mesh; H3DReader mloader; mloader.load("lshape_hex.mesh3d", &mesh); // Perform initial mesh refinement. for (int i=0; i < INIT_REF_NUM; i++) mesh.refine_all_elements(H3D_H3D_H3D_REFT_HEX_XYZ); // Create an Hcurl space with default shapeset. HcurlSpace space(&mesh, bc_types, essential_bc_values, Ord3(P_INIT_X, P_INIT_Y, P_INIT_Z)); // Initialize weak formulation. WeakForm wf; wf.add_matrix_form(biform<double, scalar>, biform<Ord, Ord>, HERMES_SYM); wf.add_matrix_form_surf(biform_surf, biform_surf_ord); wf.add_vector_form_surf(liform_surf, liform_surf_ord); // Initialize discrete 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 stiffness matrix and load vector. info("Assembling the linear problem (ndof: %d).", Space::get_num_dofs(&space)); dp.assemble(matrix, rhs); // Solve the linear system. If successful, obtain the solution. info("Solving the linear problem."); Solution sln(space.get_mesh()); if(solver->solve()) Solution::vector_to_solution(solver->get_solution(), &space, &sln); else error ("Matrix solver failed.\n"); // Output solution and mesh with polynomial orders. if (solution_output) { out_fn_vtk(&sln, "sln"); out_orders_vtk(&space, "order"); } // Time measurement. cpu_time.tick(); // Print timing information. info("Solution and mesh with polynomial orders saved. Total running time: %g s", cpu_time.accumulated()); // Clean up. delete matrix; delete rhs; delete solver; // Properly terminate the solver in the case of SOLVER_PETSC or SOLVER_MUMPS. finalize_solution_environment(matrix_solver); return 0; }
int main(int argc, char* argv[]) { // Load the mesh. Mesh mesh; H2DReader mloader; mloader.load("ffs.mesh", &mesh); // Perform initial mesh refinements. for (int i = 0; i < INIT_REF_NUM; i++) mesh.refine_all_elements(); // Boundary condition types; BCTypes bc_types; // Initialize boundary condition types and spaces with default shapesets. bc_types.add_bc_neumann(Hermes::vector<int>(BDY_SOLID_WALL, BDY_INLET_OUTLET)); 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; 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. // Unnecessary for FVM. if(P_INIT.order_h > 0 || P_INIT.order_v > 0) { wf.add_vector_form(0, callback(linear_form_0_1), HERMES_ANY, Hermes::vector<MeshFunction*>(&prev_rho_v_x)); wf.add_vector_form(1, callback(linear_form_1_0_first_flux), HERMES_ANY, Hermes::vector<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::vector<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::vector<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::vector<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::vector<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::vector<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::vector<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::vector<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::vector<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::vector<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::vector<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::vector<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::vector<MeshFunction*>(&prev_rho_v_y)); wf.add_vector_form(1, callback(linear_form_1_0_second_flux), HERMES_ANY, Hermes::vector<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::vector<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::vector<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::vector<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::vector<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::vector<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::vector<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::vector<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::vector<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::vector<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::vector<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::vector<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e)); } 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); // Surface linear forms - inner edges coming from the DG formulation. wf.add_vector_form_surf(0, linear_form_interface_0, linear_form_order, H2D_DG_INNER_EDGE, Hermes::vector<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::vector<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::vector<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::vector<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e)); // Surface linear forms - inlet / outlet edges. wf.add_vector_form_surf(0, bdy_flux_inlet_outlet_comp_0, linear_form_order, BDY_INLET_OUTLET, Hermes::vector<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::vector<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::vector<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::vector<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e)); // Surface linear forms - Solid wall edges. wf.add_vector_form_surf(0, bdy_flux_solid_wall_comp_0, linear_form_order, BDY_SOLID_WALL, Hermes::vector<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::vector<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::vector<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::vector<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e)); // Initialize the FE problem. bool is_linear = true; DiscreteProblem dp(&wf, Hermes::vector<Space*>(&space_rho, &space_rho_v_x, &space_rho_v_y, &space_e), is_linear); // If the FE problem is in fact a FV problem. if(P_INIT.order_h == 0 && P_INIT.order_v == 0) dp.set_fvm(); // Filters for visualization of pressure and the two components of velocity. SimpleFilter pressure(calc_pressure_func, Hermes::vector<MeshFunction*>(&sln_rho, &sln_rho_v_x, &sln_rho_v_y, &sln_e)); SimpleFilter u(calc_u_func, Hermes::vector<MeshFunction*>(&sln_rho, &sln_rho_v_x, &sln_rho_v_y, &sln_e)); SimpleFilter w(calc_w_func, Hermes::vector<MeshFunction*>(&sln_rho, &sln_rho_v_x, &sln_rho_v_y, &sln_e)); //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; // 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); // Output of the approximate time derivative. 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++; bool rhs_only = (iteration == 1 ? false : true); // Assemble stiffness matrix and rhs or just rhs. if (rhs_only == false) info("Assembling the stiffness matrix and right-hand side vector."); else info("Assembling the right-hand side vector (only)."); dp.assemble(matrix, rhs, rhs_only); // Solve the matrix problem. info("Solving the matrix problem."); if(solver->solve()) Solution::vector_to_solutions(solver->get_solution(), Hermes::vector<Space *>(&space_rho, &space_rho_v_x, &space_rho_v_y, &space_e), Hermes::vector<Solution *>(&sln_rho, &sln_rho_v_x, &sln_rho_v_y, &sln_e)); else error ("Matrix solver failed.\n"); // Approximate the time derivative of the solution. if(CALC_TIME_DER) { Adapt *adapt_for_time_der_calc = new Adapt(Hermes::vector<Space *>(&space_rho, &space_rho_v_x, &space_rho_v_y, &space_e)); bool solutions_for_adapt = false; double difference = adapt_for_time_der_calc->calc_err_est(Hermes::vector<Solution *>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e), Hermes::vector<Solution *>(&sln_rho, &sln_rho_v_x, &sln_rho_v_y, &sln_e), (Hermes::vector<double>*) NULL, solutions_for_adapt, HERMES_TOTAL_ERROR_ABS | HERMES_ELEMENT_ERROR_ABS) / TAU; delete adapt_for_time_der_calc; // Info about the approximate time derivative. if(iteration > 1) { info("Approximate the norm time derivative : %g.", difference); time_der_out << iteration << '\t' << difference << std::endl; } } // Determine the time step according to the CFL condition. // Only mean values on an element of each solution component are taken into account. double *solution_vector = solver->get_solution(); 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; // Copy the solutions into the previous time level ones. prev_rho.copy(&sln_rho); prev_rho_v_x.copy(&sln_rho_v_x); prev_rho_v_y.copy(&sln_rho_v_y); prev_e.copy(&sln_e); // Visualization. /* pressure.reinit(); u.reinit(); w.reinit(); sview.show(&pressure); vview.show(&u, &w); */ s1.show(&sln_rho); s2.show(&sln_rho_v_x); s3.show(&sln_rho_v_y); s4.show(&sln_e); } s1.close(); s2.close(); s3.close(); s4.close(); time_der_out.close(); return 0; }
int main(int argc, char* argv[]) { // Load the mesh file. Mesh mesh; H2DReader mloader; mloader.load("sample.mesh", &mesh); // Enter boundary markers. BCTypes bc_types; bc_types.add_bc_dirichlet(BDY_1); bc_types.add_bc_neumann(Hermes::Tuple<int>(BDY_2, BDY_3, BDY_4, BDY_5)); // Enter Dirichlet boundary values; BCValues bc_values; bc_values.add_zero(BDY_1); // Create x- and y- displacement space using the default H1 shapeset. H1Space u_space(&mesh, &bc_types, &bc_values, P_INIT); H1Space v_space(&mesh, &bc_types, &bc_values, P_INIT); info("ndof = %d.", Space::get_num_dofs(Hermes::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), BDY_3); wf.add_vector_form_surf(1, callback(linear_form_surf_1), BDY_3); // Testing n_dof and correctness of solution vector // for p_init = 1, 2, ..., 10 int success = 1; Solution xsln, ysln; for (int p_init = 1; p_init <= 10; p_init++) { printf("********* p_init = %d *********\n", p_init); u_space.set_uniform_order(p_init); v_space.set_uniform_order(p_init); // Initialize the FE problem. bool is_linear = true; DiscreteProblem dp(&wf, Hermes::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(), Hermes::Tuple<Space *>(&u_space, &v_space), Hermes::Tuple<Solution *>(&u_sln, &v_sln)); else error ("Matrix solver failed.\n"); int ndof = Space::get_num_dofs(Hermes::Tuple<Space *>(&u_space, &v_space)); printf("ndof = %d\n", ndof); double sum = 0; for (int i=0; i < ndof; i++) sum += solver->get_solution()[i]; printf("coefficient sum = %g\n", sum); // Actual test. The values of 'sum' depend on the // current shapeset. If you change the shapeset, // you need to correct these numbers. if (p_init == 1 && fabs(sum - 3.50185e-06) > 1e-3) success = 0; if (p_init == 2 && fabs(sum - 4.34916e-06) > 1e-3) success = 0; if (p_init == 3 && fabs(sum - 4.60553e-06) > 1e-3) success = 0; if (p_init == 4 && fabs(sum - 4.65616e-06) > 1e-3) success = 0; if (p_init == 5 && fabs(sum - 4.62893e-06) > 1e-3) success = 0; if (p_init == 6 && fabs(sum - 4.64336e-06) > 1e-3) success = 0; if (p_init == 7 && fabs(sum - 4.63724e-06) > 1e-3) success = 0; if (p_init == 8 && fabs(sum - 4.64491e-06) > 1e-3) success = 0; if (p_init == 9 && fabs(sum - 4.64582e-06) > 1e-3) success = 0; if (p_init == 10 && fabs(sum - 4.65028e-06) > 1e-3) success = 0; } if (success == 1) { printf("Success!\n"); return ERR_SUCCESS; } else { printf("Failure!\n"); return ERR_FAILURE; } }
matrix_t *identity_matrix(uint8_t n) { matrix_t *matrix = create_matrix(n, n); for (int i = 0; i < n; ++i) matrix->data[i][i] = 1.0; return matrix; }
int main(int argc, char **args) { // Test variable. int success_test = 1; if (argc < 2) 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. #if defined NONLIN1 Ord3 order(1, 1, 1); #else Ord3 order(2, 2, 2); #endif H1Space space(&mesh, bc_types, essential_bc_values, order); #if defined NONLIN2 // Do L2 projection of zero function. WeakForm proj_wf; proj_wf.add_matrix_form(biproj_form<double, scalar>, biproj_form<Ord, Ord>, HERMES_SYM); proj_wf.add_vector_form(liproj_form<double, scalar>, liproj_form<Ord, Ord>); bool is_linear = true; DiscreteProblem lp(&proj_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_proj = create_linear_solver(matrix_solver, matrix, rhs); // Initialize the preconditioner in the case of SOLVER_AZTECOO. if (matrix_solver == SOLVER_AZTECOO) { ((AztecOOSolver*) solver_proj)->set_solver(iterative_method); ((AztecOOSolver*) solver_proj)->set_precond(preconditioner); // Using default iteration parameters (see solver/aztecoo.h). } // Assemble the linear problem. info("Assembling (ndof: %d).", Space::get_num_dofs(&space)); lp.assemble(matrix, rhs); // Solve the linear system. info("Solving."); if(!solver_proj->solve()) error ("Matrix solver failed.\n"); delete matrix; delete rhs; #endif // Initialize the weak formulation. WeakForm wf(1); wf.add_matrix_form(0, 0, jacobi_form<double, scalar>, jacobi_form<Ord, Ord>, HERMES_NONSYM); wf.add_vector_form(0, resid_form<double, scalar>, resid_form<Ord, Ord>); // Initialize the FE problem. #if defined NONLIN2 is_linear = false; #else bool is_linear = false; #endif DiscreteProblem dp(&wf, &space, is_linear); NoxSolver solver(&dp); #if defined NONLIN2 solver.set_init_sln(solver_proj->get_solution()); delete solver_proj; #endif solver.set_conv_iters(10); info("Solving."); Solution sln(&mesh); if(solver.solve()) Solution::vector_to_solution(solver.get_solution(), &space, &sln); else error ("Matrix solver failed.\n"); Solution ex_sln(&mesh); #ifdef NONLIN1 ex_sln.set_const(100.0); #else ex_sln.set_exact(exact_solution); #endif // 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; if (success_test) { info("Success!"); return ERR_SUCCESS; } else { info("Failure!"); return ERR_FAILURE; } }
int main(int argc, char* argv[]) { // Load the mesh. Mesh basemesh; H2DReader mloader; mloader.load("GAMM-channel.mesh", &basemesh); // Initialize the meshes. Mesh mesh_flow, mesh_concentration; mesh_flow.copy(&basemesh); mesh_concentration.copy(&basemesh); for(unsigned int i = 0; i < INIT_REF_NUM_CONCENTRATION; i++) mesh_concentration.refine_all_elements(); mesh_concentration.refine_towards_boundary(BDY_DIRICHLET_CONCENTRATION, INIT_REF_NUM_CONCENTRATION_BDY); mesh_flow.refine_towards_boundary(BDY_DIRICHLET_CONCENTRATION, INIT_REF_NUM_CONCENTRATION_BDY); for(unsigned int i = 0; i < INIT_REF_NUM_FLOW; i++) mesh_flow.refine_all_elements(); // Initialize boundary condition types and spaces with default shapesets. // For the concentration. EssentialBCs bcs_concentration; bcs_concentration.add_boundary_condition(new ConcentrationTimedepEssentialBC(BDY_DIRICHLET_CONCENTRATION, CONCENTRATION_EXT, CONCENTRATION_EXT_STARTUP_TIME)); bcs_concentration.add_boundary_condition(new ConcentrationTimedepEssentialBC(BDY_SOLID_WALL_TOP, 0.0, CONCENTRATION_EXT_STARTUP_TIME)); L2Space space_rho(&mesh_flow, P_INIT_FLOW); L2Space space_rho_v_x(&mesh_flow, P_INIT_FLOW); L2Space space_rho_v_y(&mesh_flow, P_INIT_FLOW); L2Space space_e(&mesh_flow, P_INIT_FLOW); // Space for concentration. H1Space space_c(&mesh_concentration, &bcs_concentration, P_INIT_CONCENTRATION); int ndof = Space::get_num_dofs(Hermes::vector<Space*>(&space_rho, &space_rho_v_x, &space_rho_v_y, &space_e, &space_c)); info("ndof: %d", ndof); // Initialize solutions, set initial conditions. InitialSolutionEulerDensity prev_rho(&mesh_flow, RHO_EXT); InitialSolutionEulerDensityVelX prev_rho_v_x(&mesh_flow, RHO_EXT * V1_EXT); InitialSolutionEulerDensityVelY prev_rho_v_y(&mesh_flow, RHO_EXT * V2_EXT); InitialSolutionEulerDensityEnergy prev_e(&mesh_flow, QuantityCalculator::calc_energy(RHO_EXT, RHO_EXT * V1_EXT, RHO_EXT * V2_EXT, P_EXT, KAPPA)); InitialSolutionConcentration prev_c(&mesh_concentration, 0.0); // Numerical flux. OsherSolomonNumericalFlux num_flux(KAPPA); // Initialize weak formulation. EulerEquationsWeakFormSemiImplicitCoupled wf(&num_flux, KAPPA, RHO_EXT, V1_EXT, V2_EXT, P_EXT, BDY_SOLID_WALL_BOTTOM, BDY_SOLID_WALL_TOP, BDY_INLET, BDY_OUTLET, BDY_NATURAL_CONCENTRATION, &prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e, &prev_c, EPSILON, (P_INIT_FLOW == 0)); wf.set_time_step(time_step); // Initialize the FE problem. DiscreteProblem dp(&wf, Hermes::vector<Space*>(&space_rho, &space_rho_v_x, &space_rho_v_y, &space_e, &space_c)); // If the FE problem is in fact a FV problem. //if(P_INIT == 0) dp.set_fvm(); // Filters for visualization of Mach number, pressure and entropy. MachNumberFilter Mach_number(Hermes::vector<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e), KAPPA); PressureFilter pressure(Hermes::vector<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e), KAPPA); EntropyFilter entropy(Hermes::vector<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e), KAPPA, RHO_EXT, P_EXT); /* ScalarView pressure_view("Pressure", new WinGeom(0, 0, 600, 300)); ScalarView Mach_number_view("Mach number", new WinGeom(700, 0, 600, 300)); ScalarView entropy_production_view("Entropy estimate", new WinGeom(0, 400, 600, 300)); ScalarView s5("Concentration", new WinGeom(700, 400, 600, 300)); */ ScalarView s1("1", new WinGeom(0, 0, 600, 300)); ScalarView s2("2", new WinGeom(700, 0, 600, 300)); ScalarView s3("3", new WinGeom(0, 400, 600, 300)); ScalarView s4("4", new WinGeom(700, 400, 600, 300)); ScalarView s5("Concentration", new WinGeom(350, 200, 600, 300)); // 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); // Set up CFL calculation class. CFLCalculation CFL(CFL_NUMBER, KAPPA); // Set up Advection-Diffusion-Equation stability calculation class. ADEStabilityCalculation ADES(ADVECTION_STABILITY_CONSTANT, DIFFUSION_STABILITY_CONSTANT, EPSILON); int iteration = 0; double t = 0; for(t = 0.0; t < 100.0; t += time_step) { info("---- Time step %d, time %3.5f.", iteration++, t); // Set the current time step. wf.set_time_step(time_step); Space::update_essential_bc_values(&space_c, t); // Assemble stiffness matrix and rhs. info("Assembling the stiffness matrix and right-hand side vector."); dp.assemble(matrix, rhs); // Solve the matrix problem. info("Solving the matrix problem."); scalar* solution_vector = NULL; if(solver->solve()) { solution_vector = solver->get_solution(); Solution::vector_to_solutions(solution_vector, Hermes::vector<Space *>(&space_rho, &space_rho_v_x, &space_rho_v_y, &space_e, &space_c), Hermes::vector<Solution *>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e, &prev_c)); } else error ("Matrix solver failed.\n"); if(SHOCK_CAPTURING) { DiscontinuityDetector discontinuity_detector(Hermes::vector<Space *>(&space_rho, &space_rho_v_x, &space_rho_v_y, &space_e), Hermes::vector<Solution *>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e)); std::set<int> discontinuous_elements = discontinuity_detector.get_discontinuous_element_ids(DISCONTINUITY_DETECTOR_PARAM); FluxLimiter flux_limiter(solution_vector, Hermes::vector<Space *>(&space_rho, &space_rho_v_x, &space_rho_v_y, &space_e), Hermes::vector<Solution *>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e)); flux_limiter.limit_according_to_detector(discontinuous_elements); } util_time_step = time_step; CFL.calculate_semi_implicit(Hermes::vector<Solution *>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e), &mesh_flow, util_time_step); time_step = util_time_step; ADES.calculate(Hermes::vector<Solution *>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y), &mesh_concentration, util_time_step); if(util_time_step < time_step) time_step = util_time_step; // Visualization. if((iteration - 1) % EVERY_NTH_STEP == 0) { // Hermes visualization. if(HERMES_VISUALIZATION) { /* Mach_number.reinit(); pressure.reinit(); entropy.reinit(); pressure_view.show(&pressure); entropy_production_view.show(&entropy); Mach_number_view.show(&Mach_number); s5.show(&prev_c); */ s1.show(&prev_rho); s2.show(&prev_rho_v_x); s3.show(&prev_rho_v_y); s4.show(&prev_e); s5.show(&prev_c); /* s1.save_numbered_screenshot("density%i.bmp", iteration, true); s2.save_numbered_screenshot("density_v_x%i.bmp", iteration, true); s3.save_numbered_screenshot("density_v_y%i.bmp", iteration, true); s4.save_numbered_screenshot("energy%i.bmp", iteration, true); s5.save_numbered_screenshot("concentration%i.bmp", iteration, true); */ //s5.wait_for_close(); } // Output solution in VTK format. if(VTK_VISUALIZATION) { pressure.reinit(); Mach_number.reinit(); Linearizer lin; char filename[40]; sprintf(filename, "pressure-%i.vtk", iteration - 1); lin.save_solution_vtk(&pressure, filename, "Pressure", false); sprintf(filename, "pressure-3D-%i.vtk", iteration - 1); lin.save_solution_vtk(&pressure, filename, "Pressure", true); sprintf(filename, "Mach number-%i.vtk", iteration - 1); lin.save_solution_vtk(&Mach_number, filename, "MachNumber", false); sprintf(filename, "Mach number-3D-%i.vtk", iteration - 1); lin.save_solution_vtk(&Mach_number, filename, "MachNumber", true); sprintf(filename, "Concentration-%i.vtk", iteration - 1); lin.save_solution_vtk(&prev_c, filename, "Concentration", true); sprintf(filename, "Concentration-3D-%i.vtk", iteration - 1); lin.save_solution_vtk(&prev_c, filename, "Concentration", true); } } } /* pressure_view.close(); entropy_production_view.close(); Mach_number_view.close(); s5.close(); */ s1.close(); s2.close(); s3.close(); s4.close(); s5.close(); return 0; }
int main(int argc, char* argv[]) { // Load the mesh. Mesh mesh; H2DReader mloader; mloader.load("cathedral.mesh", &mesh); // Perform initial mesh refinements. for(int i = 0; i < INIT_REF_NUM; i++) mesh.refine_all_elements(); mesh.refine_towards_boundary(BDY_AIR, INIT_REF_NUM_BDY); // Enter boundary markers. BCTypes bc_types; bc_types.add_bc_dirichlet(BDY_GROUND); bc_types.add_bc_newton(BDY_AIR); // Enter Dirichlet boundary values. BCValues bc_values; bc_values.add_const(BDY_GROUND, T_INIT); // Initialize 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 solution. Solution tsln; // Set the initial condition. tsln.set_const(&mesh, T_INIT); // Initialize weak formulation. WeakForm wf; wf.add_matrix_form(bilinear_form<double, double>, bilinear_form<Ord, Ord>); wf.add_matrix_form_surf(bilinear_form_surf<double, double>, bilinear_form_surf<Ord, Ord>, BDY_AIR); wf.add_vector_form(linear_form<double, double>, linear_form<Ord, Ord>, HERMES_ANY, &tsln); wf.add_vector_form_surf(linear_form_surf<double, double>, linear_form_surf<Ord, Ord>, BDY_AIR); // 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 views. ScalarView Tview("Temperature", new WinGeom(0, 0, 450, 600)); char title[100]; sprintf(title, "Time %3.5f, exterior temperature %3.5f", TIME, temp_ext(TIME)); Tview.set_min_max_range(0,20); Tview.set_title(title); Tview.fix_scale_width(3); // Time stepping: int nsteps = (int)(FINAL_TIME/TAU + 0.5); bool rhs_only = false; for(int ts = 1; ts <= nsteps; ts++) { info("---- Time step %d, time %3.5f, ext_temp %g", ts, TIME, temp_ext(TIME)); // First time assemble both the stiffness matrix and right-hand side vector, // then just the right-hand side vector. if (rhs_only == false) info("Assembling the stiffness matrix and right-hand side vector."); else info("Assembling the right-hand side vector (only)."); dp.assemble(matrix, rhs, rhs_only); rhs_only = true; // 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, &tsln); else error ("Matrix solver failed.\n"); // Update the time variable. TIME += TAU; // Visualize the solution. sprintf(title, "Time %3.2f, exterior temperature %3.5f", TIME, temp_ext(TIME)); Tview.set_title(title); Tview.show(&tsln); } // Wait for the view to be closed. View::wait(); // Clean up. delete solver; delete matrix; delete rhs; return 0; }
int main(int argc, char **args) { // Test variable. int success_test = 1; if (argc < 3) error("Not enough parameters."); if (strcmp(args[1], "h1") != 0 && strcmp(args[1], "h1-ipol")) error("Unknown type of the projection."); // Load the mesh. Mesh mesh; H3DReader mloader; if (!mloader.load(args[2], &mesh)) error("Loading mesh file '%s'.", args[1]); // Refine the mesh. mesh.refine_all_elements(H3D_H3D_H3D_REFT_HEX_XYZ); // Initialize the space. #if defined X2_Y2_Z2 Ord3 order(2, 2, 2); #elif defined X3_Y3_Z3 Ord3 order(3, 3, 3); #elif defined XN_YM_ZO Ord3 order(2, 3, 4); #endif H1Space space(&mesh, bc_types, essential_bc_values, order); // Initialize the weak formulation. WeakForm wf; wf.add_matrix_form(bilinear_form<double, scalar>, bilinear_form<Ord, Ord>, HERMES_SYM, HERMES_ANY); wf.add_vector_form(linear_form<double, scalar>, linear_form<Ord, Ord>, HERMES_ANY); // 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. dp.assemble(matrix, rhs); // Solve the linear system. If successful, obtain the solution. info("Solving the linear problem."); Solution sln(&mesh); if(solver->solve()) Solution::vector_to_solution(solver->get_solution(), &space, &sln); else { info("Matrix solver failed."); success_test = 0; } unsigned int ne = mesh.get_num_base_elements(); for (unsigned int idx = mesh.elements.first(); idx <= ne; idx = mesh.elements.next(idx)) { Element *e = mesh.elements[idx]; Ord3 order(4, 4, 4); double error; Projection *proj; if (strcmp(args[1], "h1") == 0) proj = new H1Projection(&sln, e, space.get_shapeset()); else if (strcmp(args[1], "h1-ipol") == 0) proj = new H1ProjectionIpol(&sln, e, space.get_shapeset()); else success_test = 0; error = 0.0; error += proj->get_error(H3D_REFT_HEX_NONE, -1, order); error = sqrt(error); if (error > EPS) // Calculated solution is not precise enough. success_test = 0; // error = 0.0; error += proj->get_error(H3D_REFT_HEX_X, 20, order); error += proj->get_error(H3D_REFT_HEX_X, 21, order); error = sqrt(error); if (error > EPS) // Calculated solution is not precise enough. success_test = 0; // error = 0.0; error += proj->get_error(H3D_REFT_HEX_Y, 22, order); error += proj->get_error(H3D_REFT_HEX_Y, 23, order); error = sqrt(error); if (error > EPS) // Calculated solution is not precise enough. success_test = 0; // error = 0.0; error += proj->get_error(H3D_REFT_HEX_Z, 24, order); error += proj->get_error(H3D_REFT_HEX_Z, 25, order); error = sqrt(error); if (error > EPS) // Calculated solution is not precise enough. success_test = 0; // error = 0.0; error += proj->get_error(H3D_H3D_REFT_HEX_XY, 8, order); error += proj->get_error(H3D_H3D_REFT_HEX_XY, 9, order); error += proj->get_error(H3D_H3D_REFT_HEX_XY, 10, order); error += proj->get_error(H3D_H3D_REFT_HEX_XY, 11, order); error = sqrt(error); if (error > EPS) // Calculated solution is not precise enough. success_test = 0; // error = 0.0; error += proj->get_error(H3D_H3D_REFT_HEX_XZ, 12, order); error += proj->get_error(H3D_H3D_REFT_HEX_XZ, 13, order); error += proj->get_error(H3D_H3D_REFT_HEX_XZ, 14, order); error += proj->get_error(H3D_H3D_REFT_HEX_XZ, 15, order); error = sqrt(error); if (error > EPS) // Calculated solution is not precise enough. success_test = 0; // error = 0.0; error += proj->get_error(H3D_H3D_REFT_HEX_YZ, 16, order); error += proj->get_error(H3D_H3D_REFT_HEX_YZ, 17, order); error += proj->get_error(H3D_H3D_REFT_HEX_YZ, 18, order); error += proj->get_error(H3D_H3D_REFT_HEX_YZ, 19, order); error = sqrt(error); if (error > EPS) // Calculated solution is not precise enough. success_test = 0; // error = 0.0; for (int j = 0; j < 8; j++) error += proj->get_error(H3D_H3D_H3D_REFT_HEX_XYZ, j, order); error = sqrt(error); delete proj; if (error > EPS) // Calculated solution is not precise enough. success_test = 0; } // 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; } }
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)); if (success) { info("Success!"); return ERROR_SUCCESS; } else { info("Failure!"); return ERROR_FAILURE; } }
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); 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 = new DiscreteProblem(&wf, space, is_linear); // Set zero initial condition. double *coeff_vec = new double[ndof]; set_zero(coeff_vec, ndof); // 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."); it++; } // Plot the solution. Linearizer l(space); l.plot_solution("solution.dat"); info("Done."); return 0; }
int main(int argc, char *argv[]) { struct thread_data *threads; struct thread_data *thread; int i, ret, ch; if (argc > 1) { if (strcmp(argv[1], "--help") == 0) { usage_error(argv[0]); } init_program_parameter(argc, argv); } program_parameter(argv[0]); create_matrix(&matrix_a); create_matrix(&matrix_b); create_matrix(&matrix_c); create_matrix(&matrix_d); random_matrix(matrix_a); random_matrix(matrix_b); nonmal_matrix_multipy(matrix_a, matrix_b, matrix_d); threads = (struct thread_data *)malloc(pthread_max * sizeof(struct thread_data)); if (threads == NULL) { unix_error("malloc threads failed"); } cpu_online = sysconf(_SC_NPROCESSORS_CONF); for(i = 0; i < pthread_max; i++) { thread = threads + i; thread->index = i; if ((ret = pthread_create(&thread->thread_id, NULL, thread_func, thread)) != 0) { posix_error(ret, "pthread_create failed"); } } for(i = 0; i < pthread_max; i++) { thread = threads + i; if ((ret = pthread_join(thread->thread_id, NULL)) != 0) { posix_error(ret, "pthread_join failed"); } } if (matrix_equal(matrix_c, matrix_d) == 0) { unix_error("runtime error"); } if (dump) { dump_matrix("matrix A", matrix_a); dump_matrix("matrix B", matrix_b); dump_matrix("matrix C", matrix_c); dump_matrix("matrix D", matrix_d); } statistics(threads); free_matrix(matrix_a); free_matrix(matrix_b); free_matrix(matrix_c); free_matrix(matrix_d); free(threads); return 0; }