Esempio n. 1
0
int main (int argc, char** argv){

	LibMeshInit init (argc, argv); //initialize libmesh library

	std::cout << "Running " << argv[0];
	for (int i=1; i<argc; i++)
		std::cout << " " << argv[i];
	std::cout << std::endl << std::endl;

	Mesh mesh(init.comm());
	
	mesh.read("channel_long.exo");
	
	std::string stash_assign = "divvy.txt";
	std::ofstream output(stash_assign.c_str());

	MeshBase::element_iterator       elem_it  = mesh.elements_begin();
  const MeshBase::element_iterator elem_end = mesh.elements_end();
  for (; elem_it != elem_end; ++elem_it){
    Elem* elem = *elem_it;
    		
    if(output.is_open()){
    	output << elem->id() << " " << elem->subdomain_id() << "\n";
    }
  }
  output.close();
	
	return 0;
}
Esempio n. 2
0
UniquePtr<Elem> Pyramid5::build_side_ptr (const unsigned int i,
                                          bool proxy)
{
  libmesh_assert_less (i, this->n_sides());

  if (proxy)
    {
      switch (i)
        {
        case 0:
        case 1:
        case 2:
        case 3:
          return UniquePtr<Elem>(new Side<Tri3,Pyramid5>(this,i));

        case 4:
          return UniquePtr<Elem>(new Side<Quad4,Pyramid5>(this,i));

        default:
          libmesh_error_msg("Invalid side i = " << i);
        }
    }

  else
    {
      // Create NULL pointer to be initialized, returned later.
      Elem * face = libmesh_nullptr;

      switch (i)
        {
        case 0: // triangular face 1
        case 1: // triangular face 2
        case 2: // triangular face 3
        case 3: // triangular face 4
          {
            face = new Tri3;
            break;
          }
        case 4: // the quad face at z=0
          {
            face = new Quad4;
            break;
          }
        default:
          libmesh_error_msg("Invalid side i = " << i);
        }

      face->subdomain_id() = this->subdomain_id();

      // Set the nodes
      for (unsigned n=0; n<face->n_nodes(); ++n)
        face->set_node(n) = this->node_ptr(Pyramid5::side_nodes_map[i][n]);

      return UniquePtr<Elem>(face);
    }

  libmesh_error_msg("We'll never get here!");
  return UniquePtr<Elem>();
}
  void build_mesh()
  {
    _mesh = new SerialMesh(*TestCommWorld);

    /*
      (0,1)           (1,1)
        x---------------x
        |               |
        |               |
        |               |
        |               |
        |               |
        x---------------x
       (0,0)           (1,0)
        |               |
        |               |
        |               |
        |               |
        x---------------x
       (0,-1)          (1,-1)
     */

    _mesh->set_mesh_dimension(2);

    _mesh->add_point( Point(0.0,-1.0), 4 );
    _mesh->add_point( Point(1.0,-1.0), 5 );
    _mesh->add_point( Point(1.0, 0.0), 1 );
    _mesh->add_point( Point(1.0, 1.0), 2 );
    _mesh->add_point( Point(0.0, 1.0), 3 );
    _mesh->add_point( Point(0.0, 0.0), 0 );

    {
      Elem* elem_top = _mesh->add_elem( new Quad4 );
      elem_top->set_node(0) = _mesh->node_ptr(0);
      elem_top->set_node(1) = _mesh->node_ptr(1);
      elem_top->set_node(2) = _mesh->node_ptr(2);
      elem_top->set_node(3) = _mesh->node_ptr(3);

      Elem* elem_bottom = _mesh->add_elem( new Quad4 );
      elem_bottom->set_node(0) = _mesh->node_ptr(4);
      elem_bottom->set_node(1) = _mesh->node_ptr(5);
      elem_bottom->set_node(2) = _mesh->node_ptr(1);
      elem_bottom->set_node(3) = _mesh->node_ptr(0);

      Elem* edge = _mesh->add_elem( new Edge2 );
      edge->set_node(0) = _mesh->node_ptr(0);
      edge->set_node(1) = _mesh->node_ptr(1);

      // 2D elements will have subdomain id 0, this one will have 1
      edge->subdomain_id() = 1;
    }

    // libMesh will renumber, but we numbered according to its scheme
    // anyway. We do this because when we call uniformly_refine subsequenly,
    // it's going use skip_renumber=false.
    _mesh->prepare_for_use(false /*skip_renumber*/);
  }
Esempio n. 4
0
UniquePtr<Elem> Quad9::build_side (const unsigned int i,
                                   bool proxy) const
{
  libmesh_assert_less (i, this->n_sides());

  if (proxy)
    return UniquePtr<Elem>(new Side<Edge3,Quad9>(this,i));

  else
    {
      Elem* edge = new Edge3;
      edge->subdomain_id() = this->subdomain_id();

      switch (i)
        {
        case 0:
          {
            edge->set_node(0) = this->get_node(0);
            edge->set_node(1) = this->get_node(1);
            edge->set_node(2) = this->get_node(4);
            break;
          }
        case 1:
          {
            edge->set_node(0) = this->get_node(1);
            edge->set_node(1) = this->get_node(2);
            edge->set_node(2) = this->get_node(5);
            break;
          }
        case 2:
          {
            edge->set_node(0) = this->get_node(2);
            edge->set_node(1) = this->get_node(3);
            edge->set_node(2) = this->get_node(6);
            break;
          }
        case 3:
          {
            edge->set_node(0) = this->get_node(3);
            edge->set_node(1) = this->get_node(0);
            edge->set_node(2) = this->get_node(7);
            break;
          }
        default:
          libmesh_error_msg("Invalid side i = " << i);
        }

      return UniquePtr<Elem>(edge);
    }

  libmesh_error_msg("We'll never get here!");
  return UniquePtr<Elem>();
}
Esempio n. 5
0
bool
CombinedCreepPlasticity::modifyStrainIncrement(const Elem & current_elem, unsigned qp, SymmTensor & strain_increment, SymmTensor & d_strain_dT)
{
    bool modified = false;
    const SubdomainID current_block = current_elem.subdomain_id();
    const std::vector<ReturnMappingModel*> & rmm( _submodels[current_block] );
    const unsigned num_submodels = rmm.size();

    for (unsigned i_rmm(0); i_rmm < num_submodels; ++i_rmm)
    {
        modified |= rmm[i_rmm]->modifyStrainIncrement( current_elem, qp, strain_increment, d_strain_dT);
    }
    return modified;
}
Esempio n. 6
0
  void testExtruder()
  {
    SerialMesh src_mesh(*TestCommWorld, /*dim=*/2);

    const unsigned int n_elems_per_side = 4;
    const unsigned int num_layers = 4;
    const unsigned int n_elems_per_layer = n_elems_per_side * n_elems_per_side;


    MeshTools::Generation::build_square(src_mesh, n_elems_per_side, n_elems_per_side);
    for (unsigned int i=0; i<n_elems_per_layer; ++i)
    {
      // Retrieve the element from the mesh by ID to guarantee proper ordering instead of with iterators
      Elem * elem = src_mesh.elem(i);
      elem->subdomain_id() = i;
    }

    SerialMesh dest_mesh(*TestCommWorld, /*dim=*/3);

    RealVectorValue extrusion_vector(0, 0, 1);

    QueryElemSubdomainID new_elem_subdomain_id;

    /**
     * The test mesh is designed to be square with the subdomain corresponding to the element number.
     * We will use this to assert the correct pattern from the custom extruder.
     */
    MeshTools::Generation::build_extrusion(dest_mesh, src_mesh, num_layers, extrusion_vector, &new_elem_subdomain_id);

    for (unsigned int i=0; i<n_elems_per_layer * num_layers; ++i)
    {
      // Retrieve the element from the mesh by ID to guarantee proper ordering instead of with iterators
      Elem * elem = dest_mesh.elem(i);

      CPPUNIT_ASSERT_EQUAL((unsigned int)elem->subdomain_id(), i%n_elems_per_layer + i/n_elems_per_layer /* integer division */);
    }
  }
