int main(int argc, char* argv[]) { if (argc != 2) { printf("Usage: meshview mesh-filename\n"); exit(1); } Mesh mesh; mesh.load(argv[1], true); MeshView mv; mv.show(&mesh); 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("ffs.mesh", &mesh); mesh.refine_by_criterion(refinement_criterion, INIT_REF_NUM_STEP); // Perform initial mesh refinements. for (int i = 0; i < INIT_REF_NUM; i++) mesh.refine_all_elements(0, true); MeshView m; m.show(&mesh); // 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); L2Space<double> space_stabilization(&mesh, 0); int ndof = Space<double>::get_num_dofs(Hermes::vector<const Space<double>*>(&space_rho, &space_rho_v_x, &space_rho_v_y, &space_e)); Hermes::Mixins::Loggable::Static::info("ndof: %d", ndof); // Initialize solutions, set initial conditions. 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)); // 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)); ScalarView s1("prev_rho", new WinGeom(0, 0, 600, 300)); ScalarView s2("prev_rho_v_x", new WinGeom(700, 0, 600, 300)); ScalarView s3("prev_rho_v_y", new WinGeom(0, 400, 600, 300)); ScalarView s4("prev_e", new WinGeom(700, 400, 600, 300)); // Set up CFL calculation class. CFLCalculation CFL(CFL_NUMBER, KAPPA); // Look for a saved solution on the disk. CalculationContinuity<double> continuity(CalculationContinuity<double>::onlyTime); int iteration = 0; double t = 0; if(REUSE_SOLUTION && continuity.have_record_available()) { continuity.get_last_record()->load_mesh(&mesh); Hermes::vector<Space<double> *> spaceVector = continuity.get_last_record()->load_spaces(Hermes::vector<Mesh *>(&mesh, &mesh, &mesh, &mesh)); space_rho.copy(spaceVector[0], &mesh); space_rho_v_x.copy(spaceVector[1], &mesh); space_rho_v_y.copy(spaceVector[2], &mesh); space_e.copy(spaceVector[3], &mesh); 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> *>(&space_rho, &space_rho_v_x, &space_rho_v_y, &space_e)); continuity.get_last_record()->load_time_step_length(time_step); t = continuity.get_last_record()->get_time(); iteration = continuity.get_num(); } // Initialize weak formulation. Hermes::vector<std::string> solid_wall_markers(BDY_SOLID_WALL_BOTTOM, BDY_SOLID_WALL_TOP); Hermes::vector<std::string> inlet_markers; inlet_markers.push_back(BDY_INLET); Hermes::vector<std::string> outlet_markers; outlet_markers.push_back(BDY_OUTLET); EulerEquationsWeakFormSemiImplicit wf(KAPPA, RHO_EXT, V1_EXT, V2_EXT, P_EXT,solid_wall_markers, inlet_markers, outlet_markers, &prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e, (P_INIT == 0)); EulerEquationsWeakFormStabilization wf_stabilization(&prev_rho); // Initialize the FE problem. DiscreteProblemLinear<double> dp(&wf, Hermes::vector<const Space<double>*>(&space_rho, &space_rho_v_x, &space_rho_v_y, &space_e)); DiscreteProblem<double> dp_stabilization(&wf_stabilization, &space_stabilization); LinearSolver<double> solver(&dp); // If the FE problem is in fact a FV problem. if(P_INIT == 0) dp.set_fvm(); // Time stepping loop. for(; t < 10.0; t += time_step) { Hermes::Mixins::Loggable::Static::info("---- Time step %d, time %3.5f.", iteration++, t); CFL.set_number(0.1 + (t/7.0) * 1.0); // Set the current time step. wf.set_current_time_step(time_step); // Assemble the stiffness matrix and rhs. Hermes::Mixins::Loggable::Static::info("Assembling the stiffness matrix and right-hand side vector."); // Solve the matrix problem. Hermes::Mixins::Loggable::Static::info("Solving the matrix problem."); try { solver.solve(); if(!SHOCK_CAPTURING) { Solution<double>::vector_to_solutions(solver.get_sln_vector(), Hermes::vector<const 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; if(SHOCK_CAPTURING_TYPE == KUZMIN) flux_limiter = new FluxLimiter(FluxLimiter::Kuzmin, solver.get_sln_vector(), Hermes::vector<const Space<double> *>(&space_rho, &space_rho_v_x, &space_rho_v_y, &space_e), true); else flux_limiter = new FluxLimiter(FluxLimiter::Krivodonova, solver.get_sln_vector(), Hermes::vector<const Space<double> *>(&space_rho, &space_rho_v_x, &space_rho_v_y, &space_e)); if(SHOCK_CAPTURING_TYPE == KUZMIN) 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)); } } catch(std::exception& e) { std::cout << e.what(); } CFL.calculate(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(); 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_pressure; char filename[40]; sprintf(filename, "pressure-3D-%i.vtk", iteration - 1); lin_pressure.save_solution_vtk(&pressure, filename, "Pressure", true); Linearizer lin_mach; sprintf(filename, "Mach number-3D-%i.vtk", iteration - 1); lin_mach.save_solution_vtk(&Mach_number, filename, "MachNumber", true); } } } pressure_view.close(); entropy_production_view.close(); Mach_number_view.close(); return 0; }
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 the mesh. MeshSharedPtr mesh(new Mesh); MeshReaderH2D mloader; mloader.load("domain.mesh", mesh); // Initial mesh refinements. mesh->refine_all_elements(); mesh->refine_all_elements(); mesh->refine_towards_boundary(BDY_OBSTACLE, 2, false); // 'true' stands for anisotropic refinements. mesh->refine_towards_boundary(BDY_TOP, 2, true); mesh->refine_towards_boundary(BDY_BOTTOM, 2, true); // Show mesh. MeshView mv; mv.show(mesh); Hermes::Mixins::Loggable::Static::info("Close mesh window to continue."); // Initialize boundary conditions. EssentialBCNonConst bc_left_vel_x(BDY_LEFT, VEL_INLET, H, STARTUP_TIME); DefaultEssentialBCConst<double> bc_other_vel_x({ BDY_BOTTOM, BDY_TOP, BDY_OBSTACLE }, 0.0); EssentialBCs<double> bcs_vel_x({ &bc_left_vel_x, &bc_other_vel_x }); DefaultEssentialBCConst<double> bc_vel_y({ BDY_LEFT, BDY_BOTTOM, BDY_TOP, BDY_OBSTACLE }, 0.0); EssentialBCs<double> bcs_vel_y(&bc_vel_y); SpaceSharedPtr<double> xvel_space(new H1Space<double>(mesh, &bcs_vel_x, P_INIT_VEL)); SpaceSharedPtr<double> yvel_space(new H1Space<double>(mesh, &bcs_vel_y, P_INIT_VEL)); #ifdef PRESSURE_IN_L2 SpaceSharedPtr<double> p_space(new L2Space<double>(mesh, P_INIT_PRESSURE)); #else SpaceSharedPtr<double> p_space(new H1Space<double>(mesh, P_INIT_PRESSURE)); #endif std::vector<SpaceSharedPtr<double> > spaces({ xvel_space, yvel_space, p_space }); // Calculate and report the number of degrees of freedom. int ndof = Space<double>::get_num_dofs(spaces); Hermes::Mixins::Loggable::Static::info("ndof = %d.", ndof); // Define projection norms. NormType vel_proj_norm = HERMES_H1_NORM; #ifdef PRESSURE_IN_L2 NormType p_proj_norm = HERMES_L2_NORM; #else NormType p_proj_norm = HERMES_H1_NORM; #endif // Solutions for the Newton's iteration and time stepping. Hermes::Mixins::Loggable::Static::info("Setting zero initial conditions."); MeshFunctionSharedPtr<double> xvel_prev_time(new ZeroSolution<double>(mesh)); MeshFunctionSharedPtr<double> yvel_prev_time(new ZeroSolution<double>(mesh)); MeshFunctionSharedPtr<double> p_prev_time(new ZeroSolution<double>(mesh)); // Initialize weak formulation. WeakFormSharedPtr<double> wf(new WeakFormNSNewton(STOKES, RE, TAU, xvel_prev_time, yvel_prev_time)); // Initialize the FE problem. Hermes::Hermes2D::NewtonSolver<double> newton(wf, spaces); Hermes::Mixins::Loggable::Static::info("Solving nonlinear problem:"); newton.set_max_allowed_iterations(NEWTON_MAX_ITER); newton.set_tolerance(NEWTON_TOL, Hermes::Solvers::ResidualNormAbsolute); newton.set_jacobian_constant(); // 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); // 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; Hermes::Mixins::Loggable::Static::info("---- Time step %d, time = %g:", ts, current_time); // Update time-dependent essential BCs. if (current_time <= STARTUP_TIME) { Hermes::Mixins::Loggable::Static::info("Updating time-dependent essential BC."); Space<double>::update_essential_bc_values(spaces, current_time); } // Perform Newton's iteration. try { newton.solve(); } catch (Hermes::Exceptions::Exception e) { e.print_msg(); }; // Update previous time level solutions. Solution<double>::vector_to_solutions(newton.get_sln_vector(), spaces, { xvel_prev_time, yvel_prev_time, p_prev_time }); // Visualization. // Hermes visualization. if (HERMES_VISUALIZATION) { // 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); } } // Wait for all views to be closed. View::wait(); return 0; }