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(2); //mesh.refine_towards_boundary(BDY_SOLID_WALL_BOTTOM, 2); // Initialize boundary condition types and spaces with default shapesets. L2Space space_rho(&mesh, P_INIT); L2Space space_rho_v_x(&mesh, P_INIT); L2Space space_rho_v_y(&mesh, P_INIT); L2Space space_e(&mesh, P_INIT); int ndof = Space::get_num_dofs(Hermes::vector<Space*>(&space_rho, &space_rho_v_x, &space_rho_v_y, &space_e)); info("ndof: %d", ndof); // Initialize solutions, set initial conditions. InitialSolutionEulerDensity prev_rho(&mesh, RHO_EXT); InitialSolutionEulerDensityVelX prev_rho_v_x(&mesh, RHO_EXT * V1_EXT); InitialSolutionEulerDensityVelY prev_rho_v_y(&mesh, RHO_EXT * V2_EXT); InitialSolutionEulerDensityEnergy prev_e(&mesh, QuantityCalculator::calc_energy(RHO_EXT, RHO_EXT * V1_EXT, RHO_EXT * V2_EXT, P_EXT, KAPPA)); // Numerical flux. StegerWarmingNumericalFlux num_flux(KAPPA); // Initialize weak formulation. EulerEquationsWeakFormExplicitMultiComponentSemiImplicit wf(&num_flux, KAPPA, RHO_EXT, V1_EXT, V2_EXT, P_EXT, BDY_SOLID_WALL_BOTTOM, BDY_SOLID_WALL_TOP, BDY_INLET, BDY_OUTLET, &prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e); // Initialize the FE problem. bool is_linear = true; DiscreteProblem dp(&wf, Hermes::vector<Space*>(&space_rho, &space_rho_v_x, &space_rho_v_y, &space_e), is_linear); // If the FE problem is in fact a FV problem. //if(P_INIT == 0) dp.set_fvm(); // Filters for visualization of Mach number, pressure and entropy. MachNumberFilter Mach_number(Hermes::vector<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e), KAPPA); PressureFilter pressure(Hermes::vector<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e), KAPPA); EntropyFilter entropy(Hermes::vector<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e), KAPPA, RHO_EXT, P_EXT); ScalarView pressure_view("Pressure", new WinGeom(0, 0, 600, 300)); ScalarView Mach_number_view("Mach number", new WinGeom(700, 0, 600, 300)); ScalarView entropy_production_view("Entropy estimate", new WinGeom(0, 400, 600, 300)); ScalarView s1("1", new WinGeom(0, 0, 600, 300)); ScalarView s2("2", new WinGeom(700, 0, 600, 300)); ScalarView s3("3", new WinGeom(0, 400, 600, 300)); ScalarView s4("4", new WinGeom(700, 400, 600, 300)); // Set up the solver, matrix, and rhs according to the solver selection. SparseMatrix* matrix = create_matrix(matrix_solver); Vector* rhs = create_vector(matrix_solver); Solver* solver = create_linear_solver(matrix_solver, matrix, rhs); // Set up CFL calculation class. CFLCalculation CFL(CFL_NUMBER, KAPPA); int iteration = 0; double t = 0; for(t = 0.0; t < 3.0; t += time_step) { info("---- Time step %d, time %3.5f.", iteration++, t); // Set the current time step. wf.set_time_step(time_step); bool rhs_only = (iteration == 1 ? false : true); // Assemble stiffness matrix and rhs or just rhs. if (rhs_only == false) { info("Assembling the stiffness matrix and right-hand side vector."); dp.assemble(matrix, rhs); } else { info("Assembling the right-hand side vector (only)."); dp.assemble(NULL, rhs); } // Solve the matrix problem. info("Solving the matrix problem."); scalar* solution_vector = NULL; if(solver->solve()) { solution_vector = solver->get_solution(); Solution::vector_to_solutions(solution_vector, Hermes::vector<Space *>(&space_rho, &space_rho_v_x, &space_rho_v_y, &space_e), Hermes::vector<Solution *>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e)); } else error ("Matrix solver failed.\n"); if(SHOCK_CAPTURING) { DiscontinuityDetector discontinuity_detector(Hermes::vector<Space *>(&space_rho, &space_rho_v_x, &space_rho_v_y, &space_e), Hermes::vector<Solution *>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e)); std::set<int> discontinuous_elements = discontinuity_detector.get_discontinuous_element_ids(DISCONTINUITY_DETECTOR_PARAM); FluxLimiter flux_limiter(solution_vector, Hermes::vector<Space *>(&space_rho, &space_rho_v_x, &space_rho_v_y, &space_e), Hermes::vector<Solution *>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e)); flux_limiter.limit_according_to_detector(discontinuous_elements); } if((iteration - 1) % CFL_CALC_FREQ == 0) CFL.calculate(Hermes::vector<Solution *>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e), &mesh, time_step); // Visualization. /* Mach_number.reinit(); pressure.reinit(); entropy.reinit(); pressure_view.show(&pressure); entropy_production_view.show(&entropy); Mach_number_view.show(&Mach_number); */ s1.show(&prev_rho); s2.show(&prev_rho_v_x); s3.show(&prev_rho_v_y); s4.show(&prev_e); View::wait(); } pressure_view.close(); entropy_production_view.close(); Mach_number_view.close(); s1.close(); s2.close(); s3.close(); s4.close(); return 0; }
int main(int argc, char* argv[]) { // Load the mesh. Mesh basemesh; H2DReader mloader; mloader.load("GAMM-channel.mesh", &basemesh); // Initialize the meshes. Mesh mesh_flow, mesh_concentration; mesh_flow.copy(&basemesh); mesh_concentration.copy(&basemesh); for(unsigned int i = 0; i < INIT_REF_NUM_CONCENTRATION; i++) mesh_concentration.refine_all_elements(); mesh_concentration.refine_towards_boundary(BDY_DIRICHLET_CONCENTRATION, INIT_REF_NUM_CONCENTRATION_BDY); mesh_flow.refine_towards_boundary(BDY_DIRICHLET_CONCENTRATION, INIT_REF_NUM_CONCENTRATION_BDY); for(unsigned int i = 0; i < INIT_REF_NUM_FLOW; i++) mesh_flow.refine_all_elements(); // Initialize boundary condition types and spaces with default shapesets. // For the concentration. EssentialBCs bcs_concentration; bcs_concentration.add_boundary_condition(new ConcentrationTimedepEssentialBC(BDY_DIRICHLET_CONCENTRATION, CONCENTRATION_EXT, CONCENTRATION_EXT_STARTUP_TIME)); bcs_concentration.add_boundary_condition(new ConcentrationTimedepEssentialBC(BDY_SOLID_WALL_TOP, 0.0, CONCENTRATION_EXT_STARTUP_TIME)); L2Space space_rho(&mesh_flow, P_INIT_FLOW); L2Space space_rho_v_x(&mesh_flow, P_INIT_FLOW); L2Space space_rho_v_y(&mesh_flow, P_INIT_FLOW); L2Space space_e(&mesh_flow, P_INIT_FLOW); // Space for concentration. H1Space space_c(&mesh_concentration, &bcs_concentration, P_INIT_CONCENTRATION); int ndof = Space::get_num_dofs(Hermes::vector<Space*>(&space_rho, &space_rho_v_x, &space_rho_v_y, &space_e, &space_c)); info("ndof: %d", ndof); // Initialize solutions, set initial conditions. InitialSolutionEulerDensity prev_rho(&mesh_flow, RHO_EXT); InitialSolutionEulerDensityVelX prev_rho_v_x(&mesh_flow, RHO_EXT * V1_EXT); InitialSolutionEulerDensityVelY prev_rho_v_y(&mesh_flow, RHO_EXT * V2_EXT); InitialSolutionEulerDensityEnergy prev_e(&mesh_flow, QuantityCalculator::calc_energy(RHO_EXT, RHO_EXT * V1_EXT, RHO_EXT * V2_EXT, P_EXT, KAPPA)); InitialSolutionConcentration prev_c(&mesh_concentration, 0.0); // Numerical flux. OsherSolomonNumericalFlux num_flux(KAPPA); // Initialize weak formulation. EulerEquationsWeakFormSemiImplicitCoupled wf(&num_flux, KAPPA, RHO_EXT, V1_EXT, V2_EXT, P_EXT, BDY_SOLID_WALL_BOTTOM, BDY_SOLID_WALL_TOP, BDY_INLET, BDY_OUTLET, BDY_NATURAL_CONCENTRATION, &prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e, &prev_c, EPSILON, (P_INIT_FLOW == 0)); wf.set_time_step(time_step); // Initialize the FE problem. DiscreteProblem dp(&wf, Hermes::vector<Space*>(&space_rho, &space_rho_v_x, &space_rho_v_y, &space_e, &space_c)); // If the FE problem is in fact a FV problem. //if(P_INIT == 0) dp.set_fvm(); // Filters for visualization of Mach number, pressure and entropy. MachNumberFilter Mach_number(Hermes::vector<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e), KAPPA); PressureFilter pressure(Hermes::vector<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e), KAPPA); EntropyFilter entropy(Hermes::vector<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e), KAPPA, RHO_EXT, P_EXT); /* ScalarView pressure_view("Pressure", new WinGeom(0, 0, 600, 300)); ScalarView Mach_number_view("Mach number", new WinGeom(700, 0, 600, 300)); ScalarView entropy_production_view("Entropy estimate", new WinGeom(0, 400, 600, 300)); ScalarView s5("Concentration", new WinGeom(700, 400, 600, 300)); */ ScalarView s1("1", new WinGeom(0, 0, 600, 300)); ScalarView s2("2", new WinGeom(700, 0, 600, 300)); ScalarView s3("3", new WinGeom(0, 400, 600, 300)); ScalarView s4("4", new WinGeom(700, 400, 600, 300)); ScalarView s5("Concentration", new WinGeom(350, 200, 600, 300)); // Set up the solver, matrix, and rhs according to the solver selection. SparseMatrix* matrix = create_matrix(matrix_solver); Vector* rhs = create_vector(matrix_solver); Solver* solver = create_linear_solver(matrix_solver, matrix, rhs); // Set up CFL calculation class. CFLCalculation CFL(CFL_NUMBER, KAPPA); // Set up Advection-Diffusion-Equation stability calculation class. ADEStabilityCalculation ADES(ADVECTION_STABILITY_CONSTANT, DIFFUSION_STABILITY_CONSTANT, EPSILON); int iteration = 0; double t = 0; for(t = 0.0; t < 100.0; t += time_step) { info("---- Time step %d, time %3.5f.", iteration++, t); // Set the current time step. wf.set_time_step(time_step); Space::update_essential_bc_values(&space_c, t); // Assemble stiffness matrix and rhs. info("Assembling the stiffness matrix and right-hand side vector."); dp.assemble(matrix, rhs); // Solve the matrix problem. info("Solving the matrix problem."); scalar* solution_vector = NULL; if(solver->solve()) { solution_vector = solver->get_solution(); Solution::vector_to_solutions(solution_vector, Hermes::vector<Space *>(&space_rho, &space_rho_v_x, &space_rho_v_y, &space_e, &space_c), Hermes::vector<Solution *>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e, &prev_c)); } else error ("Matrix solver failed.\n"); if(SHOCK_CAPTURING) { DiscontinuityDetector discontinuity_detector(Hermes::vector<Space *>(&space_rho, &space_rho_v_x, &space_rho_v_y, &space_e), Hermes::vector<Solution *>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e)); std::set<int> discontinuous_elements = discontinuity_detector.get_discontinuous_element_ids(DISCONTINUITY_DETECTOR_PARAM); FluxLimiter flux_limiter(solution_vector, Hermes::vector<Space *>(&space_rho, &space_rho_v_x, &space_rho_v_y, &space_e), Hermes::vector<Solution *>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e)); flux_limiter.limit_according_to_detector(discontinuous_elements); } util_time_step = time_step; CFL.calculate_semi_implicit(Hermes::vector<Solution *>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e), &mesh_flow, util_time_step); time_step = util_time_step; ADES.calculate(Hermes::vector<Solution *>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y), &mesh_concentration, util_time_step); if(util_time_step < time_step) time_step = util_time_step; // Visualization. if((iteration - 1) % EVERY_NTH_STEP == 0) { // Hermes visualization. if(HERMES_VISUALIZATION) { /* Mach_number.reinit(); pressure.reinit(); entropy.reinit(); pressure_view.show(&pressure); entropy_production_view.show(&entropy); Mach_number_view.show(&Mach_number); s5.show(&prev_c); */ s1.show(&prev_rho); s2.show(&prev_rho_v_x); s3.show(&prev_rho_v_y); s4.show(&prev_e); s5.show(&prev_c); /* s1.save_numbered_screenshot("density%i.bmp", iteration, true); s2.save_numbered_screenshot("density_v_x%i.bmp", iteration, true); s3.save_numbered_screenshot("density_v_y%i.bmp", iteration, true); s4.save_numbered_screenshot("energy%i.bmp", iteration, true); s5.save_numbered_screenshot("concentration%i.bmp", iteration, true); */ //s5.wait_for_close(); } // Output solution in VTK format. if(VTK_VISUALIZATION) { pressure.reinit(); Mach_number.reinit(); Linearizer lin; char filename[40]; sprintf(filename, "pressure-%i.vtk", iteration - 1); lin.save_solution_vtk(&pressure, filename, "Pressure", false); sprintf(filename, "pressure-3D-%i.vtk", iteration - 1); lin.save_solution_vtk(&pressure, filename, "Pressure", true); sprintf(filename, "Mach number-%i.vtk", iteration - 1); lin.save_solution_vtk(&Mach_number, filename, "MachNumber", false); sprintf(filename, "Mach number-3D-%i.vtk", iteration - 1); lin.save_solution_vtk(&Mach_number, filename, "MachNumber", true); sprintf(filename, "Concentration-%i.vtk", iteration - 1); lin.save_solution_vtk(&prev_c, filename, "Concentration", true); sprintf(filename, "Concentration-3D-%i.vtk", iteration - 1); lin.save_solution_vtk(&prev_c, filename, "Concentration", true); } } } /* pressure_view.close(); entropy_production_view.close(); Mach_number_view.close(); s5.close(); */ s1.close(); s2.close(); s3.close(); s4.close(); s5.close(); return 0; }