Exemplo n.º 1
0
// ------------------------------------------------------------
// DivaIO class members
void DivaIO::write (const std::string & fname)
{
  // We may need to gather a ParallelMesh to output it, making that
  // const qualifier in our constructor a dirty lie
  MeshSerializer serialize(const_cast<MeshBase &>(this->mesh()), !_is_parallel_format);

  // Open the output file stream
  std::ofstream out_file(fname.c_str());

  // Make sure it opened correctly
  if (!out_file.good())
    libmesh_file_error(fname.c_str());

  this->write_stream (out_file);
}
Exemplo n.º 2
0
void XdrMGF::init (XdrMGF::XdrIO_TYPE t, const char* fn, const char*, int)
{
  m_type=t;

  // Close old file if necessary
  if (mp_fp) this->fini();


  // Open file
  switch (m_type)
    {

#ifdef LIBMESH_HAVE_XDR

    case (XdrMGF::ENCODE):
    case (XdrMGF::DECODE):
      {
        mp_fp = fopen (fn, (m_type == ENCODE) ? "w" : "r");

        // Make sure the file is ready for use
        if (!mp_fp)
          libmesh_error_msg("XDR Error: Accessing file: " << fn << " failed.");

        // Create the XDR handle
        mp_xdr_handle = new XDR;
        xdrstdio_create(mp_xdr_handle,
                        mp_fp,
                        ((m_type == ENCODE) ? XDR_ENCODE : XDR_DECODE));

        break;
      }

#endif

    case (XdrMGF::R_ASCII):
      {
        mp_in.open(fn, std::ios::in);

        // Make sure it opened correctly
        if (!mp_in.good())
          libmesh_file_error(fn);

        break;
      }

    case (XdrMGF::W_ASCII):
      {
        mp_out.open(fn, std::ios::out);

        // Make sure it opened correctly
        if (!mp_out.good())
          libmesh_file_error(fn);

        break;
      }

    default:
      libmesh_error_msg("Unrecognized file access type!");
    }





  // Read/Write the file signature
  const int  bufLen = 12;
  char       buf[bufLen+1];

  switch (m_type)
    {

#ifdef LIBMESH_HAVE_XDR

    case (XdrMGF::ENCODE):
      {
        char* p = &buf[0];
        const LegacyXdrIO::FileFormat orig = this->get_orig_flag();

        std::ostringstream name;
        if (orig == LegacyXdrIO::DEAL)
          name << "DEAL 003:003";

        else if (orig == LegacyXdrIO::MGF)
          name << "MGF  002:000";

        else if (orig == LegacyXdrIO::LIBM)
          name << "LIBM " << this->get_num_levels();

        else
          libmesh_error_msg("Unknown orig " << orig);

        // Fill the buffer
        std::sprintf(&buf[0], "%s", name.str().c_str());

        xdr_string(mp_xdr_handle, &p, bufLen);  // Writes binary signature

        break;
      }

    case (XdrMGF::DECODE):
      {
        char* p = &buf[0];
        xdr_string(mp_xdr_handle, &p, bufLen); // Reads binary signature

        // Set the number of levels used in the mesh
        this->tokenize_first_line(p);

        break;
      }

#endif

    case (XdrMGF::W_ASCII):
      {
        const LegacyXdrIO::FileFormat orig = this->get_orig_flag();

        if (orig == LegacyXdrIO::DEAL)
          std::sprintf(&buf[0], "%s %03d:%03d", "DEAL", 3, 3);

        else if (orig == LegacyXdrIO::MGF)
          std::sprintf(&buf[0], "%s %03d:%03d", "MGF ", 2, 0);

        else if (orig == LegacyXdrIO::LIBM)
          std::sprintf(&buf[0], "%s %d", "LIBM", this->get_num_levels());

        mp_out << buf << '\n';

        break;
      }

    case (XdrMGF::R_ASCII):
      {

#ifdef __HP_aCC
        // weirdly, _only_ here aCC
        // is not fond of mp_in.getline()
        // however, using mp_in.getline()
        // further below is ok...
        std::string buf_buf;
        std::getline (mp_in, buf_buf, '\n');
        libmesh_assert_less_equal (buf_buf.size(), bufLen);

        buf_buf.copy (buf, std::string::npos);
#else

        // Here we first use getline() to grab the very
        // first line of the file into a char buffer.  Then
        // this line is tokenized to look for:
        // 1.) The name LIBM, which specifies the new Mesh style.
        // 2.) The number of levels in the Mesh which is being read.
        // Note that "buf" will be further processed below, here we
        // are just attempting to get the number of levels.
        mp_in.getline(buf, bufLen+1);

#endif

        // Determine the number of levels in this mesh
        this->tokenize_first_line(buf);

        break;
      }

    default:
      libmesh_error_msg("Unknown m_type" << m_type);
    }



  // If you are reading or decoding, process the signature
  if ((m_type == R_ASCII) || (m_type == DECODE))
    {
      char name[5];
      std::strncpy(name, &buf[0], 4);
      name[4] = '\0';

      if (std::strcmp (name, "DEAL") == 0)
        {
          this->orig_flag = LegacyXdrIO::DEAL; // 0 is the DEAL identifier by definition
        }
      else if (std::strcmp (name, "MGF ") == 0)
        {
          this->orig_flag = LegacyXdrIO::MGF; // 1 is the MGF identifier by definition
        }
      else if (std::strcmp (name, "LIBM") == 0)
        {
          this->orig_flag = LegacyXdrIO::LIBM; // the New and Improved XDA
        }

      else
        libmesh_error_msg("ERROR: No originating software can be determined for header string '" << name);
    }

}
Exemplo n.º 3
0
void PostscriptIO::write (const std::string& fname)
{
  // We may need to gather a ParallelMesh to output it, making that
  // const qualifier in our constructor a dirty lie
  MeshSerializer serialize(const_cast<MeshBase&>(this->mesh()), !_is_parallel_format);

  if (this->mesh().processor_id() == 0)
    {
      // Get a constant reference to the mesh.
      const MeshBase& the_mesh = MeshOutput<MeshBase>::mesh();

      // Only works in 2D
      libmesh_assert_equal_to (the_mesh.mesh_dimension(), 2);

      // Create output file stream.
      // _out is now a private member of the class.
      _out.open(fname.c_str());

      // Make sure it opened correctly
      if (!_out.good())
        libmesh_file_error(fname.c_str());

      // The mesh bounding box gives us info about what the
      // Postscript bounding box should be.
      MeshTools::BoundingBox bbox = MeshTools::bounding_box(the_mesh);

      // Add a little extra padding to the "true" bounding box so
      // that we can still see the boundary
      const Real percent_padding = 0.01;
      const Real dx=bbox.second(0)-bbox.first(0); libmesh_assert_greater (dx, 0.0);
      const Real dy=bbox.second(1)-bbox.first(1); libmesh_assert_greater (dy, 0.0);

      const Real x_min = bbox.first(0)  - percent_padding*dx;
      const Real y_min = bbox.first(1)  - percent_padding*dy;
      const Real x_max = bbox.second(0) + percent_padding*dx;
      const Real y_max = bbox.second(1) + percent_padding*dy;

      // Width of the output as given in postscript units.
      // This usually is given by the strange unit 1/72 inch.
      // A width of 300 represents a size of roughly 10 cm.
      const Real width = 300;
      _scale = width / (x_max-x_min);
      _offset(0) = x_min;
      _offset(1) = y_min;

      // Header writing stuff stolen from Deal.II
      std::time_t  time1= std::time (0);
      std::tm     *time = std::localtime(&time1);
      _out << "%!PS-Adobe-2.0 EPSF-1.2" << '\n'
	//<< "%!PS-Adobe-1.0" << '\n' // Lars' PS version
	  << "%%Filename: " << fname << '\n'
	  << "%%Title: LibMesh Output" << '\n'
	  << "%%Creator: LibMesh: A C++ finite element library" << '\n'
	  << "%%Creation Date: "
	  << time->tm_year+1900 << "/"
	  << time->tm_mon+1 << "/"
	  << time->tm_mday << " - "
	  << time->tm_hour << ":"
	  << std::setw(2) << time->tm_min << ":"
	  << std::setw(2) << time->tm_sec << '\n'
	  << "%%BoundingBox: "
	// lower left corner
	  << "0 0 "
	// upper right corner
	  << static_cast<unsigned int>( rint((x_max-x_min) * _scale ))
	  << ' '
	  << static_cast<unsigned int>( rint((y_max-y_min) * _scale ))
	  << '\n';

      // define some abbreviations to keep
      // the output small:
      // m=move turtle to
      // l=define a line
      // s=set rgb color
      // sg=set gray value
      // lx=close the line and plot the line
      // lf=close the line and fill the interior
      _out << "/m {moveto} bind def"      << '\n'
	  << "/l {lineto} bind def"      << '\n'
	  << "/s {setrgbcolor} bind def" << '\n'
	  << "/sg {setgray} bind def"    << '\n'
	  << "/cs {curveto stroke} bind def" << '\n'
	  << "/lx {lineto closepath stroke} bind def" << '\n'
	  << "/lf {lineto closepath fill} bind def"   << '\n';

      _out << "%%EndProlog" << '\n';
      //	  << '\n';

      // Set line width in the postscript file.
      _out << line_width << " setlinewidth" << '\n';

      // Set line cap and join options
      _out << "1 setlinecap" << '\n';
      _out << "1 setlinejoin" << '\n';

      // allow only five digits for output (instead of the default
      // six); this should suffice even for fine grids, but reduces
      // the file size significantly
      _out << std::setprecision (5);

      // Loop over the active elements, draw lines for the edges.  We
      // draw even quadratic elements with straight sides, i.e. a straight
      // line sits between each pair of vertices.  Also we draw every edge
      // for an element regardless of the fact that it may overlap with
      // another.  This would probably be a useful optimization...
      MeshBase::const_element_iterator       el     = the_mesh.active_elements_begin();
      const MeshBase::const_element_iterator end_el = the_mesh.active_elements_end();
      for ( ; el != end_el; ++el)
	{
	  //const Elem* elem = *el;

	  this->plot_linear_elem(*el);
	  //this->plot_quadratic_elem(*el); // Experimental
	}

      // Issue the showpage command, and we're done.
      _out << "showpage" << std::endl;

    } // end if (this->mesh().processor_id() == 0)
}
Exemplo n.º 4
0
void GnuPlotIO::write_solution(const std::string& fname,
   			       const std::vector<Number>* soln,
			       const std::vector<std::string>* names)
{
  // Even when writing on a serialized ParallelMesh, we expect
  // non-proc-0 help with calls like n_active_elem
  // libmesh_assert_equal_to (this->mesh().processor_id(), 0);

  const MeshBase& the_mesh = MeshOutput<MeshBase>::mesh();

  dof_id_type n_active_elem = the_mesh.n_active_elem();

  if (this->mesh().processor_id() == 0)
  {
  std::stringstream data_stream_name;
  data_stream_name << fname << "_data";
  const std::string data_file_name = data_stream_name.str();

  // This class is designed only for use with 1D meshes
  libmesh_assert_equal_to (the_mesh.mesh_dimension(), 1);

  // Make sure we have a solution to plot
  libmesh_assert ((names != NULL) && (soln != NULL));

  // Create an output stream for script file
  std::ofstream out_stream(fname.c_str());

  // Make sure it opened correctly
  if (!out_stream.good())
    libmesh_file_error(fname.c_str());

  // The number of variables in the equation system
  const unsigned int n_vars =
    libmesh_cast_int<unsigned int>(names->size());

  // Write header to stream
  out_stream << "# This file was generated by gnuplot_io.C\n"
      << "# Stores 1D solution data in GNUplot format\n"
      << "# Execute this by loading gnuplot and typing "
      << "\"call '" << fname << "'\"\n"
      << "reset\n"
      << "set title \"" << _title << "\"\n"
      << "set xlabel \"x\"\n"
      << "set xtics nomirror\n";

  // Loop over the elements to find the minimum and maximum x values,
  // and also to find the element boundaries to write out as xtics
  // if requested.
  Real x_min=0., x_max=0.;

  // construct string for xtic positions at element edges
  std::stringstream xtics_stream;

  MeshBase::const_element_iterator it = the_mesh.active_elements_begin();
  const MeshBase::const_element_iterator end_it =
    the_mesh.active_elements_end();

  unsigned int count = 0;

  for( ; it != end_it; ++it)
  {
    const Elem* el = *it;

    // if el is the left edge of the mesh, print its left node position
    if(el->neighbor(0) == NULL)
    {
      x_min = (*(el->get_node(0)))(0);
      xtics_stream << "\"\" " << x_min << ", \\\n";
    }
    if(el->neighbor(1) == NULL)
    {
      x_max = (*(el->get_node(1)))(0);
    }
    xtics_stream << "\"\" " << (*(el->get_node(1)))(0);

    if(count+1 != n_active_elem)
    {
        xtics_stream << ", \\\n";
    }
    count++;
  }

  out_stream << "set xrange [" << x_min << ":" << x_max << "]\n";

  if(_grid)
    out_stream << "set x2tics (" << xtics_stream.str() << ")\nset grid noxtics noytics x2tics\n";

  if(_png_output)
  {
    out_stream << "set terminal png\n";
    out_stream << "set output \"" << fname << ".png\"\n";
  }

  out_stream << "plot "
      << axes_limits
      << " \"" << data_file_name << "\" using 1:2 title \"" << (*names)[0]
      << "\" with lines";
  if(n_vars > 1)
  {
    for(unsigned int i=1; i<n_vars; i++)
    {
      out_stream << ", \\\n\"" << data_file_name << "\" using 1:" << i+2
          << " title \"" << (*names)[i] << "\" with lines";
    }
  }

  out_stream.close();


  // Create an output stream for data file
  std::ofstream data(data_file_name.c_str());

  if (!data.good())
    {
      libMesh::err << "ERROR: opening output data file " << std::endl;
      libmesh_error();
    }

  // get ordered nodal data using a map
  typedef std::pair<Real, std::vector<Number> > key_value_pair;
  typedef std::map<Real, std::vector<Number> > map_type;
  typedef map_type::iterator map_iterator;

  map_type node_map;


  it  = the_mesh.active_elements_begin();

  for ( ; it != end_it; ++it)
  {
    const Elem* elem = *it;

    for(unsigned int i=0; i<elem->n_nodes(); i++)
    {
      std::vector<Number> values;

      // Get the global id of the node
      dof_id_type global_id = elem->node(i);

      for(unsigned int c=0; c<n_vars; c++)
      {
        values.push_back( (*soln)[global_id*n_vars + c] );
      }

      node_map[ the_mesh.point(global_id)(0) ] = values;
    }
  }


  map_iterator map_it = node_map.begin();
  const map_iterator end_map_it = node_map.end();

  for( ; map_it != end_map_it; ++map_it)
  {
    key_value_pair kvp = *map_it;
    std::vector<Number> values = kvp.second;

    data << kvp.first << "\t";

    for(unsigned int i=0; i<values.size(); i++)
    {
      data << values[i] << "\t";
    }

    data << "\n";
  }

  data.close();
  }
}
Exemplo n.º 5
0
void MEDITIO::write_ascii (const std::string & fname,
                           const std::vector<Number> * vec,
                           const std::vector<std::string> * solution_names)
{
  // Current lacks in implementation:
  //  (i)   only 3D meshes.
  //  (ii)  only QUAD4, TRI3, TET4 elements, others are omitted !
  //  (iii) no distinction between materials.
  //  (iv)  no vector output, just first scalar as output

  // libmesh_assert three dimensions (should be extended later)
  libmesh_assert_equal_to (MeshOutput<MeshBase>::mesh().mesh_dimension(), 3);

  // Open the output file stream
  std::ofstream out_stream (fname.c_str());

  // Make sure it opened correctly
  if (!out_stream.good())
    libmesh_file_error(fname.c_str());

  // Get a reference to the mesh
  const MeshBase & the_mesh = MeshOutput<MeshBase>::mesh();

  // Begin interfacing with the MEdit data file
  {
    // header:
    out_stream << "MeshVersionFormatted  1\n";
    out_stream << "Dimension  3\n";
    out_stream << "# Mesh generated by libmesh\n\n";

    // write the nodes:
    out_stream << "# Set of mesh vertices\n";
    out_stream << "Vertices\n";
    out_stream << the_mesh.n_nodes() << "\n";

    for (unsigned int v=0; v<the_mesh.n_nodes(); v++)
      out_stream << the_mesh.point(v)(0) << " " << the_mesh.point(v)(1) << " " << the_mesh.point(v)(2) << " 0\n";
  }

  {
    // write the connectivity:
    out_stream << "\n# Set of Polys\n\n";

    // count occurrences of output elements:
    int n_tri3  = 0;
    int n_quad4 = 0;
    int n_tet4  = 0;

    for (const auto & elem : the_mesh.active_element_ptr_range())
      {
        if (elem->type() == TRI3)  n_tri3++;
        if (elem->type() == QUAD4) n_quad4++;
        if (elem->type() == QUAD9) n_quad4+=4; // (QUAD9 is written as 4 QUAD4.)
        if (elem->type() == TET4)  n_tet4++;
      }

    // First: write out TRI3 elements:
    out_stream << "Triangles\n";
    out_stream << n_tri3 << "\n";

    for (const auto & elem : the_mesh.active_element_ptr_range())
      if (elem->type() == TRI3)
        out_stream << elem->node_id(0)+1  << " "
                   << elem->node_id(1)+1  << " "
                   << elem->node_id(2)+1  << " 0\n";

    // Second: write out QUAD4 elements:
    out_stream << "Quadrilaterals\n";
    out_stream << n_quad4 << "\n";

    for (const auto & elem : the_mesh.active_element_ptr_range())
      {
        if (elem->type() == QUAD4)
          {
            out_stream << elem->node_id(0)+1  << " "
                       << elem->node_id(1)+1  << " "
                       << elem->node_id(2)+1  << " "
                       << elem->node_id(3)+1  <<" 0\n";
          } // if
        else if (elem->type() == QUAD9)
          {
            out_stream << elem->node_id(0)+1  << " "
                       << elem->node_id(4)+1  << " "
                       << elem->node_id(8)+1  << " "
                       << elem->node_id(7)+1  <<" 0\n";
            out_stream << elem->node_id(7)+1  << " "
                       << elem->node_id(8)+1  << " "
                       << elem->node_id(6)+1  << " "
                       << elem->node_id(3)+1  <<" 0\n";
            out_stream << elem->node_id(4)+1  << " "
                       << elem->node_id(1)+1  << " "
                       << elem->node_id(5)+1  << " "
                       << elem->node_id(8)+1  <<" 0\n";
            out_stream << elem->node_id(8)+1  << " "
                       << elem->node_id(5)+1  << " "
                       << elem->node_id(2)+1  << " "
                       << elem->node_id(6)+1  <<" 0\n";
          }
      }

    // Third: write out TET4 elements:
    out_stream << "Tetrahedra\n";
    out_stream << n_tet4 << "\n";

    for (const auto & elem : the_mesh.active_element_ptr_range())
      if (elem->type() == TET4)
        {
          out_stream << elem->node_id(0)+1  << " "
                     << elem->node_id(1)+1  << " "
                     << elem->node_id(2)+1  << " "
                     << elem->node_id(3)+1  <<" 0\n";
        }
  }
  // end of the out file
  out_stream << '\n' << "# end of file\n";

  // optionally write the data
  if ((solution_names != nullptr) &&
      (vec != nullptr))
    {
      // Open the ".bb" file stream
      std::size_t idx = fname.find_last_of(".");
      std::string bbname = fname.substr(0,idx) + ".bb";

      std::ofstream bbout (bbname.c_str());

      // Make sure it opened correctly
      if (!bbout.good())
        libmesh_file_error(bbname.c_str());

      // Header: 3: 3D mesh, 1: scalar output, 2: node-indexed
      const std::size_t n_vars = solution_names->size();
      bbout << "3 1 " << the_mesh.n_nodes() << " 2\n";
      for (dof_id_type n=0; n<the_mesh.n_nodes(); n++)
        bbout << std::setprecision(10) << (*vec)[n*n_vars + scalar_idx] << " ";
      bbout << "\n";
    } // endif
}
Exemplo n.º 6
0
// ------------------------------------------------------------
// FroIO  members
void FroIO::write (const std::string & fname)
{
  // We may need to gather a DistributedMesh to output it, making that
  // const qualifier in our constructor a dirty lie
  MeshSerializer serialize(const_cast<MeshBase &>(this->mesh()), !_is_parallel_format);

  if (this->mesh().processor_id() == 0)
    {
      // Open the output file stream
      std::ofstream out_stream (fname.c_str());
      libmesh_assert (out_stream.good());

      // Make sure it opened correctly
      if (!out_stream.good())
        libmesh_file_error(fname.c_str());

      // Get a reference to the mesh
      const MeshBase & the_mesh = MeshOutput<MeshBase>::mesh();

      // Write the header
      out_stream << the_mesh.n_elem()  << " "
                 << the_mesh.n_nodes() << " "
                 << "0 0 "
                 << the_mesh.get_boundary_info().n_boundary_ids()  << " 1\n";

      // Write the nodes -- 1-based!
      for (unsigned int n=0; n<the_mesh.n_nodes(); n++)
        out_stream << n+1 << " \t"
                   << std::scientific
                   << std::setprecision(12)
                   << the_mesh.point(n)(0) << " \t"
                   << the_mesh.point(n)(1) << " \t"
                   << 0. << '\n';

      // Write the elements -- 1-based!
      unsigned int e = 0;
      for (const auto & elem : the_mesh.active_element_ptr_range())
        {
          // .fro likes TRI3's
          if (elem->type() != TRI3)
            libmesh_error_msg("ERROR:  .fro format only valid for triangles!\n" \
                              << "  writing of " << fname << " aborted.");

          out_stream << ++e << " \t";

          for (unsigned int n=0; n<elem->n_nodes(); n++)
            out_stream << elem->node_id(n)+1 << " \t";

          //   // LHS -> RHS Mapping, for inverted triangles
          //   out_stream << elem->node_id(0)+1 << " \t";
          //   out_stream << elem->node_id(2)+1 << " \t";
          //   out_stream << elem->node_id(1)+1 << " \t";

          out_stream << "1\n";
        }

      // Write BCs.
      {
        const std::set<boundary_id_type> & bc_ids =
          the_mesh.get_boundary_info().get_boundary_ids();

        std::vector<dof_id_type>        el;
        std::vector<unsigned short int> sl;
        std::vector<boundary_id_type>   il;

        the_mesh.get_boundary_info().build_side_list (el, sl, il);


        // Map the boundary ids into [1,n_bc_ids],
        // treat them one at a time.
        boundary_id_type bc_id=0;
        for (std::set<boundary_id_type>::const_iterator id = bc_ids.begin();
             id != bc_ids.end(); ++id)
          {
            std::deque<dof_id_type> node_list;

            std::map<dof_id_type, dof_id_type>
              forward_edges, backward_edges;

            // Get all sides on this element with the relevant BC id.
            for (std::size_t e=0; e<el.size(); e++)
              if (il[e] == *id)
                {
                  // need to build up node_list as a sorted array of edge nodes...
                  // for the following:
                  // a---b---c---d---e
                  // node_list [ a b c d e];
                  //
                  // the issue is just how to get this out of the elem/side based data structure.
                  // the approach is to build up 'chain links' like this:
                  // a---b b---c c---d d---e
                  // and piece them together.
                  //
                  // so, for an arbitrary edge n0---n1, we build the
                  // "forward_edges"  map n0-->n1
                  // "backward_edges" map n1-->n0
                  // and then start with one chain link, and add on...
                  //
                  std::unique_ptr<const Elem> side =
                    the_mesh.elem_ref(el[e]).build_side_ptr(sl[e]);

                  const dof_id_type
                    n0 = side->node_id(0),
                    n1 = side->node_id(1);

                  // insert into forward-edge set
                  forward_edges.insert (std::make_pair(n0, n1));

                  // insert into backward-edge set
                  backward_edges.insert (std::make_pair(n1, n0));

                  // go ahead and add one edge to the list -- this will give us the beginning of a
                  // chain to work from!
                  if (node_list.empty())
                    {
                      node_list.push_front(n0);
                      node_list.push_back (n1);
                    }
                }

            // we now have the node_list with one edge, the forward_edges, and the backward_edges
            // the node_list will be filled when (node_list.size() == (n_edges+1))
            // until that is the case simply add on to the beginning and end of the node_list,
            // building up a chain of ordered nodes...
            const std::size_t n_edges = forward_edges.size();

            while (node_list.size() != (n_edges+1))
              {
                const dof_id_type
                  front_node = node_list.front(),
                  back_node  = node_list.back();

                // look for front_pair in the backward_edges list
                {
                  std::map<dof_id_type, dof_id_type>::iterator
                    pos = backward_edges.find(front_node);

                  if (pos != backward_edges.end())
                    {
                      node_list.push_front(pos->second);

                      backward_edges.erase(pos);
                    }
                }

                // look for back_pair in the forward_edges list
                {
                  std::map<dof_id_type, dof_id_type>::iterator
                    pos = forward_edges.find(back_node);

                  if (pos != forward_edges.end())
                    {
                      node_list.push_back(pos->second);

                      forward_edges.erase(pos);
                    }
                }

                // libMesh::out << "node_list.size()=" << node_list.size()
                //       << ", n_edges+1=" << n_edges+1 << std::endl;
              }


            out_stream << ++bc_id << " " << node_list.size() << '\n';

            std::deque<dof_id_type>::iterator pos = node_list.begin();
            for ( ; pos != node_list.end(); ++pos)
              out_stream << *pos+1 << " \t0\n";
          }
      }
    }
}
Exemplo n.º 7
0
void TecplotIO::write_ascii (const std::string& fname,
			     const std::vector<Number>* v,
			     const std::vector<std::string>* solution_names)
{
  // Should only do this on processor 0!
  libmesh_assert_equal_to (libMesh::processor_id(), 0);

  // Create an output stream
  std::ofstream out(fname.c_str());

  // Make sure it opened correctly
  if (!out.good())
    libmesh_file_error(fname.c_str());

  // Get a constant reference to the mesh.
  const MeshBase& mesh = MeshOutput<MeshBase>::mesh();

  // Write header to stream
  {
    {
      // TODO: We used to print out the SVN revision here when we did keyword expansions...
      out << "# For a description of the Tecplot format see the Tecplot User's guide.\n"
	  << "#\n";
    }

    out << "Variables=x,y,z";

    if (solution_names != NULL)
      for (unsigned int n=0; n<solution_names->size(); n++)
	{
#ifdef LIBMESH_USE_REAL_NUMBERS

	  // Write variable names for real variables
	  out << "," << (*solution_names)[n];

#else

	  // Write variable names for complex variables
	  out << "," << "r_"   << (*solution_names)[n]
	      << "," << "i_"   << (*solution_names)[n]
	      << "," << "a_"   << (*solution_names)[n];

#endif
	}

    out << '\n';

    out << "Zone f=fepoint, n=" << mesh.n_nodes() << ", e=" << mesh.n_active_sub_elem();

    if (mesh.mesh_dimension() == 1)
      out << ", et=lineseg";
    else if (mesh.mesh_dimension() == 2)
      out << ", et=quadrilateral";
    else if (mesh.mesh_dimension() == 3)
      out << ", et=brick";
    else
      {
	// Dimension other than 1, 2, or 3?
	libmesh_error();
      }

    // Use default mesh color = black
    out << ", c=black\n";

  } // finished writing header

  for (unsigned int i=0; i<mesh.n_nodes(); i++)
    {
      // Print the point without a newline
      mesh.point(i).write_unformatted(out, false);

      if ((v != NULL) && (solution_names != NULL))
	{
	  const unsigned int n_vars = solution_names->size();


	  for (unsigned int c=0; c<n_vars; c++)
	    {
#ifdef LIBMESH_USE_REAL_NUMBERS
	      // Write real data
	      out << std::setprecision(this->ascii_precision())
		  << (*v)[i*n_vars + c] << " ";

#else
	      // Write complex data
	      out << std::setprecision(this->ascii_precision())
		  << (*v)[i*n_vars + c].real() << " "
		  << (*v)[i*n_vars + c].imag() << " "
		  << std::abs((*v)[i*n_vars + c]) << " ";

#endif
	    }
	}

      // Write a new line after the data for this node
      out << '\n';
    }

//   const_active_elem_iterator       it (mesh.elements_begin());
//   const const_active_elem_iterator end(mesh.elements_end());

  MeshBase::const_element_iterator       it  = mesh.active_elements_begin();
  const MeshBase::const_element_iterator end = mesh.active_elements_end();

  for ( ; it != end; ++it)
    (*it)->write_connectivity(out, TECPLOT);
}