$extrastylesheet
diva_io.C
Go to the documentation of this file.
00001 // The libMesh Finite Element Library.
00002 // Copyright (C) 2002-2014 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
00003 
00004 // This library is free software; you can redistribute it and/or
00005 // modify it under the terms of the GNU Lesser General Public
00006 // License as published by the Free Software Foundation; either
00007 // version 2.1 of the License, or (at your option) any later version.
00008 
00009 // This library is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012 // Lesser General Public License for more details.
00013 
00014 // You should have received a copy of the GNU Lesser General Public
00015 // License along with this library; if not, write to the Free Software
00016 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017 
00018 
00019 // C++ includes
00020 #include <fstream>
00021 
00022 // Local includes
00023 #include "libmesh/diva_io.h"
00024 #include "libmesh/boundary_mesh.h"
00025 #include "libmesh/mesh_tools.h"
00026 #include "libmesh/elem.h"
00027 #include "libmesh/boundary_info.h"
00028 
00029 namespace libMesh
00030 {
00031 
00032 // ------------------------------------------------------------
00033 // DivaIO class members
00034 void DivaIO::write (const std::string& fname)
00035 {
00036   // We may need to gather a ParallelMesh to output it, making that
00037   // const qualifier in our constructor a dirty lie
00038   MeshSerializer serialize(const_cast<MeshBase&>(this->mesh()), !_is_parallel_format);
00039 
00040   // Open the output file stream
00041   std::ofstream out_file(fname.c_str());
00042 
00043   // Make sure it opened correctly
00044   if (!out_file.good())
00045     libmesh_file_error(fname.c_str());
00046 
00047   this->write_stream (out_file);
00048 }
00049 
00050 
00051 
00052 
00053 void DivaIO::write_stream (std::ostream& out_file)
00054 {
00055   /*
00056     From Kelly: (kelly@tacc.utexas.edu)
00057 
00058     Ok, the following is the format:
00059 
00060     #points #triangles #quads #tets #prisms #pyramids #hexs
00061     loop over all points (written out x y z x y z ...)
00062     loop over all triangles (written out i1 i2 i3) (These are indices into
00063     the points going from
00064     1 to #points)
00065     loop over all quads (written out i1 i2 i3 i4) (Same numbering scheme)
00066     loop over all triangles and quads (write out b1) (This is a boundary
00067     condition for each
00068     triangle and each
00069     hex. You can put
00070     anything you want
00071     here)
00072     loop over all tets (written out i1 i2 i3 i4) (Same)
00073     loop over all pyramids (written out i1 i2 i3 i4 i5) (Same)
00074     loop over all prisms (written out i1 i2 i3 i4 i5 i6) (Same)
00075     loop over all hexs (written out i1 i2 i3 i4 i5 i6 i7 i8) (Same)
00076 
00077   */
00078 
00079   // Be sure the stream has been created successfully.
00080   libmesh_assert (out_file.good());
00081 
00082   // Can't use a constant mesh reference since we have to
00083   // sync the boundary info.
00084   libmesh_here();
00085   libMesh::err << "WARNING...  Sure you want to do this?"
00086                << std::endl;
00087   MeshBase& the_mesh = const_cast<MeshBase&>
00088     (MeshOutput<MeshBase>::mesh());
00089 
00090   if (the_mesh.mesh_dimension() < 3)
00091     {
00092       libMesh::err << "WARNING: DIVA only supports 3D meshes.\n\n"
00093                    << "Exiting without producing output.\n";
00094       return;
00095     }
00096 
00097 
00098 
00099   BoundaryMesh boundary_mesh
00100     (the_mesh.comm(),
00101      cast_int<unsigned char>(the_mesh.mesh_dimension()-1));
00102   the_mesh.get_boundary_info().sync(boundary_mesh);
00103 
00104 
00108   out_file << the_mesh.n_nodes()
00109            << ' '
00110            << (MeshTools::n_active_elem_of_type(boundary_mesh,TRI3) +
00111                MeshTools::n_active_elem_of_type(boundary_mesh,TRI6)*4)
00112            << ' '
00113            << (MeshTools::n_active_elem_of_type(boundary_mesh, QUAD4) +
00114                MeshTools::n_active_elem_of_type(boundary_mesh, QUAD8) +
00115                MeshTools::n_active_elem_of_type(boundary_mesh, QUAD9)*4)
00116            << ' '
00117            << (MeshTools::n_active_elem_of_type(the_mesh, TET4) +
00118                MeshTools::n_active_elem_of_type(the_mesh, TET10)*8)
00119            << ' '
00120            << MeshTools::n_active_elem_of_type(the_mesh, PYRAMID5)
00121            << ' '
00122            << (MeshTools::n_active_elem_of_type(the_mesh, PRISM6) +
00123                MeshTools::n_active_elem_of_type(the_mesh, PRISM18)*8)
00124            << ' '
00125            << (MeshTools::n_active_elem_of_type(the_mesh, HEX8)  +
00126                MeshTools::n_active_elem_of_type(the_mesh, HEX20) +
00127                MeshTools::n_active_elem_of_type(the_mesh, HEX27)*8)
00128            << ' '
00129            << '\n';
00130 
00131   boundary_mesh.clear();
00132 
00133 
00137   for (unsigned int v=0; v<the_mesh.n_nodes(); v++)
00138     the_mesh.point(v).write_unformatted(out_file);
00139 
00140 
00144   {
00148     for(unsigned int e=0; e<the_mesh.n_elem(); e++)
00149       if (the_mesh.elem(e)->active())
00150         for (unsigned int s=0; s<the_mesh.elem(e)->n_sides(); s++)
00151           if (the_mesh.elem(e)->neighbor(s) == NULL)
00152             {
00153               const UniquePtr<Elem> side(the_mesh.elem(e)->build_side(s));
00154 
00155               if (side->type() == TRI3)
00156                 {
00157                   out_file << side->node(0)+1 << " "
00158                            << side->node(1)+1 << " "
00159                            << side->node(2)+1 << '\n';
00160                 }
00161               else if (side->type() == TRI6)
00162                 {
00163                   out_file << side->node(0)+1 << " "
00164                            << side->node(3)+1 << " "
00165                            << side->node(5)+1 << '\n'
00166 
00167                            << side->node(3)+1 << " "
00168                            << side->node(1)+1 << " "
00169                            << side->node(4)+1 << '\n'
00170 
00171                            << side->node(5)+1 << " "
00172                            << side->node(4)+1 << " "
00173                            << side->node(2)+1 << '\n'
00174 
00175                            << side->node(3)+1 << " "
00176                            << side->node(4)+1 << " "
00177                            << side->node(5)+1 << '\n';
00178                 }
00179             }
00180 
00181 
00185     for(unsigned int e=0; e<the_mesh.n_elem(); e++)
00186       if (the_mesh.elem(e)->active())
00187         for (unsigned int s=0; s<the_mesh.elem(e)->n_sides(); s++)
00188           if (the_mesh.elem(e)->neighbor(s) == NULL)
00189             {
00190               const UniquePtr<Elem> side(the_mesh.elem(e)->build_side(s));
00191 
00192               if ((side->type() == QUAD4) ||
00193                   (side->type() == QUAD8)  )
00194                 {
00195                   out_file << side->node(0)+1 << " "
00196                            << side->node(1)+1 << " "
00197                            << side->node(2)+1 << " "
00198                            << side->node(3)+1 << '\n';
00199                 }
00200               else if (side->type() == QUAD9)
00201                 {
00202                   out_file << side->node(0)+1 << " "
00203                            << side->node(4)+1 << " "
00204                            << side->node(8)+1 << " "
00205                            << side->node(7)+1 << '\n'
00206 
00207                            << side->node(4)+1 << " "
00208                            << side->node(1)+1 << " "
00209                            << side->node(5)+1 << " "
00210                            << side->node(8)+1 << '\n'
00211 
00212                            << side->node(7)+1 << " "
00213                            << side->node(8)+1 << " "
00214                            << side->node(6)+1 << " "
00215                            << side->node(3)+1 << '\n'
00216 
00217                            << side->node(8)+1 << " "
00218                            << side->node(5)+1 << " "
00219                            << side->node(2)+1 << " "
00220                            << side->node(6)+1 << '\n';
00221                 }
00222             }
00223   }
00224 
00225 
00226 
00230   {
00234     for(unsigned int e=0; e<the_mesh.n_elem(); e++)
00235       if (the_mesh.elem(e)->active())
00236         for (unsigned short s=0; s<the_mesh.elem(e)->n_sides(); s++)
00237           if (the_mesh.elem(e)->neighbor(s) == NULL)
00238             {
00239               const UniquePtr<Elem> side(the_mesh.elem(e)->build_side(s));
00240 
00241               if ((side->type() == TRI3) ||
00242                   (side->type() == TRI6)  )
00243 
00244                 out_file << the_mesh.get_boundary_info().boundary_id(the_mesh.elem(e), s)
00245                          << '\n';
00246             }
00247 
00248 
00252     for(unsigned int e=0; e<the_mesh.n_elem(); e++)
00253       if (the_mesh.elem(e)->active())
00254         for (unsigned short s=0; s<the_mesh.elem(e)->n_sides(); s++)
00255           if (the_mesh.elem(e)->neighbor(s) == NULL)
00256             {
00257               const UniquePtr<Elem> side(the_mesh.elem(e)->build_side(s));
00258 
00259               if ((side->type() == QUAD4) ||
00260                   (side->type() == QUAD8) ||
00261                   (side->type() == QUAD9))
00262 
00263                 out_file << the_mesh.get_boundary_info().boundary_id(the_mesh.elem(e), s);
00264             }
00265   }
00266 
00267 
00268 
00272   for (unsigned int e=0; e<the_mesh.n_elem(); e++)
00273     if (the_mesh.elem(e)->active())
00274       {
00275         if (the_mesh.elem(e)->type() == TET4)
00276           {
00277             out_file << the_mesh.elem(e)->node(0)+1 << " "
00278                      << the_mesh.elem(e)->node(1)+1 << " "
00279                      << the_mesh.elem(e)->node(2)+1 << " "
00280                      << the_mesh.elem(e)->node(3)+1 << '\n';
00281           }
00282         else if (the_mesh.elem(e)->type() == TET10)
00283           {
00284             out_file << the_mesh.elem(e)->node(0)+1 << " "
00285                      << the_mesh.elem(e)->node(4)+1 << " "
00286                      << the_mesh.elem(e)->node(6)+1 << " "
00287                      << the_mesh.elem(e)->node(7)+1 << '\n';
00288 
00289             out_file << the_mesh.elem(e)->node(4)+1 << " "
00290                      << the_mesh.elem(e)->node(1)+1 << " "
00291                      << the_mesh.elem(e)->node(5)+1 << " "
00292                      << the_mesh.elem(e)->node(8)+1 << '\n';
00293 
00294             out_file << the_mesh.elem(e)->node(6)+1 << " "
00295                      << the_mesh.elem(e)->node(5)+1 << " "
00296                      << the_mesh.elem(e)->node(2)+1 << " "
00297                      << the_mesh.elem(e)->node(9)+1 << '\n';
00298 
00299             out_file << the_mesh.elem(e)->node(7)+1 << " "
00300                      << the_mesh.elem(e)->node(8)+1 << " "
00301                      << the_mesh.elem(e)->node(9)+1 << " "
00302                      << the_mesh.elem(e)->node(3)+1 << '\n';
00303 
00304             out_file << the_mesh.elem(e)->node(4)+1 << " "
00305                      << the_mesh.elem(e)->node(8)+1 << " "
00306                      << the_mesh.elem(e)->node(6)+1 << " "
00307                      << the_mesh.elem(e)->node(7)+1 << '\n';
00308 
00309             out_file << the_mesh.elem(e)->node(4)+1 << " "
00310                      << the_mesh.elem(e)->node(5)+1 << " "
00311                      << the_mesh.elem(e)->node(6)+1 << " "
00312                      << the_mesh.elem(e)->node(8)+1 << '\n';
00313 
00314             out_file << the_mesh.elem(e)->node(6)+1 << " "
00315                      << the_mesh.elem(e)->node(5)+1 << " "
00316                      << the_mesh.elem(e)->node(9)+1 << " "
00317                      << the_mesh.elem(e)->node(8)+1 << '\n';
00318 
00319             out_file << the_mesh.elem(e)->node(6)+1 << " "
00320                      << the_mesh.elem(e)->node(8)+1 << " "
00321                      << the_mesh.elem(e)->node(9)+1 << " "
00322                      << the_mesh.elem(e)->node(7)+1 << '\n';
00323           }
00324       }
00325 
00326 
00330   for (unsigned int e=0; e<the_mesh.n_elem(); e++)
00331     if (the_mesh.elem(e)->active())
00332       if (the_mesh.elem(e)->type() == PYRAMID5)
00333         {
00334           out_file << the_mesh.elem(e)->node(0)+1 << " "
00335                    << the_mesh.elem(e)->node(1)+1 << " "
00336                    << the_mesh.elem(e)->node(2)+1 << " "
00337                    << the_mesh.elem(e)->node(3)+1 << " "
00338                    << the_mesh.elem(e)->node(4)+1 << '\n';
00339         }
00340 
00341 
00342 
00346   for (unsigned int e=0; e<the_mesh.n_elem(); e++)
00347     if (the_mesh.elem(e)->active())
00348       {
00349         if (the_mesh.elem(e)->type() == PRISM6)
00350           {
00351             out_file << the_mesh.elem(e)->node(0)+1 << " "
00352                      << the_mesh.elem(e)->node(1)+1 << " "
00353                      << the_mesh.elem(e)->node(2)+1 << " "
00354                      << the_mesh.elem(e)->node(3)+1 << " "
00355                      << the_mesh.elem(e)->node(4)+1 << " "
00356                      << the_mesh.elem(e)->node(5)+1 << '\n';
00357           }
00358         else if (the_mesh.elem(e)->type() == PRISM18)
00359           libmesh_error_msg("PRISM18 element type not supported.");
00360       }
00361 
00362 
00366   for (unsigned int e=0; e<the_mesh.n_elem(); e++)
00367     if (the_mesh.elem(e)->active())
00368       if ((the_mesh.elem(e)->type() == HEX8)   ||
00369           (the_mesh.elem(e)->type() == HEX20) ||
00370           (the_mesh.elem(e)->type() == HEX27)   )
00371         {
00372           std::vector<dof_id_type> conn;
00373           for (unsigned int se=0; se<the_mesh.elem(e)->n_sub_elem(); se++)
00374             {
00375               the_mesh.elem(e)->connectivity(se, TECPLOT, conn);
00376 
00377               out_file << conn[0] << ' '
00378                        << conn[1] << ' '
00379                        << conn[2] << ' '
00380                        << conn[3] << ' '
00381                        << conn[4] << ' '
00382                        << conn[5] << ' '
00383                        << conn[6] << ' '
00384                        << conn[7] << '\n';
00385             }
00386         }
00387 }
00388 
00389 } // namespace libMesh