예제 #1
0
파일: main.cpp 프로젝트: certik/mhd-hermes
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();
}
예제 #2
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;
}