Beispiel #1
0
int main(int argc, char* argv[])
{
  // load the mesh file
  Mesh mesh;
  H2DReader mloader;
  mloader.load("square.mesh", &mesh);

  // initial mesh refinements
  for(int i = 0; i < INIT_GLOB_REF_NUM; i++) mesh.refine_all_elements();
  mesh.refine_towards_boundary(1,INIT_BDY_REF_NUM);

  // initialize the shapeset and the cache
  H1Shapeset shapeset;
  PrecalcShapeset pss(&shapeset);

  // create an H1 space
  H1Space space(&mesh, &shapeset);
  space.set_bc_types(bc_types);
  space.set_uniform_order(P_INIT);
  space.assign_dofs();

  // previous solution for the Newton's iteration
  Solution u_prev;

  // initialize the weak formulation
  WeakForm wf(1);
  wf.add_biform(0, 0, callback(jac), UNSYM, ANY, 1, &u_prev);
  wf.add_liform(0, callback(res), ANY, 1, &u_prev);

  // initialize the nonlinear system and solver
  UmfpackSolver umfpack;
  NonlinSystem nls(&wf, &umfpack);
  nls.set_spaces(1, &space);
  nls.set_pss(1, &pss);

  // use a constant function as the initial guess
  u_prev.set_const(&mesh, 3.0);
  nls.set_ic(&u_prev, &u_prev, PROJ_TYPE);

  // Newton's loop
  if (!nls.solve_newton_1(&u_prev, NEWTON_TOL, NEWTON_MAX_ITER)) error("Newton's method did not converge.");

  // visualise the solution and mesh
  ScalarView sview("Solution", 0, 0, 800, 600);
  OrderView oview("Mesh", 820, 0, 800, 600);
  char title[100];
  sprintf(title, "Solution");
  sview.set_title(title);
  sview.show(&u_prev);
  sprintf(title, "Mesh");
  oview.set_title(title);
  oview.show(&space);

  // wait for keyboard or mouse input
  View::wait();
  return 0;
}
Beispiel #2
0
int main(int argc, char* argv[])
{
    // load the mesh file
    Mesh mesh;
    H2DReader mloader;
    mloader.load("square.mesh", &mesh);

    // initial mesh refinements
    for(int i = 0; i < INIT_GLOB_REF_NUM; i++) mesh.refine_all_elements();
    mesh.refine_towards_boundary(1,INIT_BDY_REF_NUM);

    // initialize the shapeset and the cache
    H1Shapeset shapeset;
    PrecalcShapeset pss(&shapeset);

    // create an H1 space
    H1Space space(&mesh, &shapeset);
    space.set_bc_types(bc_types);
    space.set_uniform_order(P_INIT);
    space.assign_dofs();

    // previous solution for the Newton's iteration
    Solution u_prev;

    // initialize the weak formulation
    WeakForm wf(1);
    wf.add_biform(0, 0, callback(jac), UNSYM, ANY, 1, &u_prev);
    wf.add_liform(0, callback(res), ANY, 1, &u_prev);

    // initialize the nonlinear system and solver
    UmfpackSolver umfpack;
    NonlinSystem nls(&wf, &umfpack);
    nls.set_spaces(1, &space);
    nls.set_pss(1, &pss);

    // use a constant function as the initial guess
    u_prev.set_const(&mesh, 3.0);
    nls.set_ic(&u_prev, &u_prev, PROJ_TYPE);

    // Newton's loop
    bool success = nls.solve_newton_1(&u_prev, NEWTON_TOL, NEWTON_MAX_ITER);

#define ERROR_SUCCESS                               0
#define ERROR_FAILURE                               -1
    if (success) {  // should pass with NEWTON_MAX_ITER = 8 and fail with NEWTON_MAX_ITER = 7
        printf("Success!\n");
        return ERROR_SUCCESS;
    }
    else {
        printf("Failure!\n");
        return ERROR_FAILURE;
    }
}
Beispiel #3
0
Datei: semc1.c Projekt: aiju/hdl
/* add initialization statements to blocks as needed */
static void
sinitbuild(SemBlock *b)
{
    SemBlock *yes, *no, *then;
    SemInit *si;
    ASTNode *p;
    SemVar *nv, *v;
    SemTrigger *t;

    for(t = sinits; t != nil; t = t->next) {
        yes = newblock();
        no = newblock();
        then = newblock();
        yes->cont = node(ASTBLOCK, nil);
        then->phi = node(ASTBLOCK, nil);
        b->jump = node(ASTIF, t->trigger, node(ASTSEMGOTO, yes), node(ASTSEMGOTO, no));
        yes->jump = node(ASTSEMGOTO, then);
        no->jump = node(ASTSEMGOTO, then);
        mkftlist(b, 1, yes, no, nil);
        mkftlist(yes, 0, b, nil);
        mkftlist(yes, 1, then, nil);
        mkftlist(no, 0, b, nil);
        mkftlist(no, 1, then, nil);
        mkftlist(then, 0, yes, no, nil);
        for(si = t->first; si != nil; si = si->tnext) {
            v = mkvar(si->var->sym, 1);
            if(--si->var->nsinits > 0)
                nv = mkvar(si->var->sym, 1);
            else
                nv = si->var->sym->semc[1];
            yes->cont->nl = nlcat(yes->cont->nl, nl(node(ASTASS, OPNOP, node(ASTSSA, v), si->val)));
            p = node(ASTPHI);
            p->nl = nls(node(ASTSSA, v), node(ASTSSA, ssaget(sinitvars, v->sym, 1)), nil);
            then->phi->nl = nlcat(then->phi->nl, nl(node(ASTASS, OPNOP, node(ASTSSA, nv), p)));
            defsadd(sinitvars, nv, 1);
        }
        b = then;
    }
}
Beispiel #4
0
int main(int argc, char* argv[])
{
  // load the mesh
  Mesh mesh, basemesh;
  basemesh.load("square.mesh");
  for(int i = 0; i < REF_INIT; i++) basemesh.refine_all_elements();
  mesh.copy(&basemesh);
  mesh.refine_towards_boundary(1,3);

  // initialize the shapeset and the cache
  H1Shapeset shapeset;
  PrecalcShapeset pss(&shapeset);

  // create finite element space
  H1Space space(&mesh, &shapeset);
  space.set_bc_types(bc_types);
  space.set_bc_values(bc_values);
  space.set_uniform_order(P_INIT);
  space.assign_dofs();

  // enumerate basis functions
  space.assign_dofs();

  Solution Tprev, // previous time step solution, for the time integration method
           Titer; // solution converging during the Newton's iteration

  // initialize the weak formulation
  WeakForm wf(1);
  if(TIME_DISCR == 1) {
    wf.add_biform(0, 0, callback(J_euler), UNSYM, ANY, 1, &Titer);
    wf.add_liform(0, callback(F_euler), ANY, 2, &Titer, &Tprev);
  }
  else {
    wf.add_biform(0, 0, callback(J_cranic), UNSYM, ANY, 1, &Titer);
    wf.add_liform(0, callback(F_cranic), ANY, 2, &Titer, &Tprev);
  }

  // matrix solver
  UmfpackSolver solver;

  // nonlinear system class
  NonlinSystem nls(&wf, &solver);
  nls.set_spaces(1, &space);
  nls.set_pss(1, &pss);

  // visualize solution and mesh
  ScalarView view("", 0, 0, 700, 600);
  view.fix_scale_width(80);
  OrderView ordview("", 700, 0, 700, 600);

  // error estimate as a function of physical time
  GnuplotGraph graph_err;
  graph_err.set_captions("","Time step","Error");
  graph_err.add_row();

  // error estimate as a function of DOF
  GnuplotGraph graph_dofs;
  graph_dofs.set_captions("","Time step","DOFs");
  graph_dofs.add_row();

  // initial condition at zero time level
  //Tprev.set_const(&mesh, 0.0);
  Tprev.set_dirichlet_lift(&space, &pss);
  Titer.set_dirichlet_lift(&space, &pss);
  nls.set_ic(&Titer, &Titer, PROJ_TYPE);

  // view initial guess for Newton's method
  // satisfies BC conditions
  char title[100];
  sprintf(title, "Initial iteration");
  view.set_title(title);
  view.show(&Titer);
  ordview.show(&space);
  //view.wait_for_keypress(); // this may cause graphics problems

  // time stepping loop
  int nstep = (int)(T_FINAL/TAU + 0.5);
  double cpu = 0.0;
  Solution sln_coarse, sln_fine;
  for(int n = 1; n <= nstep; n++)
  {

    info("\n---- Time step %d -----------------------------------------------------------------", n);

    // time measurement
    begin_time();

    // perform periodic unrefinements
    if (n % UNREF_FREQ == 0) {
      mesh.copy(&basemesh);
      space.set_uniform_order(P_INIT);
      space.assign_dofs();
    }

    // adaptivity loop
    int at = 0, ndofs;
    bool done = false;
    double err_est, cpu;
    do
    {
     info("\n---- Time step %d, adaptivity step %d ---------------------------------------------\n", n, ++at);

      // Newton's loop for coarse mesh solution
      int it = 1;
      double res_l2_norm;
      if (n > 1 || at > 1) nls.set_ic(&sln_fine, &Titer);
      else nls.set_ic(&Titer, &Titer);
      do
      {
        info("\n---- Time step %d, adaptivity step %d, Newton step %d (Coarse mesh solution)-------\n", n, at, it++);

        nls.assemble();
        nls.solve(1, &sln_coarse);

        res_l2_norm = nls.get_residuum_l2_norm();
        info("Residuum L2 norm: %g", res_l2_norm);

        Titer.copy(&sln_coarse);
      }
      while (res_l2_norm > NEWTON_TOL_COARSE);

      // Newton's loop for fine mesh solution
      it = 1;
      RefNonlinSystem rs(&nls);
      rs.prepare();
      if (n > 1 || at > 1) rs.set_ic(&sln_fine, &Titer);
      else rs.set_ic(&Titer, &Titer);
      do
      {
        info("\n---- Time step %d, adaptivity step %d, Newton step %d (Fine mesh solution) --------\n", n, at, it++);

        rs.assemble();
        rs.solve(1, &sln_fine);

        res_l2_norm = rs.get_residuum_l2_norm();
        info("Residuum L2 norm: %g", res_l2_norm);

        Titer.copy(&sln_fine);
      }
      while (res_l2_norm > NEWTON_TOL_REF);

      // calculate error estimate wrt. fine mesh solution
      H1OrthoHP hp(1, &space);
      err_est = hp.calc_error(&sln_coarse, &sln_fine) * 100;
      info("Error estimate: %g%", err_est);

      // visualization of solution on the n-th time level
      sprintf(title, "Temperature, time level %d", n);
      //view.set_min_max_range(0,100);
      view.set_title(title);
      //view.show(&Titer);    // to see reference solution
      view.show(&sln_fine);        // to see the solution

      // visualization of mesh on the n-th time level
      sprintf(title, "hp-mesh, time level %d", n);
      ordview.set_title(title);
      ordview.show(&space);   // to see hp-mesh
      //view.wait_for_keypress();

      // if err_est too large, adapt the mesh
      if (err_est < SPACE_H1_TOL) done = true;
      else {
        hp.adapt(THRESHOLD, STRATEGY, ADAPT_TYPE, ISO_ONLY, MESH_REGULARITY);
        ndofs = space.assign_dofs();
        if (ndofs >= NDOF_STOP) done = true;
      }

      // time measurement
      cpu += end_time();
    }
    while (!done);

    // add entry to both time and DOF error graphs
    graph_err.add_values(0, n, err_est);
    graph_err.save("error.txt");
    graph_dofs.add_values(0, n, space.get_num_dofs());
    graph_dofs.save("dofs.txt");

    // copying result of the Newton's iteration into Tprev
    Tprev.copy(&Titer);
  }

  // time measurement
  cpu += end_time();
  verbose("Total running time: %g sec", cpu);

  // wait for keyboard or mouse input
  View::wait("Waiting for keyboard or mouse input.");
  return 0;
}
Beispiel #5
0
int main(int argc, char* argv[])
{
  Mesh mesh;
  mesh.load("square.mesh");
  for(int i = 0; i < REF_INIT; i++) mesh.refine_all_elements();

  H1Shapeset shapeset;
  PrecalcShapeset pss(&shapeset);

  H1Space space(&mesh, &shapeset);
  space.set_bc_types(bc_types);
  space.set_bc_values(bc_values);
  space.set_uniform_order(P_INIT);
  space.assign_dofs();

  WeakForm wf(1);
  if(TIME_DISCR == 1) {
    wf.add_biform(0, 0, bilinear_form_0_0_euler, UNSYM, ANY, 1, &Psi_iter);
    wf.add_liform(0, linear_form_0_euler, ANY, 2, &Psi_iter, &Psi_prev);
  }
  else {
    wf.add_biform(0, 0, bilinear_form_0_0_cranic, UNSYM, ANY, 1, &Psi_iter);
    wf.add_liform(0, linear_form_0_cranic, ANY, 2, &Psi_iter, &Psi_prev);
  }

  UmfpackSolver umfpack;
  NonlinSystem nls(&wf, &umfpack);
  nls.set_spaces(1, &space);
  nls.set_pss(1, &pss);

  char title[100];
  ScalarView view("", 0, 0, 700, 600);
  //view.set_min_max_range(-0.5,0.5);

  // setting initial condition at zero time level
  Psi_prev.set_exact(&mesh, fn_init);
  nls.set_ic(&Psi_prev, &Psi_prev, PROJ_TYPE);
  Psi_iter.copy(&Psi_prev);

  // view initial guess for Newton's method
  /*
  sprintf(title, "Initial guess for the Newton's method");
  view.set_title(title);
  view.show(&Psi_iter);
  view.wait_for_keypress();
  */

  Solution sln;
  // time stepping
  int nstep = (int)(T_FINAL/TAU + 0.5);
  for(int n = 1; n <= nstep; n++)
  {

    info("\n---- Time step %d -----------------------------------------------", n);

    // set initial condition for the Newton's iteration
    // actually needed only when space changes
    // otherwise initial solution vector is that one
    // from the previous time level
    //nls.set_ic(&Psi_iter, &Psi_iter);

    int it = 1;
    double res_l2_norm;
    do
    {
      info("\n---- Time step %d, Newton iter %d ---------------------------------\n", n, it++);

      nls.assemble();
      nls.solve(1, &sln);

      res_l2_norm = nls.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", n, it-1);
       view.set_title(title);
       view.show(&sln);
       view.wait_for_keypress();
      */

      Psi_iter = sln;

    }
    while (res_l2_norm > NEWTON_TOL);

    // visualization of solution on the n-th time level
    sprintf(title, "Time level %d", n);
    //view.set_min_max_range(90,100);
    view.set_title(title);
    view.show(&Psi_iter);
    //view.wait_for_keypress();

    // uncomment one of the following lines to generate a series of video frames
    //view.save_numbered_screenshot("sol%03d.bmp", n, 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



    // copying result of the Newton's iteration into Psi_prev
    Psi_prev.copy(&Psi_iter);
  }

  printf("Click into the image window and press 'q' to finish.\n");
  View::wait();
  return 0;
}
Beispiel #6
0
int main (int argc, char* argv[]) {
  // load the mesh file
  Mesh Cmesh, phimesh, basemesh;

  H2DReader mloader;

#ifdef CIRCULAR
  mloader.load("../circular.mesh", &basemesh);
  basemesh.refine_all_elements(0);
  basemesh.refine_towards_boundary(TOP_MARKER, 2);
  basemesh.refine_towards_boundary(BOT_MARKER, 4);
  MeshView mview("Mesh", 0, 600, 400, 400);
  mview.show(&basemesh);
#else
  mloader.load("../small.mesh", &basemesh);
  basemesh.refine_all_elements(1);
  //basemesh.refine_all_elements(1); // when only p-adapt is used
  //basemesh.refine_all_elements(1); // when only p-adapt is used
  basemesh.refine_towards_boundary(TOP_MARKER, REF_INIT);
  //basemesh.refine_towards_boundary(BOT_MARKER, (REF_INIT - 1) + 8); // when only p-adapt is used
  basemesh.refine_towards_boundary(BOT_MARKER, REF_INIT - 1);
#endif

  Cmesh.copy(&basemesh);
  phimesh.copy(&basemesh);

  // Spaces for concentration and the voltage
  H1Space Cspace(&Cmesh, C_bc_types, C_essential_bc_values, P_INIT);
  H1Space phispace(MULTIMESH ? &phimesh : &Cmesh, phi_bc_types, phi_essential_bc_values, P_INIT);

  // The weak form for 2 equations
  WeakForm wf(2);

  Solution C_prev_time,    // prveious time step solution, for the time integration
    C_prev_newton,   // solution convergin during the Newton's iteration
    phi_prev_time,
    phi_prev_newton;

  // Add the bilinear and linear forms
  // generally, the equation system is described:
  if (TIME_DISCR == 1) {  // Implicit Euler.
    wf.add_vector_form(0, callback(Fc_euler), H2D_ANY,
		  Tuple<MeshFunction*>(&C_prev_time, &C_prev_newton, &phi_prev_newton));
    wf.add_vector_form(1, callback(Fphi_euler), H2D_ANY, Tuple<MeshFunction*>(&C_prev_newton, &phi_prev_newton));
    wf.add_matrix_form(0, 0, callback(J_euler_DFcDYc), H2D_UNSYM, H2D_ANY, &phi_prev_newton);
    wf.add_matrix_form(0, 1, callback(J_euler_DFcDYphi), H2D_UNSYM, H2D_ANY, &C_prev_newton);
    wf.add_matrix_form(1, 0, callback(J_euler_DFphiDYc), H2D_UNSYM);
    wf.add_matrix_form(1, 1, callback(J_euler_DFphiDYphi), H2D_UNSYM);
  } else {
    wf.add_vector_form(0, callback(Fc_cranic), H2D_ANY, 
		  Tuple<MeshFunction*>(&C_prev_time, &C_prev_newton, &phi_prev_newton, &phi_prev_time));
    wf.add_vector_form(1, callback(Fphi_cranic), H2D_ANY, Tuple<MeshFunction*>(&C_prev_newton, &phi_prev_newton));
    wf.add_matrix_form(0, 0, callback(J_cranic_DFcDYc), H2D_UNSYM, H2D_ANY, Tuple<MeshFunction*>(&phi_prev_newton, &phi_prev_time));
    wf.add_matrix_form(0, 1, callback(J_cranic_DFcDYphi), H2D_UNSYM, H2D_ANY, Tuple<MeshFunction*>(&C_prev_newton, &C_prev_time));
    wf.add_matrix_form(1, 0, callback(J_cranic_DFphiDYc), H2D_UNSYM);
    wf.add_matrix_form(1, 1, callback(J_cranic_DFphiDYphi), H2D_UNSYM);
  }

  // Nonlinear solver
  NonlinSystem nls(&wf, Tuple<Space*>(&Cspace, &phispace));

  phi_prev_time.set_exact(MULTIMESH ? &phimesh : &Cmesh, voltage_ic);
  C_prev_time.set_exact(&Cmesh, concentration_ic);

  C_prev_newton.copy(&C_prev_time);
  phi_prev_newton.copy(&phi_prev_time);

  // Project the function init_cond() on the FE space
  // to obtain initial coefficient vector for the Newton's method.
  info("Projecting initial conditions to obtain initial vector for the Newton'w method.");
  nls.project_global(Tuple<MeshFunction*>(&C_prev_time, &phi_prev_time), 
      Tuple<Solution*>(&C_prev_newton, &phi_prev_newton));
  
  
  //VectorView vview("electric field [V/m]", 0, 0, 600, 600);
  ScalarView Cview("Concentration [mol/m3]", 0, 0, 800, 800);
  ScalarView phiview("Voltage [V]", 650, 0, 600, 600);
  phiview.show(&phi_prev_time);
  Cview.show(&C_prev_time);
  char title[100];

  int nstep = (int) (T_FINAL / TAU + 0.5);
  for (int n = 1; n <= nstep; n++) {
    verbose("\n---- Time step %d ----", n);
    bool verbose = true; // Default is false.
    if (!nls.solve_newton(Tuple<Solution*>(&C_prev_newton, &phi_prev_newton),
        NEWTON_TOL, NEWTON_MAX_ITER, verbose)) 
          error("Newton's method did not converge.");
    sprintf(title, "time step = %i", n);
    phiview.set_title(title);
    phiview.show(&phi_prev_newton);
    Cview.set_title(title);
    Cview.show(&C_prev_newton);
    phi_prev_time.copy(&phi_prev_newton);
    C_prev_time.copy(&C_prev_newton);
  }
  View::wait();

  return 0;
}
Beispiel #7
0
int main (int argc, char* argv[]) {

    bool adaptive = false;
    if (argc > 1) {
        std::string arg0(argv[1]);
        if (USE_ADAPTIVE.compare(arg0) == 0) {
            adaptive = true;
            info("Using adaptive solution");
        } else {
            error("Illegal argument %s", argv[1]);
            return -1;
        }
    } else {
        info("Using NON-adaptive solution");
    }

    // load the mesh file
    Mesh Cmesh, phimesh, basemesh;

    H2DReader mloader;
    mloader.load("small.mesh", &basemesh);
    basemesh.refine_towards_boundary(TOP_MARKER, REF_INIT);
    basemesh.refine_towards_boundary(BOT_MARKER, REF_INIT - 1);
    Cmesh.copy(&basemesh);
    phimesh.copy(&basemesh);

    // create the shapeset
    H1Shapeset shapeset;
    PrecalcShapeset Cpss(&shapeset);
    PrecalcShapeset phipss(&shapeset);

    // Spaces for concentration and the voltage
    H1Space C(&Cmesh, &shapeset);
    H1Space phi(MULTIMESH ? &phimesh : &Cmesh, &shapeset);

    // Initialize boundary conditions
    C.set_bc_types(C_bc_types);
    phi.set_bc_types(phi_bc_types);
    phi.set_bc_values(phi_bc_values);
    //C.set_bc_values(C_bc_values);

    // set polynomial degrees
    C.set_uniform_order(P_INIT);
    phi.set_uniform_order(P_INIT);


    // assign degrees of freedom
    int ndofs = 0;
    ndofs += C.assign_dofs(ndofs);
    ndofs += phi.assign_dofs(ndofs);
    info("ndofs: %d", ndofs);

    // The weak form for 2 equations
    WeakForm wf(2);

    Solution Cp,    // prveious time step solution, for the time integration
             Ci,   // solution convergin during the Newton's iteration
             phip,
             phii;

    // Add the bilinear and linear forms
    // generally, the equation system is described:
    // a11(u1, v1) + a12(u2, v1) + a1n(un, v1) = l1(v1)
    // a21(u1, v2) + a22(u2, v2) + a2n(un, v2) = l2(v2)
    // an1(u1, vn) + an2(u2, vn) + ann(un, vn) = ln(vn)
    wf.add_biform(0, 0, callback(J_euler_DFcDYc), UNSYM, ANY, 1, &phii);
    wf.add_biform(1, 1, callback(J_euler_DFphiDYphi), UNSYM);
    wf.add_biform(0, 1, callback(J_euler_DFcDYphi), UNSYM, ANY, 1, &Ci);
    wf.add_biform(1, 0, callback(J_euler_DFphiDYc), UNSYM);

    wf.add_liform(0, callback(Fc_euler), ANY, 3, &Cp, &Ci, &phii);
    wf.add_liform(1, callback(Fphi_euler), ANY, 2, &Ci, &phii);

    wf.add_liform_surf(1, callback(linear_form_surf_top), TOP_MARKER);

    // Nonlinear solver
    UmfpackSolver umfpack;
    NonlinSystem nls(&wf, &umfpack);
    nls.set_spaces(2, &C, &phi);
    if (MULTIMESH) {
        nls.set_pss(2, &Cpss, &phipss);
    } else {
        nls.set_pss(1, &Cpss);
    }

    info("UmfpackSolver initialized");


    //Cp.set_dirichlet_lift(&C, &Cpss);
    //phip.set_dirichlet_lift(&phi, MULTIMESH ? &phipss : &Cpss);
    Cp.set_const(&Cmesh, C_CONC);
    phip.set_const(MULTIMESH ? &phimesh : &Cmesh, 0);

    Ci.copy(&Cp);
    phii.copy(&phip);

    nls.set_ic(&Ci, &phii, &Ci, &phii);

    if (adaptive) {
        solveAdaptive(Cmesh, phimesh, basemesh, nls, C, phi, Cp, Ci, phip, phii);
    } else {
        solveNonadaptive(Cmesh, nls, Cp, Ci, phip, phii);
    }

    return 0;
}
Beispiel #8
0
int main(int argc, char* argv[])
{
  // load the mesh file
  Mesh mesh;
  H2DReader mloader;
  mloader.load("square.mesh", &mesh);

  // initial mesh refinements
  for(int i = 0; i < INIT_GLOB_REF_NUM; i++) mesh.refine_all_elements();
  mesh.refine_towards_boundary(1,INIT_BDY_REF_NUM);

  // initialize the shapeset and the cache
  H1Shapeset shapeset;
  PrecalcShapeset pss(&shapeset);

  // create an H1 space
  H1Space space(&mesh, &shapeset);
  space.set_bc_types(bc_types);
  space.set_bc_values(bc_values);
  space.set_uniform_order(P_INIT);
  space.assign_dofs();

  // previous solution for the Newton's iteration
  Solution u_prev;

  // initialize the weak formulation
  WeakForm wf(1);
  wf.add_biform(0, 0, callback(jac), UNSYM, ANY, 1, &u_prev);
  wf.add_liform(0, callback(res), ANY, 1, &u_prev);

  // initialize the nonlinear system and solver
  UmfpackSolver umfpack;
  NonlinSystem nls(&wf, &umfpack);
  nls.set_spaces(1, &space);
  nls.set_pss(1, &pss);

  // DOF and CPU convergence graphs
  SimpleGraph graph_dof, graph_cpu;

  // project the function init_cond() on the mesh 
  // to obtain initial guess u_prev for the Newton's method
  nls.set_ic(init_cond, &mesh, &u_prev, PROJ_TYPE);

  // visualise the initial ocndition
  ScalarView view("Initial condition", 0, 0, 700, 600);
  view.show(&u_prev);
  OrderView oview("Initial mesh", 720, 0, 700, 600);
  oview.show(&space);
  //printf("Click into the image window and press any key to proceed.\n");
  //view.wait_for_keypress();

  // adaptivity loop
  double cpu = 0.0, err_est;
  int a_step = 1;
  bool done = false;
  do {

    a_step++;

    // Newton's loop on the coarse mesh
    int it = 1;
    double res_l2_norm;
    Solution sln_coarse;
    do
    {
      info("\n---- Adapt step %d, Newton iter %d (coarse mesh) ---------------------------------\n", a_step, it++);
      printf("ndof = %d\n", space.get_num_dofs());

      // time measurement
      begin_time();

      // assemble the Jacobian matrix and residual vector, 
      // solve the system
      nls.assemble();
      nls.solve(1, &sln_coarse);

      // calculate the l2-norm of residual vector
      res_l2_norm = nls.get_residuum_l2_norm();
      info("Residuum L2 norm: %g\n", res_l2_norm);

      // time measurement
      cpu += end_time();

      // visualise the solution
      char title[100];
      sprintf(title, "Temperature (coarse mesh), Newton iteration %d", it-1);
      view.set_title(title);
      view.show(&sln_coarse);
      sprintf(title, "Coarse mesh, Newton iteration %d", it-1);
      oview.set_title(title);
      oview.show(&space);
      //printf("Click into the image window and press any key to proceed.\n");
      //view.wait_for_keypress();

      // save the new solution as "previous" for the 
      // next Newton's iteration
      u_prev.copy(&sln_coarse);
    }
    while (res_l2_norm > NEWTON_TOL);

    // Setting initial guess for the Newton's method on the fine mesh
    Solution sln_fine, u_prev_fine;
    RefNonlinSystem rs(&nls);
    rs.prepare();
    rs.set_ic(&u_prev, &u_prev);

    // Newton's loop on the fine mesh
    it = 1;
    do {
      info("\n---- Adapt step %d, Newton iter %d (fine mesh) ---------------------------------\n", a_step, it++);

      // time measurement
      begin_time();

      // assemble the Jacobian matrix and residual vector, 
      // solve the system
      rs.assemble();
      rs.solve(1, &sln_fine);

      // calculate the l2-norm of residual vector
      res_l2_norm = rs.get_residuum_l2_norm();
      info("Residuum L2 norm: %g\n", res_l2_norm);

      // time measurement
      cpu += end_time();

      // visualise the solution
      char title[100];
      sprintf(title, "Temperature (fine mesh), Newton iteration %d", it-1);
      view.set_title(title);
      view.show(&sln_fine);
      sprintf(title, "Fine mesh, Newton iteration %d", it-1);
      oview.set_title(title);
      oview.show(rs.get_ref_space(0));
      //printf("Click into the image window and press any key to proceed.\n");
      //view.wait_for_keypress();

      u_prev.copy(&sln_fine);
    } while (res_l2_norm > NEWTON_TOL_REF);

    // time measurement
    begin_time();

    // calculate element errors and total error estimate
    H1OrthoHP hp(1, &space);
    err_est = hp.calc_error(&sln_coarse, &sln_fine) * 100;
    info("Error estimate: %g%%", err_est);

    // add entry to DOF convergence graph
    graph_dof.add_values(space.get_num_dofs(), err_est);
    graph_dof.save("conv_dof.dat");

    // add entry to CPU convergence graph
    graph_cpu.add_values(cpu, err_est);
    graph_cpu.save("conv_cpu.dat");

    // if err_est too large, adapt the mesh
    if (err_est < ERR_STOP) done = true;
    else {
      hp.adapt(THRESHOLD, STRATEGY, ADAPT_TYPE, ISO_ONLY, MESH_REGULARITY);
      int ndof = space.assign_dofs();
      if (ndof >= NDOF_STOP) done = true;
    }

    // time measurement
    cpu += end_time();
  }
  while (!done);
  verbose("Total running time: %g sec", cpu);

  // wait for keyboard or mouse input
  View::wait();
  return 0;
}
Beispiel #9
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;
}