示例#1
0
文件: distort.C 项目: dschwen/libmesh
  // Code to save node positions, perturb the mesh, and ensure the correct nodes moved.
  void perturb_and_check(ReplicatedMesh & mesh)
  {
    // Record node positions ahead of time to make sure the correct
    // ones are moved by distort.
    std::unordered_map<dof_id_type, Point> pts_before;
    for (const auto & node : mesh.node_ptr_range())
      pts_before[node->id()] = *node;

    std::unordered_set<dof_id_type> boundary_node_ids =
      MeshTools::find_boundary_nodes (mesh);

    MeshTools::Modification::distort(mesh,
                                     /*factor=*/0.1,
                                     /*perturb_boundary=*/false);

    // Make sure the boundary nodes are not perturbed, and the
    // other nodes are.
    for (const auto & node : mesh.node_ptr_range())
      {
        bool equal = node->absolute_fuzzy_equals(pts_before[node->id()]);
        CPPUNIT_ASSERT(boundary_node_ids.count(node->id()) ? equal : !equal);
      }
  }
示例#2
0
// Begin the main program.
int main (int argc, char ** argv)
{
  // Initialize libMesh.
  LibMeshInit init (argc, argv);

  // This example requires a linear solver package.
  libmesh_example_requires(libMesh::default_solver_package() != INVALID_SOLVER_PACKAGE,
                           "--enable-petsc, --enable-trilinos, or --enable-eigen");

  // Skip this 3D example if libMesh was compiled as 1D/2D-only.
  libmesh_example_requires (3 == LIBMESH_DIM, "3D support");

  // Skip this example without --enable-node-valence
#ifndef LIBMESH_ENABLE_NODE_VALENCE
  libmesh_example_requires (false, "--enable-node-valence");
#endif

  // Skip this example without --enable-amr; requires MeshRefinement
#ifndef LIBMESH_ENABLE_AMR
  libmesh_example_requires(false, "--enable-amr");
#else

  // Skip this example without --enable-second; requires d2phi
#ifndef LIBMESH_ENABLE_SECOND_DERIVATIVES
  libmesh_example_requires(false, "--enable-second");
#else

  // Create a 2D mesh distributed across the default MPI communicator.
  // Subdivision surfaces do not appear to work with DistributedMesh yet.
  ReplicatedMesh mesh (init.comm(), 2);

  // Read the coarse square mesh.
  mesh.read ("square_mesh.off");

  // Resize the square plate to edge length L.
  const Real L = 100.;
  MeshTools::Modification::scale(mesh, L, L, L);

  // Quadrisect the mesh triangles a few times to obtain a
  // finer mesh.  Subdivision surface elements require the
  // refinement data to be removed afterward.
  MeshRefinement mesh_refinement (mesh);
  mesh_refinement.uniformly_refine (3);
  MeshTools::Modification::flatten (mesh);

  // Write the mesh before the ghost elements are added.
#if defined(LIBMESH_HAVE_VTK)
  VTKIO(mesh).write ("without_ghosts.pvtu");
#endif
#if defined(LIBMESH_HAVE_EXODUS_API)
  ExodusII_IO(mesh).write ("without_ghosts.e");
#endif

  // Print information about the triangulated mesh to the screen.
  mesh.print_info();

  // Turn the triangulated mesh into a subdivision mesh
  // and add an additional row of "ghost" elements around
  // it in order to complete the extended local support of
  // the triangles at the boundaries.  If the second
  // argument is set to true, the outermost existing
  // elements are converted into ghost elements, and the
  // actual physical mesh is thus getting smaller.
  MeshTools::Subdivision::prepare_subdivision_mesh (mesh, false);

  // Print information about the subdivision mesh to the screen.
  mesh.print_info();

  // Write the mesh with the ghost elements added.
  // Compare this to the original mesh to see the difference.
#if defined(LIBMESH_HAVE_VTK)
  VTKIO(mesh).write ("with_ghosts.pvtu");
#endif
#if defined(LIBMESH_HAVE_EXODUS_API)
  ExodusII_IO(mesh).write ("with_ghosts.e");
#endif

  // Create an equation systems object.
  EquationSystems equation_systems (mesh);

  // Declare the system and its variables.
  // Create a linear implicit system named "Shell".
  LinearImplicitSystem & system = equation_systems.add_system<LinearImplicitSystem> ("Shell");

  // Add the three translational deformation variables
  // "u", "v", "w" to "Shell".  Since subdivision shell
  // elements meet the C1-continuity requirement, no
  // rotational or other auxiliary variables are needed.
  // Loop Subdivision Elements are always interpolated
  // by quartic box splines, hence the order must always
  // be FOURTH.
  system.add_variable ("u", FOURTH, SUBDIVISION);
  system.add_variable ("v", FOURTH, SUBDIVISION);
  system.add_variable ("w", FOURTH, SUBDIVISION);

  // Give the system a pointer to the matrix and rhs assembly
  // function.
  system.attach_assemble_function (assemble_shell);

  // Use the parameters of the equation systems object to
  // tell the shell system about the material properties, the
  // shell thickness, and the external load.
  const Real h  = 1.;
  const Real E  = 1.e7;
  const Real nu = 0.;
  const Real q  = 1.;
  equation_systems.parameters.set<Real> ("thickness")       = h;
  equation_systems.parameters.set<Real> ("young's modulus") = E;
  equation_systems.parameters.set<Real> ("poisson ratio")   = nu;
  equation_systems.parameters.set<Real> ("uniform load")    = q;

  // Initialize the data structures for the equation system.
  equation_systems.init();

  // Print information about the system to the screen.
  equation_systems.print_info();

  // Solve the linear system.
  system.solve();

  // After solving the system, write the solution to a VTK
  // or ExodusII output file ready for import in, e.g.,
  // Paraview.
#if defined(LIBMESH_HAVE_VTK)
  VTKIO(mesh).write_equation_systems ("out.pvtu", equation_systems);
#endif
#if defined(LIBMESH_HAVE_EXODUS_API)
  ExodusII_IO(mesh).write_equation_systems ("out.e", equation_systems);
#endif

  // Find the center node to measure the maximum deformation of the plate.
  Node * center_node = 0;
  Real nearest_dist_sq = mesh.point(0).norm_sq();
  for (unsigned int nid=1; nid<mesh.n_nodes(); ++nid)
    {
      const Real dist_sq = mesh.point(nid).norm_sq();
      if (dist_sq < nearest_dist_sq)
        {
          nearest_dist_sq = dist_sq;
          center_node = mesh.node_ptr(nid);
        }
    }

  // Finally, we evaluate the z-displacement "w" at the center node.
  const unsigned int w_var = system.variable_number ("w");
  dof_id_type w_dof = center_node->dof_number (system.number(), w_var, 0);
  Number w = 0;
  if (w_dof >= system.get_dof_map().first_dof() &&
      w_dof <  system.get_dof_map().end_dof())
    w = system.current_solution(w_dof);
  system.comm().sum(w);


  // The analytic solution for the maximum displacement of
  // a clamped square plate in pure bending, from Taylor,
  // Govindjee, Commun. Numer. Meth. Eng. 20, 757-765, 2004.
  const Real D = E * h*h*h / (12*(1-nu*nu));
  const Real w_analytic = 0.001265319 * L*L*L*L * q / D;

  // Print the finite element solution and the analytic
  // prediction of the maximum displacement of the clamped
  // square plate to the screen.
  libMesh::out << "z-displacement of the center point: " << w << std::endl;
  libMesh::out << "Analytic solution for pure bending: " << w_analytic << std::endl;

#endif // #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES

#endif // #ifdef LIBMESH_ENABLE_AMR

  // All done.
  return 0;
}
示例#3
0
int main (int argc, char ** argv)
{
  START_LOG("Initialize and create cubes", "main");
  LibMeshInit init (argc, argv);

  // This example requires a linear solver package.
  libmesh_example_requires(libMesh::default_solver_package() != INVALID_SOLVER_PACKAGE,
                           "--enable-petsc, --enable-trilinos, or --enable-eigen");

  // Create a GetPot object to parse the command line
  GetPot command_line (argc, argv);

  // Check for proper calling arguments.
  if (argc < 3)
    libmesh_error_msg("Usage:\n" << "\t " << argv[0] << " -n 15");

  // Brief message to the user regarding the program name
  // and command line arguments.
  else
    {
      libMesh::out << "Running " << argv[0];

      for (int i=1; i<argc; i++)
        libMesh::out << " " << argv[i];

      libMesh::out << std::endl << std::endl;
    }

  // This is 3D-only problem
  const unsigned int dim = 3;

  // Skip higher-dimensional examples on a lower-dimensional libMesh build
  libmesh_example_requires(dim <= LIBMESH_DIM, "3D support");

  // Read number of elements used in each cube from command line
  int ps = 10;
  if (command_line.search(1, "-n"))
    ps = command_line.next(ps);

  // Generate eight meshes that will be stitched
  ReplicatedMesh mesh (init.comm());
  ReplicatedMesh mesh1(init.comm());
  ReplicatedMesh mesh2(init.comm());
  ReplicatedMesh mesh3(init.comm());
  ReplicatedMesh mesh4(init.comm());
  ReplicatedMesh mesh5(init.comm());
  ReplicatedMesh mesh6(init.comm());
  ReplicatedMesh mesh7(init.comm());
  MeshTools::Generation::build_cube (mesh, ps, ps, ps, -1,    0,    0,  1,  0, 1, HEX8);
  MeshTools::Generation::build_cube (mesh1, ps, ps, ps,    0,  1,    0,  1,  0, 1, HEX8);
  MeshTools::Generation::build_cube (mesh2, ps, ps, ps, -1,    0, -1,    0,  0, 1, HEX8);
  MeshTools::Generation::build_cube (mesh3, ps, ps, ps,    0,  1, -1,    0,  0, 1, HEX8);
  MeshTools::Generation::build_cube (mesh4, ps, ps, ps, -1,    0,    0,  1, -1, 0, HEX8);
  MeshTools::Generation::build_cube (mesh5, ps, ps, ps,    0,  1,    0,  1, -1, 0, HEX8);
  MeshTools::Generation::build_cube (mesh6, ps, ps, ps, -1,    0, -1,    0, -1, 0, HEX8);
  MeshTools::Generation::build_cube (mesh7, ps, ps, ps,    0,  1, -1,    0, -1, 0, HEX8);

  // Generate a single unstitched reference mesh
  ReplicatedMesh nostitch_mesh(init.comm());
  MeshTools::Generation::build_cube (nostitch_mesh, ps*2, ps*2, ps*2, -1, 1, -1, 1, -1, 1, HEX8);
  STOP_LOG("Initialize and create cubes", "main");

  START_LOG("Stitching", "main");
  // We stitch the meshes in a hierarchical way.
  mesh.stitch_meshes(mesh1, 2, 4, TOLERANCE, true, true, false, false);
  mesh2.stitch_meshes(mesh3, 2, 4, TOLERANCE, true, true, false, false);
  mesh.stitch_meshes(mesh2, 1, 3, TOLERANCE, true, true, false, false);
  mesh4.stitch_meshes(mesh5, 2, 4, TOLERANCE, true, true, false, false);
  mesh6.stitch_meshes(mesh7, 2, 4, TOLERANCE, true, true, false, false);
  mesh4.stitch_meshes(mesh6, 1, 3, TOLERANCE, true, true, false, false);
  mesh.stitch_meshes(mesh4, 0, 5, TOLERANCE, true, true, false, false);
  STOP_LOG("Stitching", "main");

  START_LOG("Initialize and solve systems", "main");
  EquationSystems equation_systems_stitch (mesh);
  assemble_and_solve(mesh, equation_systems_stitch);

  EquationSystems equation_systems_nostitch (nostitch_mesh);
  assemble_and_solve(nostitch_mesh, equation_systems_nostitch);
  STOP_LOG("Initialize and solve systems", "main");

  START_LOG("Result comparison", "main");
  ExactSolution comparison(equation_systems_stitch);
  comparison.attach_reference_solution(&equation_systems_nostitch);
  comparison.compute_error("Poisson", "u");
  Real error = comparison.l2_error("Poisson", "u");
  libmesh_assert_less(error, TOLERANCE*sqrt(TOLERANCE));
  libMesh::out << "L2 error between stitched and non-stitched cases: " << error << std::endl;
  STOP_LOG("Result comparison", "main");

  START_LOG("Output", "main");
#ifdef LIBMESH_HAVE_EXODUS_API
  ExodusII_IO(mesh).write_equation_systems("solution_stitch.exo",
                                           equation_systems_stitch);
  ExodusII_IO(nostitch_mesh).write_equation_systems("solution_nostitch.exo",
                                                    equation_systems_nostitch);
#endif // #ifdef LIBMESH_HAVE_EXODUS_API
  STOP_LOG("Output", "main");

  return 0;
}
示例#4
0
int main (int argc, char ** argv)
{
  // Initialize libMesh.
  LibMeshInit init (argc, argv);

  // This example requires a linear solver package.
  libmesh_example_requires(libMesh::default_solver_package() != INVALID_SOLVER_PACKAGE,
                           "--enable-petsc, --enable-trilinos, or --enable-eigen");

#if !defined(LIBMESH_HAVE_XDR)
  // We need XDR support to write out reduced bases
  libmesh_example_requires(false, "--enable-xdr");
#elif defined(LIBMESH_DEFAULT_SINGLE_PRECISION)
  // XDR binary support requires double precision
  libmesh_example_requires(false, "double precision");
#elif defined(LIBMESH_DEFAULT_TRIPLE_PRECISION)
  // I have no idea why long double isn't working here... [RHS]
  libmesh_example_requires(false, "double precision");
#endif

  // Skip this 2D example if libMesh was compiled as 1D-only.
  libmesh_example_requires(2 <= LIBMESH_DIM, "2D support");

  // Define the names of the input files we will read the problem properties from
  std::string eim_parameters = "eim.in";
  std::string rb_parameters  = "rb.in";
  std::string main_parameters = "reduced_basis_ex4.in";
  GetPot infile(main_parameters);

  unsigned int n_elem = infile("n_elem", 1);       // Determines the number of elements in the "truth" mesh
  const unsigned int dim = 2;                      // The number of spatial dimensions
  bool store_basis_functions = infile("store_basis_functions", false); // Do we write out basis functions?

  // Read the "online_mode" flag from the command line
  GetPot command_line (argc, argv);
  int online_mode = 0;
  if (command_line.search(1, "-online_mode"))
    online_mode = command_line.next(online_mode);

  // Create a mesh (just a simple square) on the default MPI
  // communicator.  We currently have to create a ReplicatedMesh here
  // due to a reduced_basis regression with DistributedMesh
  ReplicatedMesh mesh (init.comm(), dim);
  MeshTools::Generation::build_square (mesh,
                                       n_elem, n_elem,
                                       -1., 1.,
                                       -1., 1.,
                                       QUAD4);

  // Initialize the EquationSystems object for this mesh and attach
  // the EIM and RB Construction objects
  EquationSystems equation_systems (mesh);

  SimpleEIMConstruction & eim_construction =
    equation_systems.add_system<SimpleEIMConstruction> ("EIM");
  SimpleRBConstruction & rb_construction =
    equation_systems.add_system<SimpleRBConstruction> ("RB");

  // Initialize the data structures for the equation system.
  equation_systems.init ();

  // Print out some information about the "truth" discretization
  mesh.print_info();
  equation_systems.print_info();

  // Initialize the standard RBEvaluation object
  SimpleRBEvaluation rb_eval(mesh.comm());

  // Initialize the EIM RBEvaluation object
  SimpleEIMEvaluation eim_rb_eval(mesh.comm());

  // Set the rb_eval objects for the RBConstructions
  eim_construction.set_rb_evaluation(eim_rb_eval);
  rb_construction.set_rb_evaluation(rb_eval);

  if (!online_mode)
    {
      // Read data from input file and print state
      eim_construction.process_parameters_file(eim_parameters);
      eim_construction.print_info();

      // Perform the EIM Greedy and write out the data
      eim_construction.initialize_rb_construction();
      eim_construction.train_reduced_basis();

#if defined(LIBMESH_HAVE_CAPNPROTO)
      RBDataSerialization::RBEIMEvaluationSerialization rb_eim_eval_writer(eim_rb_eval);
      rb_eim_eval_writer.write_to_file("rb_eim_eval.bin");
#else
      eim_construction.get_rb_evaluation().legacy_write_offline_data_to_files("eim_data");
#endif

      // Read data from input file and print state
      rb_construction.process_parameters_file(rb_parameters);

      // attach the EIM theta objects to the RBConstruction and RBEvaluation objects
      eim_rb_eval.initialize_eim_theta_objects();
      rb_eval.get_rb_theta_expansion().attach_multiple_F_theta(eim_rb_eval.get_eim_theta_objects());

      // attach the EIM assembly objects to the RBConstruction object
      eim_construction.initialize_eim_assembly_objects();
      rb_construction.get_rb_assembly_expansion().attach_multiple_F_assembly(eim_construction.get_eim_assembly_objects());

      // Print out the state of rb_construction now that the EIM objects have been attached
      rb_construction.print_info();

      // Need to initialize _after_ EIM greedy so that
      // the system knows how many affine terms there are
      rb_construction.initialize_rb_construction();
      rb_construction.train_reduced_basis();

#if defined(LIBMESH_HAVE_CAPNPROTO)
      RBDataSerialization::RBEvaluationSerialization rb_eval_writer(rb_construction.get_rb_evaluation());
      rb_eval_writer.write_to_file("rb_eval.bin");
#else
      rb_construction.get_rb_evaluation().legacy_write_offline_data_to_files("rb_data");
#endif

      // Write out the basis functions, if requested
      if (store_basis_functions)
        {
          // Write out the basis functions
          eim_construction.get_rb_evaluation().write_out_basis_functions(eim_construction.get_explicit_system(),
                                                                         "eim_data");

          rb_construction.get_rb_evaluation().write_out_basis_functions(rb_construction,
                                                                        "rb_data");
        }
    }
  else
    {
#if defined(LIBMESH_HAVE_CAPNPROTO)
      RBDataDeserialization::RBEIMEvaluationDeserialization rb_eim_eval_reader(eim_rb_eval);
      rb_eim_eval_reader.read_from_file("rb_eim_eval.bin");
#else
      eim_rb_eval.legacy_read_offline_data_from_files("eim_data");
#endif

      // attach the EIM theta objects to rb_eval objects
      eim_rb_eval.initialize_eim_theta_objects();
      rb_eval.get_rb_theta_expansion().attach_multiple_F_theta(eim_rb_eval.get_eim_theta_objects());

      // Read in the offline data for rb_eval
#if defined(LIBMESH_HAVE_CAPNPROTO)
      RBDataDeserialization::RBEvaluationDeserialization rb_eval_reader(rb_eval);
      rb_eval_reader.read_from_file("rb_eval.bin", /*read_error_bound_data*/ true);
#else
      rb_eval.legacy_read_offline_data_from_files("rb_data");
#endif

      // Get the parameters at which we will do a reduced basis solve
      Real online_center_x = infile("online_center_x", 0.);
      Real online_center_y = infile("online_center_y", 0.);
      RBParameters online_mu;
      online_mu.set_value("center_x", online_center_x);
      online_mu.set_value("center_y", online_center_y);
      rb_eval.set_parameters(online_mu);
      rb_eval.print_parameters();
      rb_eval.rb_solve(rb_eval.get_n_basis_functions());

      // plot the solution, if requested
      if (store_basis_functions)
        {
          // read in the data from files
          eim_rb_eval.read_in_basis_functions(eim_construction.get_explicit_system(), "eim_data");
          rb_eval.read_in_basis_functions(rb_construction, "rb_data");

          eim_construction.load_rb_solution();
          rb_construction.load_rb_solution();
#ifdef LIBMESH_HAVE_EXODUS_API
          ExodusII_IO(mesh).write_equation_systems("RB_sol.e", equation_systems);
#endif
        }
    }
}