libMesh
fro_io.C
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2017 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
3 
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License, or (at your option) any later version.
8 
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
13 
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 
18 
19 
20 // C++ includes
21 #include <fstream>
22 #include <iomanip>
23 #include <iostream>
24 #include <deque>
25 #include <map>
26 
27 // Local includes
28 #include "libmesh/libmesh_config.h"
29 #include "libmesh/fro_io.h"
30 #include "libmesh/mesh_base.h"
31 #include "libmesh/boundary_info.h"
32 #include "libmesh/elem.h"
33 
34 namespace libMesh
35 {
36 
37 
38 
39 // ------------------------------------------------------------
40 // FroIO members
41 void FroIO::write (const std::string & fname)
42 {
43  // We may need to gather a DistributedMesh to output it, making that
44  // const qualifier in our constructor a dirty lie
45  MeshSerializer serialize(const_cast<MeshBase &>(this->mesh()), !_is_parallel_format);
46 
47  if (this->mesh().processor_id() == 0)
48  {
49  // Open the output file stream
50  std::ofstream out_stream (fname.c_str());
51  libmesh_assert (out_stream.good());
52 
53  // Make sure it opened correctly
54  if (!out_stream.good())
55  libmesh_file_error(fname.c_str());
56 
57  // Get a reference to the mesh
58  const MeshBase & the_mesh = MeshOutput<MeshBase>::mesh();
59 
60  // Write the header
61  out_stream << the_mesh.n_elem() << " "
62  << the_mesh.n_nodes() << " "
63  << "0 0 "
64  << the_mesh.get_boundary_info().n_boundary_ids() << " 1\n";
65 
66  // Write the nodes -- 1-based!
67  for (unsigned int n=0; n<the_mesh.n_nodes(); n++)
68  out_stream << n+1 << " \t"
69  << std::scientific
70  << std::setprecision(12)
71  << the_mesh.point(n)(0) << " \t"
72  << the_mesh.point(n)(1) << " \t"
73  << 0. << '\n';
74 
75  // Write the elements -- 1-based!
76  unsigned int e = 0;
77  for (const auto & elem : the_mesh.active_element_ptr_range())
78  {
79  // .fro likes TRI3's
80  if (elem->type() != TRI3)
81  libmesh_error_msg("ERROR: .fro format only valid for triangles!\n" \
82  << " writing of " << fname << " aborted.");
83 
84  out_stream << ++e << " \t";
85 
86  for (unsigned int n=0; n<elem->n_nodes(); n++)
87  out_stream << elem->node_id(n)+1 << " \t";
88 
89  // // LHS -> RHS Mapping, for inverted triangles
90  // out_stream << elem->node_id(0)+1 << " \t";
91  // out_stream << elem->node_id(2)+1 << " \t";
92  // out_stream << elem->node_id(1)+1 << " \t";
93 
94  out_stream << "1\n";
95  }
96 
97  // Write BCs.
98  {
99  const std::set<boundary_id_type> & bc_ids =
100  the_mesh.get_boundary_info().get_boundary_ids();
101 
102  std::vector<dof_id_type> el;
103  std::vector<unsigned short int> sl;
104  std::vector<boundary_id_type> il;
105 
106  the_mesh.get_boundary_info().build_side_list (el, sl, il);
107 
108 
109  // Map the boundary ids into [1,n_bc_ids],
110  // treat them one at a time.
112  for (std::set<boundary_id_type>::const_iterator id = bc_ids.begin();
113  id != bc_ids.end(); ++id)
114  {
115  std::deque<dof_id_type> node_list;
116 
117  std::map<dof_id_type, dof_id_type>
118  forward_edges, backward_edges;
119 
120  // Get all sides on this element with the relevant BC id.
121  for (std::size_t e=0; e<el.size(); e++)
122  if (il[e] == *id)
123  {
124  // need to build up node_list as a sorted array of edge nodes...
125  // for the following:
126  // a---b---c---d---e
127  // node_list [ a b c d e];
128  //
129  // the issue is just how to get this out of the elem/side based data structure.
130  // the approach is to build up 'chain links' like this:
131  // a---b b---c c---d d---e
132  // and piece them together.
133  //
134  // so, for an arbitrary edge n0---n1, we build the
135  // "forward_edges" map n0-->n1
136  // "backward_edges" map n1-->n0
137  // and then start with one chain link, and add on...
138  //
140  the_mesh.elem_ref(el[e]).build_side_ptr(sl[e]);
141 
142  const dof_id_type
143  n0 = side->node_id(0),
144  n1 = side->node_id(1);
145 
146  // insert into forward-edge set
147  forward_edges.insert (std::make_pair(n0, n1));
148 
149  // insert into backward-edge set
150  backward_edges.insert (std::make_pair(n1, n0));
151 
152  // go ahead and add one edge to the list -- this will give us the beginning of a
153  // chain to work from!
154  if (node_list.empty())
155  {
156  node_list.push_front(n0);
157  node_list.push_back (n1);
158  }
159  }
160 
161  // we now have the node_list with one edge, the forward_edges, and the backward_edges
162  // the node_list will be filled when (node_list.size() == (n_edges+1))
163  // until that is the case simply add on to the beginning and end of the node_list,
164  // building up a chain of ordered nodes...
165  const std::size_t n_edges = forward_edges.size();
166 
167  while (node_list.size() != (n_edges+1))
168  {
169  const dof_id_type
170  front_node = node_list.front(),
171  back_node = node_list.back();
172 
173  // look for front_pair in the backward_edges list
174  {
175  std::map<dof_id_type, dof_id_type>::iterator
176  pos = backward_edges.find(front_node);
177 
178  if (pos != backward_edges.end())
179  {
180  node_list.push_front(pos->second);
181 
182  backward_edges.erase(pos);
183  }
184  }
185 
186  // look for back_pair in the forward_edges list
187  {
188  std::map<dof_id_type, dof_id_type>::iterator
189  pos = forward_edges.find(back_node);
190 
191  if (pos != forward_edges.end())
192  {
193  node_list.push_back(pos->second);
194 
195  forward_edges.erase(pos);
196  }
197  }
198 
199  // libMesh::out << "node_list.size()=" << node_list.size()
200  // << ", n_edges+1=" << n_edges+1 << std::endl;
201  }
202 
203 
204  out_stream << ++bc_id << " " << node_list.size() << '\n';
205 
206  std::deque<dof_id_type>::iterator pos = node_list.begin();
207  for ( ; pos != node_list.end(); ++pos)
208  out_stream << *pos+1 << " \t0\n";
209  }
210  }
211  }
212 }
213 
214 } // namespace libMesh
const BoundaryInfo & get_boundary_info() const
The information about boundary ids on the mesh.
Definition: mesh_base.h:117
virtual UniquePtr< Elem > build_side_ptr(const unsigned int i, bool proxy=true)=0
virtual const Point & point(const dof_id_type i) const =0
const bool _is_parallel_format
Flag specifying whether this format is parallel-capable.
Definition: mesh_output.h:141
unsigned short int side
Definition: xdr_io.C:49
virtual SimpleRange< element_iterator > active_element_ptr_range()=0
const MeshBase & mesh() const
The libMesh namespace provides an interface to certain functionality in the library.
void build_side_list(std::vector< dof_id_type > &element_id_list, std::vector< unsigned short int > &side_list, std::vector< boundary_id_type > &bc_id_list) const
Creates a list of element numbers, sides, and ids for those sides.
boundary_id_type bc_id
Definition: xdr_io.C:50
const std::set< boundary_id_type > & get_boundary_ids() const
This is the MeshBase class.
Definition: mesh_base.h:68
libmesh_assert(j)
std::unique_ptr< T > UniquePtr
Definition: auto_ptr.h:46
int8_t boundary_id_type
Definition: id_types.h:51
virtual void write(const std::string &) libmesh_override
This method implements writing a mesh to a specified file.
Definition: fro_io.C:41
virtual const Elem & elem_ref(const dof_id_type i) const
Definition: mesh_base.h:490
std::size_t n_boundary_ids() const
Temporarily serialize a DistributedMesh for output; a distributed mesh is allgathered by the MeshSeri...
virtual dof_id_type n_nodes() const =0
virtual dof_id_type n_elem() const =0
processor_id_type processor_id()
Definition: libmesh_base.h:96
uint8_t dof_id_type
Definition: id_types.h:64