Esempio n. 7
0
UniquePtr<Elem> Tet10::build_side (const unsigned int i,
                                   bool proxy) const
{
  libmesh_assert_less (i, this->n_sides());

  if (proxy)
    return UniquePtr<Elem>(new Side<Tri6,Tet10>(this,i));

  else
    {
      Elem * face = new Tri6;
      face->subdomain_id() = this->subdomain_id();

      for (unsigned n=0; n<face->n_nodes(); ++n)
        face->set_node(n) = this->get_node(Tet10::side_nodes_map[i][n]);

      return UniquePtr<Elem>(face);
    }

  libmesh_error_msg("We'll never get here!");
  return UniquePtr<Elem>();
}
Esempio n. 8
0
UniquePtr<Elem> Tri6::build_side (const unsigned int i,
                                  bool proxy) const
{
  libmesh_assert_less (i, this->n_sides());

  if (proxy)
    return UniquePtr<Elem>(new Side<Edge3,Tri6>(this,i));

  else
    {
      Elem* edge = new Edge3;
      edge->subdomain_id() = this->subdomain_id();

      // Set the nodes
      for (unsigned n=0; n<edge->n_nodes(); ++n)
        edge->set_node(n) = this->get_node(Tri6::side_nodes_map[i][n]);

      return UniquePtr<Elem>(edge);
    }

  libmesh_error_msg("We'll never get here!");
  return UniquePtr<Elem>();
}
Esempio n. 9
0
void
StripeMesh::buildMesh()
{
  GeneratedMesh::buildMesh();

  Real h = (getParam<Real>("xmax") - getParam<Real>("xmin")) / _n_stripes;  // width of the stripe

  for (unsigned int en = 0; en < nElem(); en++)
  {
    // get an element
    Elem * e = elemPtr(en);

    if (!e)
    {
      mooseError("Error getting element " << en << ". StripeMesh only works with ReplicatedMesh...");
    }
    else
    {
    Point centroid = e->centroid();                             // get its centroid
    subdomain_id_type sid = floor((centroid(0) - getParam<Real>("xmin")) / h);   // figure out the subdomain ID
    e->subdomain_id() = sid;
    }
  }
}
Esempio n. 10
0
Elem *
Packing<Elem *>::unpack (std::vector<largest_id_type>::const_iterator in,
                         MeshBase * mesh)
{
#ifndef NDEBUG
  const std::vector<largest_id_type>::const_iterator original_in = in;

  const largest_id_type incoming_header = *in++;
  libmesh_assert_equal_to (incoming_header, elem_magic_header);
#endif

  // int 0: level
  const unsigned int level =
    cast_int<unsigned int>(*in++);

#ifdef LIBMESH_ENABLE_AMR
  // int 1: p level
  const unsigned int p_level =
    cast_int<unsigned int>(*in++);

  // int 2: refinement flag and encoded has_children
  const int rflag = cast_int<int>(*in++);
  const int invalid_rflag =
    cast_int<int>(Elem::INVALID_REFINEMENTSTATE);
  libmesh_assert_greater_equal (rflag, 0);

  libmesh_assert_less (rflag, invalid_rflag*2+1);

  const bool has_children = (rflag > invalid_rflag);

  const Elem::RefinementState refinement_flag = has_children ?
    cast_int<Elem::RefinementState>(rflag - invalid_rflag - 1) :
    cast_int<Elem::RefinementState>(rflag);

  // int 3: p refinement flag
  const int pflag = cast_int<int>(*in++);
  libmesh_assert_greater_equal (pflag, 0);
  libmesh_assert_less (pflag, Elem::INVALID_REFINEMENTSTATE);
  const Elem::RefinementState p_refinement_flag =
    cast_int<Elem::RefinementState>(pflag);
#else
  in += 3;
#endif // LIBMESH_ENABLE_AMR

  // int 4: element type
  const int typeint = cast_int<int>(*in++);
  libmesh_assert_greater_equal (typeint, 0);
  libmesh_assert_less (typeint, INVALID_ELEM);
  const ElemType type =
    cast_int<ElemType>(typeint);

  const unsigned int n_nodes =
    Elem::type_to_n_nodes_map[type];

  // int 5: processor id
  const processor_id_type processor_id =
    cast_int<processor_id_type>(*in++);
  libmesh_assert (processor_id < mesh->n_processors() ||
                  processor_id == DofObject::invalid_processor_id);

  // int 6: subdomain id
  const subdomain_id_type subdomain_id =
    cast_int<subdomain_id_type>(*in++);

  // int 7: dof object id
  const dof_id_type id =
    cast_int<dof_id_type>(*in++);
  libmesh_assert_not_equal_to (id, DofObject::invalid_id);

#ifdef LIBMESH_ENABLE_UNIQUE_ID
  // int 8: dof object unique id
  const unique_id_type unique_id =
    cast_int<unique_id_type>(*in++);
#endif

#ifdef LIBMESH_ENABLE_AMR
  // int 9: parent dof object id.
  // Note: If level==0, then (*in) == invalid_id.  In
  // this case, the equality check in cast_int<unsigned>(*in) will
  // never succeed.  Therefore, we should only attempt the more
  // rigorous cast verification in cases where level != 0.
  const dof_id_type parent_id =
    (level == 0)
    ? static_cast<dof_id_type>(*in++)
    : cast_int<dof_id_type>(*in++);
  libmesh_assert (level == 0 || parent_id != DofObject::invalid_id);
  libmesh_assert (level != 0 || parent_id == DofObject::invalid_id);

  // int 10: local child id
  // Note: If level==0, then which_child_am_i is not valid, so don't
  // do the more rigorous cast verification.
  const unsigned int which_child_am_i =
    (level == 0)
    ? static_cast<unsigned int>(*in++)
    : cast_int<unsigned int>(*in++);
#else
  in += 2;
#endif // LIBMESH_ENABLE_AMR

  const dof_id_type interior_parent_id =
    static_cast<dof_id_type>(*in++);

  // Make sure we don't miscount above when adding the "magic" header
  // plus the real data header
  libmesh_assert_equal_to (in - original_in, header_size + 1);

  Elem * elem = mesh->query_elem_ptr(id);

  // if we already have this element, make sure its
  // properties match, and update any missing neighbor
  // links, but then go on
  if (elem)
    {
      libmesh_assert_equal_to (elem->level(), level);
      libmesh_assert_equal_to (elem->id(), id);
      //#ifdef LIBMESH_ENABLE_UNIQUE_ID
      // No check for unique id sanity
      //#endif
      libmesh_assert_equal_to (elem->processor_id(), processor_id);
      libmesh_assert_equal_to (elem->subdomain_id(), subdomain_id);
      libmesh_assert_equal_to (elem->type(), type);
      libmesh_assert_equal_to (elem->n_nodes(), n_nodes);

#ifndef NDEBUG
      // All our nodes should be correct
      for (unsigned int i=0; i != n_nodes; ++i)
        libmesh_assert(elem->node_id(i) ==
                       cast_int<dof_id_type>(*in++));
#else
      in += n_nodes;
#endif

#ifdef LIBMESH_ENABLE_AMR
      libmesh_assert_equal_to (elem->refinement_flag(), refinement_flag);
      libmesh_assert_equal_to (elem->has_children(), has_children);

#ifdef DEBUG
      if (elem->active())
        {
          libmesh_assert_equal_to (elem->p_level(), p_level);
          libmesh_assert_equal_to (elem->p_refinement_flag(), p_refinement_flag);
        }
#endif

      libmesh_assert (!level || elem->parent() != libmesh_nullptr);
      libmesh_assert (!level || elem->parent()->id() == parent_id);
      libmesh_assert (!level || elem->parent()->child_ptr(which_child_am_i) == elem);
#endif
      // Our interior_parent link should be "close to" correct - we
      // may have to update it, but we can check for some
      // inconsistencies.
      {
        // If the sending processor sees no interior_parent here, we'd
        // better agree.
        if (interior_parent_id == DofObject::invalid_id)
          {
            if (elem->dim() < LIBMESH_DIM)
              libmesh_assert (!(elem->interior_parent()));
          }

        // If the sending processor has a remote_elem interior_parent,
        // then all we know is that we'd better have *some*
        // interior_parent
        else if (interior_parent_id == remote_elem->id())
          {
            libmesh_assert(elem->interior_parent());
          }
        else
          {
            Elem * ip = mesh->query_elem_ptr(interior_parent_id);

            // The sending processor sees an interior parent here, so
            // if we don't have that interior element, then we'd
            // better have a remote_elem signifying that fact.
            if (!ip)
              libmesh_assert_equal_to (elem->interior_parent(), remote_elem);
            else
              {
                // The sending processor has an interior_parent here,
                // and we have that element, but that does *NOT* mean
                // we're already linking to it.  Perhaps we initially
                // received elem from a processor on which the
                // interior_parent link was remote?
                libmesh_assert(elem->interior_parent() == ip ||
                               elem->interior_parent() == remote_elem);

                // If the link was originally remote, update it
                if (elem->interior_parent() == remote_elem)
                  {
                    elem->set_interior_parent(ip);
                  }
              }
          }
      }

      // Our neighbor links should be "close to" correct - we may have
      // to update a remote_elem link, and we can check for possible
      // inconsistencies along the way.
      //
      // For subactive elements, we don't bother keeping neighbor
      // links in good shape, so there's nothing we need to set or can
      // safely assert here.
      if (!elem->subactive())
        for (auto n : elem->side_index_range())
          {
            const dof_id_type neighbor_id =
              cast_int<dof_id_type>(*in++);

            // If the sending processor sees a domain boundary here,
            // we'd better agree.
            if (neighbor_id == DofObject::invalid_id)
              {
                libmesh_assert (!(elem->neighbor_ptr(n)));
                continue;
              }

            // If the sending processor has a remote_elem neighbor here,
            // then all we know is that we'd better *not* have a domain
            // boundary.
            if (neighbor_id == remote_elem->id())
              {
                libmesh_assert(elem->neighbor_ptr(n));
                continue;
              }

            Elem * neigh = mesh->query_elem_ptr(neighbor_id);

            // The sending processor sees a neighbor here, so if we
            // don't have that neighboring element, then we'd better
            // have a remote_elem signifying that fact.
            if (!neigh)
              {
                libmesh_assert_equal_to (elem->neighbor_ptr(n), remote_elem);
                continue;
              }

            // The sending processor has a neighbor here, and we have
            // that element, but that does *NOT* mean we're already
            // linking to it.  Perhaps we initially received both elem
            // and neigh from processors on which their mutual link was
            // remote?
            libmesh_assert(elem->neighbor_ptr(n) == neigh ||
                           elem->neighbor_ptr(n) == remote_elem);

            // If the link was originally remote, we should update it,
            // and make sure the appropriate parts of its family link
            // back to us.
            if (elem->neighbor_ptr(n) == remote_elem)
              {
                elem->set_neighbor(n, neigh);

                elem->make_links_to_me_local(n);
              }
          }

      // Our p level and refinement flags should be "close to" correct
      // if we're not an active element - we might have a p level
      // increased or decreased by changes in remote_elem children.
      //
      // But if we have remote_elem children, then we shouldn't be
      // doing a projection on this inactive element on this
      // processor, so we won't need correct p settings.  Couldn't
      // hurt to update, though.
#ifdef LIBMESH_ENABLE_AMR
      if (elem->processor_id() != mesh->processor_id())
        {
          elem->hack_p_level(p_level);
          elem->set_p_refinement_flag(p_refinement_flag);
        }
#endif // LIBMESH_ENABLE_AMR

      // FIXME: We should add some debug mode tests to ensure that the
      // encoded indexing and boundary conditions are consistent.
    }
  else
    {
      // We don't already have the element, so we need to create it.

      // Find the parent if necessary
      Elem * parent = libmesh_nullptr;
#ifdef LIBMESH_ENABLE_AMR
      // Find a child element's parent
      if (level > 0)
        {
          // Note that we must be very careful to construct the send
          // connectivity so that parents are encountered before
          // children.  If we get here and can't find the parent that
          // is a fatal error.
          parent = mesh->elem_ptr(parent_id);
        }
      // Or assert that the sending processor sees no parent
      else
        libmesh_assert_equal_to (parent_id, DofObject::invalid_id);
#else
      // No non-level-0 elements without AMR
      libmesh_assert_equal_to (level, 0);
#endif

      elem = Elem::build(type,parent).release();
      libmesh_assert (elem);

#ifdef LIBMESH_ENABLE_AMR
      if (level != 0)
        {
          // Since this is a newly created element, the parent must
          // have previously thought of this child as a remote element.
          libmesh_assert_equal_to (parent->child_ptr(which_child_am_i), remote_elem);

          parent->add_child(elem, which_child_am_i);
        }

      // Assign the refinement flags and levels
      elem->set_p_level(p_level);
      elem->set_refinement_flag(refinement_flag);
      elem->set_p_refinement_flag(p_refinement_flag);
      libmesh_assert_equal_to (elem->level(), level);

      // If this element should have children, assign remote_elem to
      // all of them for now, for consistency.  Later unpacked
      // elements may overwrite that.
      if (has_children)
        {
          const unsigned int nc = elem->n_children();
          for (unsigned int c=0; c != nc; ++c)
            elem->add_child(const_cast<RemoteElem *>(remote_elem), c);
        }

#endif // LIBMESH_ENABLE_AMR

      // Assign the IDs
      elem->subdomain_id()  = subdomain_id;
      elem->processor_id()  = processor_id;
      elem->set_id()        = id;
#ifdef LIBMESH_ENABLE_UNIQUE_ID
      elem->set_unique_id() = unique_id;
#endif

      // Assign the connectivity
      libmesh_assert_equal_to (elem->n_nodes(), n_nodes);

      for (unsigned int n=0; n != n_nodes; n++)
        elem->set_node(n) =
          mesh->node_ptr
          (cast_int<dof_id_type>(*in++));

      // Set interior_parent if found
      {
        // We may be unpacking an element that was a ghost element on the
        // sender, in which case the element's interior_parent may not be
        // known by the packed element.  We'll have to set such
        // interior_parents to remote_elem ourselves and wait for a
        // later packed element to give us better information.
        if (interior_parent_id == remote_elem->id())
          {
            elem->set_interior_parent
              (const_cast<RemoteElem *>(remote_elem));
          }
        else if (interior_parent_id != DofObject::invalid_id)
          {
            // If we don't have the interior parent element, then it's
            // a remote_elem until we get it.
            Elem * ip = mesh->query_elem_ptr(interior_parent_id);
            if (!ip )
              elem->set_interior_parent
                (const_cast<RemoteElem *>(remote_elem));
            else
              elem->set_interior_parent(ip);
          }
      }

      for (auto n : elem->side_index_range())
        {
          const dof_id_type neighbor_id =
            cast_int<dof_id_type>(*in++);

          if (neighbor_id == DofObject::invalid_id)
            continue;

          // We may be unpacking an element that was a ghost element on the
          // sender, in which case the element's neighbors may not all be
          // known by the packed element.  We'll have to set such
          // neighbors to remote_elem ourselves and wait for a later
          // packed element to give us better information.
          if (neighbor_id == remote_elem->id())
            {
              elem->set_neighbor(n, const_cast<RemoteElem *>(remote_elem));
              continue;
            }

          // If we don't have the neighbor element, then it's a
          // remote_elem until we get it.
          Elem * neigh = mesh->query_elem_ptr(neighbor_id);
          if (!neigh)
            {
              elem->set_neighbor(n, const_cast<RemoteElem *>(remote_elem));
              continue;
            }

          // If we have the neighbor element, then link to it, and
          // make sure the appropriate parts of its family link back
          // to us.
          elem->set_neighbor(n, neigh);

          elem->make_links_to_me_local(n);
        }

      elem->unpack_indexing(in);
    }

  in += elem->packed_indexing_size();

  // If this is a coarse element,
  // add any element side or edge boundary condition ids
  if (level == 0)
    {
      for (auto s : elem->side_index_range())
        {
          const boundary_id_type num_bcs =
            cast_int<boundary_id_type>(*in++);

          for (boundary_id_type bc_it=0; bc_it < num_bcs; bc_it++)
            mesh->get_boundary_info().add_side
              (elem, s, cast_int<boundary_id_type>(*in++));
        }

      for (auto e : elem->edge_index_range())
        {
          const boundary_id_type num_bcs =
            cast_int<boundary_id_type>(*in++);

          for (boundary_id_type bc_it=0; bc_it < num_bcs; bc_it++)
            mesh->get_boundary_info().add_edge
              (elem, e, cast_int<boundary_id_type>(*in++));
        }

      for (unsigned short sf=0; sf != 2; ++sf)
        {
          const boundary_id_type num_bcs =
            cast_int<boundary_id_type>(*in++);

          for (boundary_id_type bc_it=0; bc_it < num_bcs; bc_it++)
            mesh->get_boundary_info().add_shellface
              (elem, sf, cast_int<boundary_id_type>(*in++));
        }
    }

  // Return the new element
  return elem;
}
Esempio n. 11
0
// Begin the main program.
int main (int argc, char ** argv)
{
  // Initialize libMesh and any dependent libaries, like in example 2.
  LibMeshInit init (argc, argv);

  // Only our PETSc interface currently supports solves restricted to
  // subdomains
  libmesh_example_requires(libMesh::default_solver_package() == PETSC_SOLVERS, "--enable-petsc");

  // Skip adaptive examples on a non-adaptive libMesh build
#ifndef LIBMESH_ENABLE_AMR
  libmesh_example_requires(false, "--enable-amr");
#else

  // Declare a performance log for the main program
  // PerfLog perf_main("Main Program");

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

  // Check for proper calling arguments.
  if (argc < 3)
    {
      // This handy function will print the file name, line number,
      // specified message, and then throw an exception.
      libmesh_error_msg("Usage:\n" << "\t " << argv[0] << " -d 2(3)" << " -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;
    }


  // Read problem dimension from command line.  Use int
  // instead of unsigned since the GetPot overload is ambiguous
  // otherwise.
  int dim = 2;
  if (command_line.search(1, "-d"))
    dim = command_line.next(dim);

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

  // Create a mesh with user-defined dimension.
  // Read number of elements from command line
  int ps = 15;
  if (command_line.search(1, "-n"))
    ps = command_line.next(ps);

  // Read FE order from command line
  std::string order = "FIRST";
  if (command_line.search(2, "-Order", "-o"))
    order = command_line.next(order);

  // Read FE Family from command line
  std::string family = "LAGRANGE";
  if (command_line.search(2, "-FEFamily", "-f"))
    family = command_line.next(family);

  // Cannot use discontinuous basis.
  if ((family == "MONOMIAL") || (family == "XYZ"))
    libmesh_error_msg("This example requires a C^0 (or higher) FE basis.");

  // Create a mesh, with dimension to be overridden later, on the
  // default MPI communicator.
  Mesh mesh(init.comm());

  // Use the MeshTools::Generation mesh generator to create a uniform
  // grid on the square [-1,1]^D.  We instruct the mesh generator
  // to build a mesh of 8x8 Quad9 elements in 2D, or Hex27
  // elements in 3D.  Building these higher-order elements allows
  // us to use higher-order approximation, as in example 3.

  Real halfwidth = dim > 1 ? 1. : 0.;
  Real halfheight = dim > 2 ? 1. : 0.;

  if ((family == "LAGRANGE") && (order == "FIRST"))
    {
      // No reason to use high-order geometric elements if we are
      // solving with low-order finite elements.
      MeshTools::Generation::build_cube (mesh,
                                         ps,
                                         (dim>1) ? ps : 0,
                                         (dim>2) ? ps : 0,
                                         -1., 1.,
                                         -halfwidth, halfwidth,
                                         -halfheight, halfheight,
                                         (dim==1)    ? EDGE2 :
                                         ((dim == 2) ? QUAD4 : HEX8));
    }

  else
    {
      MeshTools::Generation::build_cube (mesh,
                                         ps,
                                         (dim>1) ? ps : 0,
                                         (dim>2) ? ps : 0,
                                         -1., 1.,
                                         -halfwidth, halfwidth,
                                         -halfheight, halfheight,
                                         (dim==1)    ? EDGE3 :
                                         ((dim == 2) ? QUAD9 : HEX27));
    }


  // To demonstate solving on a subdomain, we will solve only on the
  // interior of a circle (ball in 3d) with radius 0.8.  So show that
  // this also works well on locally refined meshes, we refine once
  // all elements that are located on the boundary of this circle (or
  // ball).
  {
    // A MeshRefinement object is needed to refine meshes.
    MeshRefinement meshRefinement(mesh);

    // Loop over all elements.
    MeshBase::element_iterator       elem_it  = mesh.elements_begin();
    const MeshBase::element_iterator elem_end = mesh.elements_end();
    for (; elem_it != elem_end; ++elem_it)
      {
        Elem * elem = *elem_it;
        if (elem->active())
          {
            // Just check whether the current element has at least one
            // node inside and one node outside the circle.
            bool node_in = false;
            bool node_out = false;
            for (unsigned int i=0; i<elem->n_nodes(); i++)
              {
                double d = elem->point(i).norm();
                if (d<0.8)
                  {
                    node_in = true;
                  }
                else
                  {
                    node_out = true;
                  }
              }
            if (node_in && node_out)
              {
                elem->set_refinement_flag(Elem::REFINE);
              }
            else
              {
                elem->set_refinement_flag(Elem::DO_NOTHING);
              }
          }
        else
          {
            elem->set_refinement_flag(Elem::INACTIVE);
          }
      }

    // Now actually refine.
    meshRefinement.refine_elements();
  }

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

  // Now set the subdomain_id of all elements whose centroid is inside
  // the circle to 1.
  {
    // Loop over all elements.
    MeshBase::element_iterator       elem_it  = mesh.elements_begin();
    const MeshBase::element_iterator elem_end = mesh.elements_end();
    for (; elem_it != elem_end; ++elem_it)
      {
        Elem * elem = *elem_it;
        double d = elem->centroid().norm();
        if (d<0.8)
          {
            elem->subdomain_id() = 1;
          }
      }
  }

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

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


  // Add the variable "u" to "Poisson".  "u"
  // will be approximated using second-order approximation.
  system.add_variable("u",
                      Utility::string_to_enum<Order>   (order),
                      Utility::string_to_enum<FEFamily>(family));

  // Give the system a pointer to the matrix assembly
  // function.
  system.attach_assemble_function (assemble_poisson);

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

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

  // Restrict solves to those elements that have subdomain_id set to 1.
  std::set<subdomain_id_type> id_list;
  id_list.insert(1);
  SystemSubsetBySubdomain::SubdomainSelectionByList selection(id_list);
  SystemSubsetBySubdomain subset(system, selection);
  system.restrict_solve_to(&subset, SUBSET_ZERO);

  // Note that using SUBSET_ZERO will cause all dofs outside the
  // subdomain to be cleared.  This will, however, cause some hanging
  // nodes outside the subdomain to have inconsistent values.

  // Solve the system "Poisson", just like example 2.
  equation_systems.get_system("Poisson").solve();

  // After solving the system write the solution
  // to a GMV-formatted plot file.
  if (dim == 1)
    {
      GnuPlotIO plot(mesh, "Subdomains Example 1, 1D", GnuPlotIO::GRID_ON);
      plot.write_equation_systems("gnuplot_script", equation_systems);
    }
  else
    {
      GMVIO (mesh).write_equation_systems ((dim == 3) ?
                                           "out_3.gmv" : "out_2.gmv", equation_systems);
#ifdef LIBMESH_HAVE_EXODUS_API
      ExodusII_IO (mesh).write_equation_systems ((dim == 3) ?
                                                 "out_3.e" : "out_2.e", equation_systems);
#endif // #ifdef LIBMESH_HAVE_EXODUS_API
    }

#endif // #ifndef LIBMESH_ENABLE_AMR

  // All done.
  return 0;
}
Esempio n. 12
0
void VTKIO::cells_to_vtk()
{
  const MeshBase& mesh = MeshOutput<MeshBase>::mesh();

  vtkSmartPointer<vtkCellArray> cells = vtkSmartPointer<vtkCellArray>::New();
  vtkSmartPointer<vtkIdList> pts = vtkSmartPointer<vtkIdList>::New();

  std::vector<int> types(mesh.n_active_local_elem());
  unsigned active_element_counter = 0;

  vtkSmartPointer<vtkIntArray> elem_id = vtkSmartPointer<vtkIntArray>::New();
  elem_id->SetName("libmesh_elem_id");
  elem_id->SetNumberOfComponents(1);

  vtkSmartPointer<vtkIntArray> subdomain_id = vtkSmartPointer<vtkIntArray>::New();
  subdomain_id->SetName("subdomain_id");
  subdomain_id->SetNumberOfComponents(1);

  MeshBase::const_element_iterator it = mesh.active_local_elements_begin();
  const MeshBase::const_element_iterator end = mesh.active_local_elements_end();
  for (; it != end; ++it, ++active_element_counter)
    {
      Elem *elem = *it;

      pts->SetNumberOfIds(elem->n_nodes());

      // get the connectivity for this element
      std::vector<dof_id_type> conn;
      elem->connectivity(0, VTK, conn);

      for (unsigned int i=0; i<conn.size(); ++i)
        {
          // If the node ID is not found in the _local_node_map, we'll
          // add it to the _vtk_grid.  NOTE[JWP]: none of the examples
          // I have actually enters this section of code...
          if (_local_node_map.find(conn[i]) == _local_node_map.end())
            {
              dof_id_type global_node_id = elem->node(i);

              const Node* the_node = mesh.node_ptr(global_node_id);

              // Error checking...
              if (the_node == NULL)
                {
                  libMesh::err << "Error getting pointer to node "
                               << global_node_id
                               << "!" << std::endl;
                  libmesh_error();
                }

              // InsertNextPoint accepts either a double or float array of length 3.
              Real pt[3] = {0., 0., 0.};
              for (unsigned int d=0; d<LIBMESH_DIM; ++d)
                pt[d] = (*the_node)(d);

              // Insert the point into the _vtk_grid
              vtkIdType local = _vtk_grid->GetPoints()->InsertNextPoint(pt);

              // Update the _local_node_map with the ID returned by VTK
              _local_node_map[global_node_id] = local;
            }

          // Otherwise, the node ID was found in the _local_node_map, so
          // insert it into the vtkIdList.
          pts->InsertId(i, _local_node_map[conn[i]]);
        }

      vtkIdType vtkcellid = cells->InsertNextCell(pts);
      types[active_element_counter] = this->get_elem_type(elem->type());
      elem_id->InsertTuple1(vtkcellid, elem->id());
      subdomain_id->InsertTuple1(vtkcellid, elem->subdomain_id());
    } // end loop over active elements

  _vtk_grid->SetCells(&types[0], cells);
  _vtk_grid->GetCellData()->AddArray(elem_id);
  _vtk_grid->GetCellData()->AddArray(subdomain_id);
}
Esempio n. 13
0
// Begin the main program.
int main (int argc, char** argv)
{
  // Initialize libMesh and any dependent libaries, like in example 2.
  LibMeshInit init (argc, argv);

  // Declare a performance log for the main program
  // PerfLog perf_main("Main Program");

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

  // Check for proper calling arguments.
  if (argc < 3)
    {
      // This handy function will print the file name, line number,
      // specified message, and then throw an exception.
      libmesh_error_msg("Usage:\n" << "\t " << argv[0] << " -d 2(3)" << " -n 15");
    }

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

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

      std::cout << std::endl << std::endl;
    }


  // Read problem dimension from command line.  Use int
  // instead of unsigned since the GetPot overload is ambiguous
  // otherwise.
  int dim = 2;
  if ( command_line.search(1, "-d") )
    dim = command_line.next(dim);

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

  // Create a mesh with user-defined dimension on the default MPI
  // communicator.
  Mesh mesh (init.comm(), dim);

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

  // Read FE order from command line
  std::string order = "SECOND";
  if ( command_line.search(2, "-Order", "-o") )
    order = command_line.next(order);

  // Read FE Family from command line
  std::string family = "LAGRANGE";
  if ( command_line.search(2, "-FEFamily", "-f") )
    family = command_line.next(family);

  // Cannot use discontinuous basis.
  if ((family == "MONOMIAL") || (family == "XYZ"))
    {
      if (mesh.processor_id() == 0)
        libmesh_error_msg("This example requires a C^0 (or higher) FE basis.");
    }

  // Use the MeshTools::Generation mesh generator to create a uniform
  // grid on the square [-1,1]^D.  We instruct the mesh generator
  // to build a mesh of 8x8 \p Quad9 elements in 2D, or \p Hex27
  // elements in 3D.  Building these higher-order elements allows
  // us to use higher-order approximation, as in example 3.

  Real halfwidth = dim > 1 ? 1. : 0.;
  Real halfheight = dim > 2 ? 1. : 0.;

  if ((family == "LAGRANGE") && (order == "FIRST"))
    {
      // No reason to use high-order geometric elements if we are
      // solving with low-order finite elements.
      MeshTools::Generation::build_cube (mesh,
                                         ps,
                                         (dim>1) ? ps : 0,
                                         (dim>2) ? ps : 0,
                                         -1., 1.,
                                         -halfwidth, halfwidth,
                                         -halfheight, halfheight,
                                         (dim==1)    ? EDGE2 :
                                         ((dim == 2) ? QUAD4 : HEX8));
    }

  else
    {
      MeshTools::Generation::build_cube (mesh,
                                         ps,
                                         (dim>1) ? ps : 0,
                                         (dim>2) ? ps : 0,
                                         -1., 1.,
                                         -halfwidth, halfwidth,
                                         -halfheight, halfheight,
                                         (dim==1)    ? EDGE3 :
                                         ((dim == 2) ? QUAD9 : HEX27));
    }

  {
    MeshBase::element_iterator       el     = mesh.elements_begin();
    const MeshBase::element_iterator end_el = mesh.elements_end();

    for ( ; el != end_el; ++el)
      {
        Elem* elem = *el;
        const Point cent = elem->centroid();
        if (dim > 1)
          {
            if ((cent(0) > 0) == (cent(1) > 0))
              elem->subdomain_id() = 1;
          }
        else
          {
            if (cent(0) > 0)
              elem->subdomain_id() = 1;
          }
      }
  }

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

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

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


  std::set<subdomain_id_type> active_subdomains;


  // Add the variable "u" to "Poisson".  "u"
  // will be approximated using second-order approximation.
  active_subdomains.clear(); active_subdomains.insert(0);
  system.add_variable("u",
                      Utility::string_to_enum<Order>   (order),
                      Utility::string_to_enum<FEFamily>(family),
                      &active_subdomains);

  // Add the variable "v" to "Poisson".  "v"
  // will be approximated using second-order approximation.
  active_subdomains.clear(); active_subdomains.insert(1);
  system.add_variable("v",
                      Utility::string_to_enum<Order>   (order),
                      Utility::string_to_enum<FEFamily>(family),
                      &active_subdomains);

  // Give the system a pointer to the matrix assembly
  // function.
  system.attach_assemble_function (assemble_poisson);

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

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

  // Solve the system "Poisson", just like example 2.
  equation_systems.get_system("Poisson").solve();

  // After solving the system write the solution
  // to a GMV-formatted plot file.
  if(dim == 1)
    {
      GnuPlotIO plot(mesh,"Subdomains Example 2, 1D",GnuPlotIO::GRID_ON);
      plot.write_equation_systems("gnuplot_script",equation_systems);
    }
  else
    {
#ifdef LIBMESH_HAVE_EXODUS_API
      ExodusII_IO (mesh).write_equation_systems ((dim == 3) ?
                                                 "out_3.e" : "out_2.e",equation_systems);
#endif // #ifdef LIBMESH_HAVE_EXODUS_API
    }

  // All done.
  return 0;
}
Esempio n. 14
0
UniquePtr<Elem> InfHex18::build_side (const unsigned int i,
                                      bool proxy) const
{
  libmesh_assert_less (i, this->n_sides());

  if (proxy)
    {
      switch (i)
        {
          // base
        case 0:
          return UniquePtr<Elem>(new Side<Quad9,InfHex18>(this,i));

          // ifem sides
        case 1:
        case 2:
        case 3:
        case 4:
          return UniquePtr<Elem>(new Side<InfQuad6,InfHex18>(this,i));

        default:
          libmesh_error_msg("Invalid side i = " << i);
        }
    }

  else
    {
      // Create NULL pointer to be initialized, returned later.
      Elem* face = NULL;

      // Think of a unit cube: (-1,1) x (-1,1) x (1,1)
      switch (i)
        {
          // the base face
        case 0:
          {
            face = new Quad9;
            break;
          }

          // connecting to another infinite element
        case 1:
        case 2:
        case 3:
        case 4:
          {
            face = new InfQuad6;
            break;
          }

        default:
          libmesh_error_msg("Invalid side i = " << i);
        }

      face->subdomain_id() = this->subdomain_id();

      // Set the nodes
      for (unsigned n=0; n<face->n_nodes(); ++n)
        face->set_node(n) = this->get_node(InfHex18::side_nodes_map[i][n]);

      return UniquePtr<Elem>(face);
    }

  libmesh_error_msg("We'll never get here!");
  return UniquePtr<Elem>();
}
Esempio n. 15
0
UniquePtr<Elem> InfPrism12::build_side_ptr (const unsigned int i,
                                            bool proxy)
{
  libmesh_assert_less (i, this->n_sides());

  if (proxy)
    {
      switch (i)
        {
          // base
        case 0:
          return UniquePtr<Elem>(new Side<Tri6,InfPrism12>(this,i));

          // ifem sides
        case 1:
        case 2:
        case 3:
          return UniquePtr<Elem>(new Side<InfQuad6,InfPrism12>(this,i));

        default:
          libmesh_error_msg("Invalid side i = " << i);
        }
    }

  else
    {
      // Create NULL pointer to be initialized, returned later.
      Elem * face = libmesh_nullptr;

      switch (i)
        {
        case 0: // the triangular face at z=-1, base face
          {
            face = new Tri6;
            break;
          }

        case 1: // the quad face at y=0
        case 2: // the other quad face
        case 3: // the quad face at x=0
          {
            face = new InfQuad6;
            break;
          }

        default:
          libmesh_error_msg("Invalid side i = " << i);
        }

      face->subdomain_id() = this->subdomain_id();

      // Set the nodes
      for (unsigned n=0; n<face->n_nodes(); ++n)
        face->set_node(n) = this->node_ptr(InfPrism12::side_nodes_map[i][n]);

      return UniquePtr<Elem>(face);
    }

  libmesh_error_msg("We'll never get here!");
  return UniquePtr<Elem>();
}
Esempio n. 16
0
void ExodusII_IO::read (const std::string& fname)
{
  // This is a serial-only process for now;
  // the Mesh should be read on processor 0 and
  // broadcast later
//  libmesh_assert_equal_to (libMesh::processor_id(), 0);

#ifndef LIBMESH_HAVE_EXODUS_API

  libMesh::err <<  "ERROR, ExodusII API is not defined.\n"
	        << "Input file " << fname << " cannot be read"
	        << std::endl;
  libmesh_error();

#else

  // Get a reference to the mesh we are reading
  MeshBase& mesh = MeshInput<MeshBase>::mesh();

  // Clear any existing mesh data
  mesh.clear();

  // Keep track of what kinds of elements this file contains
  elems_of_dimension.clear();
  elems_of_dimension.resize(4, false);

#ifdef DEBUG
  this->verbose(true);
#endif


  ExodusII_IO_Helper::ElementMaps em;     // Instantiate the ElementMaps interface

  exio_helper->open(fname.c_str());       // Open the exodus file, if possible
  exio_helper->read_header();             // Get header information from exodus file
  exio_helper->print_header();            // Print header information

  //assertion fails due to inconsistent mesh dimension
//  libmesh_assert_equal_to (static_cast<unsigned int>(exio_helper->get_num_dim()), mesh.mesh_dimension()); // Be sure number of dimensions
                                                                                // is equal to the number of
                                                                                // dimensions in the mesh supplied.

  exio_helper->read_nodes();                        // Read nodes from the exodus file
  mesh.reserve_nodes(exio_helper->get_num_nodes()); // Reserve space for the nodes.

  // Loop over the nodes, create Nodes with local processor_id 0.
  for (int i=0; i<exio_helper->get_num_nodes(); i++)
    mesh.add_point (Point(exio_helper->get_x(i),
			  exio_helper->get_y(i),
			  exio_helper->get_z(i)), i);

  libmesh_assert_equal_to (static_cast<unsigned int>(exio_helper->get_num_nodes()), mesh.n_nodes());

  exio_helper->read_block_info();                 // Get information about all the blocks
  mesh.reserve_elem(exio_helper->get_num_elem()); // Reserve space for the elements


  // Read in the element connectivity for each block.
  int nelem_last_block = 0;

  std::map<int, unsigned int> exodus_id_to_mesh_id;

  // Loop over all the blocks
  for (int i=0; i<exio_helper->get_num_elem_blk(); i++)
    {
      // Read the information for block i
      exio_helper->read_elem_in_block (i);
      int subdomain_id = exio_helper->get_block_id(i);

      // populate the map of names
      mesh.subdomain_name(static_cast<subdomain_id_type>(subdomain_id)) =
        exio_helper->get_block_name(i);

      // Set any relevant node/edge maps for this element
      const std::string type_str (exio_helper->get_elem_type());
      const ExodusII_IO_Helper::Conversion conv = em.assign_conversion(type_str);
      //if (_verbose)
      //libMesh::out << "Reading a block of " << type_str << " elements." << std::endl;

      // Loop over all the faces in this block
      int jmax = nelem_last_block+exio_helper->get_num_elem_this_blk();
      for (int j=nelem_last_block; j<jmax; j++)
	{
	  Elem* elem = Elem::build (conv.get_canonical_type()).release();
	  libmesh_assert (elem);
          elem->subdomain_id() = static_cast<subdomain_id_type>(subdomain_id) ;
          //elem->set_id(j);// Don't try to second guess the Element ID setting scheme!

          elems_of_dimension[elem->dim()] = true;

	  elem = mesh.add_elem (elem); // Catch the Elem pointer that the Mesh throws back

          exodus_id_to_mesh_id[j+1] = elem->id();

	  // Set all the nodes for this element
	  for (int k=0; k<exio_helper->get_num_nodes_per_elem(); k++)
	    {
	      int gi = (j-nelem_last_block)*exio_helper->get_num_nodes_per_elem() + conv.get_node_map(k); // global index
	      int node_number   = exio_helper->get_connect(gi);             // Global node number (1-based)
	      elem->set_node(k) = mesh.node_ptr((node_number-1)); // Set node number
	                                                          // Subtract 1 since
		                                                  // exodus is internally 1-based
	    }
	}

      // running sum of # of elements per block,
      // (should equal total number of elements in the end)
      nelem_last_block += exio_helper->get_num_elem_this_blk();
    }
  libmesh_assert_equal_to (static_cast<unsigned int>(nelem_last_block), mesh.n_elem());

   // Set the mesh dimension to the largest encountered for an element
  for (unsigned int i=0; i!=4; ++i)
    if (elems_of_dimension[i])
      mesh.set_mesh_dimension(i);

  // Read in sideset information -- this is useful for applying boundary conditions
  {
    exio_helper->read_sideset_info(); // Get basic information about ALL sidesets
    int offset=0;
    for (int i=0; i<exio_helper->get_num_side_sets(); i++)
      {
	offset += (i > 0 ? exio_helper->get_num_sides_per_set(i-1) : 0); // Compute new offset
	exio_helper->read_sideset (i, offset);

        mesh.boundary_info->sideset_name(exio_helper->get_side_set_id(i)) =
          exio_helper->get_side_set_name(i);
      }

    const std::vector<int>& elem_list = exio_helper->get_elem_list();
    const std::vector<int>& side_list = exio_helper->get_side_list();
    const std::vector<int>& id_list   = exio_helper->get_id_list();

    for (unsigned int e=0; e<elem_list.size(); e++)
      {
	// Set any relevant node/edge maps for this element

        Elem * elem = mesh.elem(exodus_id_to_mesh_id[elem_list[e]]);

	const ExodusII_IO_Helper::Conversion conv =
	  em.assign_conversion(elem->type());

	mesh.boundary_info->add_side (exodus_id_to_mesh_id[elem_list[e]],
				      conv.get_side_map(side_list[e]-1),
				      id_list[e]);
      }
  }

  // Read nodeset info
  {
    exio_helper->read_nodeset_info();

    for (int nodeset=0; nodeset<exio_helper->get_num_node_sets(); nodeset++)
      {
        int nodeset_id = exio_helper->get_nodeset_id(nodeset);

        mesh.boundary_info->nodeset_name(nodeset_id) =
          exio_helper->get_node_set_name(nodeset);

        exio_helper->read_nodeset(nodeset);

        const std::vector<int>& node_list = exio_helper->get_node_list();

        for(unsigned int node=0; node<node_list.size(); node++)
          mesh.boundary_info->add_node(node_list[node]-1, nodeset_id);
      }
  }

#if LIBMESH_DIM < 3
  if (mesh.mesh_dimension() > LIBMESH_DIM)
    {
      libMesh::err << "Cannot open dimension " <<
		      mesh.mesh_dimension() <<
		      " mesh file when configured without " <<
                      mesh.mesh_dimension() << "D support." <<
                      std::endl;
      libmesh_error();
    }
#endif

#endif
}
Esempio n. 17
0
UniquePtr<Elem> InfQuad6::build_side (const unsigned int i,
                                      bool proxy) const
{
  // libmesh_assert_less (i, this->n_sides());

  if (proxy)
    {
      switch (i)
        {
        case 0:
          return UniquePtr<Elem>(new Side<Edge3,InfQuad6>(this,i));

        case 1:
        case 2:
          return UniquePtr<Elem>(new Side<InfEdge2,InfQuad6>(this,i));

        default:
          libmesh_error_msg("Invalid side i = " << i);
        }
    }

  else
    {
      // Create NULL pointer to be initialized, returned later.
      Elem* edge = NULL;

      switch (i)
        {
        case 0:
          {
            edge = new Edge3;

            edge->set_node(0) = this->get_node(0);
            edge->set_node(1) = this->get_node(1);
            edge->set_node(2) = this->get_node(4);

            break;
          }

        case 1:
          {
            // adjacent to another infinite element
            edge = new InfEdge2;

            edge->set_node(0) = this->get_node(1);
            edge->set_node(1) = this->get_node(3);

            break;
          }

        case 2:
          {
            // adjacent to another infinite element
            edge = new InfEdge2;

            edge->set_node(0) = this->get_node(0); // be aware of swapped nodes,
            edge->set_node(1) = this->get_node(2); // compared to conventional side numbering

            break;
          }
        default:
          libmesh_error_msg("Invalid side i = " << i);
        }

      edge->subdomain_id() = this->subdomain_id();
      return UniquePtr<Elem>(edge);
    }

  libmesh_error_msg("We'll never get here!");
  return UniquePtr<Elem>();
}
Esempio n. 18
0
void unpack(std::vector<largest_id_type>::const_iterator in,
            Elem** out,
            MeshBase* mesh)
{
#ifndef NDEBUG
  const std::vector<largest_id_type>::const_iterator original_in = in;

  const largest_id_type incoming_header = *in++;
  libmesh_assert_equal_to (incoming_header, elem_magic_header);
#endif

  // int 0: level
  const unsigned int level =
    static_cast<unsigned int>(*in++);

#ifdef LIBMESH_ENABLE_AMR
  // int 1: p level
  const unsigned int p_level =
    static_cast<unsigned int>(*in++);

  // int 2: refinement flag
  const int rflag = *in++;
  libmesh_assert_greater_equal (rflag, 0);
  libmesh_assert_less (rflag, Elem::INVALID_REFINEMENTSTATE);
  const Elem::RefinementState refinement_flag =
    static_cast<Elem::RefinementState>(rflag);

  // int 3: p refinement flag
  const int pflag = *in++;
  libmesh_assert_greater_equal (pflag, 0);
  libmesh_assert_less (pflag, Elem::INVALID_REFINEMENTSTATE);
  const Elem::RefinementState p_refinement_flag =
    static_cast<Elem::RefinementState>(pflag);
#else
  in += 3;
#endif // LIBMESH_ENABLE_AMR

  // int 4: element type
  const int typeint = *in++;
  libmesh_assert_greater_equal (typeint, 0);
  libmesh_assert_less (typeint, INVALID_ELEM);
  const ElemType type =
    static_cast<ElemType>(typeint);

  const unsigned int n_nodes =
    Elem::type_to_n_nodes_map[type];

  // int 5: processor id
  const processor_id_type processor_id =
    static_cast<processor_id_type>(*in++);
  libmesh_assert (processor_id < mesh->n_processors() ||
                  processor_id == DofObject::invalid_processor_id);

  // int 6: subdomain id
  const subdomain_id_type subdomain_id =
    static_cast<subdomain_id_type>(*in++);

  // int 7: dof object id
  const dof_id_type id =
    static_cast<dof_id_type>(*in++);
  libmesh_assert_not_equal_to (id, DofObject::invalid_id);

#ifdef LIBMESH_ENABLE_UNIQUE_ID
  // int 8: dof object unique id
  const unique_id_type unique_id =
    static_cast<unique_id_type>(*in++);
#endif

#ifdef LIBMESH_ENABLE_AMR
  // int 9: parent dof object id
  const dof_id_type parent_id =
    static_cast<dof_id_type>(*in++);
  libmesh_assert (level == 0 || parent_id != DofObject::invalid_id);
  libmesh_assert (level != 0 || parent_id == DofObject::invalid_id);

  // int 10: local child id
  const unsigned int which_child_am_i =
    static_cast<unsigned int>(*in++);
#else
  in += 2;
#endif // LIBMESH_ENABLE_AMR

  // Make sure we don't miscount above when adding the "magic" header
  // plus the real data header
  libmesh_assert_equal_to (in - original_in, header_size + 1);

  Elem *elem = mesh->query_elem(id);

  // if we already have this element, make sure its
  // properties match, and update any missing neighbor
  // links, but then go on
  if (elem)
    {
      libmesh_assert_equal_to (elem->level(), level);
      libmesh_assert_equal_to (elem->id(), id);
//#ifdef LIBMESH_ENABLE_UNIQUE_ID
      // No check for unqiue id sanity
//#endif
      libmesh_assert_equal_to (elem->processor_id(), processor_id);
      libmesh_assert_equal_to (elem->subdomain_id(), subdomain_id);
      libmesh_assert_equal_to (elem->type(), type);
      libmesh_assert_equal_to (elem->n_nodes(), n_nodes);

#ifndef NDEBUG
      // All our nodes should be correct
      for (unsigned int i=0; i != n_nodes; ++i)
        libmesh_assert(elem->node(i) ==
                       static_cast<dof_id_type>(*in++));
#else
      in += n_nodes;
#endif

#ifdef LIBMESH_ENABLE_AMR
      libmesh_assert_equal_to (elem->p_level(), p_level);
      libmesh_assert_equal_to (elem->refinement_flag(), refinement_flag);
      libmesh_assert_equal_to (elem->p_refinement_flag(), p_refinement_flag);

      libmesh_assert (!level || elem->parent() != NULL);
      libmesh_assert (!level || elem->parent()->id() == parent_id);
      libmesh_assert (!level || elem->parent()->child(which_child_am_i) == elem);
#endif

      // Our neighbor links should be "close to" correct - we may have
      // to update them, but we can check for some inconsistencies.
      for (unsigned int n=0; n != elem->n_neighbors(); ++n)
        {
          const dof_id_type neighbor_id =
            static_cast<dof_id_type>(*in++);

	  // If the sending processor sees a domain boundary here,
	  // we'd better agree.
          if (neighbor_id == DofObject::invalid_id)
            {
              libmesh_assert (!(elem->neighbor(n)));
              continue;
            }

	  // If the sending processor has a remote_elem neighbor here,
	  // then all we know is that we'd better *not* have a domain
	  // boundary.
          if (neighbor_id == remote_elem->id())
            {
              libmesh_assert(elem->neighbor(n));
              continue;
            }

          Elem *neigh = mesh->query_elem(neighbor_id);

          // The sending processor sees a neighbor here, so if we
          // don't have that neighboring element, then we'd better
          // have a remote_elem signifying that fact.
          if (!neigh)
            {
              libmesh_assert_equal_to (elem->neighbor(n), remote_elem);
              continue;
            }

          // The sending processor has a neighbor here, and we have
          // that element, but that does *NOT* mean we're already
	  // linking to it.  Perhaps we initially received both elem
	  // and neigh from processors on which their mutual link was
	  // remote?
          libmesh_assert(elem->neighbor(n) == neigh ||
			 elem->neighbor(n) == remote_elem);

	  // If the link was originally remote, we should update it,
	  // and make sure the appropriate parts of its family link
	  // back to us.
	  if (elem->neighbor(n) == remote_elem)
            {
              elem->set_neighbor(n, neigh);

              elem->make_links_to_me_local(n);
	    }
	}

      // FIXME: We should add some debug mode tests to ensure that the
      // encoded indexing and boundary conditions are consistent.
    }
  else
    {
      // We don't already have the element, so we need to create it.

      // Find the parent if necessary
      Elem *parent = NULL;
#ifdef LIBMESH_ENABLE_AMR
      // Find a child element's parent
      if (level > 0)
        {
	  // Note that we must be very careful to construct the send
	  // connectivity so that parents are encountered before
	  // children.  If we get here and can't find the parent that
	  // is a fatal error.
          parent = mesh->elem(parent_id);
        }
      // Or assert that the sending processor sees no parent
      else
        libmesh_assert_equal_to (parent_id, static_cast<dof_id_type>(-1));
#else
      // No non-level-0 elements without AMR
      libmesh_assert_equal_to (level, 0);
#endif

      elem = Elem::build(type,parent).release();
      libmesh_assert (elem);

#ifdef LIBMESH_ENABLE_AMR
      if (level != 0)
        {
          // Since this is a newly created element, the parent must
          // have previously thought of this child as a remote element.
          libmesh_assert_equal_to (parent->child(which_child_am_i), remote_elem);

          parent->add_child(elem, which_child_am_i);
        }

      // Assign the refinement flags and levels
      elem->set_p_level(p_level);
      elem->set_refinement_flag(refinement_flag);
      elem->set_p_refinement_flag(p_refinement_flag);
      libmesh_assert_equal_to (elem->level(), level);

      // If this element definitely should have children, assign
      // remote_elem to all of them for now, for consistency.  Later
      // unpacked elements may overwrite that.
      if (!elem->active())
        for (unsigned int c=0; c != elem->n_children(); ++c)
          elem->add_child(const_cast<RemoteElem*>(remote_elem), c);

#endif // LIBMESH_ENABLE_AMR

      // Assign the IDs
      elem->subdomain_id()  = subdomain_id;
      elem->processor_id()  = processor_id;
      elem->set_id()        = id;
#ifdef LIBMESH_ENABLE_UNIQUE_ID
      elem->set_unique_id() = unique_id;
#endif

      // Assign the connectivity
      libmesh_assert_equal_to (elem->n_nodes(), n_nodes);

      for (unsigned int n=0; n != n_nodes; n++)
        elem->set_node(n) =
          mesh->node_ptr
	    (static_cast<dof_id_type>(*in++));

      for (unsigned int n=0; n<elem->n_neighbors(); n++)
        {
          const dof_id_type neighbor_id =
            static_cast<dof_id_type>(*in++);

          if (neighbor_id == DofObject::invalid_id)
	    continue;

          // We may be unpacking an element that was a ghost element on the
          // sender, in which case the element's neighbors may not all be
          // known by the packed element.  We'll have to set such
          // neighbors to remote_elem ourselves and wait for a later
          // packed element to give us better information.
          if (neighbor_id == remote_elem->id())
            {
              elem->set_neighbor(n, const_cast<RemoteElem*>(remote_elem));
	      continue;
	    }

          // If we don't have the neighbor element, then it's a
          // remote_elem until we get it.
          Elem *neigh = mesh->query_elem(neighbor_id);
          if (!neigh)
            {
              elem->set_neighbor(n, const_cast<RemoteElem*>(remote_elem));
	      continue;
	    }

          // If we have the neighbor element, then link to it, and
          // make sure the appropriate parts of its family link back
          // to us.
          elem->set_neighbor(n, neigh);

          elem->make_links_to_me_local(n);
        }

      elem->unpack_indexing(in);
    }

  in += elem->packed_indexing_size();

  // If this is a coarse element,
  // add any element side boundary condition ids
  if (level == 0)
    for (unsigned int s = 0; s != elem->n_sides(); ++s)
      {
        const int num_bcs = *in++;
        libmesh_assert_greater_equal (num_bcs, 0);

        for(int bc_it=0; bc_it < num_bcs; bc_it++)
          mesh->boundary_info->add_side (elem, s, *in++);
      }

  // Return the new element
  *out = elem;
}
Esempio n. 19
0
UniquePtr<Elem> Pyramid13::build_side (const unsigned int i, bool proxy) const
{
  libmesh_assert_less (i, this->n_sides());

  if (proxy)
    {
      switch (i)
        {
        case 0:
        case 1:
        case 2:
        case 3:
          return UniquePtr<Elem>(new Side<Tri6,Pyramid13>(this,i));

        case 4:
          return UniquePtr<Elem>(new Side<Quad8,Pyramid13>(this,i));

        default:
          libmesh_error_msg("Invalid side i = " << i);
        }
    }

  else
    {
      // Create NULL pointer to be initialized, returned later.
      Elem* face = NULL;

      switch (i)
        {
        case 0:  // triangular face 1
          {
            face = new Tri6;

            face->set_node(0) = this->get_node(0);
            face->set_node(1) = this->get_node(1);
            face->set_node(2) = this->get_node(4);
            face->set_node(3) = this->get_node(5);
            face->set_node(4) = this->get_node(10);
            face->set_node(5) = this->get_node(9);

            break;
          }
        case 1:  // triangular face 2
          {
            face = new Tri6;

            face->set_node(0) = this->get_node(1);
            face->set_node(1) = this->get_node(2);
            face->set_node(2) = this->get_node(4);
            face->set_node(3) = this->get_node(6);
            face->set_node(4) = this->get_node(11);
            face->set_node(5) = this->get_node(10);

            break;
          }
        case 2:  // triangular face 3
          {
            face = new Tri6;

            face->set_node(0) = this->get_node(2);
            face->set_node(1) = this->get_node(3);
            face->set_node(2) = this->get_node(4);
            face->set_node(3) = this->get_node(7);
            face->set_node(4) = this->get_node(12);
            face->set_node(5) = this->get_node(11);

            break;
          }
        case 3:  // triangular face 4
          {
            face = new Tri6;

            face->set_node(0) = this->get_node(3);
            face->set_node(1) = this->get_node(0);
            face->set_node(2) = this->get_node(4);
            face->set_node(3) = this->get_node(8);
            face->set_node(4) = this->get_node(9);
            face->set_node(5) = this->get_node(12);

            break;
          }
        case 4:  // the quad face at z=0
          {
            face = new Quad8;

            face->set_node(0) = this->get_node(0);
            face->set_node(1) = this->get_node(3);
            face->set_node(2) = this->get_node(2);
            face->set_node(3) = this->get_node(1);
            face->set_node(4) = this->get_node(8);
            face->set_node(5) = this->get_node(7);
            face->set_node(6) = this->get_node(6);
            face->set_node(7) = this->get_node(5);

            break;
          }
        default:
          libmesh_error_msg("Invalid side i = " << i);
        }

      face->subdomain_id() = this->subdomain_id();
      return UniquePtr<Elem>(face);
    }

  libmesh_error_msg("We'll never get here!");
  return UniquePtr<Elem>();
}
Esempio n. 20
0
// Begin the main program.
int main (int argc, char ** argv)
{
  // Initialize libMesh, like in example 2.
  LibMeshInit init (argc, argv);

  // This example requires Infinite Elements
#ifndef LIBMESH_ENABLE_INFINITE_ELEMENTS
  libmesh_example_requires(false, "--enable-ifem");
#else

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

  // Tell the user what we are doing.
  libMesh::out << "Running ex6 with dim = 3" << std::endl << std::endl;

  // Create a serialized mesh, distributed across the default MPI
  // communicator.
  // InfElemBuilder still requires some updates to be DistributedMesh
  // compatible

  ReplicatedMesh mesh(init.comm());

  // Use the internal mesh generator to create elements
  // on the square [-1,1]^3, of type Hex8.
  MeshTools::Generation::build_cube (mesh,
                                     4, 4, 4,
                                     -1., 1.,
                                     -1., 1.,
                                     -1., 1.,
                                     HEX8);

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

  // Write the mesh before the infinite elements are added
#ifdef LIBMESH_HAVE_EXODUS_API
  ExodusII_IO(mesh).write ("orig_mesh.e");
#endif

  // Normally, when a mesh is imported or created in
  // libMesh, only conventional elements exist.  The infinite
  // elements used here, however, require prescribed
  // nodal locations (with specified distances from an imaginary
  // origin) and configurations that a conventional mesh creator
  // in general does not offer.  Therefore, an efficient method
  // for building infinite elements is offered.  It can account
  // for symmetry planes and creates infinite elements in a fully
  // automatic way.
  //
  // Right now, the simplified interface is used, automatically
  // determining the origin.  Check MeshBase for a generalized
  // method that can even return the element faces of interior
  // vibrating surfaces.  The bool determines whether to be
  // verbose.
  InfElemBuilder builder(mesh);
  builder.build_inf_elem(true);

  // Reassign subdomain_id() of all infinite elements.
  // Otherwise, the exodus-api will fail on the mesh.
  MeshBase::element_iterator       elem_it  = mesh.elements_begin();
  const MeshBase::element_iterator elem_end = mesh.elements_end();
  for (; elem_it != elem_end; ++elem_it)
    {
      Elem* elem = *elem_it;
      if(elem->infinite())
        {
          elem->subdomain_id() = 1;
        }
    }



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

  // Write the mesh with the infinite elements added.
  // Compare this to the original mesh.
#ifdef LIBMESH_HAVE_EXODUS_API
  ExodusII_IO(mesh).write ("ifems_added.e");
#endif

  // After building infinite elements, we have to let
  // the elements find their neighbors again.
  mesh.find_neighbors();

  // Create an equation systems object, where ThinSystem
  // offers only the crucial functionality for solving a
  // system.  Use ThinSystem when you want the sleekest
  // system possible.
  EquationSystems equation_systems (mesh);

  // Declare the system and its variables.
  // Create a system named "Wave".  This can
  // be a simple, steady system
  equation_systems.add_system<LinearImplicitSystem> ("Wave");

  // Create an FEType describing the approximation
  // characteristics of the InfFE object.  Note that
  // the constructor automatically defaults to some
  // sensible values.  But use FIRST order
  // approximation.
  FEType fe_type(FIRST);

  // Add the variable "p" to "Wave".  Note that there exist
  // various approaches in adding variables.  In example 3,
  // add_variable took the order of approximation and used
  // default values for the FEFamily, while here the FEType
  // is used.
  equation_systems.get_system("Wave").add_variable("p", fe_type);

  // Give the system a pointer to the matrix assembly
  // function.
  equation_systems.get_system("Wave").attach_assemble_function (assemble_wave);

  // Set the speed of sound and fluid density
  // as EquationSystems parameter,
  // so that assemble_wave() can access it.
  equation_systems.parameters.set<Real>("speed")         = 1.;
  equation_systems.parameters.set<Real>("fluid density") = 1.;

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

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

  // Solve the system "Wave".
  equation_systems.get_system("Wave").solve();

  // Write the whole EquationSystems object to file.
  // For infinite elements, the concept of nodal_soln()
  // is not applicable. Therefore, writing the mesh in
  // some format @e always gives all-zero results at
  // the nodes of the infinite elements.  Instead,
  // use the FEInterface::compute_data() methods to
  // determine physically correct results within an
  // infinite element.
  equation_systems.write ("eqn_sys.dat", WRITE);

  // All done.
  return 0;

#endif // else part of ifndef LIBMESH_ENABLE_INFINITE_ELEMENTS
}
Esempio n. 21
0
void CheckpointIO::read_connectivity (Xdr & io)
{
  // convenient reference to our mesh
  MeshBase & mesh = MeshInput<MeshBase>::mesh();

  unsigned int n_active_levels;
  io.data(n_active_levels, "# n_active_levels");

  // Keep track of the highest dimensional element we've added to the mesh
  unsigned int highest_elem_dim = 1;

  for(unsigned int level=0; level < n_active_levels; level++)
    {
      xdr_id_type n_elem_at_level = 0;
      io.data (n_elem_at_level, "");

      for (unsigned int i=0; i<n_elem_at_level; i++)
        {
          // id type pid subdomain_id parent_id
          std::vector<largest_id_type> elem_data(5);
          io.data_stream
            (&elem_data[0], cast_int<unsigned int>(elem_data.size()),
             cast_int<unsigned int>(elem_data.size()));

#ifdef LIBMESH_ENABLE_UNIQUE_ID
          largest_id_type unique_id = 0;
          io.data(unique_id, "# unique id");
#endif

#ifdef LIBMESH_ENABLE_AMR
          unsigned int p_level = 0;

          io.data(p_level, "# p_level");
#endif

          unsigned int n_nodes = Elem::type_to_n_nodes_map[elem_data[1]];

          // Snag the node ids this element was connected to
          std::vector<largest_id_type> conn_data(n_nodes);
          io.data_stream
            (&conn_data[0], cast_int<unsigned int>(conn_data.size()),
             cast_int<unsigned int>(conn_data.size()));

          const dof_id_type id                 =
            cast_int<dof_id_type>      (elem_data[0]);
          const ElemType elem_type             =
            static_cast<ElemType>      (elem_data[1]);
          const processor_id_type proc_id      =
            cast_int<processor_id_type>(elem_data[2]);
          const subdomain_id_type subdomain_id =
            cast_int<subdomain_id_type>(elem_data[3]);
          const dof_id_type parent_id          =
            cast_int<dof_id_type>      (elem_data[4]);

          Elem * parent =
            (parent_id == DofObject::invalid_processor_id) ?
            libmesh_nullptr : mesh.elem_ptr(parent_id);

          // Create the element
          Elem * elem = Elem::build(elem_type, parent).release();

#ifdef LIBMESH_ENABLE_UNIQUE_ID
          elem->set_unique_id() = unique_id;
#endif

          if(elem->dim() > highest_elem_dim)
            highest_elem_dim = elem->dim();

          elem->set_id()       = id;
          elem->processor_id() = proc_id;
          elem->subdomain_id() = subdomain_id;

#ifdef LIBMESH_ENABLE_AMR
          elem->hack_p_level(p_level);

          // Set parent connections
          if(parent)
            {
              parent->add_child(elem);
              parent->set_refinement_flag (Elem::INACTIVE);
              elem->set_refinement_flag   (Elem::JUST_REFINED);
            }
#endif

          libmesh_assert(elem->n_nodes() == conn_data.size());

          // Connect all the nodes to this element
          for (unsigned int n=0; n<conn_data.size(); n++)
            elem->set_node(n) =
              mesh.node_ptr(cast_int<dof_id_type>(conn_data[n]));

          mesh.add_elem(elem);
        }
    }

  mesh.set_mesh_dimension(cast_int<unsigned char>(highest_elem_dim));
}
Esempio n. 22
0
void ExodusII_IO::read (const std::string & fname)
{
  // Get a reference to the mesh we are reading
  MeshBase & mesh = MeshInput<MeshBase>::mesh();

  // Clear any existing mesh data
  mesh.clear();

  // Keep track of what kinds of elements this file contains
  elems_of_dimension.clear();
  elems_of_dimension.resize(4, false);

#ifdef DEBUG
  this->verbose(true);
#endif

  // Instantiate the ElementMaps interface
  ExodusII_IO_Helper::ElementMaps em(*exio_helper);

  // Open the exodus file in EX_READ mode
  exio_helper->open(fname.c_str(), /*read_only=*/true);

  // Get header information from exodus file
  exio_helper->read_header();

  // Read the QA records
  exio_helper->read_qa_records();

  // Print header information
  exio_helper->print_header();

  // Read nodes from the exodus file
  exio_helper->read_nodes();

  // Reserve space for the nodes.
  mesh.reserve_nodes(exio_helper->num_nodes);

  // Read the node number map from the Exodus file.  This is
  // required if we want to preserve the numbering of nodes as it
  // exists in the Exodus file.  If the Exodus file does not contain
  // a node_num_map, the identity map is returned by this call.
  exio_helper->read_node_num_map();

  // Loop over the nodes, create Nodes with local processor_id 0.
  for (int i=0; i<exio_helper->num_nodes; i++)
    {
      // Use the node_num_map to get the correct ID for Exodus
      int exodus_id = exio_helper->node_num_map[i];

      // Catch the node that was added to the mesh
      Node * added_node = mesh.add_point (Point(exio_helper->x[i], exio_helper->y[i], exio_helper->z[i]), exodus_id-1);

      // If the Mesh assigned an ID different from what is in the
      // Exodus file, we should probably error.
      if (added_node->id() != static_cast<unsigned>(exodus_id-1))
        libmesh_error_msg("Error!  Mesh assigned node ID "    \
                          << added_node->id()                         \
                          << " which is different from the (zero-based) Exodus ID " \
                          << exodus_id-1                              \
                          << "!");
    }

  // This assert is no longer valid if the nodes are not numbered
  // sequentially starting from 1 in the Exodus file.
  // libmesh_assert_equal_to (static_cast<unsigned int>(exio_helper->num_nodes), mesh.n_nodes());

  // Get information about all the blocks
  exio_helper->read_block_info();

  // Reserve space for the elements
  mesh.reserve_elem(exio_helper->num_elem);

  // Read the element number map from the Exodus file.  This is
  // required if we want to preserve the numbering of elements as it
  // exists in the Exodus file.  If the Exodus file does not contain
  // an elem_num_map, the identity map is returned by this call.
  exio_helper->read_elem_num_map();

  // Read in the element connectivity for each block.
  int nelem_last_block = 0;

  // Loop over all the blocks
  for (int i=0; i<exio_helper->num_elem_blk; i++)
    {
      // Read the information for block i
      exio_helper->read_elem_in_block (i);
      int subdomain_id = exio_helper->get_block_id(i);

      // populate the map of names
      std::string subdomain_name = exio_helper->get_block_name(i);
      if (!subdomain_name.empty())
        mesh.subdomain_name(static_cast<subdomain_id_type>(subdomain_id)) = subdomain_name;

      // Set any relevant node/edge maps for this element
      const std::string type_str (exio_helper->get_elem_type());
      const ExodusII_IO_Helper::Conversion conv = em.assign_conversion(type_str);

      // Loop over all the faces in this block
      int jmax = nelem_last_block+exio_helper->num_elem_this_blk;
      for (int j=nelem_last_block; j<jmax; j++)
        {
          Elem * elem = Elem::build (conv.get_canonical_type()).release();
          libmesh_assert (elem);
          elem->subdomain_id() = static_cast<subdomain_id_type>(subdomain_id) ;

          // Use the elem_num_map to obtain the ID of this element in the Exodus file
          int exodus_id = exio_helper->elem_num_map[j];

          // Assign this element the same ID it had in the Exodus
          // file, but make it zero-based by subtracting 1.  Note:
          // some day we could use 1-based numbering in libmesh and
          // thus match the Exodus numbering exactly, but at the
          // moment libmesh is zero-based.
          elem->set_id(exodus_id-1);

          // Record that we have seen an element of dimension elem->dim()
          elems_of_dimension[elem->dim()] = true;

          // Catch the Elem pointer that the Mesh throws back
          elem = mesh.add_elem (elem);

          // If the Mesh assigned an ID different from what is in the
          // Exodus file, we should probably error.
          if (elem->id() != static_cast<unsigned>(exodus_id-1))
            libmesh_error_msg("Error!  Mesh assigned ID "       \
                              << elem->id()                             \
                              << " which is different from the (zero-based) Exodus ID " \
                              << exodus_id-1                            \
                              << "!");

          // Set all the nodes for this element
          for (int k=0; k<exio_helper->num_nodes_per_elem; k++)
            {
              // global index
              int gi = (j-nelem_last_block)*exio_helper->num_nodes_per_elem + conv.get_node_map(k);

              // The entries in 'connect' are actually (1-based)
              // indices into the node_num_map, so to get the right
              // node ID we:
              // 1.) Subtract 1 from connect[gi]
              // 2.) Pass it through node_num_map to get the corresponding Exodus ID
              // 3.) Subtract 1 from that, since libmesh node numbering is "zero"-based,
              //     even when the Exodus node numbering doesn't start with 1.
              int libmesh_node_id = exio_helper->node_num_map[exio_helper->connect[gi] - 1] - 1;

              // Set the node pointer in the Elem
              elem->set_node(k) = mesh.node_ptr(libmesh_node_id);
            }
        }

      // running sum of # of elements per block,
      // (should equal total number of elements in the end)
      nelem_last_block += exio_helper->num_elem_this_blk;
    }

  // This assert isn't valid if the Exodus file's numbering doesn't
  // start with 1!  For example, if Exodus's elem_num_map is 21, 22,
  // 23, 24, 25, 26, 27, 28, 29, 30, ... 84, then by the time you are
  // done with the loop above, mesh.n_elem() will report 84 and
  // nelem_last_block will be 64.
  // libmesh_assert_equal_to (static_cast<unsigned>(nelem_last_block), mesh.n_elem());

  // Set the mesh dimension to the largest encountered for an element
  for (unsigned char i=0; i!=4; ++i)
    if (elems_of_dimension[i])
      mesh.set_mesh_dimension(i);

  // Read in sideset information -- this is useful for applying boundary conditions
  {
    // Get basic information about all sidesets
    exio_helper->read_sideset_info();
    int offset=0;
    for (int i=0; i<exio_helper->num_side_sets; i++)
      {
        // Compute new offset
        offset += (i > 0 ? exio_helper->num_sides_per_set[i-1] : 0);
        exio_helper->read_sideset (i, offset);

        std::string sideset_name = exio_helper->get_side_set_name(i);
        if (!sideset_name.empty())
          mesh.get_boundary_info().sideset_name
            (cast_int<boundary_id_type>(exio_helper->get_side_set_id(i)))
            = sideset_name;
      }

    for (unsigned int e=0; e<exio_helper->elem_list.size(); e++)
      {
        // The numbers in the Exodus file sidesets should be thought
        // of as (1-based) indices into the elem_num_map array.  So,
        // to get the right element ID we have to:
        // 1.) Subtract 1 from elem_list[e] (to get a zero-based index)
        // 2.) Pass it through elem_num_map (to get the corresponding Exodus ID)
        // 3.) Subtract 1 from that, since libmesh is "zero"-based,
        //     even when the Exodus numbering doesn't start with 1.
        dof_id_type libmesh_elem_id =
          cast_int<dof_id_type>(exio_helper->elem_num_map[exio_helper->elem_list[e] - 1] - 1);

        // Set any relevant node/edge maps for this element
        Elem * elem = mesh.elem(libmesh_elem_id);

        const ExodusII_IO_Helper::Conversion conv = em.assign_conversion(elem->type());

        // Map the zero-based Exodus side numbering to the libmesh side numbering
        int mapped_side = conv.get_side_map(exio_helper->side_list[e]-1);

        // Check for errors
        if (mapped_side == ExodusII_IO_Helper::Conversion::invalid_id)
          libmesh_error_msg("Invalid 1-based side id: "                 \
                            << exio_helper->side_list[e]                \
                            << " detected for "                         \
                            << Utility::enum_to_string(elem->type()));

        // Add this (elem,side,id) triplet to the BoundaryInfo object.
        mesh.get_boundary_info().add_side (libmesh_elem_id,
                                           cast_int<unsigned short>(mapped_side),
                                           cast_int<boundary_id_type>(exio_helper->id_list[e]));
      }
  }

  // Read nodeset info
  {
    exio_helper->read_nodeset_info();

    for (int nodeset=0; nodeset<exio_helper->num_node_sets; nodeset++)
      {
        boundary_id_type nodeset_id =
          cast_int<boundary_id_type>(exio_helper->nodeset_ids[nodeset]);

        std::string nodeset_name = exio_helper->get_node_set_name(nodeset);
        if (!nodeset_name.empty())
          mesh.get_boundary_info().nodeset_name(nodeset_id) = nodeset_name;

        exio_helper->read_nodeset(nodeset);

        for (unsigned int node=0; node<exio_helper->node_list.size(); node++)
          {
            // As before, the entries in 'node_list' are 1-based
            // indcies into the node_num_map array, so we have to map
            // them.  See comment above.
            int libmesh_node_id = exio_helper->node_num_map[exio_helper->node_list[node] - 1] - 1;
            mesh.get_boundary_info().add_node(cast_int<dof_id_type>(libmesh_node_id),
                                              nodeset_id);
          }
      }
  }

#if LIBMESH_DIM < 3
  if (mesh.mesh_dimension() > LIBMESH_DIM)
    libmesh_error_msg("Cannot open dimension "        \
                      << mesh.mesh_dimension()            \
                      << " mesh file when configured without "        \
                      << mesh.mesh_dimension()                        \
                      << "D support.");
#endif
}
Esempio n. 23
0
void
AnnularMesh::buildMesh()
{
  const Real dt = (_tmax - _tmin) / _nt;

  MeshBase & mesh = getMesh();
  mesh.clear();
  mesh.set_mesh_dimension(2);
  mesh.set_spatial_dimension(2);
  BoundaryInfo & boundary_info = mesh.get_boundary_info();

  const unsigned num_angular_nodes = (_full_annulus ? _nt : _nt + 1);
  const unsigned num_nodes =
      (_rmin > 0.0 ? (_nr + 1) * num_angular_nodes : _nr * num_angular_nodes + 1);
  const unsigned min_nonzero_layer_num = (_rmin > 0.0 ? 0 : 1);
  std::vector<Node *> nodes(num_nodes);
  unsigned node_id = 0;

  // add nodes at rmax that aren't yet connected to any elements
  Real current_r = _rmax;
  for (unsigned angle_num = 0; angle_num < num_angular_nodes; ++angle_num)
  {
    const Real angle = _tmin + angle_num * dt;
    const Real x = current_r * std::cos(angle);
    const Real y = current_r * std::sin(angle);
    nodes[node_id] = mesh.add_point(Point(x, y, 0.0), node_id);
    node_id++;
  }

  // add nodes at smaller radii, and connect them with elements
  for (unsigned layer_num = _nr; layer_num > min_nonzero_layer_num; --layer_num)
  {
    if (layer_num == 1)
      current_r = _rmin; // account for precision loss
    else
      current_r -= _len * std::pow(_growth_r, layer_num - 1);

    // add node at angle = _tmin
    nodes[node_id] = mesh.add_point(
        Point(current_r * std::cos(_tmin), current_r * std::sin(_tmin), 0.0), node_id);
    node_id++;
    for (unsigned angle_num = 1; angle_num < num_angular_nodes; ++angle_num)
    {
      const Real angle = _tmin + angle_num * dt;
      const Real x = current_r * std::cos(angle);
      const Real y = current_r * std::sin(angle);
      nodes[node_id] = mesh.add_point(Point(x, y, 0.0), node_id);
      Elem * elem = mesh.add_elem(new Quad4);
      elem->set_node(0) = nodes[node_id];
      elem->set_node(1) = nodes[node_id - 1];
      elem->set_node(2) = nodes[node_id - num_angular_nodes - 1];
      elem->set_node(3) = nodes[node_id - num_angular_nodes];
      elem->subdomain_id() = _quad_subdomain_id;
      node_id++;

      if (layer_num == _nr)
        // add outer boundary (boundary_id = 1)
        boundary_info.add_side(elem, 2, 1);
      if (layer_num == 1)
        // add inner boundary (boundary_id = 0)
        boundary_info.add_side(elem, 0, 0);
      if (!_full_annulus && angle_num == 1)
        // add tmin boundary (boundary_id = 2)
        boundary_info.add_side(elem, 1, 2);
      if (!_full_annulus && angle_num == num_angular_nodes - 1)
        // add tmin boundary (boundary_id = 3)
        boundary_info.add_side(elem, 3, 3);
    }
    if (_full_annulus)
    {
      // add element connecting to node at angle=0
      Elem * elem = mesh.add_elem(new Quad4);
      elem->set_node(0) = nodes[node_id - num_angular_nodes];
      elem->set_node(1) = nodes[node_id - 1];
      elem->set_node(2) = nodes[node_id - num_angular_nodes - 1];
      elem->set_node(3) = nodes[node_id - 2 * num_angular_nodes];
      elem->subdomain_id() = _quad_subdomain_id;

      if (layer_num == _nr)
        // add outer boundary (boundary_id = 1)
        boundary_info.add_side(elem, 2, 1);
      if (layer_num == 1)
        // add inner boundary (boundary_id = 0)
        boundary_info.add_side(elem, 0, 0);
    }
  }

  // add single node at origin, if relevant
  if (_rmin == 0.0)
  {
    nodes[node_id] = mesh.add_point(Point(0.0, 0.0, 0.0), node_id);
    boundary_info.add_node(node_id, 0); // boundary_id=0 is centre
    for (unsigned angle_num = 0; angle_num < num_angular_nodes - 1; ++angle_num)
    {
      Elem * elem = mesh.add_elem(new Tri3);
      elem->set_node(0) = nodes[node_id];
      elem->set_node(1) = nodes[node_id - num_angular_nodes + angle_num];
      elem->set_node(2) = nodes[node_id - num_angular_nodes + angle_num + 1];
      elem->subdomain_id() = _tri_subdomain_id;
    }
    if (_full_annulus)
    {
      Elem * elem = mesh.add_elem(new Tri3);
      elem->set_node(0) = nodes[node_id];
      elem->set_node(1) = nodes[node_id - 1];
      elem->set_node(2) = nodes[node_id - num_angular_nodes];
      elem->subdomain_id() = _tri_subdomain_id;
    }
  }

  boundary_info.sideset_name(0) = "rmin";
  boundary_info.sideset_name(1) = "rmax";
  boundary_info.nodeset_name(0) = "rmin";
  boundary_info.nodeset_name(1) = "rmax";
  if (!_full_annulus)
  {
    boundary_info.sideset_name(2) = "tmin";
    boundary_info.sideset_name(3) = "tmax";
    boundary_info.nodeset_name(2) = "tmin";
    boundary_info.nodeset_name(3) = "tmax";
  }

  mesh.prepare_for_use(false);
}
Esempio n. 24
0
void MeshTools::Subdivision::all_subdivision(MeshBase & mesh)
{
  std::vector<Elem *> new_elements;
  new_elements.reserve(mesh.n_elem());
  const bool mesh_has_boundary_data =
    (mesh.get_boundary_info().n_boundary_ids() > 0);

  std::vector<Elem *> new_boundary_elements;
  std::vector<short int> new_boundary_sides;
  std::vector<boundary_id_type> new_boundary_ids;

  MeshBase::const_element_iterator       el     = mesh.elements_begin();
  const MeshBase::const_element_iterator end_el = mesh.elements_end();
  for (; el != end_el; ++el)
    {
      const Elem * elem = *el;
      libmesh_assert_equal_to(elem->type(), TRI3);

      Elem * tri = new Tri3Subdivision;
      tri->set_id(elem->id());
      tri->subdomain_id() = elem->subdomain_id();
      tri->set_node(0) = (*el)->get_node(0);
      tri->set_node(1) = (*el)->get_node(1);
      tri->set_node(2) = (*el)->get_node(2);

      if (mesh_has_boundary_data)
        {
          for (unsigned short side = 0; side < elem->n_sides(); ++side)
            {
              const boundary_id_type boundary_id =
                mesh.get_boundary_info().boundary_id(elem, side);
              if (boundary_id != BoundaryInfo::invalid_id)
                {
                  // add the boundary id to the list of new boundary ids
                  new_boundary_ids.push_back(boundary_id);
                  new_boundary_elements.push_back(tri);
                  new_boundary_sides.push_back(side);
                }
            }

          // remove the original element from the BoundaryInfo structure
          mesh.get_boundary_info().remove(elem);
        }

      new_elements.push_back(tri);
      mesh.insert_elem(tri);
    }
  mesh.prepare_for_use();

  if (mesh_has_boundary_data)
    {
      // If the old mesh had boundary data, the new mesh better have some too.
      libmesh_assert_greater(new_boundary_elements.size(), 0);

      // We should also be sure that the lengths of the new boundary data vectors
      // are all the same.
      libmesh_assert_equal_to(new_boundary_sides.size(), new_boundary_elements.size());
      libmesh_assert_equal_to(new_boundary_sides.size(), new_boundary_ids.size());

      // Add the new boundary info to the mesh.
      for (unsigned int s = 0; s < new_boundary_elements.size(); ++s)
        mesh.get_boundary_info().add_side(new_boundary_elements[s],
                                          new_boundary_sides[s],
                                          new_boundary_ids[s]);
    }

  mesh.prepare_for_use();
}
Esempio n. 25
0
UniquePtr<Elem> InfPrism6::build_side (const unsigned int i,
                                       bool proxy) const
{
  libmesh_assert_less (i, this->n_sides());

  if (proxy)
    {
      switch (i)
        {
          // base
        case 0:
          return UniquePtr<Elem>(new Side<Tri3,InfPrism6>(this,i));

          // ifem sides
        case 1:
        case 2:
        case 3:
          return UniquePtr<Elem>(new Side<InfQuad4,InfPrism6>(this,i));

        default:
          libmesh_error_msg("Invalid side i = " << i);
        }
    }

  else
    {
      // Create NULL pointer to be initialized, returned later.
      Elem* face = NULL;

      switch (i)
        {
        case 0:  // the triangular face at z=-1, base face
          {
            face = new Tri3;

            // Note that for this face element, the normal points inward
            face->set_node(0) = this->get_node(0);
            face->set_node(1) = this->get_node(1);
            face->set_node(2) = this->get_node(2);

            break;
          }

        case 1:  // the quad face at y=0
          {
            face = new InfQuad4;

            face->set_node(0) = this->get_node(0);
            face->set_node(1) = this->get_node(1);
            face->set_node(2) = this->get_node(3);
            face->set_node(3) = this->get_node(4);

            break;
          }

        case 2:  // the other quad face
          {
            face = new InfQuad4;

            face->set_node(0) = this->get_node(1);
            face->set_node(1) = this->get_node(2);
            face->set_node(2) = this->get_node(4);
            face->set_node(3) = this->get_node(5);

            break;
          }

        case 3: // the quad face at x=0
          {
            face = new InfQuad4;

            face->set_node(0) = this->get_node(2);
            face->set_node(1) = this->get_node(0);
            face->set_node(2) = this->get_node(5);
            face->set_node(3) = this->get_node(3);

            break;
          }

        default:
          libmesh_error_msg("Invalid side i = " << i);
        }

      face->subdomain_id() = this->subdomain_id();
      return UniquePtr<Elem>(face);
    }

  libmesh_error_msg("We'll never get here!");
  return UniquePtr<Elem>();
}
Esempio n. 26
0
void
CombinedCreepPlasticity::computeStress( const Elem & current_elem,
                                        unsigned qp, const SymmElasticityTensor & elasticityTensor,
                                        const SymmTensor & stress_old, SymmTensor & strain_increment,
                                        SymmTensor & stress_new )
{
    // Given the stretching, compute the stress increment and add it to the old stress. Also update the creep strain
    // stress = stressOld + stressIncrement
    // creep_strain = creep_strainOld + creep_strainIncrement

    if(_t_step == 0) return;

    if (_output_iteration_info == true)
    {
        Moose::out
                << std::endl
                << "iteration output for CombinedCreepPlasticity solve:"
                << " time=" <<_t
                << " temperature=" << _temperature[qp]
                << " int_pt=" << qp
                << std::endl;
    }

    // compute trial stress
    stress_new = elasticityTensor * strain_increment;
    stress_new += stress_old;

    const SubdomainID current_block = current_elem.subdomain_id();
    const std::vector<ReturnMappingModel*> & rmm( _submodels[current_block] );
    const unsigned num_submodels = rmm.size();

    SymmTensor inelastic_strain_increment;

    SymmTensor elastic_strain_increment;
    SymmTensor stress_new_last( stress_new );
    Real delS(_absolute_tolerance+1);
    Real first_delS(delS);
    unsigned int counter(0);

    while(counter < _max_its &&
            delS > _absolute_tolerance &&
            (delS/first_delS) > _relative_tolerance &&
            (num_submodels != 1 || counter < 1))
    {
        elastic_strain_increment = strain_increment;
        stress_new = elasticityTensor * (elastic_strain_increment - inelastic_strain_increment);
        stress_new += stress_old;

        for (unsigned i_rmm(0); i_rmm < num_submodels; ++i_rmm)
        {
            rmm[i_rmm]->computeStress( current_elem, qp, elasticityTensor, stress_old, elastic_strain_increment,
                                       stress_new, inelastic_strain_increment );
        }

        // now check convergence
        SymmTensor deltaS(stress_new_last - stress_new);
        delS = std::sqrt(deltaS.doubleContraction(deltaS));
        if (counter == 0)
        {
            first_delS = delS;
        }
        stress_new_last = stress_new;

        if (_output_iteration_info == true)
        {
            Moose::out
                    << "stress_it=" << counter
                    << " rel_delS=" << (0 == first_delS ? 0 : delS/first_delS)
                    << " rel_tol="  << _relative_tolerance
                    << " abs_delS=" << delS
                    << " abs_tol="  << _absolute_tolerance
                    << std::endl;
        }

        ++counter;
    }

    if(counter == _max_its &&
            delS > _absolute_tolerance &&
            (delS/first_delS) > _relative_tolerance)
    {
        mooseError("Max stress iteration hit during CombinedCreepPlasticity solve!");
    }

    strain_increment = elastic_strain_increment;

}
Esempio n. 27
0
UniquePtr<Elem> InfHex8::build_side (const unsigned int i,
                                     bool proxy) const
{
  libmesh_assert_less (i, this->n_sides());

  if (proxy)
    {
      switch (i)
        {
          // base
        case 0:
          return UniquePtr<Elem>(new Side<Quad4,InfHex8>(this,i));

          // ifem sides
        case 1:
        case 2:
        case 3:
        case 4:
          return UniquePtr<Elem>(new Side<InfQuad4,InfHex8>(this,i));

        default:
          libmesh_error_msg("Invalid side i = " << i);
        }
    }

  else
    {
      // Create NULL pointer to be initialized, returned later.
      Elem* face = NULL;

      // Think of a unit cube: (-1,1) x (-1,1) x (1,1)
      switch (i)
        {
        case 0: // the base face
          {
            face = new Quad4;

            // Only here, the face element's normal points inward
            face->set_node(0) = this->get_node(0);
            face->set_node(1) = this->get_node(1);
            face->set_node(2) = this->get_node(2);
            face->set_node(3) = this->get_node(3);

            break;
          }

        case 1:  // connecting to another infinite element
          {
            face = new InfQuad4;

            face->set_node(0) = this->get_node(0);
            face->set_node(1) = this->get_node(1);
            face->set_node(2) = this->get_node(4);
            face->set_node(3) = this->get_node(5);

            break;
          }

        case 2:  // connecting to another infinite element
          {
            face = new InfQuad4;

            face->set_node(0) = this->get_node(1);
            face->set_node(1) = this->get_node(2);
            face->set_node(2) = this->get_node(5);
            face->set_node(3) = this->get_node(6);

            break;
          }

        case 3:  // connecting to another infinite element
          {
            face = new InfQuad4;

            face->set_node(0) = this->get_node(2);
            face->set_node(1) = this->get_node(3);
            face->set_node(2) = this->get_node(6);
            face->set_node(3) = this->get_node(7);

            break;
          }

        case 4:  // connecting to another infinite element
          {
            face = new InfQuad4;

            face->set_node(0) = this->get_node(3);
            face->set_node(1) = this->get_node(0);
            face->set_node(2) = this->get_node(7);
            face->set_node(3) = this->get_node(4);

            break;
          }

        default:
          libmesh_error_msg("Invalid side i = " << i);
        }

      face->subdomain_id() = this->subdomain_id();
      return UniquePtr<Elem>(face);
    }

  libmesh_error_msg("We'll never get here!");
  return UniquePtr<Elem>();
}
Esempio n. 28
0
// The main program
int main(int argc, char** argv)
{
  //for record-keeping
  std::cout << "Running: " << argv[0];
  for (int i=1; i<argc; i++)
    std::cout << " " << argv[i];
  std::cout << std::endl << std::endl;

  clock_t begin = std::clock();
  
  // Initialize libMesh
  LibMeshInit init(argc, argv);
  
  // Parameters
  GetPot solverInfile("fem_system_params.in");
  const bool transient                  = solverInfile("transient", false);
  unsigned int n_timesteps              = solverInfile("n_timesteps", 1);
  const int nx                          = solverInfile("nx",100);
  const int ny                          = solverInfile("ny",100);
  const int nz                          = solverInfile("nz",100);
  GetPot infile("contamTrans.in");
  //std::string find_mesh_here            = infile("initial_mesh","mesh.exo");
  bool doContinuation                   = infile("do_continuation",false);
  bool splitSuperAdj                    = infile("split_super_adjoint",true); //solve as single adjoint or two forwards
  int maxIter                           = infile("max_model_refinements",0);  //maximum number of model refinements
  double refStep                        = infile("refinement_step",0.1); //additional proportion of domain refined per step
    //this refers to additional basis functions...number of elements will be more...
  double qoiErrorTol                    = infile("relative_error_tolerance",0.01); //stopping criterion
  //bool doDivvyMatlab                    = infile("do_divvy_in_Matlab",false); //output files to determine next refinement in Matlab
  bool avoid_sides                      = infile("avoid_sides",false); //DEBUG, whether to avoid sides while refining

  if(refStep*maxIter > 1)
    maxIter = round(ceil(1./refStep));

  Mesh mesh(init.comm());
  Mesh mesh2(init.comm()); 
  
  //create mesh
  unsigned int dim;
  if(nz == 0){ //to check if oscillations happen in 2D as well...
    dim = 2;
    MeshTools::Generation::build_square(mesh, nx, ny, 0., 2300., 0., 1650., QUAD9);
    MeshTools::Generation::build_square(mesh2, nx, ny, 0., 2300., 0., 1650., QUAD9);
  }else{
    dim = 3;
    MeshTools::Generation::build_cube(mesh, nx, ny, nz, 0., 2300., 0., 1650., 0., 100., HEX27);
    MeshTools::Generation::build_cube(mesh2, nx, ny, nz, 0., 2300., 0., 1650., 0., 100., HEX27);
  }
  
  mesh.print_info(); //DEBUG
  
  // Create an equation systems object.
  EquationSystems equation_systems (mesh);
  EquationSystems equation_systems_mix(mesh2);
  
  //name system
  ConvDiff_PrimarySys & system_primary = 
    equation_systems.add_system<ConvDiff_PrimarySys>("ConvDiff_PrimarySys"); //for primary variables
  ConvDiff_AuxSys & system_aux = 
    equation_systems.add_system<ConvDiff_AuxSys>("ConvDiff_AuxSys"); //for auxiliary variables
  ConvDiff_MprimeSys & system_mix = 
    equation_systems_mix.add_system<ConvDiff_MprimeSys>("Diff_ConvDiff_MprimeSys"); //for superadj
  ConvDiff_PrimarySadjSys & system_sadj_primary = 
    equation_systems.add_system<ConvDiff_PrimarySadjSys>("ConvDiff_PrimarySadjSys"); //for split superadj
  ConvDiff_AuxSadjSys & system_sadj_aux = 
    equation_systems.add_system<ConvDiff_AuxSadjSys>("ConvDiff_AuxSadjSys"); //for split superadj
    
  //steady-state problem  
  system_primary.time_solver =
    AutoPtr<TimeSolver>(new SteadySolver(system_primary));
  system_aux.time_solver =
    AutoPtr<TimeSolver>(new SteadySolver(system_aux));
  system_mix.time_solver =
    AutoPtr<TimeSolver>(new SteadySolver(system_mix));
  system_sadj_primary.time_solver =
    AutoPtr<TimeSolver>(new SteadySolver(system_sadj_primary));
  system_sadj_aux.time_solver =
    AutoPtr<TimeSolver>(new SteadySolver(system_sadj_aux));
  libmesh_assert_equal_to (n_timesteps, 1);
  
  // Initialize the system
  equation_systems.init ();
  equation_systems_mix.init();
  
  //initial guess for primary state
  read_initial_parameters();
  system_primary.project_solution(initial_value, initial_grad,
                          equation_systems.parameters);
  finish_initialization();

  //nonlinear solver options
  NewtonSolver *solver_sadj_primary = new NewtonSolver(system_sadj_primary); 
  system_sadj_primary.time_solver->diff_solver() = AutoPtr<DiffSolver>(solver_sadj_primary); 
  solver_sadj_primary->quiet = solverInfile("solver_quiet", true);
  solver_sadj_primary->verbose = !solver_sadj_primary->quiet;
  solver_sadj_primary->max_nonlinear_iterations =
    solverInfile("max_nonlinear_iterations", 15);
  solver_sadj_primary->relative_step_tolerance =
    solverInfile("relative_step_tolerance", 1.e-3);
  solver_sadj_primary->relative_residual_tolerance =
    solverInfile("relative_residual_tolerance", 0.0);
  solver_sadj_primary->absolute_residual_tolerance =
    solverInfile("absolute_residual_tolerance", 0.0);
  NewtonSolver *solver_sadj_aux = new NewtonSolver(system_sadj_aux); 
  system_sadj_aux.time_solver->diff_solver() = AutoPtr<DiffSolver>(solver_sadj_aux); 
  solver_sadj_aux->quiet = solverInfile("solver_quiet", true);
  solver_sadj_aux->verbose = !solver_sadj_aux->quiet;
  solver_sadj_aux->max_nonlinear_iterations =
    solverInfile("max_nonlinear_iterations", 15);
  solver_sadj_aux->relative_step_tolerance =
    solverInfile("relative_step_tolerance", 1.e-3);
  solver_sadj_aux->relative_residual_tolerance =
    solverInfile("relative_residual_tolerance", 0.0);
  solver_sadj_aux->absolute_residual_tolerance =
    solverInfile("absolute_residual_tolerance", 0.0);
  NewtonSolver *solver_primary = new NewtonSolver(system_primary); 
  system_primary.time_solver->diff_solver() = AutoPtr<DiffSolver>(solver_primary); 
  solver_primary->quiet = solverInfile("solver_quiet", true);
  solver_primary->verbose = !solver_primary->quiet;
  solver_primary->max_nonlinear_iterations =
    solverInfile("max_nonlinear_iterations", 15);
  solver_primary->relative_step_tolerance =
    solverInfile("relative_step_tolerance", 1.e-3);
  solver_primary->relative_residual_tolerance =
    solverInfile("relative_residual_tolerance", 0.0);
  solver_primary->absolute_residual_tolerance =
    solverInfile("absolute_residual_tolerance", 0.0);
  NewtonSolver *solver_aux = new NewtonSolver(system_aux); 
  system_aux.time_solver->diff_solver() = AutoPtr<DiffSolver>(solver_aux); 
  solver_aux->quiet = solverInfile("solver_quiet", true);
  solver_aux->verbose = !solver_aux->quiet;
  solver_aux->max_nonlinear_iterations =
    solverInfile("max_nonlinear_iterations", 15);
  solver_aux->relative_step_tolerance =
    solverInfile("relative_step_tolerance", 1.e-3);
  solver_aux->relative_residual_tolerance =
    solverInfile("relative_residual_tolerance", 0.0);
  solver_aux->absolute_residual_tolerance =
    solverInfile("absolute_residual_tolerance", 0.0);
  solver_primary->require_residual_reduction = solverInfile("require_residual_reduction",true);
  solver_sadj_primary->require_residual_reduction = solverInfile("require_residual_reduction",true);
  solver_aux->require_residual_reduction = solverInfile("require_residual_reduction",true);
  solver_sadj_aux->require_residual_reduction = solverInfile("require_residual_reduction",true);  
  
  //linear solver options
  solver_primary->max_linear_iterations       = solverInfile("max_linear_iterations",10000);
  solver_primary->initial_linear_tolerance    = solverInfile("initial_linear_tolerance",1.e-13);
  solver_primary->minimum_linear_tolerance    = solverInfile("minimum_linear_tolerance",1.e-13);
  solver_primary->linear_tolerance_multiplier = solverInfile("linear_tolerance_multiplier",1.e-3);
  solver_aux->max_linear_iterations           = solverInfile("max_linear_iterations",10000);
  solver_aux->initial_linear_tolerance        = solverInfile("initial_linear_tolerance",1.e-13);
  solver_aux->minimum_linear_tolerance        = solverInfile("minimum_linear_tolerance",1.e-13);
  solver_aux->linear_tolerance_multiplier     = solverInfile("linear_tolerance_multiplier",1.e-3);
  solver_sadj_primary->max_linear_iterations       = solverInfile("max_linear_iterations",10000);
  solver_sadj_primary->initial_linear_tolerance    = solverInfile("initial_linear_tolerance",1.e-13);
  solver_sadj_primary->minimum_linear_tolerance    = solverInfile("minimum_linear_tolerance",1.e-13);
  solver_sadj_primary->linear_tolerance_multiplier = solverInfile("linear_tolerance_multiplier",1.e-3);
  solver_sadj_aux->max_linear_iterations           = solverInfile("max_linear_iterations",10000);
  solver_sadj_aux->initial_linear_tolerance        = solverInfile("initial_linear_tolerance",1.e-13);
  solver_sadj_aux->minimum_linear_tolerance        = solverInfile("minimum_linear_tolerance",1.e-13);
  solver_sadj_aux->linear_tolerance_multiplier     = solverInfile("linear_tolerance_multiplier",1.e-3);
  
  /*if(doDivvyMatlab){
    //DOF maps and such to help visualize
    std::ofstream output_global_dof("global_dof_map.dat");
    for(unsigned int i = 0 ; i < system_mix.get_mesh().n_elem(); i++){
      std::vector< dof_id_type > di;
      system_mix.get_dof_map().dof_indices(system_mix.get_mesh().elem(i), di);
      if(output_global_dof.is_open()){
        output_global_dof << i << " ";
        for(unsigned int j = 0; j < di.size(); j++)
          output_global_dof << di[j] << " ";
        output_global_dof << "\n";
      }
    }
    output_global_dof.close();
    std::ofstream output_elem_cent("elem_centroids.dat");
    for(unsigned int i = 0 ; i < system_mix.get_mesh().n_elem(); i++){
      Point elem_cent = system_mix.get_mesh().elem(i)->centroid();
      if(output_elem_cent.is_open()){
        output_elem_cent << elem_cent(0) << " " << elem_cent(1) << "\n";
      }
    }
    output_elem_cent.close();
  }*/
  
  //inverse dof map (elements in support of each node, assuming every 6 dofs belong to same node)
  std::vector<std::set<dof_id_type> > node_to_elem; 
  node_to_elem.resize(round(system_mix.n_dofs()/6.));
  for(unsigned int i = 0 ; i < system_mix.get_mesh().n_elem(); i++){
    std::vector< dof_id_type > di;
    system_mix.get_dof_map().dof_indices(system_mix.get_mesh().elem(i), di);
    for(unsigned int j = 0; j < di.size(); j++)
      node_to_elem[round(floor(di[j]/6.))].insert(i);
  }

  int refIter = 0;
  double relError = 2.*qoiErrorTol;
  while(refIter <= maxIter && relError > qoiErrorTol){
    if(!doContinuation){ //clear out previous solutions
      system_primary.solution->zero();
      system_aux.solution->zero();
      system_sadj_primary.solution->zero();
      system_sadj_aux.solution->zero();
    }
    system_mix.solution->zero();
    
    clock_t begin_inv = std::clock();
    system_primary.solve();
    system_primary.clearQoI();
    clock_t end_inv = std::clock();
    clock_t begin_err_est = std::clock();
    std::cout << "\n End primary solve, begin auxiliary solve..." << std::endl;
    system_aux.solve();
    std::cout << "\n End auxiliary solve..." << std::endl;
    clock_t end_aux = std::clock();
    
    system_primary.postprocess();
    system_aux.postprocess();
    
    system_sadj_primary.set_c_vals(system_primary.get_c_vals());
    system_sadj_aux.set_auxc_vals(system_aux.get_auxc_vals());

    equation_systems_mix.reinit();
    //combine primary and auxiliary variables into psi
    DirectSolutionTransfer sol_transfer(init.comm()); 
    sol_transfer.transfer(system_aux.variable(system_aux.variable_number("aux_c")),
      system_mix.variable(system_mix.variable_number("aux_c")));
    sol_transfer.transfer(system_aux.variable(system_aux.variable_number("aux_zc")),
      system_mix.variable(system_mix.variable_number("aux_zc")));
    sol_transfer.transfer(system_aux.variable(system_aux.variable_number("aux_fc")),
      system_mix.variable(system_mix.variable_number("aux_fc")));
    AutoPtr<NumericVector<Number> > just_aux = system_mix.solution->clone();
    sol_transfer.transfer(system_primary.variable(system_primary.variable_number("c")),
      system_mix.variable(system_mix.variable_number("c")));
    sol_transfer.transfer(system_primary.variable(system_primary.variable_number("zc")),
      system_mix.variable(system_mix.variable_number("zc")));
    sol_transfer.transfer(system_primary.variable(system_primary.variable_number("fc")),
      system_mix.variable(system_mix.variable_number("fc")));

    if(!splitSuperAdj){ //solve super-adjoint as single adjoint
      system_mix.assemble_qoi_sides = true; //QoI doesn't involve sides
      
      std::cout << "\n~*~*~*~*~*~*~*~*~ adjoint solve start ~*~*~*~*~*~*~*~*~\n" << std::endl;
      std::pair<unsigned int, Real> adjsolve = system_mix.adjoint_solve();
      std::cout << "number of iterations to solve adjoint: " << adjsolve.first << std::endl;
      std::cout << "final residual of adjoint solve: " << adjsolve.second << std::endl;
      std::cout << "\n~*~*~*~*~*~*~*~*~ adjoint solve end ~*~*~*~*~*~*~*~*~" << std::endl;
  
      NumericVector<Number> &dual_sol = system_mix.get_adjoint_solution(0); //DEBUG
      
      system_mix.assemble(); //calculate residual to correspond to solution
      
      //std::cout << "\n sadj norm: " << system_mix.calculate_norm(dual_sol, L2) << std::endl; //DEBUG
      //std::cout << system_mix.calculate_norm(dual_sol, 0, L2) << std::endl; //DEBUG
      //std::cout << system_mix.calculate_norm(dual_sol, 1, L2) << std::endl; //DEBUG
      //std::cout << system_mix.calculate_norm(dual_sol, 2, L2) << std::endl; //DEBUG
      //std::cout << system_mix.calculate_norm(dual_sol, 3, L2) << std::endl; //DEBUG
      //std::cout << system_mix.calculate_norm(dual_sol, 4, L2) << std::endl; //DEBUG
      //std::cout << system_mix.calculate_norm(dual_sol, 5, L2) << std::endl; //DEBUG
    }else{ //solve super-adjoint as
      system_mix.assemble(); //calculate residual to correspond to solution
      std::cout << "\n Begin primary super-adjoint solve...\n" << std::endl;
      system_sadj_primary.solve();
      std::cout << "\n End primary super-adjoint solve, begin auxiliary super-adjoint solve...\n" << std::endl;
      system_sadj_aux.solve();
      std::cout << "\n End auxiliary super-adjoint solve...\n" << std::endl;
      const std::string & adjoint_solution0_name = "adjoint_solution0";
      system_mix.add_vector(adjoint_solution0_name, false, GHOSTED);
      system_mix.set_vector_as_adjoint(adjoint_solution0_name,0);
      NumericVector<Number> &eep = system_mix.add_adjoint_rhs(0);
      system_mix.set_adjoint_already_solved(true);
      NumericVector<Number> &dual_sol = system_mix.get_adjoint_solution(0);
      NumericVector<Number> &primal_sol = *system_mix.solution;
      dual_sol.swap(primal_sol);
      sol_transfer.transfer(system_sadj_aux.variable(system_sadj_aux.variable_number("sadj_aux_c")),
        system_mix.variable(system_mix.variable_number("aux_c")));
      sol_transfer.transfer(system_sadj_aux.variable(system_sadj_aux.variable_number("sadj_aux_zc")),
        system_mix.variable(system_mix.variable_number("aux_zc")));
      sol_transfer.transfer(system_sadj_aux.variable(system_sadj_aux.variable_number("sadj_aux_fc")),
        system_mix.variable(system_mix.variable_number("aux_fc")));
      sol_transfer.transfer(system_sadj_primary.variable(system_sadj_primary.variable_number("sadj_c")),
        system_mix.variable(system_mix.variable_number("c")));
      sol_transfer.transfer(system_sadj_primary.variable(system_sadj_primary.variable_number("sadj_zc")),
        system_mix.variable(system_mix.variable_number("zc")));
      sol_transfer.transfer(system_sadj_primary.variable(system_sadj_primary.variable_number("sadj_fc")),
        system_mix.variable(system_mix.variable_number("fc")));
      //std::cout << "\n sadj norm: " << system_mix.calculate_norm(primal_sol, L2) << std::endl; //DEBUG
      dual_sol.swap(primal_sol);
      //std::cout << "\n sadj norm: " << system_mix.calculate_norm(primal_sol, L2) << std::endl; //DEBUG
      //std::cout << system_sadj_primary.calculate_norm(*system_sadj_primary.solution, 0, L2) << std::endl; //DEBUG
      //std::cout << system_sadj_primary.calculate_norm(*system_sadj_primary.solution, 1, L2) << std::endl; //DEBUG
      //std::cout << system_sadj_primary.calculate_norm(*system_sadj_primary.solution, 2, L2) << std::endl; //DEBUG
      //std::cout << system_sadj_aux.calculate_norm(*system_sadj_aux.solution, 0, L2) << std::endl; //DEBUG
      //std::cout << system_sadj_aux.calculate_norm(*system_sadj_aux.solution, 1, L2) << std::endl; //DEBUG
      //std::cout << system_sadj_aux.calculate_norm(*system_sadj_aux.solution, 2, L2) << std::endl; //DEBUG
    }
    NumericVector<Number> &dual_solution = system_mix.get_adjoint_solution(0);
/*  
    NumericVector<Number> &primal_solution = *system_mix.solution; //DEBUG
    primal_solution.swap(dual_solution); //DEBUG
    ExodusII_IO(mesh).write_timestep("super_adjoint.exo",
                                   equation_systems,
                                   1, /  his number indicates how many time steps are being written to the file
                                   system_mix.time); //DEBUG
    primal_solution.swap(dual_solution); //DEBUG
*/
    //adjoint-weighted residual
    AutoPtr<NumericVector<Number> > adjresid = system_mix.solution->zero_clone();
    adjresid->pointwise_mult(*system_mix.rhs,dual_solution); 
    adjresid->scale(-0.5);
    std::cout << "\n -0.5*M'_HF(psiLF)(superadj): " << adjresid->sum() << std::endl; //DEBUG
    
    //LprimeHF(psiLF)
    AutoPtr<NumericVector<Number> > LprimeHF_psiLF = system_mix.solution->zero_clone();
    LprimeHF_psiLF->pointwise_mult(*system_mix.rhs,*just_aux);
    std::cout << " L'_HF(psiLF): " << LprimeHF_psiLF->sum() << std::endl; //DEBUG
    
    //QoI and error estimate
    std::cout << "QoI: " << std::setprecision(17) << system_primary.getQoI() << std::endl;
    std::cout << "QoI Error estimate: " << std::setprecision(17) 
        << adjresid->sum()+LprimeHF_psiLF->sum() << std::endl; 
        
    relError = fabs((adjresid->sum()+LprimeHF_psiLF->sum())/system_primary.getQoI());
    
    //print out information
    std::cout << "Estimated absolute relative qoi error: " << relError << std::endl << std::endl;
    std::cout << "Estimated HF QoI: " << std::setprecision(17) << system_primary.getQoI()+adjresid->sum()+LprimeHF_psiLF->sum() << std::endl;
    clock_t end = clock();
    std::cout << "Time so far: " << double(end-begin)/CLOCKS_PER_SEC << " seconds..." << std::endl;
    std::cout << "Time for inverse problem: " << double(end_inv-begin_inv)/CLOCKS_PER_SEC << " seconds..." << std::endl;
    std::cout << "Time for extra error estimate bits: " << double(end-begin_err_est)/CLOCKS_PER_SEC << " seconds..." << std::endl;
    std::cout << "    Time to get auxiliary problems: " << double(end_aux-begin_err_est)/CLOCKS_PER_SEC << " seconds..." << std::endl;
    std::cout << "    Time to get superadjoint: " << double(end-end_aux)/CLOCKS_PER_SEC << " seconds...\n" << std::endl;
    
    //proportion of domain refined at this iteration
    MeshBase::element_iterator       elem_it  = mesh.elements_begin();
    const MeshBase::element_iterator elem_end = mesh.elements_end();
    double numMarked = 0.;
    for (; elem_it != elem_end; ++elem_it){
      Elem* elem = *elem_it;
      numMarked += elem->subdomain_id();
    }
    std::cout << "Refinement fraction: " << numMarked/system_mix.get_mesh().n_elem() << std::endl << std::endl;

    
    //output at each iteration
    std::stringstream ss;
    ss << refIter;
    std::string str = ss.str();
    std::string write_error_basis_blame = 
      (infile("error_est_output_file_basis_blame", "error_est_breakdown_basis_blame")) + str + ".dat";
    std::ofstream output2(write_error_basis_blame);
    for(unsigned int i = 0 ; i < adjresid->size(); i++){
      if(output2.is_open())
        output2 << (*adjresid)(i) + (*LprimeHF_psiLF)(i) << "\n";
    }
    output2.close();
    
    if(refIter < maxIter && relError > qoiErrorTol){ //if further refinement needed
    
      //collapse error contributions into nodes
      std::vector<std::pair<Number,dof_id_type> > node_errs(round(system_mix.n_dofs()/6.));
      for(unsigned int node_num = 0; node_num < node_errs.size(); node_num++){
        node_errs[node_num] = std::pair<Number,dof_id_type>
                             (fabs((*adjresid)(6*node_num) + (*LprimeHF_psiLF)(6*node_num)
                            + (*adjresid)(6*node_num+1) + (*LprimeHF_psiLF)(6*node_num+1)
                            + (*adjresid)(6*node_num+2) + (*LprimeHF_psiLF)(6*node_num+2)
                            + (*adjresid)(6*node_num+3) + (*LprimeHF_psiLF)(6*node_num+3)
                            + (*adjresid)(6*node_num+4) + (*LprimeHF_psiLF)(6*node_num+4)
                            + (*adjresid)(6*node_num+5) + (*LprimeHF_psiLF)(6*node_num+5)), node_num);
      }
  
      //find nodes contributing the most
      //double refPcnt = std::min((refIter+1)*refStep,1.);
      double refPcnt = std::min(refStep,1.); //additional refinement (compared to previous iteration)
      int cutoffLoc = round(node_errs.size()*refPcnt);
      std::sort(node_errs.begin(), node_errs.end()); 
      std::reverse(node_errs.begin(), node_errs.end()); 
      
      //find elements in support of worst offenders
      std::vector<dof_id_type> markMe;
      markMe.reserve(cutoffLoc*8);
      for(int i = 0; i < cutoffLoc; i++){
        markMe.insert(markMe.end(), node_to_elem[node_errs[i].second].begin(), node_to_elem[node_errs[i].second].end());
      }
  
      //mark those elements for refinement.
      for(int i = 0; i < markMe.size(); i++){
        if(!avoid_sides || (avoid_sides && !mesh.elem(markMe[i])->on_boundary()))
          mesh.elem(markMe[i])->subdomain_id() = 1; //assuming HF regions marked with 1
      }
  
      //to test whether assignment matches matlab's
      /*std::string stash_assign = "divvy_c_poke.txt";
      std::ofstream output_dbg(stash_assign.c_str());
      MeshBase::element_iterator       elem_it  = mesh.elements_begin();
      const MeshBase::element_iterator elem_end = mesh.elements_end();
      for (; elem_it != elem_end; ++elem_it){
        Elem* elem = *elem_it;
            
        if(output_dbg.is_open()){
          output_dbg << elem->id() << " " << elem->subdomain_id() << "\n";
        }
      }
      output_dbg.close();*/
      
#ifdef LIBMESH_HAVE_EXODUS_API
    std::stringstream ss2;
    ss2 << refIter + 1;
    std::string str = ss2.str();
    std::string write_divvy = "divvy" + str + ".exo";
    ExodusII_IO (mesh).write_equation_systems(write_divvy,equation_systems); //DEBUG
#endif // #ifdef LIBMESH_HAVE_EXODUS_API
    }
    refIter += 1;
  }
  
  std::string stash_assign = "divvy_final.txt";
  std::ofstream output_dbg(stash_assign.c_str());
  MeshBase::element_iterator       elem_it  = mesh.elements_begin();
  const MeshBase::element_iterator elem_end = mesh.elements_end();
  double numMarked = 0.;
  for (; elem_it != elem_end; ++elem_it){
    Elem* elem = *elem_it;
    numMarked += elem->subdomain_id();
    if(output_dbg.is_open()){
      output_dbg << elem->id() << " " << elem->subdomain_id() << "\n";
    }
  }
  output_dbg.close();
  
  std::cout << "\nRefinement concluded..." << std::endl;
  std::cout << "Final refinement fraction: " << numMarked/system_mix.get_mesh().n_elem() << std::endl;
  std::cout << "Final estimated relative error: " << relError << std::endl;
  
  return 0; //done

} //end main
Esempio n. 29
0
int main (int argc, char** argv){

	LibMeshInit init (argc, argv); //initialize libmesh library

	std::cout << "Running " << argv[0];
	for (int i=1; i<argc; i++)
		std::cout << " " << argv[i];
	std::cout << std::endl << std::endl;

	Mesh mesh(init.comm());
	
	//T-channel
	//mesh.read("mesh.e");
	//MeshRefinement meshRefinement(mesh);
	//meshRefinement.uniformly_refine(0);
	
	//1D - for debugging
	//int n = 20;
	//MeshTools::Generation::build_line(mesh, n, 0.0, 1.0, EDGE2); //n linear elements from 0 to 1
	
	//nice geometry (straight channel) 
	MeshTools::Generation::build_square (mesh, 
																					250, 50,
                                         -0.0, 5.0,
                                         -0.0, 1.0,
                                         QUAD9);

	//read in subdomain assignments
	
	std::vector<double> prev_assign(mesh.n_elem(), 0.);
	std::string read_assign = "do_divvy.txt";
	if(FILE *fp=fopen(read_assign.c_str(),"r")){
		int flag = 1;
		int elemNum, assign;
		int ind = 0;
		while(flag != -1){
			flag = fscanf(fp, "%d %d",&elemNum,&assign);
			if(flag != -1){
				prev_assign[ind] = assign;
				ind += 1;
			}
		}
		fclose(fp);
	}
	

	//to stash subdomain assignments
	std::string stash_assign = "divvy.txt";
	std::ofstream output(stash_assign.c_str());

	MeshBase::element_iterator       elem_it  = mesh.elements_begin();
  const MeshBase::element_iterator elem_end = mesh.elements_end();
  for (; elem_it != elem_end; ++elem_it){
    Elem* elem = *elem_it;
    Point c = elem->centroid();
    //Point cshift1(c(0)-0.63, c(1)-0.5);

    elem->subdomain_id() = prev_assign[elem->id()];
    //TEST/DEBUG
    //if(fabs(c(0)-3.0) < 0.35 && fabs(c(1)-0.5) < 0.35)
    //  elem->subdomain_id() = 1;
    		
    if(output.is_open()){
    	output << elem->id() << " " << elem->subdomain_id() << "\n";
    }
  }
  output.close();


	EquationSystems equation_systems (mesh);

	#ifdef LIBMESH_HAVE_EXODUS_API
    ExodusII_IO (mesh).write_equation_systems("meep.exo",equation_systems);
  #endif // #ifdef LIBMESH_HAVE_EXODUS_API

	return 0;
} // end main
Esempio n. 30
0
void UnstructuredMesh::copy_nodes_and_elements(const UnstructuredMesh & other_mesh,
                                               const bool skip_find_neighbors)
{
  // We're assuming our subclass data needs no copy
  libmesh_assert_equal_to (_n_parts, other_mesh._n_parts);
  libmesh_assert (std::equal(_elem_dims.begin(), _elem_dims.end(), other_mesh._elem_dims.begin()));
  libmesh_assert_equal_to (_is_prepared, other_mesh._is_prepared);

  // We're assuming the other mesh has proper element number ordering,
  // so that we add parents before their children.
#ifdef DEBUG
  MeshTools::libmesh_assert_valid_amr_elem_ids(other_mesh);
#endif

  //Copy in Nodes
  {
    //Preallocate Memory if necessary
    this->reserve_nodes(other_mesh.n_nodes());

    const_node_iterator it = other_mesh.nodes_begin();
    const_node_iterator end = other_mesh.nodes_end();

    for (; it != end; ++it)
      {
        const Node * oldn = *it;

        // Add new nodes in old node Point locations
#ifdef LIBMESH_ENABLE_UNIQUE_ID
        Node *newn =
#endif
          this->add_point(*oldn, oldn->id(), oldn->processor_id());

#ifdef LIBMESH_ENABLE_UNIQUE_ID
        newn->set_unique_id() = oldn->unique_id();
#endif
      }
  }

  //Copy in Elements
  {
    //Preallocate Memory if necessary
    this->reserve_elem(other_mesh.n_elem());

    // Declare a map linking old and new elements, needed to copy the neighbor lists
    std::map<const Elem *, Elem *> old_elems_to_new_elems;

    // Loop over the elements
    MeshBase::const_element_iterator it = other_mesh.elements_begin();
    const MeshBase::const_element_iterator end = other_mesh.elements_end();

    // FIXME: Where do we set element IDs??
    for (; it != end; ++it)
      {
        //Look at the old element
        const Elem * old = *it;
        //Build a new element
        Elem * newparent = old->parent() ?
          this->elem_ptr(old->parent()->id()) : libmesh_nullptr;
        UniquePtr<Elem> ap = Elem::build(old->type(), newparent);
        Elem * el = ap.release();

        el->subdomain_id() = old->subdomain_id();

        for (unsigned int s=0; s != old->n_sides(); ++s)
          if (old->neighbor_ptr(s) == remote_elem)
            el->set_neighbor(s, const_cast<RemoteElem *>(remote_elem));

#ifdef LIBMESH_ENABLE_AMR
        if (old->has_children())
          for (unsigned int c=0; c != old->n_children(); ++c)
            if (old->child_ptr(c) == remote_elem)
              el->add_child(const_cast<RemoteElem *>(remote_elem), c);

        //Create the parent's child pointers if necessary
        if (newparent)
          {
            unsigned int oldc = old->parent()->which_child_am_i(old);
            newparent->add_child(el, oldc);
          }

        // Copy the refinement flags
        el->set_refinement_flag(old->refinement_flag());

        // Use hack_p_level since we may not have sibling elements
        // added yet
        el->hack_p_level(old->p_level());

        el->set_p_refinement_flag(old->p_refinement_flag());
#endif // #ifdef LIBMESH_ENABLE_AMR

        //Assign all the nodes
        for(unsigned int i=0;i<el->n_nodes();i++)
          el->set_node(i) = this->node_ptr(old->node_id(i));

        // And start it off in the same subdomain
        el->processor_id() = old->processor_id();

        // Give it the same ids
        el->set_id(old->id());

#ifdef LIBMESH_ENABLE_UNIQUE_ID
        el->set_unique_id() = old->unique_id();
#endif

        //Hold onto it
        if(!skip_find_neighbors)
          {
            this->add_elem(el);
          }
        else
          {
            Elem * new_el = this->add_elem(el);
            old_elems_to_new_elems[old] = new_el;
          }

        // Add the link between the original element and this copy to the map
        if(skip_find_neighbors)
          old_elems_to_new_elems[old] = el;
      }

    // Loop (again) over the elements to fill in the neighbors
    if(skip_find_neighbors)
      {
        it = other_mesh.elements_begin();
        for (; it != end; ++it)
          {
            Elem * old_elem = *it;
            Elem * new_elem = old_elems_to_new_elems[old_elem];
            for (unsigned int s=0; s != old_elem->n_neighbors(); ++s)
              {
                const Elem * old_neighbor = old_elem->neighbor_ptr(s);
                Elem * new_neighbor = old_elems_to_new_elems[old_neighbor];
                new_elem->set_neighbor(s, new_neighbor);
              }
          }
      }
  }

  //Finally prepare the new Mesh for use.  Keep the same numbering and
  //partitioning but also the same renumbering and partitioning
  //policies as our source mesh.
  this->allow_renumbering(false);
  this->skip_partitioning(true);
  this->prepare_for_use(false, skip_find_neighbors);
  this->allow_renumbering(other_mesh.allow_renumbering());
  this->skip_partitioning(other_mesh.skip_partitioning());
}