示例#1
0
//----------------------------------------------------------------------------
fei::SharedPtr<fei::LinearSystem>
fei::LinearSystem::Factory::createLinearSystem(fei::SharedPtr<fei::MatrixGraph>& matrixGraph)
{
  fei::SharedPtr<fei::LinearSystem>
    linsys(new snl_fei::LinearSystem_General(matrixGraph));

  return(linsys);
}
示例#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;
}