コード例 #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
ファイル: main.cpp プロジェクト: regmi/hermes2d
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;
}
コード例 #3
0
ファイル: main.cpp プロジェクト: davidquantum/hermes2dold
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;
}