示例#1
0
int main(int argc, char* argv[])
{
  // Load the mesh.
  MeshSharedPtr mesh(new Mesh);
  MeshReaderH2D mloader;
  mloader.load("square.mesh", mesh);

  // Perform initial mesh refinements.
  for(int i = 0; i < INIT_GLOB_REF_NUM; i++)
    mesh->refine_all_elements();
  mesh->refine_towards_boundary("Bdy", INIT_BDY_REF_NUM);

  // Initialize boundary conditions.
  CustomEssentialBCNonConst bc_essential("Bdy");
  EssentialBCs<double> bcs(&bc_essential);

  // Create an H1 space with default shapeset.
  SpaceSharedPtr<double> space(new H1Space<double>(mesh, &bcs, P_INIT));
  int ndof = space->get_num_dofs();

  // Initialize previous iteration solution for the Picard's method.
  MeshFunctionSharedPtr<double> init_condition(new ConstantSolution<double>(mesh, INIT_COND_CONST));

  // Initialize the weak formulation.
  CustomNonlinearity lambda(alpha);
  Hermes2DFunction<double> src(-heat_src);
  CustomWeakFormPicard wf(init_condition, &lambda, &src);

  // Initialize the Picard solver.
  PicardSolver<double> picard(&wf, space);
  picard.set_max_allowed_iterations(PICARD_MAX_ITER);
  logger.info("Default tolerance");
  try
  {
    picard.solve(init_condition);
  }
  catch(std::exception& e)
  {
    std::cout << e.what();
  }

  int iter_1 = picard.get_num_iters();

  logger.info("Adjusted tolerance without Anderson");
  // Perform the Picard's iteration (Anderson acceleration on by default).
  picard.clear_tolerances();
  picard.set_tolerance(PICARD_TOL, Hermes::Solvers::SolutionChangeAbsolute);
  try
  {
    picard.solve(init_condition);
  }
  catch(std::exception& e)
  {
    std::cout << e.what();
  }
  int iter_2 = picard.get_num_iters();

  // Translate the coefficient vector into a Solution. 
  MeshFunctionSharedPtr<double> sln(new Solution<double>);
  Solution<double>::vector_to_solution(picard.get_sln_vector(), space, sln);
  logger.info("Default tolerance without Anderson and good initial guess");
  PicardSolver<double> picard2(&wf, space);
  picard2.set_tolerance(1e-3, Hermes::Solvers::SolutionChangeRelative);
  picard2.set_max_allowed_iterations(PICARD_MAX_ITER);
  try
  {
    picard2.solve(sln);
  }
  catch(std::exception& e)
  {
    std::cout << e.what();
  }
  int iter_3 = picard2.get_num_iters();

  logger.info("Default tolerance with Anderson and good initial guess");
  picard2.use_Anderson_acceleration(true);
  picard2.set_num_last_vector_used(PICARD_NUM_LAST_ITER_USED);
  picard2.set_anderson_beta(PICARD_ANDERSON_BETA);
  try
  {
    picard2.solve(sln);
  }
  catch(std::exception& e)
  {
    std::cout << e.what();
  }
  int iter_4 = picard2.get_num_iters();

#ifdef SHOW_OUTPUT
  // Visualise the solution and mesh.
  ScalarView s_view("Solution", new WinGeom(0, 0, 440, 350));
  s_view.show_mesh(false);
  s_view.show(sln);
  OrderView o_view("Mesh", new WinGeom(450, 0, 420, 350));
  o_view.show(space);

  // Wait for all views to be closed.
  View::wait();
#endif

  bool success = Testing::test_value(iter_1, 14, "# of iterations 1", 1); // Tested value as of September 2013.
  success = Testing::test_value(iter_2, 12, "# of iterations 2", 1) & success; // Tested value as of September 2013.
  success = Testing::test_value(iter_3, 3, "# of iterations 3", 1) & success; // Tested value as of September 2013.
  success = Testing::test_value(iter_4, 3, "# of iterations 4", 1) & success; // Tested value as of September 2013.

  if(success)
  {
    printf("Success!\n");
    return 0;
  }
  else
  {
    printf("Failure!\n");
    return -1;
  }
}
示例#2
0
int main(int argc, char* argv[])
{
  // Define nonlinear magnetic permeability via a cubic spline.
  Hermes::vector<double> mu_inv_pts(0.0,      0.5,      0.9,      1.0,      1.1,      1.2,      1.3,
                                    1.4,      1.6,      1.7,      1.8,      1.9,      3.0,      5.0,     10.0);
  Hermes::vector<double> mu_inv_val(1/1500.0, 1/1480.0, 1/1440.0, 1/1400.0, 1/1300.0, 1/1150.0, 1/950.0,
                                    1/750.0,  1/250.0,  1/180.0,  1/175.0,  1/150.0,  1/20.0,   1/10.0,  1/5.0);
  /*
  // This is for debugging (iron is assumed linear with mu_r = 300.0
  Hermes::vector<double> mu_inv_pts(0.0,      10.0);
  Hermes::vector<double> mu_inv_val(1/300.0,   1/300.0);
  */

  // Create the cubic spline (and plot it for visual control).
  double bc_left = 0.0;
  double bc_right = 0.0;
  bool first_der_left = false;
  bool first_der_right = false;
  bool extrapolate_der_left = false;
  bool extrapolate_der_right = false;
  CubicSpline mu_inv_iron(mu_inv_pts, mu_inv_val, bc_left, bc_right, first_der_left, first_der_right,
                          extrapolate_der_left, extrapolate_der_right);
  info("Saving cubic spline into a Pylab file spline.dat.");
  // The interval of definition of the spline will be
  // extended by "interval_extension" on both sides.
  double interval_extension = 1.0; 
  bool plot_derivative = false;
  mu_inv_iron.plot("spline.dat", interval_extension, plot_derivative);
  plot_derivative = true;
  mu_inv_iron.plot("spline_der.dat", interval_extension, plot_derivative);

  // Load the mesh.
  Mesh mesh;
  MeshReaderH2D mloader;
  mloader.load("actuator.mesh", &mesh);

  // Perform initial mesh refinements.
  for(int i = 0; i < INIT_REF_NUM; i++) mesh.refine_all_elements();

  //MeshView mv("Mesh", new WinGeom(0, 0, 400, 400));
  //mv.show(&mesh);

  // Initialize boundary conditions.
  DefaultEssentialBCConst<double> bc_essential(BDY_DIRICHLET, 0.0);
  EssentialBCs<double> bcs(&bc_essential);

  // Create an H1 space with default shapeset.
  H1Space<double> space(&mesh, &bcs, P_INIT);
  info("ndof: %d", Space<double>::get_num_dofs(&space));

  // Initialize the weak formulation
  // This determines the increase of integration order
  // for the axisymmetric term containing 1/r. Default is 3.
  int order_inc = 3; 
  CustomWeakFormMagnetostatics wf(MAT_IRON_1, MAT_IRON_2, &mu_inv_iron, MAT_AIR,
                                  MAT_COPPER, MU_VACUUM, CURRENT_DENSITY, order_inc);

  // Initialize the FE problem.
  DiscreteProblem<double> dp(&wf, &space);
  
  // Initialize the solution.
  ConstantSolution<double> sln(&mesh, INIT_COND);

  // Project the initial condition on the FE space to obtain initial
  // coefficient vector for the Newton's method.
  info("Projecting to obtain initial vector for the Newton's method.");
  double* coeff_vec = new double[Space<double>::get_num_dofs(&space)] ;
  OGProjection<double>::project_global(&space, &sln, coeff_vec, matrix_solver_type);

  // Perform Newton's iteration.
  Hermes::Hermes2D::NewtonSolver<double> newton(&dp, matrix_solver_type);
  bool verbose = true;
  newton.set_verbose_output(verbose);
  try
  {
    newton.solve(coeff_vec, NEWTON_TOL, NEWTON_MAX_ITER);
  }
  catch(Hermes::Exceptions::Exception e)
  {
    e.printMsg();
    error("Newton's iteration failed.");
  };

  // Translate the resulting coefficient vector into the Solution sln.
  Solution<double>::vector_to_solution(coeff_vec, &space, &sln);

  // Cleanup.
  delete [] coeff_vec;

  // Visualise the solution and mesh.
  ScalarView s_view1("Vector potencial", new WinGeom(0, 0, 350, 450));
  FilterVectorPotencial vector_potencial(Hermes::vector<MeshFunction<double> *>(&sln, &sln),
                                         Hermes::vector<int>(H2D_FN_VAL, H2D_FN_VAL));
  s_view1.show_mesh(false);
  s_view1.show(&vector_potencial);

  ScalarView s_view2("Flux density", new WinGeom(360, 0, 350, 450));
  FilterFluxDensity flux_density(Hermes::vector<MeshFunction<double> *>(&sln, &sln));
  s_view2.show_mesh(false);
  s_view2.show(&flux_density);

  OrderView o_view("Mesh", new WinGeom(720, 0, 350, 450));
  o_view.show(&space);

  // Wait for all views to be closed.
  View::wait();
  return 0;
}
int main(int argc, char* argv[])
{
  // Define nonlinear thermal conductivity lambda(u) via a cubic spline.
  // Step 1: Fill the x values and use lambda_macro(u) = 1 + u^4 for the y values.
#define lambda_macro(x) (1 + Hermes::pow(x, 4))
  Hermes::vector<double> lambda_pts(-2.0, -1.5, -1.0, -0.5, 0.0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 4.0, 5.0);
  Hermes::vector<double> lambda_val;
  for (unsigned int i = 0; i < lambda_pts.size(); i++) 
    lambda_val.push_back(lambda_macro(lambda_pts[i]));
  // Step 2: Create the cubic spline (and plot it for visual control). 
  double bc_left = 0.0;
  double bc_right = 0.0;
  bool first_der_left = false;
  bool first_der_right = false;
  bool extrapolate_der_left = true;
  bool extrapolate_der_right = true;
  CubicSpline lambda(lambda_pts, lambda_val, bc_left, bc_right, first_der_left, first_der_right,
                     extrapolate_der_left, extrapolate_der_right);
  info("Saving cubic spline into a Pylab file spline.dat.");
  double interval_extension = 3.0; // The interval of definition of the spline will be 
                                   // extended by "interval_extension" on both sides.
  lambda.plot("spline.dat", interval_extension);

  // Load the mesh.
  Mesh mesh;
  MeshReaderH2D mloader;
  mloader.load("square.mesh", &mesh);

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

  // Initialize boundary conditions.
  CustomEssentialBCNonConst bc_essential("Bdy");
  EssentialBCs<double> bcs(&bc_essential);

  // Create an H1 space with default shapeset.
  H1Space<double> space(&mesh, &bcs, P_INIT);
  int ndof = space.get_num_dofs();
  info("ndof: %d", ndof);

  // Initialize the weak formulation.
  Hermes2DFunction<double> src(-heat_src);
  DefaultWeakFormPoisson<double> wf(HERMES_ANY, &lambda, &src);

  // Initialize the FE problem.
  DiscreteProblem<double> dp(&wf, &space);

  // Project the initial condition on the FE space to obtain initial 
  // coefficient vector for the Newton's method.
  // NOTE: If you want to start from the zero vector, just define 
  // coeff_vec to be a vector of ndof zeros (no projection is needed).
  info("Projecting to obtain initial vector for the Newton's method.");
  double* coeff_vec = new double[ndof];
  CustomInitialCondition init_sln(&mesh);
  OGProjection<double>::project_global(&space, &init_sln, coeff_vec, matrix_solver); 

  // Initialize Newton solver.
  NewtonSolver<double> newton(&dp, matrix_solver);

  // Perform Newton's iteration.
  bool freeze_jacobian = false;
  if (!newton.solve(coeff_vec, NEWTON_TOL, NEWTON_MAX_ITER, freeze_jacobian)) 
    error("Newton's iteration failed.");

  // Translate the resulting coefficient vector into a Solution.
  Solution<double> sln;
  Solution<double>::vector_to_solution(newton.get_sln_vector(), &space, &sln);

  // Get info about time spent during assembling in its respective parts.
  //dp.get_all_profiling_output(std::cout);

  // Clean up.
  delete [] coeff_vec;

  // Visualise the solution and mesh.
  ScalarView s_view("Solution", new WinGeom(0, 0, 440, 350));
  s_view.show_mesh(false);
  s_view.show(&sln);
  OrderView<double> o_view("Mesh", new WinGeom(450, 0, 400, 350));
  o_view.show(&space);

  // Wait for all views to be closed.
  View::wait();
  return 0;
}