int main(int argc, char* argv[]) { // Initialize Python Py_Initialize(); PySys_SetArgv(argc, argv); if (import_hermes2d___hermes2d()) throw std::runtime_error("hermes2d failed to import."); cmd("import utils"); // load the mesh file Mesh mesh; mesh.load("domain-quad.mesh"); // unstructured triangular mesh available in domain-tri.mesh // a-priori mesh refinements mesh.refine_all_elements(); mesh.refine_towards_boundary(marker_obstacle, 4, false); //mesh.refine_towards_boundary(marker_bottom, 4); //mesh.refine_towards_boundary(marker_top, 4); // plot the mesh: //insert_object("mesh", Mesh_from_C(&mesh)); //cmd("mesh.plot(lib='mpl', method='orders')"); // 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 H1ShapesetBeuchler 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 BC: xprev and yprev are zero xprev.set_zero(&mesh); yprev.set_zero(&mesh); // set up weak formulation WeakForm wf(3); wf.add_biform(0, 0, bilinear_form_sym_0_0_1_1, SYM); wf.add_biform(0, 0, bilinear_form_unsym_0_0_1_1, UNSYM, ANY, 2, &xprev, &yprev); wf.add_biform(1, 1, bilinear_form_sym_0_0_1_1, SYM); wf.add_biform(1, 1, bilinear_form_unsym_0_0_1_1, UNSYM, ANY, 2, &xprev, &yprev); wf.add_biform(0, 2, bilinear_form_unsym_0_2, ANTISYM); wf.add_biform(1, 2, bilinear_form_unsym_1_2, ANTISYM); wf.add_liform(0, linear_form_0, ANY, 1, &xprev); wf.add_liform(1, linear_form_1, 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); //pview.show_mesh(false); // 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 DummySolver umfpack; LinSystem sys(&wf, &umfpack); sys.set_spaces(3, &xvel, &yvel, &press); sys.set_pss(3, &pss_h1, &pss_h1, &pss_l2); cmd("from hermes2d import Linearizer, Vectorizer"); cmd("from scipy.sparse import csc_matrix"); cmd("from scipy.sparse.linalg.dsolve import spsolve"); cmd("from scipy.sparse.linalg import cg"); // 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; psln.set_zero(&mesh); sys.assemble(); //sys.solve(3, &xsln, &ysln, &psln); int *Ap, *Ai, n, nnz; scalar *Ax; sys.get_matrix(Ap, Ai, Ax, n); nnz = Ap[n]; scalar *rhs; sys.get_rhs(rhs, n); insert_int_array("Ap", Ap, n+1); insert_int_array("Ai", Ai, nnz); insert_double_array("Ax", Ax, nnz); insert_double_array("rhs", rhs, n); cmd("A = csc_matrix((Ax, Ai, Ap))"); cmd("x = spsolve(A, rhs)"); double *X; array_double_numpy2c_inplace(get_symbol("x"), &X, &n); xsln.set_fe_solution(sys.get_space(0), sys.get_pss(0), X); ysln.set_fe_solution(sys.get_space(1), sys.get_pss(1), X); psln.set_fe_solution(sys.get_space(2), sys.get_pss(2), X); insert_object("xsln", Solution_from_C(&xsln)); insert_object("ysln", Solution_from_C(&ysln)); insert_object("psln", Solution_from_C(&psln)); cmd("l = Linearizer()"); cmd("l.process_solution(psln)"); cmd("vert = l.get_vertices()"); cmd("triangles = l.get_triangles()"); cmd("utils.plot(vert, triangles)"); cmd("v = Vectorizer()"); cmd("v.process_solution(xsln, ysln)"); cmd("v_vert = v.get_vertices()"); cmd("v_triangles = v.get_triangles()"); cmd("utils.plot_vec(v_vert, v_triangles)"); //cmd("import IPython; IPython.ipapi.set_trace()"); // 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; } //View::wait(); }
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; }