/** \brief compare 2 ipport_aview_t and return value ala strcmp/memcmp */ int ipport_aview_t::compare(const ipport_aview_t &other) const throw() { // handle the null case if( is_null() && !other.is_null() ) return -1; if( !is_null() && other.is_null() ) return +1; if( is_null() && other.is_null() ) return 0; // handle the address if( lview() < other.lview() ) return -1; if( lview() > other.lview() ) return +1; // handle the port if( pview() < other.pview() ) return -1; if( pview() > other.pview() ) return +1; return 0; }
void ObjectTransactiontestUnit::test_update() { matador::object_store store; store.attach<person>("person"); auto hans = store.insert(new person("Hans", matador::date(12, 3, 1980), 180)); matador::transaction tr(store); try { tr.begin(); UNIT_ASSERT_EQUAL(hans->height(), 180U, "height must be valid"); hans->height(183); UNIT_ASSERT_EQUAL(hans->height(), 183U, "height must be valid"); UNIT_ASSERT_GREATER(hans->id(), 0UL, "id must be valid"); tr.commit(); } catch (std::exception &) { UNIT_FAIL("shouldn't come here"); } UNIT_ASSERT_EQUAL(hans->height(), 183U, "height must be valid"); UNIT_ASSERT_GREATER(hans->id(), 0UL, "id must be valid"); matador::object_view<person> pview(store); UNIT_ASSERT_FALSE(pview.empty(), "view must not be empty"); }
void ObjectTransactiontestUnit::test_insert() { matador::object_store store; store.attach<person>("person"); matador::transaction tr(store); try { tr.begin(); auto hans = store.insert(new person("Hans", matador::date(12, 3, 1980), 180)); UNIT_ASSERT_GREATER(hans->id(), 0UL, "id must be valid"); tr.commit(); } catch (std::exception &) { tr.rollback(); } matador::object_view<person> pview(store); auto p = pview.front(); UNIT_ASSERT_GREATER(p->id(), 0UL, "id must be valid"); UNIT_ASSERT_EQUAL(p->name(), "Hans", "name must be 'Hans'"); }
void ObjectTransactiontestUnit::test_delete_rollback() { matador::object_store store; store.attach<person>("person"); auto hans = store.insert(new person("Hans", matador::date(12, 3, 1980), 180)); UNIT_ASSERT_GREATER(hans->id(), 0UL, "id must be valid"); matador::transaction tr(store); try { tr.begin(); store.remove(hans); tr.rollback(); } catch (std::exception &) { tr.rollback(); } matador::object_view<person> pview(store); auto p = pview.front(); UNIT_ASSERT_EQUAL(pview.size(), 1UL, "size must be one"); UNIT_ASSERT_GREATER(p.id(), 0UL, "id must be valid"); UNIT_ASSERT_FALSE(p.ptr() == nullptr, "object must be nullptr"); UNIT_ASSERT_GREATER(p->id(), 0UL, "id must be valid"); UNIT_ASSERT_EQUAL(p->name(), "Hans", "name must be 'Hans'"); }
/** \brief check if the ipport_aview_t is sane (independantly of the state run/cfg) */ bool ipport_aview_t::is_sane_common() const throw() { // sanity check - the lview() MUST be non-null DBG_ASSERT( !lview().is_null() ); // sanity check - the lview().ipaddr() MUST be is_any() or is_fully_qualified DBG_ASSERT( lview().ipaddr().is_any() || lview().ipaddr().is_fully_qualified() ); // if the pview is not null, the ipport_aview_t is inetreachable // - so pview().port() MUST be non-null zero // - so pview().ipaddr() MUST BE either fully_qualified or any // - if it is any, it is up to the receiver of the xmit_listen_ipport to determine // the ip_addr_t from its own view of the source ip_addr_t which sent the xmit_listen_ipport if(!pview().is_null()) DBG_ASSERT( pview().port() ); if(!pview().is_null()) DBG_ASSERT( pview().ipaddr().is_any() || pview().ipaddr().is_fully_qualified() ); // if this point is reached, return true return true; }
/** \brief convert the object to a string */ std::string ipport_aview_t::to_string() const throw() { std::ostringstream oss; // handle the null case if( is_null() ) return "null"; // build the string to return oss << "[lview=" << lview(); oss << " pview=" << pview(); oss << "]"; // return the just built string return oss.str(); }
void ObjectTransactiontestUnit::test_insert_rollback() { matador::object_store store; store.attach<person>("person"); matador::transaction tr(store); try { tr.begin(); auto hans = store.insert(new person("Hans", matador::date(12, 3, 1980), 180)); UNIT_ASSERT_GREATER(hans->id(), 0UL, "id must be valid"); tr.rollback(); } catch (std::exception &) { UNIT_FAIL("shouldn't come here"); } matador::object_view<person> pview(store); UNIT_ASSERT_TRUE(pview.empty(), "view must be empty"); }
int main(int argc, char* argv[]) { // load the mesh file Mesh mesh; mesh.load("domain.mesh"); // a-priori mesh refinements mesh.refine_all_elements(); mesh.refine_towards_boundary(5, 4, false); mesh.refine_towards_boundary(1, 4); mesh.refine_towards_boundary(3, 4); // initialize the shapeset and the cache H1ShapesetBeuchler shapeset; PrecalcShapeset pss(&shapeset); // spaces for velocities and pressure H1Space xvel(&mesh, &shapeset); H1Space yvel(&mesh, &shapeset); H1Space press(&mesh, &shapeset); // initialize boundary conditions xvel.set_bc_types(xvel_bc_type); xvel.set_bc_values(xvel_bc_value); yvel.set_bc_types(yvel_bc_type); press.set_bc_types(press_bc_type); // set velocity and pressure polynomial degrees xvel.set_uniform_order(P_INIT_VEL); yvel.set_uniform_order(P_INIT_VEL); press.set_uniform_order(P_INIT_PRESSURE); // assign degrees of freedom int ndofs = 0; ndofs += xvel.assign_dofs(ndofs); ndofs += yvel.assign_dofs(ndofs); ndofs += press.assign_dofs(ndofs); // velocities from the previous time step and for the Newton's iteration Solution xprev, yprev, xiter, yiter, piter; xprev.set_zero(&mesh); yprev.set_zero(&mesh); xiter.set_zero(&mesh); yiter.set_zero(&mesh); piter.set_zero(&mesh); // set up weak formulation WeakForm wf(3); if (NEWTON_ON) { wf.add_biform(0, 0, callback(bilinear_form_sym_0_0_1_1), SYM); wf.add_biform(0, 0, callback(newton_bilinear_form_unsym_0_0), UNSYM, ANY, 2, &xprev, &yprev); wf.add_biform(0, 1, callback(newton_bilinear_form_unsym_0_1), UNSYM, ANY, 2, &xprev, &yprev); wf.add_biform(0, 2, callback(bilinear_form_unsym_0_2), ANTISYM); wf.add_biform(1, 0, callback(newton_bilinear_form_unsym_1_0), UNSYM, ANY, 2, &xprev, &yprev); wf.add_biform(1, 1, callback(bilinear_form_sym_0_0_1_1), SYM); wf.add_biform(1, 1, callback(newton_bilinear_form_unsym_1_1), UNSYM, ANY, 2, &xprev, &yprev); wf.add_biform(1, 2, callback(bilinear_form_unsym_1_2), ANTISYM); wf.add_liform(0, callback(newton_F_0), ANY, 5, &xprev, &yprev, &xiter, &yiter, &piter); wf.add_liform(1, callback(newton_F_1), ANY, 5, &xprev, &yprev, &xiter, &yiter, &piter); wf.add_liform(2, callback(newton_F_2), ANY, 2, &xiter, &yiter); } else { wf.add_biform(0, 0, callback(bilinear_form_sym_0_0_1_1), SYM); wf.add_biform(0, 0, callback(simple_bilinear_form_unsym_0_0_1_1), UNSYM, ANY, 2, &xprev, &yprev); wf.add_biform(1, 1, callback(bilinear_form_sym_0_0_1_1), SYM); wf.add_biform(1, 1, callback(simple_bilinear_form_unsym_0_0_1_1), UNSYM, ANY, 2, &xprev, &yprev); wf.add_biform(0, 2, callback(bilinear_form_unsym_0_2), ANTISYM); wf.add_biform(1, 2, callback(bilinear_form_unsym_1_2), ANTISYM); wf.add_liform(0, callback(simple_linear_form), ANY, 1, &xprev); wf.add_liform(1, callback(simple_linear_form), ANY, 1, &yprev); } // visualization VectorView vview("velocity [m/s]", 0, 0, 1500, 470); ScalarView pview("pressure [Pa]", 0, 530, 1500, 470); 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); // matrix solver UmfpackSolver umfpack; // linear system LinSystem linsys(&wf, &umfpack); // nonlinear system NonlinSystem nonsys(&wf, &umfpack); if (NEWTON_ON) { // set up the nonlinear system nonsys.set_spaces(3, &xvel, &yvel, &press); nonsys.set_pss(1, &pss); } else { // set up the linear system linsys.set_spaces(3, &xvel, &yvel, &press); linsys.set_pss(1, &pss); } // main loop char title[100]; int num_time_steps = FINAL_TIME / TAU; for (int i = 1; i <= num_time_steps; i++) { TIME += TAU; info("\n---- Time step %d, time = %g -----------------------------------", i, TIME); // this is needed to update the time-dependent boundary conditions ndofs = 0; ndofs += xvel.assign_dofs(ndofs); ndofs += yvel.assign_dofs(ndofs); ndofs += press.assign_dofs(ndofs); if (NEWTON_ON) { Solution xsln, ysln, psln; int it = 1; double res_l2_norm; do { info("\n---- Time step %d, Newton iter %d ---------------------------------\n", i, it++); // assemble and solve nonsys.assemble(); nonsys.solve(3, &xsln, &ysln, &psln); res_l2_norm = nonsys.get_residuum_l2_norm(); info("Residuum L2 norm: %g\n", res_l2_norm); // want to see Newtons iterations //sprintf(title, "Time level %d, Newton iteration %d", i, it-1); //vview.set_title(title); //vview.show(&xsln, &ysln, EPS_LOW); //pview.show(&psln); //pview.wait_for_keypress(); xiter = xsln; yiter = ysln; piter = psln; } while (res_l2_norm > NEWTON_TOL); // visualization at the end of the time step sprintf(title, "Velocity, time %g", TIME); vview.set_title(title); vview.show(&xprev, &yprev, EPS_LOW); sprintf(title, "Pressure, time %g", TIME); pview.set_title(title); pview.show(&piter); // copying result of the Newton's iteration into xprev, yprev xprev.copy(&xiter); yprev.copy(&yiter); } else { // assemble and solve Solution xsln, ysln, psln; linsys.assemble(); linsys.solve(3, &xsln, &ysln, &psln); // visualization sprintf(title, "Velocity, time %g", TIME); vview.set_title(title); vview.show(&xsln, &ysln, EPS_LOW); sprintf(title, "Pressure, time %g", TIME); pview.set_title(title); pview.show(&psln); //pview.wait_for_keypress(); xprev = xsln; yprev = ysln; } // uncomment one of the following lines to generate a series of video frames //vview.save_numbered_screenshot("velocity%03d.bmp", i, true); //pview.save_numbered_screenshot("pressure%03d.bmp", i, true); // the frames can then be converted to a video file with the command // mencoder "mf://velocity*.bmp" -mf fps=20 -o velocity.avi -ovc lavc -lavcopts vcodec=mpeg4 } // wait for keyboard or mouse input View::wait("Waiting for keyboard or mouse input."); 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[]) { Hermes2D hermes_2D; // Load the mesh. Mesh mesh; H2DReader mloader; mloader.load("domain.mesh", &mesh); // Initial mesh refinements. for (int i=0; i < 4; i++) mesh.refine_all_elements(); mesh.refine_towards_boundary(HERMES_ANY, 4); // Initialize boundary conditions. DefaultEssentialBCConst zero_vel_bc_x_brl(Hermes::vector<std::string>("Bottom", "Right", "Left"), 0.0); DefaultEssentialBCConst vel_bc_x_top(Hermes::vector<std::string>("Top"), XVEL_TOP); EssentialBCs bcs_vel_x(Hermes::vector<EssentialBoundaryCondition*>(&vel_bc_x_top, &zero_vel_bc_x_brl)); DefaultEssentialBCConst zero_vel_bc_y(Hermes::vector<std::string>("Bottom", "Right", "Top", "Left"), 0.0); EssentialBCs bcs_vel_y(&zero_vel_bc_y); EssentialBCs bcs_pressure; // Spaces for velocity components and pressure. H1Space xvel_space(&mesh, &bcs_vel_x, P_INIT_VEL); H1Space yvel_space(&mesh, &bcs_vel_y, P_INIT_VEL); #ifdef PRESSURE_IN_L2 L2Space p_space(&mesh, &bcs_pressure, P_INIT_PRESSURE); #else H1Space p_space(&mesh, &bcs_pressure, P_INIT_PRESSURE); #endif Hermes::vector<Space *> spaces = Hermes::vector<Space *>(&xvel_space, &yvel_space, &p_space); // Calculate and report the number of degrees of freedom. int ndof = Space::get_num_dofs(spaces); info("ndof = %d.", ndof); // Define projection norms. ProjNormType vel_proj_norm = HERMES_H1_NORM; #ifdef PRESSURE_IN_L2 ProjNormType p_proj_norm = HERMES_L2_NORM; #else ProjNormType p_proj_norm = HERMES_H1_NORM; #endif ProjNormType t_proj_norm = HERMES_H1_NORM; // Solutions for the Newton's iteration and time stepping. info("Setting initial conditions."); Solution xvel_prev_time, yvel_prev_time, p_prev_time; xvel_prev_time.set_zero(&mesh); yvel_prev_time.set_zero(&mesh); p_prev_time.set_zero(&mesh); Hermes::vector<Solution*> slns = Hermes::vector<Solution*>(&xvel_prev_time, &yvel_prev_time, &p_prev_time); // Initialize weak formulation. WeakForm* wf = new WeakFormDrivenCavity(Re, "Top", time_step, &xvel_prev_time, &yvel_prev_time); // Initialize the FE problem. DiscreteProblem dp(wf, spaces); // Set up the solver, matrix, and rhs according to the solver selection. SparseMatrix* matrix = create_matrix(matrix_solver); Vector* rhs = create_vector(matrix_solver); Solver* solver = create_linear_solver(matrix_solver, matrix, rhs); // Initialize views. VectorView vview("velocity", new WinGeom(0, 0, 400, 400)); ScalarView pview("pressure", new WinGeom(410, 0, 400, 400)); //vview.set_min_max_range(0, 1.6); vview.fix_scale_width(80); pview.fix_scale_width(80); pview.show_mesh(true); // Project the initial condition on the FE space to obtain initial // coefficient vector for the Newton's method. scalar* coeff_vec = new scalar[ndof]; // Newton's vector is set to zero (no OG projection needed). memset(coeff_vec, 0, ndof * sizeof(double)); /* // This can be used for more complicated initial conditions. info("Projecting initial condition to obtain initial vector for the Newton's method."); OGProjection::project_global(spaces, slns, coeff_vec, matrix_solver, Hermes::vector<ProjNormType>(vel_proj_norm, vel_proj_norm, p_proj_norm, t_proj_norm)); */ // Time-stepping loop: char title[100]; double current_time = 0; int num_time_steps = T_FINAL / time_step; for (int ts = 1; ts <= num_time_steps; ts++) { info("---- Time step %d, time = %g:", ts, current_time); // Perform Newton's iteration. info("Solving nonlinear problem:"); bool verbose = true; bool jacobian_changed = true; if (!hermes_2D.solve_newton(coeff_vec, &dp, solver, matrix, rhs, jacobian_changed, NEWTON_TOL, NEWTON_MAX_ITER, verbose)) error("Newton's iteration failed."); // Update previous time level solutions. Solution::vector_to_solutions(coeff_vec, spaces, slns); // Show the solution at the end of time step. sprintf(title, "Velocity, time %g", current_time); vview.set_title(title); vview.show(&xvel_prev_time, &yvel_prev_time); sprintf(title, "Pressure, time %g", current_time); pview.set_title(title); pview.show(&p_prev_time); // Update current time. current_time += time_step; } // Clean up. 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[]) { Hermes2D hermes_2D; // Load the mesh. Mesh mesh; H2DReader mloader; mloader.load("domain-excentric.mesh", &mesh); //mloader.load("domain-concentric.mesh", &mesh); // Initial mesh refinements. for (int i=0; i < INIT_REF_NUM; i++) mesh.refine_all_elements(); mesh.refine_towards_boundary("Inner", INIT_BDY_REF_NUM_INNER, false); // true for anisotropic refinements mesh.refine_towards_boundary("Outer", INIT_BDY_REF_NUM_OUTER, false); // false for isotropic refinements // Initialize boundary conditions. EssentialBCNonConstX bc_inner_vel_x(std::string("Inner"), VEL, STARTUP_TIME); EssentialBCNonConstY bc_inner_vel_y(std::string("Inner"), VEL, STARTUP_TIME); DefaultEssentialBCConst bc_outer_vel(std::string("Outer"), 0.0); EssentialBCs bcs_vel_x(Hermes::vector<EssentialBoundaryCondition *>(&bc_inner_vel_x, &bc_outer_vel)); EssentialBCs bcs_vel_y(Hermes::vector<EssentialBoundaryCondition *>(&bc_inner_vel_y, &bc_outer_vel)); EssentialBCs bcs_pressure; // Spaces for velocity components and pressure. H1Space xvel_space(&mesh, &bcs_vel_x, P_INIT_VEL); H1Space yvel_space(&mesh, &bcs_vel_y, P_INIT_VEL); #ifdef PRESSURE_IN_L2 L2Space p_space(&mesh, &bcs_pressure, P_INIT_PRESSURE); #else H1Space p_space(&mesh, &bcs_pressure, P_INIT_PRESSURE); #endif Hermes::vector<Space *> spaces = Hermes::vector<Space *>(&xvel_space, &yvel_space, &p_space); // Calculate and report the number of degrees of freedom. int ndof = Space::get_num_dofs(spaces); info("ndof = %d.", ndof); // Define projection norms. ProjNormType vel_proj_norm = HERMES_H1_NORM; #ifdef PRESSURE_IN_L2 ProjNormType p_proj_norm = HERMES_L2_NORM; #else ProjNormType p_proj_norm = HERMES_H1_NORM; #endif // Solutions for the Newton's iteration and time stepping. info("Setting initial conditions."); Solution xvel_prev_time, yvel_prev_time, p_prev_time; xvel_prev_time.set_zero(&mesh); yvel_prev_time.set_zero(&mesh); p_prev_time.set_zero(&mesh); Hermes::vector<Solution*> slns = Hermes::vector<Solution*>(&xvel_prev_time, &yvel_prev_time, &p_prev_time); // Initialize weak formulation. WeakForm* wf = new WeakFormNSNewton(STOKES, RE, TAU, &xvel_prev_time, &yvel_prev_time); // Initialize the FE problem. DiscreteProblem dp(wf, spaces); // Set up the solver, matrix, and rhs according to the solver selection. SparseMatrix* matrix = create_matrix(matrix_solver); Vector* rhs = create_vector(matrix_solver); Solver* solver = create_linear_solver(matrix_solver, matrix, rhs); // Initialize views. VectorView vview("velocity [m/s]", new WinGeom(0, 0, 600, 500)); ScalarView pview("pressure [Pa]", new WinGeom(610, 0, 600, 500)); //vview.set_min_max_range(0, 1.6); vview.fix_scale_width(80); //pview.set_min_max_range(-0.9, 1.0); pview.fix_scale_width(80); pview.show_mesh(true); // Project the initial condition on the FE space to obtain initial // coefficient vector for the Newton's method. scalar* coeff_vec = new scalar[Space::get_num_dofs(spaces)]; // Newton's vector is set to zero (no OG projection needed). memset(coeff_vec, 0, ndof * sizeof(double)); /* // This can be used for more complicated initial conditions. info("Projecting initial condition to obtain initial vector for the Newton's method."); OGProjection::project_global(spaces, slns, coeff_vec, matrix_solver, Hermes::vector<ProjNormType>(vel_proj_norm, vel_proj_norm, p_proj_norm)); */ // Time-stepping loop: char title[100]; int num_time_steps = T_FINAL / TAU; for (int ts = 1; ts <= num_time_steps; ts++) { current_time += TAU; info("---- Time step %d, time = %g:", ts, current_time); // Update time-dependent essential BCs. info("Updating time-dependent essential BC."); Space::update_essential_bc_values(Hermes::vector<Space *>(&xvel_space, &yvel_space, &p_space), current_time); // Perform Newton's iteration. info("Solving nonlinear problem:"); bool verbose = true; bool jacobian_changed = true; if (!hermes_2D.solve_newton(coeff_vec, &dp, solver, matrix, rhs, jacobian_changed, NEWTON_TOL, NEWTON_MAX_ITER, verbose)) error("Newton's iteration failed."); // Update previous time level solutions. Solution::vector_to_solutions(coeff_vec, spaces, slns); // Show the solution at the end of time step. sprintf(title, "Velocity, time %g", current_time); vview.set_title(title); vview.show(&xvel_prev_time, &yvel_prev_time); sprintf(title, "Pressure, time %g", current_time); pview.set_title(title); pview.show(&p_prev_time); } // Clean up. delete [] coeff_vec; delete matrix; delete rhs; delete solver; // Wait for all views to be closed. View::wait(); return 0; }
int main(int argc, char* argv[]) { // Load the mesh. Mesh mesh_whole_domain, mesh_with_hole; Hermes::vector<Mesh*> meshes (&mesh_whole_domain, &mesh_with_hole); MeshReaderH2DXML mloader; mloader.load("domain.xml", meshes); // Temperature mesh: Initial uniform mesh refinements in graphite. meshes[0]->refine_by_criterion(element_in_graphite, INIT_REF_NUM_TEMPERATURE_GRAPHITE); // Temperature mesh: Initial uniform mesh refinements in fluid. meshes[0]->refine_by_criterion(element_in_fluid, INIT_REF_NUM_TEMPERATURE_FLUID); // Fluid mesh: Initial uniform mesh refinements. for(int i = 0; i < INIT_REF_NUM_FLUID; i++) meshes[1]->refine_all_elements(); // Initial refinements towards boundary of graphite. for(unsigned int meshes_i = 0; meshes_i < meshes.size(); meshes_i++) meshes[meshes_i]->refine_towards_boundary("Inner Wall", INIT_REF_NUM_BDY_GRAPHITE); // Initial refinements towards the top and bottom edges. for(unsigned int meshes_i = 0; meshes_i < meshes.size(); meshes_i++) meshes[meshes_i]->refine_towards_boundary("Outer Wall", INIT_REF_NUM_BDY_WALL); /* View both meshes. */ MeshView m1("Mesh for temperature"), m2("Mesh for fluid"); m1.show(&mesh_whole_domain); m2.show(&mesh_with_hole); // Initialize boundary conditions. EssentialBCNonConst bc_inlet_vel_x("Inlet", VEL_INLET, H, STARTUP_TIME); DefaultEssentialBCConst<double> bc_other_vel_x(Hermes::vector<std::string>("Outer Wall", "Inner Wall"), 0.0); EssentialBCs<double> bcs_vel_x(Hermes::vector<EssentialBoundaryCondition<double> *>(&bc_inlet_vel_x, &bc_other_vel_x)); DefaultEssentialBCConst<double> bc_vel_y(Hermes::vector<std::string>("Inlet", "Outer Wall", "Inner Wall"), 0.0); EssentialBCs<double> bcs_vel_y(&bc_vel_y); EssentialBCs<double> bcs_pressure; DefaultEssentialBCConst<double> bc_temperature(Hermes::vector<std::string>("Outer Wall", "Inlet"), 20.0); EssentialBCs<double> bcs_temperature(&bc_temperature); // Spaces for velocity components, pressure and temperature. H1Space<double> xvel_space(&mesh_with_hole, &bcs_vel_x, P_INIT_VEL); H1Space<double> yvel_space(&mesh_with_hole, &bcs_vel_y, P_INIT_VEL); #ifdef PRESSURE_IN_L2 L2Space<double> p_space(&mesh_with_hole, P_INIT_PRESSURE); #else H1Space<double> p_space(&mesh_with_hole, &bcs_pressure, P_INIT_PRESSURE); #endif H1Space<double> temperature_space(&mesh_whole_domain, &bcs_temperature, P_INIT_TEMPERATURE); Hermes::vector<Space<double> *> all_spaces(&xvel_space, &yvel_space, &p_space, &temperature_space); Hermes::vector<const Space<double> *> all_spaces_const(&xvel_space, &yvel_space, &p_space, &temperature_space); // Calculate and report the number of degrees of freedom. int ndof = Space<double>::get_num_dofs(Hermes::vector<const Space<double> *>(&xvel_space, &yvel_space, &p_space, &temperature_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 ProjNormType temperature_proj_norm = HERMES_H1_NORM; Hermes::vector<ProjNormType> all_proj_norms = Hermes::vector<ProjNormType>(vel_proj_norm, vel_proj_norm, p_proj_norm, temperature_proj_norm); // Initial conditions and such. info("Setting initial conditions."); ZeroSolution xvel_prev_time(&mesh_with_hole), yvel_prev_time(&mesh_with_hole), p_prev_time(&mesh_with_hole); CustomInitialConditionTemperature temperature_init_cond(&mesh_whole_domain, HOLE_MID_X, HOLE_MID_Y, 0.5*OBSTACLE_DIAMETER, TEMPERATURE_INIT_FLUID, TEMPERATURE_INIT_GRAPHITE); Solution<double> temperature_prev_time; Hermes::vector<Solution<double> *> all_solutions = Hermes::vector<Solution<double> *>(&xvel_prev_time, &yvel_prev_time, &p_prev_time, &temperature_prev_time); Hermes::vector<MeshFunction<double> *> all_meshfns = Hermes::vector<MeshFunction<double> *>(&xvel_prev_time, &yvel_prev_time, &p_prev_time, &temperature_init_cond); // Project all initial conditions on their FE spaces to obtain aninitial // coefficient vector for the Newton's method. We use local projection // to avoid oscillations in temperature on the graphite-fluid interface // FIXME - currently the LocalProjection only does the lowest-order part (linear // interpolation) at the moment. Higher-order part needs to be added. double* coeff_vec = new double[ndof]; info("Projecting initial condition to obtain initial vector for the Newton's method."); //OGProjection<double>::project_global(all_spaces, all_meshfns, coeff_vec, matrix_solver, all_proj_norms); LocalProjection<double>::project_local(all_spaces_const, all_meshfns, coeff_vec, matrix_solver, all_proj_norms); // Translate the solution vector back to Solutions. This is needed to replace // the discontinuous initial condition for temperature_prev_time with its projection. Solution<double>::vector_to_solutions(coeff_vec, all_spaces_const, all_solutions); // Calculate Reynolds number. double reynolds_number = VEL_INLET * OBSTACLE_DIAMETER / KINEMATIC_VISCOSITY_FLUID; info("RE = %g", reynolds_number); if (reynolds_number < 1e-8) error("Re == 0 will not work - the equations use 1/Re."); // Initialize weak formulation. CustomWeakFormHeatAndFlow wf(STOKES, reynolds_number, time_step, &xvel_prev_time, &yvel_prev_time, &temperature_prev_time, HEAT_SOURCE_GRAPHITE, SPECIFIC_HEAT_GRAPHITE, SPECIFIC_HEAT_FLUID, RHO_GRAPHITE, RHO_FLUID, THERMAL_CONDUCTIVITY_GRAPHITE, THERMAL_CONDUCTIVITY_FLUID, SIMPLE_TEMPERATURE_ADVECTION); // Initialize the FE problem. DiscreteProblem<double> dp(&wf, all_spaces_const); // Initialize the Newton solver. NewtonSolver<double> newton(&dp, matrix_solver); // Initialize views. Views::VectorView vview("velocity [m/s]", new Views::WinGeom(0, 0, 700, 360)); Views::ScalarView pview("pressure [Pa]", new Views::WinGeom(0, 415, 700, 350)); Views::ScalarView tempview("temperature [C]", new Views::WinGeom(0, 795, 700, 350)); //vview.set_min_max_range(0, 0.5); vview.fix_scale_width(80); //pview.set_min_max_range(-0.9, 1.0); pview.fix_scale_width(80); pview.show_mesh(false); tempview.fix_scale_width(80); tempview.show_mesh(false); // Time-stepping loop: char title[100]; int num_time_steps = T_FINAL / time_step; double current_time = 0.0; for (int ts = 1; ts <= num_time_steps; ts++) { current_time += time_step; 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, &temperature_space), current_time); } // Perform Newton's iteration. info("Solving nonlinear problem:"); bool verbose = true; // Perform Newton's iteration and translate the resulting coefficient vector into previous time level solutions. newton.set_verbose_output(verbose); try { newton.solve(coeff_vec, NEWTON_TOL, NEWTON_MAX_ITER); } catch(Hermes::Exceptions::Exception e) { e.printMsg(); error("Newton's iteration failed."); }; { Hermes::vector<Solution<double> *> tmp(&xvel_prev_time, &yvel_prev_time, &p_prev_time, &temperature_prev_time); Solution<double>::vector_to_solutions(newton.get_sln_vector(), Hermes::vector<const Space<double> *>(&xvel_space, &yvel_space, &p_space, &temperature_space), tmp); } // Show the solution at the end of time step. sprintf(title, "Velocity [m/s], time %g s", current_time); vview.set_title(title); vview.show(&xvel_prev_time, &yvel_prev_time); sprintf(title, "Pressure [Pa], time %g s", current_time); pview.set_title(title); pview.show(&p_prev_time); sprintf(title, "Temperature [C], time %g s", current_time); tempview.set_title(title); tempview.show(&temperature_prev_time, Views::HERMES_EPS_HIGH); } delete [] coeff_vec; // Wait for all views to be closed. Views::View::wait(); return 0; }
int main(int argc, char* argv[]) { // Load the mesh. MeshSharedPtr mesh(new Mesh); MeshReaderH2D mloader; mloader.load("domain-excentric.mesh", mesh); //mloader.load("domain-concentric.mesh", mesh); // Initial mesh refinements. for (int i = 0; i < INIT_REF_NUM; i++) mesh->refine_all_elements(); // Use 'true' for anisotropic refinements. mesh->refine_towards_boundary("Inner", INIT_BDY_REF_NUM_INNER, false); // Use 'false' for isotropic refinements. mesh->refine_towards_boundary("Outer", INIT_BDY_REF_NUM_OUTER, false); // Initialize boundary conditions. EssentialBCNonConstX bc_inner_vel_x(std::string("Inner"), VEL, STARTUP_TIME); EssentialBCNonConstY bc_inner_vel_y(std::string("Inner"), VEL, STARTUP_TIME); DefaultEssentialBCConst<double> bc_outer_vel(std::string("Outer"), 0.0); EssentialBCs<double> bcs_vel_x({ &bc_inner_vel_x, &bc_outer_vel }); EssentialBCs<double> bcs_vel_y({ &bc_inner_vel_y, &bc_outer_vel }); // Spaces for velocity components and pressure. 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 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 views. VectorView vview("velocity [m/s]", new WinGeom(0, 0, 600, 500)); ScalarView pview("pressure [Pa]", new WinGeom(610, 0, 600, 500)); //vview.set_min_max_range(0, 1.6); vview.fix_scale_width(80); //pview.set_min_max_range(-0.9, 1.0); pview.fix_scale_width(80); pview.show_mesh(true); // Initialize the FE problem. Hermes::Hermes2D::NewtonSolver<double> newton(wf, spaces); newton.set_verbose_output(true); newton.set_max_allowed_iterations(NEWTON_MAX_ITER); newton.set_tolerance(NEWTON_TOL, Hermes::Solvers::ResidualNormAbsolute); // 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. Hermes::Mixins::Loggable::Static::info("Updating time-dependent essential BC."); Space<double>::update_essential_bc_values(spaces, current_time); // Perform Newton's iteration. Hermes::Mixins::Loggable::Static::info("Solving nonlinear problem:"); try { newton.solve(); } catch (Hermes::Exceptions::Exception e) { e.print_msg(); throw Hermes::Exceptions::Exception("Newton's iteration failed."); }; // Update previous time level solutions. Solution<double>::vector_to_solutions(newton.get_sln_vector(), spaces, { xvel_prev_time, yvel_prev_time, p_prev_time }); // 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; }
int main(int argc, char* argv[]) { // load the mesh file Mesh mesh; H2DReader mloader; mloader.load("domain.mesh", &mesh); // a-priori mesh refinements mesh.refine_all_elements(); mesh.refine_towards_boundary(5, 4, false); mesh.refine_towards_boundary(1, 4); mesh.refine_towards_boundary(3, 4); // initialize shapesets and the cache H1ShapesetBeuchler h1_shapeset; PrecalcShapeset h1_pss(&h1_shapeset); #ifdef PRESSURE_IN_L2 L2Shapeset l2_shapeset; PrecalcShapeset l2_pss(&l2_shapeset); #endif // spaces for velocities and pressure H1Space xvel_space(&mesh, &h1_shapeset); H1Space yvel_space(&mesh, &h1_shapeset); #ifdef PRESSURE_IN_L2 L2Space p_space(&mesh, &l2_shapeset); #else H1Space p_space(&mesh, &h1_shapeset); #endif // initialize boundary conditions xvel_space.set_bc_types(xvel_bc_type); xvel_space.set_bc_values(xvel_bc_value); yvel_space.set_bc_types(yvel_bc_type); p_space.set_bc_types(p_bc_type); // set velocity and pressure polynomial degrees xvel_space.set_uniform_order(P_INIT_VEL); yvel_space.set_uniform_order(P_INIT_VEL); p_space.set_uniform_order(P_INIT_PRESSURE); // assign degrees of freedom int ndofs = 0; ndofs += xvel_space.assign_dofs(ndofs); ndofs += yvel_space.assign_dofs(ndofs); ndofs += p_space.assign_dofs(ndofs); // solutions for the Newton's iteration and time stepping Solution xvel_prev_time, yvel_prev_time, xvel_prev_newton, yvel_prev_newton, p_prev; xvel_prev_time.set_zero(&mesh); yvel_prev_time.set_zero(&mesh); xvel_prev_newton.set_zero(&mesh); yvel_prev_newton.set_zero(&mesh); p_prev.set_zero(&mesh); // set up weak formulation WeakForm wf(3); if (NEWTON) { wf.add_biform(0, 0, callback(bilinear_form_sym_0_0_1_1), SYM); wf.add_biform(0, 0, callback(newton_bilinear_form_unsym_0_0), UNSYM, ANY, 2, &xvel_prev_newton, &yvel_prev_newton); wf.add_biform(0, 1, callback(newton_bilinear_form_unsym_0_1), UNSYM, ANY, 1, &xvel_prev_newton); wf.add_biform(0, 2, callback(bilinear_form_unsym_0_2), ANTISYM); wf.add_biform(1, 0, callback(newton_bilinear_form_unsym_1_0), UNSYM, ANY, 1, &yvel_prev_newton); wf.add_biform(1, 1, callback(bilinear_form_sym_0_0_1_1), SYM); wf.add_biform(1, 1, callback(newton_bilinear_form_unsym_1_1), UNSYM, ANY, 2, &xvel_prev_newton, &yvel_prev_newton); wf.add_biform(1, 2, callback(bilinear_form_unsym_1_2), ANTISYM); wf.add_liform(0, callback(newton_F_0), ANY, 5, &xvel_prev_time, &yvel_prev_time, &xvel_prev_newton, &yvel_prev_newton, &p_prev); wf.add_liform(1, callback(newton_F_1), ANY, 5, &xvel_prev_time, &yvel_prev_time, &xvel_prev_newton, &yvel_prev_newton, &p_prev); wf.add_liform(2, callback(newton_F_2), ANY, 2, &xvel_prev_newton, &yvel_prev_newton); } else { wf.add_biform(0, 0, callback(bilinear_form_sym_0_0_1_1), SYM); wf.add_biform(0, 0, callback(simple_bilinear_form_unsym_0_0_1_1), UNSYM, ANY, 2, &xvel_prev_time, &yvel_prev_time); wf.add_biform(1, 1, callback(bilinear_form_sym_0_0_1_1), SYM); wf.add_biform(1, 1, callback(simple_bilinear_form_unsym_0_0_1_1), UNSYM, ANY, 2, &xvel_prev_time, &yvel_prev_time); wf.add_biform(0, 2, callback(bilinear_form_unsym_0_2), ANTISYM); wf.add_biform(1, 2, callback(bilinear_form_unsym_1_2), ANTISYM); wf.add_liform(0, callback(simple_linear_form), ANY, 1, &xvel_prev_time); wf.add_liform(1, callback(simple_linear_form), ANY, 1, &yvel_prev_time); } // visualization VectorView vview("velocity [m/s]", 0, 0, 1500, 470); ScalarView pview("pressure [Pa]", 0, 530, 1500, 470); 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); // matrix solver UmfpackSolver umfpack; // linear system LinSystem ls(&wf, &umfpack); // nonlinear system NonlinSystem nls(&wf, &umfpack); if (NEWTON) { // set up the nonlinear system nls.set_spaces(3, &xvel_space, &yvel_space, &p_space); #ifdef PRESSURE_IN_L2 nls.set_pss(3, &h1_pss, &h1_pss, &l2_pss); #else nls.set_pss(1, &h1_pss); #endif } else { // set up the linear system ls.set_spaces(3, &xvel_space, &yvel_space, &p_space); #ifdef PRESSURE_IN_L2 ls.set_pss(3, &h1_pss, &h1_pss, &l2_pss); #else ls.set_pss(1, &h1_pss); #endif } // time-stepping loop char title[100]; int num_time_steps = T_FINAL / TAU; for (int i = 1; i <= num_time_steps; i++) { TIME += TAU; info("\n---- Time step %d, time = %g:\n", i, TIME); // this is needed to update the time-dependent boundary conditions ndofs = 0; ndofs += xvel_space.assign_dofs(ndofs); ndofs += yvel_space.assign_dofs(ndofs); ndofs += p_space.assign_dofs(ndofs); if (NEWTON) { // Newton's method if (!nls.solve_newton_3(&xvel_prev_newton, &yvel_prev_newton, &p_prev, NEWTON_TOL, NEWTON_MAX_ITER)) error("Newton's method did not converge."); // show the solution at the end of time step sprintf(title, "Velocity, time %g", TIME); vview.set_title(title); vview.show(&xvel_prev_newton, &yvel_prev_newton, EPS_LOW); sprintf(title, "Pressure, time %g", TIME); pview.set_title(title); pview.show(&p_prev); // copy the result of the Newton's iteration into the // previous time level solutions xvel_prev_time.copy(&xvel_prev_newton); yvel_prev_time.copy(&yvel_prev_newton); } else { // assemble and solve Solution xvel_sln, yvel_sln, p_sln; ls.assemble(); ls.solve(3, &xvel_sln, &yvel_sln, &p_sln); // show the solution at the end of time step sprintf(title, "Velocity, time %g", TIME); vview.set_title(title); vview.show(&xvel_sln, &yvel_sln, EPS_LOW); sprintf(title, "Pressure, time %g", TIME); pview.set_title(title); pview.show(&p_sln); // this copy destroys xvel_sln and yvel_sln // which are no longer needed xvel_prev_time = xvel_sln; yvel_prev_time = yvel_sln; } } // wait for keyboard or mouse input View::wait(); 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; }
int main(int argc, char* argv[]) { // load the mesh file Mesh mesh; H2DReader mloader; mloader.load("domain-quad.mesh", &mesh); // unstructured triangular mesh available in domain-tri.mesh // a-priori mesh refinements mesh.refine_all_elements(); mesh.refine_towards_boundary(5, 4, false); mesh.refine_towards_boundary(1, 4); mesh.refine_towards_boundary(3, 4); // display the mesh //MeshView mview("Navier-Stokes Example - Mesh", 100, 100, 1100, 400); //mview.show(&mesh); //mview.wait_for_keypress(); // initialize the shapesets and the cache H1Shapeset shapeset_h1; PrecalcShapeset pss_h1(&shapeset_h1); L2Shapeset shapeset_l2; PrecalcShapeset pss_l2(&shapeset_l2); // H1 spaces for velocities and L2 for pressure H1Space xvel(&mesh, &shapeset_h1); H1Space yvel(&mesh, &shapeset_h1); L2Space press(&mesh, &shapeset_l2); // initialize boundary conditions xvel.set_bc_types(xvel_bc_type); xvel.set_bc_values(xvel_bc_value); yvel.set_bc_types(yvel_bc_type); press.set_bc_types(press_bc_type); // set velocity and pressure polynomial degrees xvel.set_uniform_order(P_INIT_VEL); yvel.set_uniform_order(P_INIT_VEL); press.set_uniform_order(P_INIT_PRESSURE); // assign degrees of freedom int ndofs = 0; ndofs += xvel.assign_dofs(ndofs); ndofs += yvel.assign_dofs(ndofs); ndofs += press.assign_dofs(ndofs); // initial condition: xprev and yprev are zero Solution xprev, yprev; xprev.set_zero(&mesh); yprev.set_zero(&mesh); // set up weak formulation WeakForm wf(3); wf.add_biform(0, 0, callback(bilinear_form_sym_0_0_1_1), SYM); wf.add_biform(0, 0, callback(bilinear_form_unsym_0_0_1_1), UNSYM, ANY, 2, &xprev, &yprev); wf.add_biform(1, 1, callback(bilinear_form_sym_0_0_1_1), SYM); wf.add_biform(1, 1, callback(bilinear_form_unsym_0_0_1_1), UNSYM, ANY, 2, &xprev, &yprev); wf.add_biform(0, 2, callback(bilinear_form_unsym_0_2), ANTISYM); wf.add_biform(1, 2, callback(bilinear_form_unsym_1_2), ANTISYM); wf.add_liform(0, callback(linear_form), ANY, 1, &xprev); wf.add_liform(1, callback(linear_form), ANY, 1, &yprev); // visualization VectorView vview("velocity [m/s]", 0, 0, 1500, 470); ScalarView pview("pressure [Pa]", 0, 530, 1500, 470); vview.set_min_max_range(0, 1.6); vview.fix_scale_width(80); pview.show_mesh(false); pview.fix_scale_width(80); // fixing scale width (for nicer videos). Note: creation of videos is // discussed in a separate example vview.fix_scale_width(5); pview.fix_scale_width(5); // set up the linear system UmfpackSolver umfpack; LinSystem sys(&wf, &umfpack); sys.set_spaces(3, &xvel, &yvel, &press); sys.set_pss(3, &pss_h1, &pss_h1, &pss_l2); // main loop char title[100]; int num_time_steps = FINAL_TIME / TAU; for (int i = 1; i <= num_time_steps; i++) { TIME += TAU; info("\n---- Time step %d, time = %g -----------------------------------", i, TIME); // this is needed to update the time-dependent boundary conditions ndofs = 0; ndofs += xvel.assign_dofs(ndofs); ndofs += yvel.assign_dofs(ndofs); ndofs += press.assign_dofs(ndofs); // assemble and solve Solution xsln, ysln, psln; sys.assemble(); sys.solve(3, &xsln, &ysln, &psln); // visualization sprintf(title, "Velocity, time %g", TIME); vview.set_title(title); vview.show(&xprev, &yprev, EPS_LOW); sprintf(title, "Pressure, time %g", TIME); pview.set_title(title); pview.show(&psln); xprev = xsln; yprev = ysln; } // wait for keyboard or mouse input View::wait("Waiting for all views to be closed."); return 0; }