fro_io.C
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2014 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 ParallelMesh 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.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!
78 
79  for (unsigned int e=0 ; it != end; ++it)
80  {
81  // .fro likes TRI3's
82  if ((*it)->type() != TRI3)
83  {
84  libMesh::err << "ERROR: .fro format only valid for triangles!\n"
85  << " writing of " << fname << " aborted.\n"
86  << std::endl;
87  libmesh_error();
88  }
89 
90  out_stream << ++e << " \t";
91 
92  for (unsigned int n=0; n<(*it)->n_nodes(); n++)
93  out_stream << (*it)->node(n)+1 << " \t";
94 
95 // // LHS -> RHS Mapping, for inverted triangles
96 // out_stream << (*it)->node(0)+1 << " \t";
97 // out_stream << (*it)->node(2)+1 << " \t";
98 // out_stream << (*it)->node(1)+1 << " \t";
99 
100  out_stream << "1\n";
101  }
102 
103  // Write BCs.
104  {
105  const std::set<boundary_id_type>& bc_ids =
106  the_mesh.boundary_info->get_boundary_ids();
107 
108  std::vector<dof_id_type> el;
109  std::vector<unsigned short int> sl;
110  std::vector<boundary_id_type> il;
111 
112  the_mesh.boundary_info->build_side_list (el, sl, il);
113 
114 
115  // Map the boundary ids into [1,n_bc_ids],
116  // treat them one at a time.
118  for (std::set<boundary_id_type>::const_iterator id = bc_ids.begin();
119  id != bc_ids.end(); ++id)
120  {
121  std::deque<dof_id_type> node_list;
122 
123  std::map<dof_id_type, dof_id_type>
124  forward_edges, backward_edges;
125 
126  // Get all sides on this element with the relevant BC id.
127  for (std::size_t e=0; e<el.size(); e++)
128  if (il[e] == *id)
129  {
130  // need to build up node_list as a sorted array of edge nodes...
131  // for the following:
132  // a---b---c---d---e
133  // node_list [ a b c d e];
134  //
135  // the issue is just how to get this out of the elem/side based data structure.
136  // the approach is to build up 'chain links' like this:
137  // a---b b---c c---d d---e
138  // and piece them together.
139  //
140  // so, for an arbitray edge n0---n1, we build the
141  // "forward_edges" map n0-->n1
142  // "backward_edges" map n1-->n0
143  // and then start with one chain link, and add on...
144  //
145  AutoPtr<Elem> side = the_mesh.elem(el[e])->build_side(sl[e]);
146 
147  const dof_id_type
148  n0 = side->node(0),
149  n1 = side->node(1);
150 
151  // insert into forward-edge set
152  forward_edges.insert (std::make_pair(n0, n1));
153 
154  // insert into backward-edge set
155  backward_edges.insert (std::make_pair(n1, n0));
156 
157  // go ahead and add one edge to the list -- this will give us the beginning of a
158  // chain to work from!
159  if (node_list.empty())
160  {
161  node_list.push_front(n0);
162  node_list.push_back (n1);
163  }
164  }
165 
166  // we now have the node_list with one edge, the forward_edges, and the backward_edges
167  // the node_list will be filled when (node_list.size() == (n_edges+1))
168  // until that is the case simply add on to the beginning and end of the node_list,
169  // building up a chain of ordered nodes...
170  const std::size_t n_edges = forward_edges.size();
171 
172  while (node_list.size() != (n_edges+1))
173  {
174  const dof_id_type
175  front_node = node_list.front(),
176  back_node = node_list.back();
177 
178  // look for front_pair in the backward_edges list
179  {
180  std::map<dof_id_type, dof_id_type>::iterator
181  pos = backward_edges.find(front_node);
182 
183  if (pos != backward_edges.end())
184  {
185  node_list.push_front(pos->second);
186 
187  backward_edges.erase(pos);
188  }
189  }
190 
191  // look for back_pair in the forward_edges list
192  {
193  std::map<dof_id_type, dof_id_type>::iterator
194  pos = forward_edges.find(back_node);
195 
196  if (pos != forward_edges.end())
197  {
198  node_list.push_back(pos->second);
199 
200  forward_edges.erase(pos);
201  }
202  }
203 
204 // libMesh::out << "node_list.size()=" << node_list.size()
205 // << ", n_edges+1=" << n_edges+1 << std::endl;
206  }
207 
208 
209  out_stream << ++bc_id << " " << node_list.size() << '\n';
210 
211  std::deque<dof_id_type>::iterator pos = node_list.begin();
212  for ( ; pos != node_list.end(); ++pos)
213  out_stream << *pos+1 << " \t0\n";
214  }
215  }
216  }
217 }
218 
219 } // namespace libMesh

Site Created By: libMesh Developers
Last modified: February 07 2014 16:57:05 UTC

Hosted By:
SourceForge.net Logo