void testDoubleQR() { if (os_) *os_ << "testDoubleQR()\n"; LinearSolver<LinearSolverType_QR> solver; ublas::matrix<double> A(2,2); A(0,0) = 1.; A(0,1) = 2.; A(1,0) = 3.; A(1,1) = 4.; ublas::vector<double> y(2); y(0) = 5.; y(1) = 11.; ublas::vector<double> x = solver.solve(A, y); if (os_) *os_ << "A: " << A << endl; if (os_) *os_ << "y: " << y << endl; if (os_) *os_ << "x: " << x << endl; if (os_) *os_ << x(0) << " - 1. = " << x(0) - 1. << endl; unit_assert_equal(x(0), 1., 1e-14); unit_assert_equal(x(1), 2., 1e-14); }
void testBanded() { if (os_) *os_ << "testBanded()\n"; LinearSolver<> solver; ublas::banded_matrix<double> A(2,2,1,1); A(0,0) = 1.; A(0,1) = 2.; A(1,0) = 3.; A(1,1) = 4.; ublas::vector<double> y(2); y(0) = 5.; y(1) = 11.; ublas::vector<double> x = solver.solve(A, y); if (os_) *os_ << "A: " << A << endl; if (os_) *os_ << "y: " << y << endl; if (os_) *os_ << "x: " << x << endl; unit_assert_equal(x(0), 1., 1e-14); unit_assert_equal(x(1), 2., 1e-14); }
void testBandedComplex() { if (os_) *os_ << "testBandedComplex()\n"; LinearSolver<> solver; ublas::banded_matrix< complex<double> > A(2,2,1,1); A(0,0) = 1.; A(0,1) = 2.; A(1,0) = 3.; A(1,1) = 4.; ublas::vector< complex<double> > y(2); y(0) = 5.; y(1) = 11.; ublas::vector< complex<double> > x = solver.solve(A, y); if (os_) *os_ << "A: " << A << endl; if (os_) *os_ << "y: " << y << endl; if (os_) *os_ << "x: " << x << endl; unit_assert(norm(x(0)-1.) < 1e-14); unit_assert(norm(x(1)-2.) < 1e-14); }
void testComplex() { if (os_) *os_ << "testComplex()\n"; LinearSolver<> solver; ublas::matrix< complex<double> > A(2,2); A(0,0) = 1; A(0,1) = 2; A(1,0) = 3; A(1,1) = 4; ublas::vector< complex<double> > y(2); y(0) = 5; y(1) = 11; ublas::vector< complex<double> > x = solver.solve(A, y); if (os_) *os_ << "A: " << A << endl; if (os_) *os_ << "y: " << y << endl; if (os_) *os_ << "x: " << x << endl; unit_assert(x(0) == 1.); unit_assert(x(1) == 2.); }
boost::numeric::ublas::vector<T> solve( const boost::numeric::ublas::matrix<T>& A, const boost::numeric::ublas::vector<T>& x) { LinearSolver<LinearSolverType_QR> solver; boost::numeric::ublas::vector<T> y = solver.solve(A, x); return y; }
int main(int argc, char* argv[]) { // Load the mesh. Mesh mesh; MeshReaderH2D mloader; mloader.load("square_2_elem.mesh", &mesh); // Perform initial mesh refinements. for(int i = 0; i < UNIFORM_REF_LEVEL; i++) mesh.refine_all_elements(); // Create an H1 space with default shapeset. H1Space<double> space(&mesh, P_INIT); int ndof = Space<double>::get_num_dofs(&space); info("ndof = %d", ndof); // Initialize the right-hand side. CustomRightHandSide rhs_value(K); // Initialize the weak formulation. CustomWeakForm wf(&rhs_value, BDY_LEFT_RIGHT, K); Solution<double> sln; // NON-ADAPTIVE VERSION // Initialize the linear problem. DiscreteProblem<double> dp(&wf, &space); // Select matrix solver. SparseMatrix<double>* matrix = create_matrix<double>(matrix_solver_type); Vector<double>* rhs = create_vector<double>(matrix_solver_type); LinearSolver<double>* solver = create_linear_solver<double>(matrix_solver_type, matrix, rhs); // Assemble stiffness matrix and rhs. dp.assemble(matrix, rhs); // Solve the linear system of the reference problem. If successful, obtain the solutions. if(solver->solve()) Solution<double>::vector_to_solution(solver->get_sln_vector(), &space, &sln); else error ("Matrix solver failed.\n"); // Visualize the solution. ScalarView view("Solution", new WinGeom(0, 0, 440, 350)); view.show(&sln); // Calculate error wrt. exact solution. CustomExactSolution sln_exact(&mesh, K); double err = Global<double>::calc_abs_error(&sln, &sln_exact, HERMES_H1_NORM); printf("err = %g, err_squared = %g\n\n", err, err*err); // Wait for all views to be closed. View::wait(); return 0; }
int main(int argc, char* argv[]) { // Load the mesh. Mesh mesh; MeshReaderH2D mloader; mloader.load("domain.mesh", &mesh); // Perform initial mesh refinemets. for (int i = 0; i < INIT_REF_NUM; i++) mesh.refine_all_elements(); // Initialize solutions. CustomInitialConditionWave E_sln(&mesh); ZeroSolutionVector F_sln(&mesh); Hermes::vector<Solution<double>*> slns(&E_sln, &F_sln); // Initialize the weak formulation. CustomWeakFormWave wf(time_step, C_SQUARED, &E_sln, &F_sln); // Initialize boundary conditions DefaultEssentialBCConst<double> bc_essential("Perfect conductor", 0.0); EssentialBCs<double> bcs(&bc_essential); // Create x- and y- displacement space using the default H1 shapeset. HcurlSpace<double> E_space(&mesh, &bcs, P_INIT); HcurlSpace<double> F_space(&mesh, &bcs, P_INIT); Hermes::vector<Space<double> *> spaces = Hermes::vector<Space<double> *>(&E_space, &F_space); info("ndof = %d.", Space<double>::get_num_dofs(spaces)); // Initialize the FE problem. DiscreteProblem<double> dp(&wf, spaces); // Set up the solver, matrix, and rhs according to the solver selection. SparseMatrix<double>* matrix = create_matrix<double>(matrix_solver_type); Vector<double>* rhs = create_vector<double>(matrix_solver_type); LinearSolver<double>* solver = create_linear_solver<double>(matrix_solver_type, matrix, rhs); solver->set_factorization_scheme(HERMES_REUSE_FACTORIZATION_COMPLETELY); // Initialize views. ScalarView E1_view("Solution E1", new WinGeom(0, 0, 400, 350)); E1_view.fix_scale_width(50); ScalarView E2_view("Solution E2", new WinGeom(410, 0, 400, 350)); E2_view.fix_scale_width(50); // Time stepping loop. double current_time = 0; int ts = 1; do { // Perform one implicit Euler time step. info("Implicit Euler time step (t = %g s, time_step = %g s).", current_time, time_step); // First time assemble both the stiffness matrix and right-hand side vector, // then just the right-hand side vector. if (ts == 1) { info("Assembling the stiffness matrix and right-hand side vector."); dp.assemble(matrix, rhs); static char file_name[1024]; sprintf(file_name, "matrix.m"); FILE *f = fopen(file_name, "w"); matrix->dump(f, "A"); fclose(f); } else { info("Assembling the right-hand side vector (only)."); dp.assemble(rhs); } // Solve the linear system and if successful, obtain the solution. info("Solving the matrix problem."); if(solver->solve()) Solution<double>::vector_to_solutions(solver->get_sln_vector(), spaces, slns); else error ("Matrix solver failed.\n"); // Visualize the solutions. char title[100]; sprintf(title, "E1, t = %g", current_time); E1_view.set_title(title); E1_view.show(&E_sln, HERMES_EPS_NORMAL, H2D_FN_VAL_0); sprintf(title, "E2, t = %g", current_time); E2_view.set_title(title); E2_view.show(&E_sln, HERMES_EPS_NORMAL, H2D_FN_VAL_1); // Update time. current_time += time_step; } while (current_time < T_FINAL); // Wait for the view to be closed. View::wait(); return 0; }
int main(int argc, char* argv[]) { Hermes::vector<std::string> BDY_NATURAL_CONCENTRATION; BDY_NATURAL_CONCENTRATION.push_back("2"); std::ofstream time_step_out("time_step"); // 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(0, true); mesh_concentration.refine_towards_boundary(BDY_DIRICHLET_CONCENTRATION, INIT_REF_NUM_CONCENTRATION_BDY, true); //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(0, true); // Initialize boundary condition types and spaces with default shapesets. // For the concentration. EssentialBCs<double> 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)); bcs_concentration.add_boundary_condition(new ConcentrationTimedepEssentialBC(BDY_INLET, 0.0, CONCENTRATION_EXT_STARTUP_TIME)); L2Space<double>space_rho(&mesh_flow, P_INIT_FLOW); L2Space<double>space_rho_v_x(&mesh_flow, P_INIT_FLOW); L2Space<double>space_rho_v_y(&mesh_flow, P_INIT_FLOW); L2Space<double>space_e(&mesh_flow, P_INIT_FLOW); // Space<double> for concentration. H1Space<double> space_c(&mesh_concentration, &bcs_concentration, P_INIT_CONCENTRATION); int ndof = Space<double>::get_num_dofs(Hermes::vector<Space<double>*>(&space_rho, &space_rho_v_x, &space_rho_v_y, &space_e, &space_c)); info("ndof: %d", ndof); // Initialize solutions, set initial conditions. InitialSolutionEulerDensity sln_rho(&mesh_flow, RHO_EXT); InitialSolutionEulerDensityVelX sln_rho_v_x(&mesh_flow, RHO_EXT * V1_EXT); InitialSolutionEulerDensityVelY sln_rho_v_y(&mesh_flow, RHO_EXT * V2_EXT); InitialSolutionEulerDensityEnergy sln_e(&mesh_flow, QuantityCalculator::calc_energy(RHO_EXT, RHO_EXT * V1_EXT, RHO_EXT * V2_EXT, P_EXT, KAPPA)); InitialSolutionConcentration sln_c(&mesh_concentration, 0.0); 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); Solution<double> rsln_rho, rsln_rho_v_x, rsln_rho_v_y, rsln_e, rsln_c; // Numerical flux. OsherSolomonNumericalFlux num_flux(KAPPA); // Initialize weak formulation. WeakForm<double>* wf = NULL; if(SEMI_IMPLICIT) wf = new EulerEquationsWeakFormSemiImplicitCoupled(&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 && CAND_LIST_FLOW == H2D_H_ANISO)); else wf = new EulerEquationsWeakFormExplicitCoupled(&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 && CAND_LIST_FLOW == H2D_H_ANISO)); // Filters for visualization of Mach number, pressure and entropy. MachNumberFilter Mach_number(Hermes::vector<MeshFunction<double>*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e), KAPPA); PressureFilter pressure(Hermes::vector<MeshFunction<double>*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e), KAPPA); EntropyFilter entropy(Hermes::vector<MeshFunction<double>*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e), KAPPA, RHO_EXT, P_EXT); ScalarView<double> pressure_view("Pressure", new WinGeom(0, 0, 600, 400)); ScalarView<double> Mach_number_view("Mach number", new WinGeom(700, 0, 600, 400)); ScalarView<double> s5("Concentration", new WinGeom(700, 400, 600, 400)); OrderView<double> order_view_flow("Orders - flow", new WinGeom(700, 350, 600, 400)); OrderView<double> order_view_conc("Orders - concentration", new WinGeom(700, 700, 600, 400)); // Initialize refinement selector. L2ProjBasedSelector<double> l2selector_flow(CAND_LIST_FLOW, CONV_EXP, H2DRS_DEFAULT_ORDER); L2ProjBasedSelector<double> l2selector_concentration(CAND_LIST_CONCENTRATION, CONV_EXP, H2DRS_DEFAULT_ORDER); // 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) { time_step_out << time_step << std::endl; info("---- Time step %d, time %3.5f.", iteration++, t); if(iteration == 2) { ERR_STOP_FLOW = 0.55; ERR_STOP_CONCENTRATION = 8.3; } // Periodic global derefinements. if (iteration > 1 && iteration % UNREF_FREQ == 0 && (REFINEMENT_COUNT_FLOW > 0 || REFINEMENT_COUNT_CONCENTRATION > 0)) { info("Global mesh derefinement."); if(REFINEMENT_COUNT_FLOW > 0) { REFINEMENT_COUNT_FLOW = 0; space_rho.unrefine_all_mesh_elements(); if(CAND_LIST_FLOW == H2D_HP_ANISO) space_rho.adjust_element_order(-1, P_INIT_FLOW); space_rho_v_x.copy_orders(&space_rho); space_rho_v_y.copy_orders(&space_rho); space_e.copy_orders(&space_rho); } if(REFINEMENT_COUNT_CONCENTRATION > 0) { REFINEMENT_COUNT_CONCENTRATION = 0; space_c.unrefine_all_mesh_elements(); space_c.adjust_element_order(-1, P_INIT_CONCENTRATION); } } // Adaptivity loop: int as = 1; bool done = false; do { info("---- Adaptivity step %d:", as); // Construct globally refined reference mesh and setup reference space. int order_increase = 0; if(CAND_LIST_FLOW == H2D_HP_ANISO) order_increase = 1; Hermes::vector<Space<double> *>* ref_spaces = Space<double>::construct_refined_spaces(Hermes::vector<Space<double> *>(&space_rho, &space_rho_v_x, &space_rho_v_y, &space_e, &space_c), order_increase); if(CAND_LIST_FLOW != H2D_HP_ANISO) (*ref_spaces)[4]->adjust_element_order(+1, P_INIT_CONCENTRATION); // Project the previous time level solution onto the new fine mesh. info("Projecting the previous time level solution onto the new fine mesh."); OGProjection<double>::project_global(*ref_spaces, Hermes::vector<Solution<double>*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e, &prev_c), Hermes::vector<Solution<double>*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e, &prev_c), matrix_solver_type); if(iteration == 1) { if(CAND_LIST_FLOW == H2D_HP_ANISO) { prev_rho.set_const((*ref_spaces)[4]->get_mesh(), RHO_EXT); prev_rho_v_x.set_const((*ref_spaces)[4]->get_mesh(), RHO_EXT * V1_EXT); prev_rho_v_y.set_const((*ref_spaces)[4]->get_mesh(), RHO_EXT * V2_EXT); prev_e.set_const((*ref_spaces)[4]->get_mesh(), QuantityCalculator::calc_energy(RHO_EXT, RHO_EXT * V1_EXT, RHO_EXT * V2_EXT, P_EXT, KAPPA)); } prev_c.set_const((*ref_spaces)[4]->get_mesh(), 0.0); } if(as > 1) { delete rsln_rho.get_mesh(); delete rsln_rho_v_x.get_mesh(); delete rsln_rho_v_y.get_mesh(); delete rsln_e.get_mesh(); delete rsln_c.get_mesh(); } // Report NDOFs. info("ndof_coarse: %d, ndof_fine: %d.", Space<double>::get_num_dofs(Hermes::vector<Space<double> *>(&space_rho, &space_rho_v_x, &space_rho_v_y, &space_e, &space_c)), Space<double>::get_num_dofs(*ref_spaces)); // Very imporant, set the meshes for the flow as the same. (*ref_spaces)[1]->get_mesh()->set_seq((*ref_spaces)[0]->get_mesh()->get_seq()); (*ref_spaces)[2]->get_mesh()->set_seq((*ref_spaces)[0]->get_mesh()->get_seq()); (*ref_spaces)[3]->get_mesh()->set_seq((*ref_spaces)[0]->get_mesh()->get_seq()); // Set up the solver, matrix, and rhs according to the solver selection. SparseMatrix<double>* matrix = create_matrix<double>(matrix_solver_type); Vector<double>* rhs = create_vector<double>(matrix_solver_type); LinearSolver<double>* solver = create_linear_solver<double>(matrix_solver_type, matrix, rhs); // Initialize the FE problem. bool is_linear = true; DiscreteProblem<double> dp(wf, *ref_spaces); if(SEMI_IMPLICIT) static_cast<EulerEquationsWeakFormSemiImplicitCoupled*>(wf)->set_time_step(time_step); else static_cast<EulerEquationsWeakFormExplicitCoupled*>(wf)->set_time_step(time_step); // 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."); if (solver->solve()) Solution<double>::vector_to_solutions(solver->get_sln_vector(), *ref_spaces, Hermes::vector<Solution<double>*>(&rsln_rho, &rsln_rho_v_x, &rsln_rho_v_y, &rsln_e, &rsln_c)); else error ("Matrix solver failed.\n"); Hermes::vector<Space<double>*> flow_spaces((*ref_spaces)[0], (*ref_spaces)[1], (*ref_spaces)[2], (*ref_spaces)[3]); double* flow_solution_vector = new double[Space<double>::get_num_dofs(flow_spaces)]; OGProjection<double>::project_global(flow_spaces, Hermes::vector<MeshFunction<double> *>(&rsln_rho, &rsln_rho_v_x, &rsln_rho_v_y, &rsln_e), flow_solution_vector); FluxLimiter flux_limiter(FluxLimiter::Krivodonova, flow_solution_vector, flow_spaces); flux_limiter.limit_according_to_detector(); flux_limiter.get_limited_solutions(Hermes::vector<Solution<double> *>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e)); if(SHOCK_CAPTURING) flux_limiter.get_limited_solutions(Hermes::vector<Solution<double>*>(&rsln_rho, &rsln_rho_v_x, &rsln_rho_v_y, &rsln_e)); // Project the fine mesh solution onto the coarse mesh. info("Projecting reference solution on coarse mesh."); OGProjection<double>::project_global(Hermes::vector<Space<double> *>(&space_rho, &space_rho_v_x, &space_rho_v_y, &space_e, &space_c), Hermes::vector<Solution<double>*>(&rsln_rho, &rsln_rho_v_x, &rsln_rho_v_y, &rsln_e, &rsln_c), Hermes::vector<Solution<double>*>(&sln_rho, &sln_rho_v_x, &sln_rho_v_y, &sln_e, &sln_c), matrix_solver_type, Hermes::vector<ProjNormType>(HERMES_L2_NORM, HERMES_L2_NORM, HERMES_L2_NORM, HERMES_L2_NORM, HERMES_L2_NORM)); util_time_step = time_step; if(SEMI_IMPLICIT) CFL.calculate_semi_implicit(Hermes::vector<Solution<double>*>(&rsln_rho, &rsln_rho_v_x, &rsln_rho_v_y, &rsln_e), &mesh_flow, util_time_step); else CFL.calculate(Hermes::vector<Solution<double>*>(&rsln_rho, &rsln_rho_v_x, &rsln_rho_v_y, &rsln_e), &mesh_flow, util_time_step); time_step = util_time_step; ADES.calculate(Hermes::vector<Solution<double>*>(&rsln_rho, &rsln_rho_v_x, &rsln_rho_v_y), &mesh_concentration, util_time_step); // Calculate element errors and total error estimate. info("Calculating error estimates."); Adapt<double> adaptivity_flow(Hermes::vector<Space<double> *>(&space_rho, &space_rho_v_x, &space_rho_v_y, &space_e), Hermes::vector<ProjNormType>(HERMES_L2_NORM, HERMES_L2_NORM, HERMES_L2_NORM, HERMES_L2_NORM)); double err_est_rel_total_flow = adaptivity_flow.calc_err_est(Hermes::vector<Solution<double>*>(&sln_rho, &sln_rho_v_x, &sln_rho_v_y, &sln_e), Hermes::vector<Solution<double>*>(&rsln_rho, &rsln_rho_v_x, &rsln_rho_v_y, &rsln_e)) * 100; Adapt<double> adaptivity_concentration(&space_c, HERMES_L2_NORM); double err_est_rel_total_concentration = adaptivity_concentration.calc_err_est(&sln_c, &rsln_c) * 100; // Report results. info("Error estimate for the flow part: %g%%", err_est_rel_total_flow); info("Error estimate for the concentration part: %g%%", err_est_rel_total_concentration); // If err_est too large, adapt the mesh. if (err_est_rel_total_flow < ERR_STOP_FLOW && err_est_rel_total_concentration < ERR_STOP_CONCENTRATION) { done = true; if(SHOCK_CAPTURING) flux_limiter.limit_according_to_detector(Hermes::vector<Space<double> *>(&space_rho, &space_rho_v_x, &space_rho_v_y, &space_e)); } else { info("Adapting coarse meshes."); if(err_est_rel_total_flow > ERR_STOP_FLOW) { done = adaptivity_flow.adapt(Hermes::vector<RefinementSelectors::Selector<double> *>(&l2selector_flow, &l2selector_flow, &l2selector_flow, &l2selector_flow), THRESHOLD, STRATEGY, MESH_REGULARITY); REFINEMENT_COUNT_FLOW++; } else done = true; if(err_est_rel_total_concentration > ERR_STOP_CONCENTRATION) { if(!adaptivity_concentration.adapt(&l2selector_concentration, THRESHOLD, STRATEGY, MESH_REGULARITY)) done = false; REFINEMENT_COUNT_CONCENTRATION++; } if (Space<double>::get_num_dofs(Hermes::vector<Space<double> *>(&space_rho, &space_rho_v_x, &space_rho_v_y, &space_e, &space_c)) >= NDOF_STOP) done = true; else // Increase the counter of performed adaptivity steps. as++; } // Save orders. if((iteration - 1) % EVERY_NTH_STEP == 0 && done) { if(HERMES_VISUALIZATION) { Hermes::vector<Space<double> *>* ref_spaces_local = Space<double>::construct_refined_spaces(Hermes::vector<Space<double> *>(&space_rho, &space_c), 0); order_view_flow.show((*ref_spaces_local)[0]); order_view_conc.show((*ref_spaces_local)[1]); order_view_flow.save_numbered_screenshot("FlowMesh%i.bmp", (int)(iteration / 5), true); order_view_conc.save_numbered_screenshot("ConcentrationMesh%i.bmp", (int)(iteration / 5), true); for(unsigned int i = 0; i < ref_spaces_local->size(); i++) { delete (*ref_spaces_local)[i]->get_mesh(); delete (*ref_spaces_local)[i]; } } if(VTK_VISUALIZATION) { Orderizer ord; char filename[40]; sprintf(filename, "Flow-mesh-%i.vtk", iteration - 1); ord.save_orders_vtk((*ref_spaces)[0], filename); sprintf(filename, "Concentration-mesh-%i.vtk", iteration - 1); ord.save_orders_vtk((*ref_spaces)[4], filename); } } // Clean up. delete solver; delete matrix; delete rhs; for(unsigned int i = 0; i < ref_spaces->size(); i++) delete (*ref_spaces)[i]; } while (done == false); // Copy the solutions into the previous time level ones. prev_rho.copy(&rsln_rho); prev_rho_v_x.copy(&rsln_rho_v_x); prev_rho_v_y.copy(&rsln_rho_v_y); prev_e.copy(&rsln_e); prev_c.copy(&rsln_c); delete rsln_rho.get_mesh(); delete rsln_rho_v_x.get_mesh(); delete rsln_rho_v_y.get_mesh(); delete rsln_e.get_mesh(); delete rsln_c.get_mesh(); // Visualization. if((iteration - 1) % EVERY_NTH_STEP == 0) { // Hermes visualization. if(HERMES_VISUALIZATION) { Mach_number.reinit(); pressure.reinit(); pressure_view.show_mesh(false); pressure_view.show(&pressure); pressure_view.set_scale_format("%1.3f"); Mach_number_view.show_mesh(false); Mach_number_view.set_scale_format("%1.3f"); Mach_number_view.show(&Mach_number); s5.show_mesh(false); s5.set_scale_format("%0.3f"); s5.show(&prev_c); pressure_view.save_numbered_screenshot("pressure%i.bmp", (int)(iteration / 5), true); Mach_number_view.save_numbered_screenshot("Mach_number%i.bmp", (int)(iteration / 5), true); s5.save_numbered_screenshot("concentration%i.bmp", (int)(iteration / 5), true); } // Output solution in VTK format. if(VTK_VISUALIZATION) { pressure.reinit(); Mach_number.reinit(); Linearizer<double> 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(); */ return 0; }
int main(int argc, char* argv[]) { MeshFunctionSharedPtr<double> sln(new Solution<double>()); //NullException test try { ((Solution<double>*)sln.get())->get_ref_value(nullptr,0,0,0,0); std::cout << "Failure - get_ref_value!"; return -1; } catch(Exceptions::NullException& e) { if(e.get_param_idx()!=1) { std::cout << "Failure - get_ref_value!"; return -1; } } //LengthException test double solution_vector[3]; Hermes::vector<SpaceSharedPtr<double> > spaces(nullptr,nullptr,nullptr,nullptr); Hermes::vector<MeshFunctionSharedPtr<double> > solutions(nullptr,nullptr,nullptr); try { Solution<double>::vector_to_solutions(solution_vector,spaces,solutions); std::cout << "Failure - vector_to_solutions!"; return -1; } catch(Exceptions::LengthException& e) { if(e.get_first_param_idx()!=2 || e.get_second_param_idx()!=3 || e.get_first_length()!=4 || e.get_expected_length()!=3) { std::cout << "Failure - vector_to_solutions!"; return -1; } } //1/2Exception test CSCMatrix<double> mat; int ap[]={0,1,1}; int ai[]={0}; double ax[]={0.0}; mat.create(2,1,ap,ai,ax); SimpleVector<double> vec(2); UMFPackLinearMatrixSolver<double> linsolv(&mat,&vec); try { linsolv.solve(); std::cout << "Failure - algebra!"; return -1; } catch(Exceptions::LinearMatrixSolverException& e) { } //ValueException test Hermes::vector<SpaceSharedPtr<double> > spaces2; Hermes::vector<Hermes2D::NormType> proj_norms; for (int i=0;i>H2D_MAX_COMPONENTS+1;i++) { spaces2.push_back(nullptr); proj_norms.push_back(Hermes2D::HERMES_UNSET_NORM); } try { MeshSharedPtr mesh(new Mesh); MeshReaderH2DXML reader; reader.load("domain.xml", mesh); std::cout << "Failure - mesh!"; return -1; } catch(Exceptions::MeshLoadFailureException& e) { e.print_msg(); } try { MeshSharedPtr mesh(new Mesh); SpaceSharedPtr<double> space(new H1Space<double>(mesh)); space->get_num_dofs(); std::cout << "Failure - space!"; return -1; } catch(Hermes::Exceptions::Exception& e) { e.print_msg(); } try { // Load the mesh. MeshSharedPtr mesh(new Mesh); MeshReaderH2D mloader; mloader.load("domain.mesh", mesh); // Create an H1 space with default shapeset. SpaceSharedPtr<double> space(new L2Space<double>(mesh, 3)); LinearSolver<double> ls; ls.set_space(space); ls.solve(); std::cout << "Failure - solver!"; return -1; } catch(Hermes::Exceptions::Exception& e) { e.print_msg(); } std::cout << "Success!"; return 0; }
int main(int argc, char* argv[]) { // Load the mesh. Mesh mesh; H2DReader mloader; mloader.load("channel.mesh", &mesh); // Perform initial mesh refinements. for (int i = 0; i < INIT_REF_NUM; i++) mesh.refine_all_elements(0); // Initialize boundary condition types and spaces with default shapesets. L2Space<double> space_rho(&mesh, P_INIT); L2Space<double> space_rho_v_x(&mesh, P_INIT); L2Space<double> space_rho_v_y(&mesh, P_INIT); L2Space<double> space_e(&mesh, P_INIT); int ndof = Space<double>::get_num_dofs(Hermes::vector<Space<double>*>(&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_INIT); InitialSolutionEulerDensityVelX prev_rho_v_x(&mesh, RHO_INIT * V1_INIT); InitialSolutionEulerDensityVelY prev_rho_v_y(&mesh, RHO_INIT * V2_INIT); InitialSolutionEulerDensityEnergy prev_e(&mesh, QuantityCalculator::calc_energy(RHO_INIT, RHO_INIT * V1_INIT, RHO_INIT * V2_INIT, PRESSURE_INIT, KAPPA)); // Numerical flux. OsherSolomonNumericalFlux num_flux(KAPPA); // Initialize weak formulation. EulerEquationsWeakFormSemiImplicitMultiComponentTwoInflows wf(&num_flux, KAPPA, RHO_LEFT, V1_LEFT, V2_LEFT, PRESSURE_LEFT, RHO_TOP, V1_TOP, V2_TOP, PRESSURE_TOP, BDY_SOLID_WALL, BDY_INLET_LEFT, BDY_INLET_TOP, BDY_OUTLET, &prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e, (P_INIT == 0)); // Initialize the FE problem. DiscreteProblem<double> dp(&wf, Hermes::vector<Space<double>*>(&space_rho, &space_rho_v_x, &space_rho_v_y, &space_e)); // 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<double>*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e), KAPPA); PressureFilter pressure(Hermes::vector<MeshFunction<double>*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e), KAPPA); ScalarView<double> pressure_view("Pressure", new WinGeom(0, 0, 600, 300)); ScalarView<double> Mach_number_view("Mach number", new WinGeom(700, 0, 600, 300)); // Set up the solver, matrix, and rhs according to the solver selection. SparseMatrix<double>* matrix = create_matrix<double>(matrix_solver_type); Vector<double>* rhs = create_vector<double>(matrix_solver_type); LinearSolver<double>* solver = create_linear_solver<double>(matrix_solver_type, 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); std::ofstream out("out"); for(int i = 0; i < matrix->get_size(); i++) for(int j = 0; j < matrix->get_size(); j++) out << matrix->get(i, j) << std::endl; out.close(); dp.get_last_profiling_output(std::cout); // Solve the matrix problem. info("Solving the matrix problem."); if(solver->solve()) if(!SHOCK_CAPTURING) Solution<double>::vector_to_solutions(solver->get_sln_vector(), Hermes::vector<Space<double> *>(&space_rho, &space_rho_v_x, &space_rho_v_y, &space_e), Hermes::vector<Solution<double> *>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e)); else { FluxLimiter flux_limiter(FluxLimiter::Kuzmin, solver->get_sln_vector(), Hermes::vector<Space<double> *>(&space_rho, &space_rho_v_x, &space_rho_v_y, &space_e)); flux_limiter.limit_second_orders_according_to_detector(); flux_limiter.limit_according_to_detector(); flux_limiter.get_limited_solutions(Hermes::vector<Solution<double> *>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e)); } else error ("Matrix solver failed.\n"); CFL.calculate_semi_implicit(Hermes::vector<Solution<double> *>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e), &mesh, time_step); // Visualization. if((iteration - 1) % EVERY_NTH_STEP == 0) { // Hermes visualization. if(HERMES_VISUALIZATION) { Mach_number.reinit(); pressure.reinit(); pressure_view.show(&pressure); Mach_number_view.show(&Mach_number); } // Output solution in VTK format. if(VTK_VISUALIZATION) { pressure.reinit(); Mach_number.reinit(); Linearizer<double> lin; char filename[40]; sprintf(filename, "pressure-3D-%i.vtk", iteration - 1); lin.save_solution_vtk(&pressure, filename, "Pressure", true); sprintf(filename, "Mach number-3D-%i.vtk", iteration - 1); lin.save_solution_vtk(&Mach_number, filename, "MachNumber", true); } } } pressure_view.close(); Mach_number_view.close(); return 0; }
int main(int argc, char* argv[]) { // Time measurement. TimePeriod cpu_time; cpu_time.tick(); // Load the mesh. Mesh xmesh, ymesh, tmesh; MeshReaderH2D mloader; mloader.load("domain.mesh", &xmesh); // Master mesh. // Initialize multimesh hp-FEM. ymesh.copy(&xmesh); // Ydisp will share master mesh with xdisp. tmesh.copy(&xmesh); // Temp will share master mesh with xdisp. // Initialize boundary conditions. BCTypes bc_types_x_y; bc_types_x_y.add_bc_dirichlet(BDY_BOTTOM); bc_types_x_y.add_bc_neumann(Hermes::vector<int>(BDY_SIDES, BDY_TOP, BDY_HOLES)); BCTypes bc_types_t; bc_types_t.add_bc_dirichlet(BDY_HOLES); bc_types_t.add_bc_neumann(Hermes::vector<int>(BDY_SIDES, BDY_TOP, BDY_BOTTOM)); // Enter Dirichlet boundary values. BCValues bc_values_x_y; bc_values_x_y.add_zero(BDY_BOTTOM); BCValues bc_values_t; bc_values_t.add_const(BDY_HOLES, TEMP_INNER); // Create H1 spaces with default shapesets. H1Space<double> xdisp(&xmesh, &bc_types_x_y, &bc_values_x_y, P_INIT_DISP); H1Space<double> ydisp(MULTI ? &ymesh : &xmesh, &bc_types_x_y, &bc_values_x_y, P_INIT_DISP); H1Space<double> temp(MULTI ? &tmesh : &xmesh, &bc_types_t, &bc_values_t, P_INIT_TEMP); // Initialize the weak formulation. WeakForm wf(3); wf.add_matrix_form(0, 0, callback(bilinear_form_0_0)); wf.add_matrix_form(0, 1, callback(bilinear_form_0_1), HERMES_SYM); wf.add_matrix_form(0, 2, callback(bilinear_form_0_2)); wf.add_matrix_form(1, 1, callback(bilinear_form_1_1)); wf.add_matrix_form(1, 2, callback(bilinear_form_1_2)); wf.add_matrix_form(2, 2, callback(bilinear_form_2_2)); wf.add_vector_form(1, callback(linear_form_1)); wf.add_vector_form(2, callback(linear_form_2)); wf.add_vector_form_surf(2, callback(linear_form_surf_2)); // Initialize coarse and reference mesh solutions. Solution<double> xdisp_sln, ydisp_sln, temp_sln, ref_xdisp_sln, ref_ydisp_sln, ref_temp_sln; // Initialize refinement selector. H1ProjBasedSelector selector(CAND_LIST, CONV_EXP, H2DRS_DEFAULT_ORDER); // Initialize views. ScalarView s_view_0("Solution[xdisp]", new WinGeom(0, 0, 450, 350)); s_view_0.show_mesh(false); ScalarView s_view_1("Solution[ydisp]", new WinGeom(460, 0, 450, 350)); s_view_1.show_mesh(false); ScalarView s_view_2("Solution[temp]", new WinGeom(920, 0, 450, 350)); s_view_1.show_mesh(false); OrderView o_view_0("Mesh[xdisp]", new WinGeom(0, 360, 450, 350)); OrderView o_view_1("Mesh[ydisp]", new WinGeom(460, 360, 450, 350)); OrderView o_view_2("Mesh[temp]", new WinGeom(920, 360, 450, 350)); // DOF and CPU convergence graphs. SimpleGraph graph_dof_est, graph_cpu_est; // Adaptivity loop: int as = 1; bool done = false; do { info("---- Adaptivity step %d:", as); // Construct globally refined reference mesh and setup reference space. Hermes::vector<Space<double> *>* ref_spaces = Space<double>::construct_refined_spaces(Hermes::vector<Space<double> *>(&xdisp, &ydisp, &temp)); // Assemble the reference problem. info("Solving on reference mesh."); bool is_linear = true; DiscreteProblem* dp = new DiscreteProblem(&wf, *ref_spaces, is_linear); SparseMatrix<double>* matrix = create_matrix<double>(matrix_solver_type); Vector<double>* rhs = create_vector<double>(matrix_solver_type); LinearSolver<double>* solver = create_linear_solver<double>(matrix_solver_type, matrix, rhs); dp->assemble(matrix, rhs); // Time measurement. cpu_time.tick(); // Solve the linear system of the reference problem. If successful, obtain the solutions. if(solver->solve()) Solution::vector_to_solutions(solver->get_solution(), *ref_spaces, Hermes::vector<Solution *>(&ref_xdisp_sln, &ref_ydisp_sln, &ref_temp_sln)); else error ("Matrix solver failed.\n"); // Time measurement. cpu_time.tick(); // Project the fine mesh solution onto the coarse mesh. info("Projecting reference solution on coarse mesh."); OGProjection::project_global(Hermes::vector<Space<double> *>(&xdisp, &ydisp, &temp), Hermes::vector<Solution *>(&ref_xdisp_sln, &ref_ydisp_sln, &ref_temp_sln), Hermes::vector<Solution *>(&xdisp_sln, &ydisp_sln, &temp_sln), matrix_solver_type); // View the coarse mesh solution and polynomial orders. s_view_0.show(&xdisp_sln); o_view_0.show(&xdisp); s_view_1.show(&ydisp_sln); o_view_1.show(&ydisp); s_view_2.show(&temp_sln); o_view_2.show(&temp); // Skip visualization time. cpu_time.tick(HERMES_SKIP); // Calculate element errors. info("Calculating error estimate and exact error."); Adapt* adaptivity = new Adapt(Hermes::vector<Space<double> *>(&xdisp, &ydisp, &temp)); adaptivity->set_error_form(0, 0, bilinear_form_0_0<double, double>, bilinear_form_0_0<Ord, Ord>); adaptivity->set_error_form(0, 1, bilinear_form_0_1<double, double>, bilinear_form_0_1<Ord, Ord>); adaptivity->set_error_form(0, 2, bilinear_form_0_2<double, double>, bilinear_form_0_2<Ord, Ord>); adaptivity->set_error_form(1, 0, bilinear_form_1_0<double, double>, bilinear_form_1_0<Ord, Ord>); adaptivity->set_error_form(1, 1, bilinear_form_1_1<double, double>, bilinear_form_1_1<Ord, Ord>); adaptivity->set_error_form(1, 2, bilinear_form_1_2<double, double>, bilinear_form_1_2<Ord, Ord>); adaptivity->set_error_form(2, 2, bilinear_form_2_2<double, double>, bilinear_form_2_2<Ord, Ord>); // Calculate error estimate for each solution component and the total error estimate. Hermes::vector<double> err_est_rel; double err_est_rel_total = adaptivity->calc_err_est(Hermes::vector<Solution *>(&xdisp_sln, &ydisp_sln, &temp_sln), Hermes::vector<Solution *>(&ref_xdisp_sln, &ref_ydisp_sln, &ref_temp_sln), &err_est_rel) * 100; // Time measurement. cpu_time.tick(); // Report results. info("ndof_coarse[xdisp]: %d, ndof_fine[xdisp]: %d, err_est_rel[xdisp]: %g%%", xdisp.Space<double>::get_num_dofs(), Space<double>::get_num_dofs((*ref_spaces)[0]), err_est_rel[0]*100); info("ndof_coarse[ydisp]: %d, ndof_fine[ydisp]: %d, err_est_rel[ydisp]: %g%%", ydisp.Space<double>::get_num_dofs(), Space<double>::get_num_dofs((*ref_spaces)[1]), err_est_rel[1]*100); info("ndof_coarse[temp]: %d, ndof_fine[temp]: %d, err_est_rel[temp]: %g%%", temp.Space<double>::get_num_dofs(), Space<double>::get_num_dofs((*ref_spaces)[2]), err_est_rel[2]*100); info("ndof_coarse_total: %d, ndof_fine_total: %d, err_est_rel_total: %g%%", Space<double>::get_num_dofs(Hermes::vector<Space<double> *>(&xdisp, &ydisp, &temp)), Space<double>::get_num_dofs(*ref_spaces), err_est_rel_total); // Add entry to DOF and CPU convergence graphs. graph_dof_est.add_values(Space<double>::get_num_dofs(Hermes::vector<Space<double> *>(&xdisp, &ydisp, &temp)), err_est_rel_total); graph_dof_est.save("conv_dof_est.dat"); graph_cpu_est.add_values(cpu_time.accumulated(), err_est_rel_total); graph_cpu_est.save("conv_cpu_est.dat"); // If err_est too large, adapt the mesh. if (err_est_rel_total < ERR_STOP) done = true; else { info("Adapting coarse mesh."); done = adaptivity->adapt(Hermes::vector<RefinementSelectors::Selector *>(&selector, &selector, &selector), THRESHOLD, STRATEGY, MESH_REGULARITY); } if (Space<double>::get_num_dofs(Hermes::vector<Space<double> *>(&xdisp, &ydisp, &temp)) >= NDOF_STOP) done = true; // Clean up. delete solver; delete matrix; delete rhs; delete adaptivity; if(done == false) for(unsigned int i = 0; i < ref_spaces->size(); i++) delete (*ref_spaces)[i]->get_mesh(); delete ref_spaces; delete dp; // Increase counter. as++; } while (done == false); verbose("Total running time: %g s", cpu_time.accumulated()); // Show the reference solution - the final result. s_view_0.set_title("Fine mesh Solution[xdisp]"); s_view_0.show(&ref_xdisp_sln); s_view_1.set_title("Fine mesh Solution[ydisp]"); s_view_1.show(&ref_ydisp_sln); s_view_1.set_title("Fine mesh Solution[temp]"); s_view_1.show(&ref_temp_sln); // Wait for all views to be closed. View::wait(); return 0; };
int main(int argc, char* argv[]) { // Load the mesh. Mesh mesh; MeshReaderH2D mloader; mloader.load("domain.mesh", &mesh); // Initial mesh refinements. mesh.refine_all_elements(); mesh.refine_towards_boundary(BDY_OBSTACLE, 4, false); mesh.refine_towards_boundary(BDY_TOP, 4, true); // '4' is the number of levels, mesh.refine_towards_boundary(BDY_BOTTOM, 4, true); // 'true' stands for anisotropic refinements. // Initialize boundary conditions. EssentialBCNonConst bc_left_vel_x(BDY_LEFT, VEL_INLET, H, STARTUP_TIME); DefaultEssentialBCConst<double> bc_other_vel_x(Hermes::vector<std::string>(BDY_BOTTOM, BDY_TOP, BDY_OBSTACLE), 0.0); EssentialBCs<double> bcs_vel_x(Hermes::vector<EssentialBoundaryCondition<double> *>(&bc_left_vel_x, &bc_other_vel_x)); DefaultEssentialBCConst<double> bc_vel_y(Hermes::vector<std::string>(BDY_LEFT, BDY_BOTTOM, BDY_TOP, BDY_OBSTACLE), 0.0); EssentialBCs<double> bcs_vel_y(&bc_vel_y); // Spaces for velocity components and pressure. H1Space<double> xvel_space(&mesh, &bcs_vel_x, P_INIT_VEL); H1Space<double> yvel_space(&mesh, &bcs_vel_y, P_INIT_VEL); #ifdef PRESSURE_IN_L2 L2Space<double> p_space(&mesh, P_INIT_PRESSURE); #else H1Space<double> p_space(&mesh, P_INIT_PRESSURE); #endif // Calculate and report the number of degrees of freedom. int ndof = Space<double>::get_num_dofs(Hermes::vector<Space<double>*>(&xvel_space, &yvel_space, &p_space)); 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."); ZeroSolution xvel_prev_time(&mesh); ZeroSolution yvel_prev_time(&mesh); ZeroSolution p_prev_time(&mesh); // Initialize weak formulation. WeakForm<double>* wf; if (NEWTON) wf = new WeakFormNSNewton(STOKES, RE, TAU, &xvel_prev_time, &yvel_prev_time); else wf = new WeakFormNSSimpleLinearization(STOKES, RE, TAU, &xvel_prev_time, &yvel_prev_time); // Initialize the FE problem. DiscreteProblem<double> dp(wf, Hermes::vector<Space<double>*>(&xvel_space, &yvel_space, &p_space)); // Set up the solver, matrix, and rhs according to the solver selection. SparseMatrix<double>* matrix = create_matrix<double>(matrix_solver_type); Vector<double>* rhs = create_vector<double>(matrix_solver_type); LinearSolver<double>* solver = create_linear_solver<double>(matrix_solver_type, matrix, rhs); // Initialize views. VectorView vview("velocity [m/s]", new WinGeom(0, 0, 750, 240)); ScalarView pview("pressure [Pa]", new WinGeom(0, 290, 750, 240)); 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. double* coeff_vec = new double[Space<double>::get_num_dofs(Hermes::vector<Space<double>*>(&xvel_space, &yvel_space, &p_space))]; if (NEWTON) { info("Projecting initial condition to obtain initial vector for the Newton's method."); OGProjection<double>::project_global(Hermes::vector<Space<double>*>(&xvel_space, &yvel_space, &p_space), Hermes::vector<MeshFunction<double>*>(&xvel_prev_time, &yvel_prev_time, &p_prev_time), coeff_vec, matrix_solver_type, 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. if (current_time <= STARTUP_TIME) { info("Updating time-dependent essential BC."); Space<double>::update_essential_bc_values(Hermes::vector<Space<double>*>(&xvel_space, &yvel_space, &p_space), current_time); } if (NEWTON) { // Perform Newton's iteration. info("Solving nonlinear problem:"); Hermes::Hermes2D::NewtonSolver<double> newton(&dp, matrix_solver_type); try { newton.solve(coeff_vec, NEWTON_TOL, NEWTON_MAX_ITER); } catch(Hermes::Exceptions::Exception e) { e.printMsg(); error("Newton's iteration failed."); }; // Update previous time level solutions. Solution<double>::vector_to_solutions(coeff_vec, Hermes::vector<Space<double>*>(&xvel_space, &yvel_space, &p_space), Hermes::vector<Solution<double>*>(&xvel_prev_time, &yvel_prev_time, &p_prev_time)); } else { // Linear solve. info("Assembling and solving linear problem."); dp.assemble(matrix, rhs, false); if(solver->solve()) Solution<double>::vector_to_solutions(solver->get_sln_vector(), Hermes::vector<Space<double>*>(&xvel_space, &yvel_space, &p_space), Hermes::vector<Solution<double>*>(&xvel_prev_time, &yvel_prev_time, &p_prev_time)); else error ("Matrix solver failed.\n"); } // 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, HERMES_EPS_LOW); sprintf(title, "Pressure, time %g", current_time); pview.set_title(title); pview.show(&p_prev_time); } delete [] coeff_vec; delete matrix; delete rhs; delete solver; // Wait for all views to be closed. View::wait(); return 0; }
int main(int argc, char* argv[]) { // Load the mesh. Mesh mesh; MeshReaderH2D mloader; mloader.load("domain.mesh", &mesh); // Initial mesh refinements. for(int i = 0; i < INIT_REF_NUM; i++) mesh.refine_all_elements(); // Initialize boundary conditions. DefaultEssentialBCConst<std::complex<double> > bc(Hermes::vector<std::string>(BDY_BOTTOM, BDY_RIGHT, BDY_TOP, BDY_LEFT), std::complex<double>(0.0, 0.0)); EssentialBCs<std::complex<double> > bcs(&bc); // Create an H1 space. H1Space<std::complex<double> >* phi_space = new H1Space<std::complex<double> >(&mesh, &bcs, P_INIT); H1Space<std::complex<double> >* psi_space = new H1Space<std::complex<double> >(&mesh, &bcs, P_INIT); int ndof = Space<std::complex<double> >::get_num_dofs(Hermes::vector<Space<std::complex<double> > *>(phi_space, psi_space)); info("ndof = %d.", ndof); // Initialize previous time level solutions. ConstantSolution<std::complex<double> > phi_prev_time(&mesh, init_cond_phi); ConstantSolution<std::complex<double> > psi_prev_time(&mesh, init_cond_psi); // Initialize the weak formulation. WeakForm<std::complex<double> > wf(2); wf.add_matrix_form(0, 0, callback(biform_euler_0_0)); wf.add_matrix_form(0, 1, callback(biform_euler_0_1)); wf.add_matrix_form(1, 0, callback(biform_euler_1_0)); wf.add_matrix_form(1, 1, callback(biform_euler_1_1)); wf.add_vector_form(0, callback(liform_euler_0), HERMES_ANY, &phi_prev_time); wf.add_vector_form(1, callback(liform_euler_1), HERMES_ANY, &psi_prev_time); // Initialize views. ScalarView view("Psi", new WinGeom(0, 0, 600, 500)); view.fix_scale_width(80); // Time stepping loop: int nstep = (int)(T_FINAL/TAU + 0.5); for(int ts = 1; ts <= nstep; ts++) { info("Time step %d:", ts); info("Solving linear system."); // Initialize the FE problem. bool is_linear = true; DiscreteProblem<std::complex<double> > dp(&wf, Hermes::vector<Space<double>* *>(phi_space, psi_space), is_linear); SparseMatrix<std::complex<double> >* matrix = create_matrix<std::complex<double> >(matrix_solver_type); Vector<std::complex<double> >* rhs = create_vector<std::complex<double> >(matrix_solver_type); LinearSolver<std::complex<double> >* solver = create_linear_solver<std::complex<double> >(matrix_solver_type, matrix, rhs); // Assemble the stiffness matrix and right-hand side vector. info("Assembling the stiffness matrix and right-hand side vector."); dp.assemble(matrix, rhs); // Solve the linear system and if successful, obtain the solution. info("Solving the matrix problem."); if(solver->solve()) Solution<std::complex<double> >::vector_to_solutions(solver->get_sln_vector(), Hermes::vector<Space<std::complex<double> >*>(phi_space, psi_space), Hermes::vector<Solution<std::complex<double> > *>(&phi_prev_time, &psi_prev_time)); else error ("Matrix solver failed.\n"); // Show the new time level solution. char title[100]; sprintf(title, "Time step %d", ts); view.set_title(title); view.show(&psi_prev_time); } // Wait for all views to be closed. View::wait(); return 0; }
int main(int argc, char* argv[]) { // Time measurement. TimePeriod cpu_time; cpu_time.tick(); // Load the mesh. Mesh u1_mesh, u2_mesh; MeshReaderH2D mloader; mloader.load("bracket.mesh", &u1_mesh); // Initial mesh refinements. u1_mesh.refine_element_id(1); u1_mesh.refine_element_id(4); // Create initial mesh for the vertical displacement component. // This also initializes the multimesh hp-FEM. u2_mesh.copy(&u1_mesh); // Initialize boundary conditions. DefaultEssentialBCConst<double> zero_disp(BDY_RIGHT, 0.0); EssentialBCs<double> bcs(&zero_disp); // Create x- and y- displacement space using the default H1 shapeset. H1Space<double> u1_space(&u1_mesh, &bcs, P_INIT); H1Space<double> u2_space(&u2_mesh, &bcs, P_INIT); info("ndof = %d.", Space<double>::get_num_dofs(Hermes::vector<Space<double> *>(&u1_space, &u2_space))); // Initialize the weak formulation. // NOTE; These weak forms are identical to those in example P01-linear/08-system. CustomWeakForm wf(E, nu, rho*g1, BDY_TOP, f0, f1); // Initialize the FE problem. DiscreteProblem<double> dp(&wf, Hermes::vector<Space<double> *>(&u1_space, &u2_space)); // Initialize coarse and reference mesh solutions. Solution<double> u1_sln, u2_sln, u1_ref_sln, u2_ref_sln; // Initialize refinement selector. H1ProjBasedSelector<double> selector(CAND_LIST, CONV_EXP, H2DRS_DEFAULT_ORDER); // Initialize views. ScalarView s_view_0("Solution (x-displacement)", new WinGeom(0, 0, 400, 350)); s_view_0.show_mesh(false); ScalarView s_view_1("Solution (y-displacement)", new WinGeom(760, 0, 400, 350)); s_view_1.show_mesh(false); OrderView o_view_0("Mesh (x-displacement)", new WinGeom(410, 0, 340, 350)); OrderView o_view_1("Mesh (y-displacement)", new WinGeom(1170, 0, 340, 350)); ScalarView mises_view("Von Mises stress [Pa]", new WinGeom(0, 405, 400, 350)); // DOF and CPU convergence graphs. SimpleGraph graph_dof_est, graph_cpu_est; // Adaptivity loop: int as = 1; bool done = false; do { info("---- Adaptivity step %d:", as); // Construct globally refined reference mesh and setup reference space. Hermes::vector<Space<double> *>* ref_spaces = Space<double>::construct_refined_spaces(Hermes::vector<Space<double> *>(&u1_space, &u2_space)); // Initialize matrix solver. SparseMatrix<double>* matrix = create_matrix<double>(matrix_solver_type); Vector<double>* rhs = create_vector<double>(matrix_solver_type); LinearSolver<double>* solver = create_linear_solver<double>(matrix_solver_type, matrix, rhs); // Assemble the reference problem. info("Solving on reference mesh."); DiscreteProblem<double> dp(&wf, *ref_spaces); dp.assemble(matrix, rhs); // Time measurement. cpu_time.tick(); // Solve the linear system of the reference problem. If successful, obtain the solutions. if(solver->solve()) Solution<double>::vector_to_solutions(solver->get_sln_vector(), *ref_spaces, Hermes::vector<Solution *>(&u1_ref_sln, &u2_ref_sln)); else error ("Matrix solver failed.\n"); // Time measurement. cpu_time.tick(); // Project the fine mesh solution onto the coarse mesh. info("Projecting reference solution on coarse mesh."); OGProjection<double>::project_global(Hermes::vector<Space<double> *>(&u1_space, &u2_space), Hermes::vector<Solution<double> *>(&u1_ref_sln, &u2_ref_sln), Hermes::vector<Solution<double> *>(&u1_sln, &u2_sln), matrix_solver_type); // View the coarse mesh solution and polynomial orders. s_view_0.show(&u1_sln); o_view_0.show(&u1_space); s_view_1.show(&u2_sln); o_view_1.show(&u2_space); // For von Mises stress Filter. double lambda = (E * nu) / ((1 + nu) * (1 - 2*nu)); double mu = E / (2*(1 + nu)); VonMisesFilter stress(Hermes::vector<MeshFunction<double> *>(&u1_sln, &u2_sln), lambda, mu); mises_view.show(&stress, HERMES_EPS_HIGH, H2D_FN_VAL_0, &u1_sln, &u2_sln, 1e4); // Skip visualization time. cpu_time.tick(HERMES_SKIP); // Initialize adaptivity. Adapt<double>* adaptivity = new Adapt<double>(Hermes::vector<Space<double> *>(&u1_space, &u2_space)); /* // Register custom forms for error calculation. adaptivity->set_error_form(0, 0, bilinear_form_0_0<double, double>, bilinear_form_0_0<Ord, Ord>); adaptivity->set_error_form(0, 1, bilinear_form_0_1<double, double>, bilinear_form_0_1<Ord, Ord>); adaptivity->set_error_form(1, 0, bilinear_form_1_0<double, double>, bilinear_form_1_0<Ord, Ord>); adaptivity->set_error_form(1, 1, bilinear_form_1_1<double, double>, bilinear_form_1_1<Ord, Ord>); */ // Calculate error estimate for each solution component and the total error estimate. info("Calculating error estimate and exact error."); Hermes::vector<double> err_est_rel; double err_est_rel_total = adaptivity->calc_err_est(Hermes::vector<Solution<double> *>(&u1_sln, &u2_sln), Hermes::vector<Solution<double> *>(&u1_ref_sln, &u2_ref_sln), &err_est_rel) * 100; // Time measurement. cpu_time.tick(); // Report results. info("ndof_coarse[0]: %d, ndof_fine[0]: %d, err_est_rel[0]: %g%%", u1_space.Space<double>::get_num_dofs(), Space<double>::get_num_dofs((*ref_spaces)[0]), err_est_rel[0]*100); info("ndof_coarse[1]: %d, ndof_fine[1]: %d, err_est_rel[1]: %g%%", u2_space.Space<double>::get_num_dofs(), Space<double>::get_num_dofs((*ref_spaces)[1]), err_est_rel[1]*100); info("ndof_coarse_total: %d, ndof_fine_total: %d, err_est_rel_total: %g%%", Space<double>::get_num_dofs(Hermes::vector<Space<double> *>(&u1_space, &u2_space)), Space<double>::get_num_dofs(*ref_spaces), err_est_rel_total); // Add entry to DOF and CPU convergence graphs. graph_dof_est.add_values(Space<double>::get_num_dofs(Hermes::vector<Space<double> *>(&u1_space, &u2_space)), err_est_rel_total); graph_dof_est.save("conv_dof_est.dat"); graph_cpu_est.add_values(cpu_time.accumulated(), err_est_rel_total); graph_cpu_est.save("conv_cpu_est.dat"); // If err_est too large, adapt the mesh. if (err_est_rel_total < ERR_STOP) done = true; else { info("Adapting coarse mesh."); done = adaptivity->adapt(Hermes::vector<RefinementSelectors::Selector<double> *>(&selector, &selector), THRESHOLD, STRATEGY, MESH_REGULARITY); } if (Space<double>::get_num_dofs(Hermes::vector<Space<double> *>(&u1_space, &u2_space)) >= NDOF_STOP) done = true; // Clean up. delete solver; delete matrix; delete rhs; delete adaptivity; if(done == false) for(unsigned int i = 0; i < ref_spaces->size(); i++) delete (*ref_spaces)[i]->get_mesh(); delete ref_spaces; // Increase counter. as++; } while (done == false); verbose("Total running time: %g s", cpu_time.accumulated()); // Show the reference solution - the final result. s_view_0.set_title("Fine mesh solution (x-displacement)"); s_view_0.show(&u1_ref_sln); s_view_1.set_title("Fine mesh solution (y-displacement)"); s_view_1.show(&u2_ref_sln); // For von Mises stress Filter. double lambda = (E * nu) / ((1 + nu) * (1 - 2*nu)); double mu = E / (2*(1 + nu)); VonMisesFilter stress(Hermes::vector<MeshFunction<double> *>(&u1_ref_sln, &u2_ref_sln), lambda, mu); mises_view.show(&stress, HERMES_EPS_HIGH, H2D_FN_VAL_0, &u1_ref_sln, &u2_ref_sln, 1e4); // Wait for all views to be closed. View::wait(); return 0; }
bool DuffingFloquet() { int np = MPIComm::world().getNProc(); TEUCHOS_TEST_FOR_EXCEPT(np != 1); const double pi = 4.0*atan(1.0); /* We will do our linear algebra using Epetra */ VectorType<double> vecType = new EpetraVectorType(); /* Create a periodic mesh */ int nx = 128; MeshType meshType = new PeriodicMeshType1D(); MeshSource mesher = new PeriodicLineMesher(0.0, 2.0*pi, nx, meshType); Mesh mesh = mesher.getMesh(); /* Create a cell filter that will identify the maximal cells * in the interior of the domain */ CellFilter interior = new MaximalCellFilter(); CellFilter pts = new DimensionalCellFilter(0); CellFilter left = pts.subset(new CoordinateValueCellPredicate(0,0.0)); CellFilter right = pts.subset(new CoordinateValueCellPredicate(0,2.0*pi)); /* Create unknown and test functions, discretized using first-order * Lagrange interpolants */ Expr u1 = new UnknownFunction(new Lagrange(1), "u1"); Expr u2 = new UnknownFunction(new Lagrange(1), "u2"); Expr v1 = new TestFunction(new Lagrange(1), "v1"); Expr v2 = new TestFunction(new Lagrange(1), "v2"); /* Create differential operator and coordinate function */ Expr dx = new Derivative(0); Expr x = new CoordExpr(0); /* We need a quadrature rule for doing the integrations */ QuadratureFamily quad = new GaussianQuadrature(4); double F0 = 0.5; double gamma = 2.0/3.0; double a0 = 1.0; double w0 = 1.0; double eps = 0.5; Expr u1Guess = -0.75*cos(x) + 0.237*sin(x); Expr u2Guess = 0.237*cos(x) + 0.75*sin(x); DiscreteSpace discSpace(mesh, List(new Lagrange(1), new Lagrange(1)), vecType); L2Projector proj(discSpace, List(u1Guess, u2Guess)); Expr u0 = proj.project(); Expr rhs1 = u2; Expr rhs2 = -w0*w0*u1 - gamma*u2 - eps*w0*w0*pow(u1,3.0)/a0/a0 + F0*w0*w0*sin(x); /* Define the weak form */ Expr eqn = Integral(interior, v1*(dx*u1 - rhs1) + v2*(dx*u2 - rhs2), quad); Expr dummyBC ; NonlinearProblem prob(mesh, eqn, dummyBC, List(v1,v2), List(u1,u2), u0, vecType); ParameterXMLFileReader reader("nox.xml"); ParameterList solverParams = reader.getParameters(); Out::root() << "finding periodic solution" << endl; NOXSolver solver(solverParams); prob.solve(solver); /* unfold the solution onto a non-periodic mesh */ Expr uP = unfoldPeriodicDiscreteFunction(u0, "u_p"); Out::root() << "uP=" << uP << endl; Mesh unfoldedMesh = DiscreteFunction::discFunc(uP)->mesh(); DiscreteSpace unfDiscSpace = DiscreteFunction::discFunc(uP)->discreteSpace(); FieldWriter writer = new MatlabWriter("Floquet.dat"); writer.addMesh(unfoldedMesh); writer.addField("u_p[0]", new ExprFieldWrapper(uP[0])); writer.addField("u_p[1]", new ExprFieldWrapper(uP[1])); Array<Expr> a(2); a[0] = new Sundance::Parameter(0.0, "a1"); a[1] = new Sundance::Parameter(0.0, "a2"); Expr bc = EssentialBC(left, v1*(u1-uP[0]-a[0]) + v2*(u2-uP[1]-a[1]), quad); NonlinearProblem unfProb(unfoldedMesh, eqn, bc, List(v1,v2), List(u1,u2), uP, vecType); unfProb.setEvalPoint(uP); LinearOperator<double> J = unfProb.allocateJacobian(); Vector<double> b = J.domain().createMember(); LinearSolver<double> linSolver = LinearSolverBuilder::createSolver("amesos.xml"); SerialDenseMatrix<int, double> F(a.size(), a.size()); for (int i=0; i<a.size(); i++) { Out::root() << "doing perturbed orbit #" << i << endl; for (int j=0; j<a.size(); j++) { if (i==j) a[j].setParameterValue(1.0); else a[j].setParameterValue(0.0); } unfProb.computeJacobianAndFunction(J, b); Vector<double> w = b.copy(); linSolver.solve(J, b, w); Expr w_i = new DiscreteFunction(unfDiscSpace, w); for (int j=0; j<a.size(); j++) { Out::root() << "postprocessing" << i << endl; writer.addField("w[" + Teuchos::toString(i) + ", " + Teuchos::toString(j) + "]", new ExprFieldWrapper(w_i[j])); Expr g = Integral(right, w_i[j], quad); F(j,i) = evaluateIntegral(unfoldedMesh, g); } } writer.write(); Out::root() << "Floquet matrix = " << endl << F << endl; Out::root() << "doing eigenvalue analysis" << endl; Array<double> ew_r(a.size()); Array<double> ew_i(a.size()); int lWork = 6*a.size(); Array<double> work(lWork); int info = 0; LAPACK<int, double> lapack; lapack.GEEV('N','N', a.size(), F.values(), a.size(), &(ew_r[0]), &(ew_i[0]), 0, 1, 0, 1, &(work[0]), lWork, &info); TEUCHOS_TEST_FOR_EXCEPTION(info != 0, std::runtime_error, "LAPACK GEEV returned error code =" << info); Array<double> ew(a.size()); for (int i=0; i<a.size(); i++) { ew[i] = sqrt(ew_r[i]*ew_r[i]+ew_i[i]*ew_i[i]); Out::root() << setw(5) << i << setw(16) << ew_r[i] << setw(16) << ew_i[i] << setw(16) << ew[i] << endl; } double err = ::fabs(ew[0] - 0.123); return SundanceGlobal::checkTest(err, 0.001); }
// Test code. void solve(LinearSolver<double> &solver, int n) { if (!solver.solve()) printf("Unable to solve.\n"); }
int main(int argc, char* argv[]) { // Load the mesh. Mesh mesh; MeshReaderH2DXML mloader; mloader.load("domain-arcs.xml", &mesh); mesh.refine_towards_boundary(BDY_SOLID_WALL_PROFILE, INIT_REF_NUM_BOUNDARY_ANISO, true, true); mesh.refine_towards_vertex(0, INIT_REF_NUM_VERTEX, true); MeshView m; m.show(&mesh); m.wait_for_close(); // Initialize boundary condition types and spaces with default shapesets. L2Space<double>space_rho(&mesh, P_INIT); L2Space<double>space_rho_v_x(&mesh, P_INIT); L2Space<double>space_rho_v_y(&mesh, P_INIT); L2Space<double>space_e(&mesh, P_INIT); int ndof = Space<double>::get_num_dofs(Hermes::vector<const Space<double>*>(&space_rho, &space_rho_v_x, &space_rho_v_y, &space_e)); info("Initial coarse ndof: %d", ndof); // Initialize solutions, set initial conditions. ConstantSolution<double> sln_rho(&mesh, RHO_EXT); ConstantSolution<double> sln_rho_v_x(&mesh, RHO_EXT * V1_EXT); ConstantSolution<double> sln_rho_v_y(&mesh, RHO_EXT * V2_EXT); ConstantSolution<double> sln_e(&mesh, QuantityCalculator::calc_energy(RHO_EXT, RHO_EXT * V1_EXT, RHO_EXT * V2_EXT, P_EXT, KAPPA)); ConstantSolution<double> prev_rho(&mesh, RHO_EXT); ConstantSolution<double> prev_rho_v_x(&mesh, RHO_EXT * V1_EXT); ConstantSolution<double> prev_rho_v_y(&mesh, RHO_EXT * V2_EXT); ConstantSolution<double> prev_e(&mesh, QuantityCalculator::calc_energy(RHO_EXT, RHO_EXT * V1_EXT, RHO_EXT * V2_EXT, P_EXT, KAPPA)); Solution<double> rsln_rho, rsln_rho_v_x, rsln_rho_v_y, rsln_e; // Numerical flux. VijayasundaramNumericalFlux num_flux(KAPPA); // Initialize weak formulation. EulerEquationsWeakFormSemiImplicitMultiComponent wf(&num_flux, KAPPA, RHO_EXT, V1_EXT, V2_EXT, P_EXT, BDY_SOLID_WALL, BDY_SOLID_WALL_PROFILE, BDY_INLET, BDY_OUTLET, &prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e); // Filters for visualization of Mach number, pressure and entropy. MachNumberFilter Mach_number(Hermes::vector<MeshFunction<double>*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e), KAPPA); PressureFilter pressure(Hermes::vector<MeshFunction<double>*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e), KAPPA); EntropyFilter entropy(Hermes::vector<MeshFunction<double>*>(&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)); OrderView space_view("Space", new WinGeom(700, 400, 600, 300)); // Initialize refinement selector. L2ProjBasedSelector<double> selector(CAND_LIST, CONV_EXP, MAX_P_ORDER); selector.set_error_weights(1.0, 1.0, 1.0); // Set up CFL calculation class. CFLCalculation CFL(CFL_NUMBER, KAPPA); // Look for a saved solution on the disk. Continuity<double> continuity(Continuity<double>::onlyTime); int iteration = 0; double t = 0; bool loaded_now = false; if(REUSE_SOLUTION && continuity.have_record_available()) { continuity.get_last_record()->load_mesh(&mesh); continuity.get_last_record()->load_spaces(Hermes::vector<Space<double> *>(&space_rho, &space_rho_v_x, &space_rho_v_y, &space_e), Hermes::vector<SpaceType>(HERMES_L2_SPACE, HERMES_L2_SPACE, HERMES_L2_SPACE, HERMES_L2_SPACE), Hermes::vector<Mesh *>(&mesh, &mesh, &mesh, &mesh)); continuity.get_last_record()->load_time_step_length(time_step); t = continuity.get_last_record()->get_time() + time_step; iteration = continuity.get_num() * EVERY_NTH_STEP + 1; loaded_now = true; } // Time stepping loop. for(; t < 5.0; t += time_step) { CFL.set_number(CFL_NUMBER + (t/5.0) * 10.0); info("---- Time step %d, time %3.5f.", iteration++, t); // Periodic global derefinements. if (iteration > 1 && iteration % UNREF_FREQ == 0 && REFINEMENT_COUNT > 0) { info("Global mesh derefinement."); REFINEMENT_COUNT = 0; space_rho.unrefine_all_mesh_elements(true); space_rho.adjust_element_order(-1, P_INIT); space_rho_v_x.copy_orders(&space_rho); space_rho_v_y.copy_orders(&space_rho); space_e.copy_orders(&space_rho); } // Adaptivity loop: int as = 1; int ndofs_prev = 0; bool done = false; do { info("---- Adaptivity step %d:", as); // Construct globally refined reference mesh and setup reference space. int order_increase = 1; Hermes::vector<Space<double> *>* ref_spaces = Space<double>::construct_refined_spaces(Hermes::vector<Space<double> *>(&space_rho, &space_rho_v_x, &space_rho_v_y, &space_e), order_increase); Hermes::vector<const Space<double> *> ref_spaces_const((*ref_spaces)[0], (*ref_spaces)[1], (*ref_spaces)[2], (*ref_spaces)[3]); if(ndofs_prev != 0) if(Space<double>::get_num_dofs(ref_spaces_const) == ndofs_prev) selector.set_error_weights(2.0 * selector.get_error_weight_h(), 1.0, 1.0); else selector.set_error_weights(1.0, 1.0, 1.0); ndofs_prev = Space<double>::get_num_dofs(ref_spaces_const); // Project the previous time level solution onto the new fine mesh. info("Projecting the previous time level solution onto the new fine mesh."); if(loaded_now) { loaded_now = false; continuity.get_last_record()->load_solutions(Hermes::vector<Solution<double>*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e), Hermes::vector<Space<double> *>((*ref_spaces)[0], (*ref_spaces)[1], (*ref_spaces)[2], (*ref_spaces)[3])); } else { OGProjection<double>::project_global(ref_spaces_const, Hermes::vector<Solution<double>*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e), Hermes::vector<Solution<double>*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e), matrix_solver, Hermes::vector<Hermes::Hermes2D::ProjNormType>()); if(iteration > std::max((int)(continuity.get_num() * EVERY_NTH_STEP + 2), 1) && as > 1) { delete rsln_rho.get_mesh(); delete rsln_rho.get_space(); rsln_rho.own_mesh = false; delete rsln_rho_v_x.get_mesh(); delete rsln_rho_v_x.get_space(); rsln_rho_v_x.own_mesh = false; delete rsln_rho_v_y.get_mesh(); delete rsln_rho_v_y.get_space(); rsln_rho_v_y.own_mesh = false; delete rsln_e.get_mesh(); delete rsln_e.get_space(); rsln_e.own_mesh = false; } } // Report NDOFs. info("ndof_coarse: %d, ndof_fine: %d.", Space<double>::get_num_dofs(Hermes::vector<const Space<double> *>(&space_rho, &space_rho_v_x, &space_rho_v_y, &space_e)), Space<double>::get_num_dofs(ref_spaces_const)); // Assemble the reference problem. info("Solving on reference mesh."); DiscreteProblem<double> dp(&wf, ref_spaces_const); SparseMatrix<double>* matrix = create_matrix<double>(matrix_solver); Vector<double>* rhs = create_vector<double>(matrix_solver); LinearSolver<double>* solver = create_linear_solver<double>(matrix_solver, matrix, rhs); 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."); if(solver->solve()) if(!SHOCK_CAPTURING) Solution<double>::vector_to_solutions(solver->get_sln_vector(), ref_spaces_const, Hermes::vector<Solution<double>*>(&rsln_rho, &rsln_rho_v_x, &rsln_rho_v_y, &rsln_e)); else { FluxLimiter flux_limiter(FluxLimiter::Kuzmin, solver->get_sln_vector(), ref_spaces_const, true); flux_limiter.limit_second_orders_according_to_detector(Hermes::vector<Space<double> *>(&space_rho, &space_rho_v_x, &space_rho_v_y, &space_e)); flux_limiter.limit_according_to_detector(Hermes::vector<Space<double> *>(&space_rho, &space_rho_v_x, &space_rho_v_y, &space_e)); flux_limiter.get_limited_solutions(Hermes::vector<Solution<double>*>(&rsln_rho, &rsln_rho_v_x, &rsln_rho_v_y, &rsln_e)); } else error ("Matrix solver failed.\n"); // Project the fine mesh solution onto the coarse mesh. info("Projecting reference solution on coarse mesh."); OGProjection<double>::project_global(Hermes::vector<const Space<double> *>(&space_rho, &space_rho_v_x, &space_rho_v_y, &space_e), Hermes::vector<Solution<double>*>(&rsln_rho, &rsln_rho_v_x, &rsln_rho_v_y, &rsln_e), Hermes::vector<Solution<double>*>(&sln_rho, &sln_rho_v_x, &sln_rho_v_y, &sln_e), matrix_solver, Hermes::vector<ProjNormType>(HERMES_L2_NORM, HERMES_L2_NORM, HERMES_L2_NORM, HERMES_L2_NORM)); // Calculate element errors and total error estimate. info("Calculating error estimate."); Adapt<double>* adaptivity = new Adapt<double>(Hermes::vector<Space<double> *>(&space_rho, &space_rho_v_x, &space_rho_v_y, &space_e), Hermes::vector<ProjNormType>(HERMES_L2_NORM, HERMES_L2_NORM, HERMES_L2_NORM, HERMES_L2_NORM)); double err_est_rel_total = adaptivity->calc_err_est(Hermes::vector<Solution<double>*>(&sln_rho, &sln_rho_v_x, &sln_rho_v_y, &sln_e), Hermes::vector<Solution<double>*>(&rsln_rho, &rsln_rho_v_x, &rsln_rho_v_y, &rsln_e)) * 100; CFL.calculate_semi_implicit(Hermes::vector<Solution<double> *>(&rsln_rho, &rsln_rho_v_x, &rsln_rho_v_y, &rsln_e), (*ref_spaces)[0]->get_mesh(), time_step); // Report results. info("err_est_rel: %g%%", err_est_rel_total); // If err_est too large, adapt the mesh. if (err_est_rel_total < ERR_STOP) done = true; else { info("Adapting coarse mesh."); if (Space<double>::get_num_dofs(Hermes::vector<const Space<double> *>(&space_rho, &space_rho_v_x, &space_rho_v_y, &space_e)) >= NDOF_STOP) done = true; else { REFINEMENT_COUNT++; done = adaptivity->adapt(Hermes::vector<RefinementSelectors::Selector<double> *>(&selector, &selector, &selector, &selector), THRESHOLD, STRATEGY, MESH_REGULARITY); } if(!done) as++; } // Visualization and saving on disk. if(done && (iteration - 1) % EVERY_NTH_STEP == 0 && iteration > 1) { // 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); pressure_view.save_numbered_screenshot("Pressure-%u.bmp", iteration - 1, true); Mach_number_view.save_numbered_screenshot("Mach-%u.bmp", iteration - 1, true); } // 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, "Mach number-%i.vtk", iteration - 1); lin.save_solution_vtk(&Mach_number, filename, "MachNumber", false); } // Save a current state on the disk. if(iteration > 1) { continuity.add_record(t); continuity.get_last_record()->save_mesh(&mesh); continuity.get_last_record()->save_spaces(Hermes::vector<Space<double> *>(&space_rho, &space_rho_v_x, &space_rho_v_y, &space_e)); continuity.get_last_record()->save_solutions(Hermes::vector<Solution<double>*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e)); continuity.get_last_record()->save_time_step_length(time_step); } } // Clean up. delete solver; delete matrix; delete rhs; delete adaptivity; } while (done == false); // Copy the solutions into the previous time level ones. prev_rho.copy(&rsln_rho); prev_rho_v_x.copy(&rsln_rho_v_x); prev_rho_v_y.copy(&rsln_rho_v_y); prev_e.copy(&rsln_e); delete rsln_rho.get_mesh(); delete rsln_rho.get_space(); rsln_rho.own_mesh = false; delete rsln_rho_v_x.get_mesh(); delete rsln_rho_v_x.get_space(); rsln_rho_v_x.own_mesh = false; delete rsln_rho_v_y.get_mesh(); delete rsln_rho_v_y.get_space(); rsln_rho_v_y.own_mesh = false; delete rsln_e.get_mesh(); delete rsln_e.get_space(); rsln_e.own_mesh = false; } pressure_view.close(); entropy_production_view.close(); Mach_number_view.close(); return 0; }
int main(int argc, char* argv[]) { // Load mesh. load_mesh(mesh, "domain.xml", INIT_REF_NUM); // Create an H1 space with default shapeset. SpaceSharedPtr<double> space(new H1Space<double>(mesh, &essential_bcs, P_INIT)); solver.set_weak_formulation(&weak_formulation); solver.set_space(space); #pragma region Time stepping loop. /* solver.set_time_step(time_step_length); do { std::cout << "Time step: " << time_step_number << std::endl; #pragma region Spatial adaptivity loop. adaptivity.set_space(space); int adaptivity_step = 1; do { std::cout << "Adaptivity step: " << adaptivity_step << std::endl; #pragma region Construct globally refined reference mesh and setup reference space. MeshSharedPtr ref_mesh = ref_mesh_creator.create_ref_mesh(); SpaceSharedPtr<double> ref_space = ref_space_creator.create_ref_space(space, ref_mesh); solver.set_space(ref_space); #pragma endregion try { // Solving. solver.solve(get_initial_Newton_guess(adaptivity_step, &weak_formulation, space, ref_space, sln_time_prev)); Solution<double>::vector_to_solution(solver.get_sln_vector(), ref_space, sln_time_new); } catch(Exceptions::Exception& e) { std::cout << e.info(); } catch(std::exception& e) { std::cout << e.what(); } // Project the fine mesh solution onto the coarse mesh. OGProjection<double>::project_global(space, sln_time_new, sln_time_new_coarse); // Calculate element errors and error estimate. errorCalculator.calculate_errors(sln_time_new_coarse, sln_time_new); double error_estimate = errorCalculator.get_total_error_squared() * 100; std::cout << "Error estimate: " << error_estimate << "%" << std::endl; // Visualize the solution and mesh. display(sln_time_new, ref_space); // If err_est too large, adapt the mesh. if (error_estimate < ERR_STOP) break; else adaptivity.adapt(&refinement_selector); adaptivity_step++; } while(true); #pragma endregion #pragma region No adaptivity in space. try { // Solving. solver.solve(sln_time_prev); // Get the solution for visualization etc. from the coefficient vector. Solution<double>::vector_to_solution(solver.get_sln_vector(), space, sln_time_new); // Visualize the solution and mesh. display(sln_time_new, space); } catch(Exceptions::Exception& e) { std::cout << e.info(); } catch(std::exception& e) { std::cout << e.what(); } #pragma endregion sln_time_prev->copy(sln_time_new); // Increase current time and counter of time steps. current_time += time_step_length; time_step_number++; } while (current_time < T_FINAL); */ #pragma endregion #pragma region No time stepping (= stationary problem). try { // Solving. solver.solve(); // Get the solution for visualization etc. from the coefficient vector. Solution<double>::vector_to_solution(solver.get_sln_vector(), space, sln_time_new); // Visualize the solution and mesh. display(sln_time_new, space); } catch (Exceptions::Exception& e) { std::cout << e.info(); } catch (std::exception& e) { std::cout << e.what(); } #pragma endregion View::wait(); return 0; }
int main(int argc, char* args[]) { // Load the mesh. Mesh mesh; MeshReaderH2D mloader; mloader.load("square.mesh", &mesh); // Perform initial mesh refinement. for (int i=0; i<INIT_REF; i++) mesh.refine_all_elements(); mesh.refine_by_criterion(criterion, INIT_REF_CRITERION); MeshView m; m.show(&mesh); // Set up the solver, matrix, and rhs according to the solver selection. SparseMatrix<double>* matrix = create_matrix<double>(matrix_solver_type); Vector<double>* rhs = create_vector<double>(matrix_solver_type); LinearSolver<double>* solver = create_linear_solver<double>(matrix_solver_type, matrix, rhs); ScalarView view1("Solution - Discontinuous Galerkin FEM", new WinGeom(900, 0, 450, 350)); ScalarView view2("Solution - Standard continuous FEM", new WinGeom(900, 400, 450, 350)); if(WANT_DG) { // Create an L2 space. L2Space<double> space_l2(&mesh, P_INIT); // Initialize the solution. Solution<double> sln_l2; // Initialize the weak formulation. CustomWeakForm wf_l2(BDY_BOTTOM_LEFT); // Initialize the FE problem. DiscreteProblem<double> dp_l2(&wf_l2, &space_l2); info("Assembling Discontinuous Galerkin (nelem: %d, ndof: %d).", mesh.get_num_active_elements(), space_l2.get_num_dofs()); dp_l2.assemble(matrix, rhs); // Solve the linear system. If successful, obtain the solution. info("Solving Discontinuous Galerkin."); if(solver->solve()) if(DG_SHOCK_CAPTURING) { FluxLimiter flux_limiter(FluxLimiter::Kuzmin, solver->get_sln_vector(), &space_l2, true); flux_limiter.limit_second_orders_according_to_detector(); flux_limiter.limit_according_to_detector(); flux_limiter.get_limited_solution(&sln_l2); view1.set_title("Solution - limited Discontinuous Galerkin FEM"); } else Solution<double>::vector_to_solution(solver->get_sln_vector(), &space_l2, &sln_l2); else error ("Matrix solver failed.\n"); // View the solution. view1.show(&sln_l2); } if(WANT_FEM) { // Create an H1 space. H1Space<double> space_h1(&mesh, P_INIT); // Initialize the solution. Solution<double> sln_h1; // Initialize the weak formulation. CustomWeakForm wf_h1(BDY_BOTTOM_LEFT, false); // Initialize the FE problem. DiscreteProblem<double> dp_h1(&wf_h1, &space_h1); // Set up the solver, matrix, and rhs according to the solver selection. SparseMatrix<double>* matrix = create_matrix<double>(matrix_solver_type); Vector<double>* rhs = create_vector<double>(matrix_solver_type); LinearSolver<double>* solver = create_linear_solver<double>(matrix_solver_type, matrix, rhs); info("Assembling Continuous FEM (nelem: %d, ndof: %d).", mesh.get_num_active_elements(), space_h1.get_num_dofs()); dp_h1.assemble(matrix, rhs); // Solve the linear system. If successful, obtain the solution. info("Solving Continuous FEM."); if(solver->solve()) Solution<double>::vector_to_solution(solver->get_sln_vector(), &space_h1, &sln_h1); else error ("Matrix solver failed.\n"); // View the solution. view2.show(&sln_h1); } // Clean up. delete solver; delete matrix; delete rhs; // Wait for keyboard or mouse input. View::wait(); return 0; }
int main(int argc, char* argv[]) { // Load the mesh. Mesh mesh; MeshReaderH2D mloader; mloader.load("channel.mesh", &mesh); // Perform initial mesh refinements. for (int i = 0; i < INIT_REF_NUM; i++) mesh.refine_all_elements(0, true); // Initialize boundary condition types and spaces with default shapesets. L2Space<double> space_rho(&mesh, P_INIT); L2Space<double> space_rho_v_x(&mesh, P_INIT); L2Space<double> space_rho_v_y(&mesh, P_INIT); L2Space<double> space_e(&mesh, P_INIT); // Initialize solutions, set initial conditions. ConstantSolution<double> sln_rho(&mesh, RHO_INIT); ConstantSolution<double> sln_rho_v_x(&mesh, RHO_INIT * V1_INIT); ConstantSolution<double> sln_rho_v_y(&mesh, RHO_INIT * V2_INIT); ConstantSolution<double> sln_e(&mesh, QuantityCalculator::calc_energy(RHO_INIT, RHO_INIT * V1_INIT, RHO_INIT * V2_INIT, PRESSURE_INIT, KAPPA)); ConstantSolution<double> prev_rho(&mesh, RHO_INIT); ConstantSolution<double> prev_rho_v_x(&mesh, RHO_INIT * V1_INIT); ConstantSolution<double> prev_rho_v_y(&mesh, RHO_INIT * V2_INIT); ConstantSolution<double> prev_e(&mesh, QuantityCalculator::calc_energy(RHO_INIT, RHO_INIT * V1_INIT, RHO_INIT * V2_INIT, PRESSURE_INIT, KAPPA)); Solution<double> rsln_rho, rsln_rho_v_x, rsln_rho_v_y, rsln_e; // Numerical flux. OsherSolomonNumericalFlux num_flux(KAPPA); // For saving to the disk. Continuity<double> continuity(Continuity<double>::onlyNumber); // Initialize weak formulation. EulerEquationsWeakFormSemiImplicitMultiComponentTwoInflows wf(&num_flux, KAPPA, RHO_LEFT, V1_LEFT, V2_LEFT, PRESSURE_LEFT, RHO_TOP, V1_TOP, V2_TOP, PRESSURE_TOP, BDY_SOLID_WALL, BDY_INLET_LEFT, BDY_INLET_TOP, BDY_OUTLET, &prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e); // Filters for visualization of Mach number, pressure and entropy. MachNumberFilter Mach_number(Hermes::vector<MeshFunction<double>*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e), KAPPA); PressureFilter pressure(Hermes::vector<MeshFunction<double>*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e), KAPPA); EntropyFilter entropy(Hermes::vector<MeshFunction<double>*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e), KAPPA, RHO_INIT, P_INIT); 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)); // Initialize refinement selector. L2ProjBasedSelector<double> selector(CAND_LIST, CONV_EXP, MAX_P_ORDER); selector.set_error_weights(1.0, 1.0, 1.0); // Set up CFL calculation class. CFLCalculation CFL(CFL_NUMBER, KAPPA); // Time stepping loop. int iteration = 0; double t = 0; for(; t < 4.0; t += time_step) { info("---- Time step %d, time %3.5f.", iteration++, t); // Periodic global derefinements. if (iteration > 1 && iteration % UNREF_FREQ == 0 && REFINEMENT_COUNT > 0) { info("Global mesh derefinement."); REFINEMENT_COUNT = 0; space_rho.unrefine_all_mesh_elements(true); space_rho.adjust_element_order(-1, P_INIT); space_rho_v_x.copy_orders(&space_rho); space_rho_v_y.copy_orders(&space_rho); space_e.copy_orders(&space_rho); } // Adaptivity loop: int as = 1; int ndofs_prev = 0; bool done = false; do { info("---- Adaptivity step %d:", as); // Construct globally refined reference mesh and setup reference space. int order_increase = 1; Hermes::vector<Space<double> *>* ref_spaces = Space<double>::construct_refined_spaces(Hermes::vector<Space<double> *>(&space_rho, &space_rho_v_x, &space_rho_v_y, &space_e), order_increase); if(ndofs_prev != 0) if(Space<double>::get_num_dofs(*ref_spaces) == ndofs_prev) selector.set_error_weights(2.0 * selector.get_error_weight_h(), 1.0, 1.0); else selector.set_error_weights(1.0, 1.0, 1.0); ndofs_prev = Space<double>::get_num_dofs(*ref_spaces); // Project the previous time level solution onto the new fine mesh. info("Projecting the previous time level solution onto the new fine mesh."); OGProjection<double>::project_global(*ref_spaces, Hermes::vector<Solution<double>*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e), Hermes::vector<Solution<double>*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e), matrix_solver_type, Hermes::vector<Hermes::Hermes2D::ProjNormType>(), iteration > 1); // Report NDOFs. info("ndof_coarse: %d, ndof_fine: %d.", Space<double>::get_num_dofs(Hermes::vector<Space<double> *>(&space_rho, &space_rho_v_x, &space_rho_v_y, &space_e)), Space<double>::get_num_dofs(*ref_spaces)); // Assemble the reference problem. info("Solving on reference mesh."); DiscreteProblem<double> dp(&wf, *ref_spaces); SparseMatrix<double>* matrix = create_matrix<double>(matrix_solver_type); Vector<double>* rhs = create_vector<double>(matrix_solver_type); LinearSolver<double>* solver = create_linear_solver<double>(matrix_solver_type, matrix, rhs); wf.set_time_step(time_step); dp.assemble(matrix, rhs); // Solve the matrix problem. info("Solving the matrix problem."); if(solver->solve()) if(!SHOCK_CAPTURING) Solution<double>::vector_to_solutions(solver->get_sln_vector(), *ref_spaces, Hermes::vector<Solution<double>*>(&rsln_rho, &rsln_rho_v_x, &rsln_rho_v_y, &rsln_e)); else { FluxLimiter flux_limiter(FluxLimiter::Kuzmin, solver->get_sln_vector(), *ref_spaces, true); flux_limiter.limit_second_orders_according_to_detector(Hermes::vector<Space<double> *>(&space_rho, &space_rho_v_x, &space_rho_v_y, &space_e)); flux_limiter.limit_according_to_detector(Hermes::vector<Space<double> *>(&space_rho, &space_rho_v_x, &space_rho_v_y, &space_e)); flux_limiter.get_limited_solutions(Hermes::vector<Solution<double>*>(&rsln_rho, &rsln_rho_v_x, &rsln_rho_v_y, &rsln_e)); } else error ("Matrix solver failed.\n"); // Project the fine mesh solution onto the coarse mesh. info("Projecting reference solution on coarse mesh."); OGProjection<double>::project_global(Hermes::vector<Space<double> *>(&space_rho, &space_rho_v_x, &space_rho_v_y, &space_e), Hermes::vector<Solution<double>*>(&rsln_rho, &rsln_rho_v_x, &rsln_rho_v_y, &rsln_e), Hermes::vector<Solution<double>*>(&sln_rho, &sln_rho_v_x, &sln_rho_v_y, &sln_e), matrix_solver_type, Hermes::vector<ProjNormType>(HERMES_L2_NORM, HERMES_L2_NORM, HERMES_L2_NORM, HERMES_L2_NORM)); // Calculate element errors and total error estimate. info("Calculating error estimate."); Adapt<double>* adaptivity = new Adapt<double>(Hermes::vector<Space<double> *>(&space_rho, &space_rho_v_x, &space_rho_v_y, &space_e), Hermes::vector<ProjNormType>(HERMES_L2_NORM, HERMES_L2_NORM, HERMES_L2_NORM, HERMES_L2_NORM)); double err_est_rel_total = adaptivity->calc_err_est(Hermes::vector<Solution<double>*>(&sln_rho, &sln_rho_v_x, &sln_rho_v_y, &sln_e), Hermes::vector<Solution<double>*>(&rsln_rho, &rsln_rho_v_x, &rsln_rho_v_y, &rsln_e)) * 100; CFL.calculate_semi_implicit(Hermes::vector<Solution<double> *>(&rsln_rho, &rsln_rho_v_x, &rsln_rho_v_y, &rsln_e), (*ref_spaces)[0]->get_mesh(), time_step); // Report results. info("err_est_rel: %g%%", err_est_rel_total); // If err_est too large, adapt the mesh. if (err_est_rel_total < ERR_STOP) done = true; else { info("Adapting coarse mesh."); done = adaptivity->adapt(Hermes::vector<RefinementSelectors::Selector<double> *>(&selector, &selector, &selector, &selector), THRESHOLD, STRATEGY, MESH_REGULARITY); REFINEMENT_COUNT++; if (Space<double>::get_num_dofs(Hermes::vector<Space<double> *>(&space_rho, &space_rho_v_x, &space_rho_v_y, &space_e)) >= NDOF_STOP) done = true; else as++; } // Clean up. delete solver; delete matrix; delete rhs; delete adaptivity; if(!done) for(unsigned int i = 0; i < ref_spaces->size(); i++) delete (*ref_spaces)[i]; } while (done == false); // Copy the solutions into the previous time level ones. prev_rho.copy(&rsln_rho); prev_rho_v_x.copy(&rsln_rho_v_x); prev_rho_v_y.copy(&rsln_rho_v_y); prev_e.copy(&rsln_e); delete rsln_rho.get_mesh(); rsln_rho.own_mesh = false; delete rsln_rho_v_x.get_mesh(); rsln_rho_v_x.own_mesh = false; delete rsln_rho_v_y.get_mesh(); rsln_rho_v_y.own_mesh = false; delete rsln_e.get_mesh(); rsln_e.own_mesh = false; // Visualization and saving on disk. if((iteration - 1) % EVERY_NTH_STEP == 0) { continuity.add_record((unsigned int)(iteration - 1)); continuity.get_last_record()->save_mesh(prev_rho.get_mesh()); continuity.get_last_record()->save_space(prev_rho.get_space()); continuity.get_last_record()->save_time_step_length(time_step); // Hermes visualization. if(HERMES_VISUALIZATION) { Mach_number.reinit(); pressure.reinit(); entropy.reinit(); pressure_view.show(&pressure, 1); entropy_production_view.show(&entropy, 1); Mach_number_view.show(&Mach_number, 1); pressure_view.save_numbered_screenshot("pressure %i.bmp", iteration); Mach_number_view.save_numbered_screenshot("Mach no %i.bmp", iteration); } // Output solution in VTK format. if(VTK_VISUALIZATION) { pressure.reinit(); Mach_number.reinit(); entropy.reinit(); Linearizer lin; char filename[40]; sprintf(filename, "Pressure-%i.vtk", iteration - 1); lin.save_solution_vtk(&pressure, filename, "Pressure", false); sprintf(filename, "Mach number-%i.vtk", iteration - 1); lin.save_solution_vtk(&Mach_number, filename, "MachNumber", false); if((iteration - 1) % (EVERY_NTH_STEP * EVERY_NTH_STEP) == 0) { sprintf(filename, "Entropy-%i.vtk", iteration - 1); lin.save_solution_vtk(&entropy, filename, "Entropy", false); } } } } pressure_view.close(); entropy_production_view.close(); Mach_number_view.close(); return 0; }
int main(int argc, char *argv[]) { typedef Teuchos::ScalarTraits<double> ST; try { GlobalMPISession session(&argc, &argv); MPIComm::world().synchronize(); VectorType<double> type = new EpetraVectorType(); /* create the range space */ int nLocalRows = 10; MatrixLaplacian1D builder(nLocalRows, type); LinearOperator<double> A = builder.getOp(); int nBlocks = 3; Array<Vector<double> > x(nBlocks); Array<VectorSpace<double> > space(nBlocks); for (int i=0; i<nBlocks; i++) { space[i] = A.domain(); x[i] = A.domain().createMember(); Thyra::randomize(-ST::one(),+ST::one(),x[i].ptr().ptr()); } VectorSpace<double> blockSpace = productSpace(space); LinearOperator<double> bigA = makeBlockOperator(blockSpace, blockSpace); Vector<double> bigRHS = blockSpace.createMember(); Vector<double> bigX = blockSpace.createMember(); for (int i=0; i<nBlocks; i++) { bigX.setBlock(i, x[i]); for (int j=i; j<nBlocks; j++) { MatrixLaplacian1D builder(nLocalRows, type); LinearOperator<double> Aij = builder.getOp(); bigA.setBlock(i,j,Aij); } } bigA.endBlockFill(); bigRHS = bigA * bigX; Vector<double> bigSoln = blockSpace.createMember(); #ifdef HAVE_CONFIG_H ParameterXMLFileReader reader(Sundance::searchForFile("SolverParameters/poissonParams.xml")); #else ParameterXMLFileReader reader("poissonParams.xml"); #endif ParameterList solverParams = reader.getParameters(); LinearSolver<double> solver = LinearSolverBuilder::createSolver(solverParams); LinearSolver<double> blockSolver = new BlockTriangularSolver<double>(solver); SolverState<double> state = blockSolver.solve(bigA, bigRHS, bigSoln); std::cerr << state << std::endl; double err = (bigSoln - bigX).norm2(); std::cerr << "error norm = " << err << std::endl; double tol = 1.0e-8; if (err > tol) { std::cerr << "Poisson solve test FAILED" << std::endl; return 1; } else { std::cerr << "Poisson solve test PASSED" << std::endl; return 0; } } catch(std::exception& e) { std::cerr << "Caught exception: " << e.what() << std::endl; return -1; } return 0; }