Rheolef  7.2
an efficient C++ finite element environment
space_constitution_get.icc
Go to the documentation of this file.
1 // input space_constitution files:
22 // shared functions used in space_constitution_get.cc
23 // and space_constitution_get_old.cc
24 //
25 // author: Pierre.Saramito@imag.fr
26 //
27 // date: 19 dec 2011
28 //
29 // Note:
30 // - some technical stuff with bison & flex
31 // - some others for distributed issues:
32 // * lecture du fichier sur proc=0 -> arbre sur proc=0
33 // * lecture ecriture arbre sur stringstream sur proc=0
34 // * broadcast string sur ts procs
35 // * lecture du stringstream sur ts les proc -> arbre
36 // * conversion arbre en space_constitution sur ts les procs
37 //
38 
39 //
40 #include <sstream> // flex include it, but in namespace rheolef
41 #include <cstring>
42 #include "rheolef/space.h"
43 #include "rheolef/basis_get.h"
44 
45 namespace rheolef {
46 
47 // ================================================================================
48 // part 0 : symbol table
49 // ================================================================================
50 
51 static std::vector<std::string> symbol_table;
52 static const std::string& symbol (size_t i) { return symbol_table[i]; }
53 static size_t insert (const std::string& str) {
54  size_t i = symbol_table.size();
55  symbol_table.push_back (str);
56  return i;
57 }
58 // ================================================================================
59 // part 1 : temporary data structure: tree
60 // ================================================================================
61 struct basis_geo_t {
62  basis_geo_t (std::string b="", std::string g="")
63  : basis(b), geo(g) {}
64  std::string basis, geo;
65 };
66 
67 struct tree_type {
68 // data:
69  bool is_hier;
71  std::list<tree_type> hier;
72  std::string spec;
73 // allocators:
74  tree_type(const std::string& basis, const std::string& geo)
75  : is_hier(false), basis_geo(basis,geo), hier(), spec("undef") {}
76  tree_type() : is_hier(true), basis_geo(), hier(), spec("undef") {}
77  tree_type(const std::string& s, const std::list<tree_type>& h) : is_hier(true), basis_geo(), hier(h), spec(s) {}
78 };
79 static
80 void
81 tree_dump (const tree_type& x, std::ostream& out, size_t level = 0)
82 {
83  if (!x.is_hier) {
84  out << x.basis_geo.basis;
85  out << "{" << x.basis_geo.geo << "}";
86  return;
87  }
88  if (x.spec != "mixed") { out << x.spec; }
89  if (x.spec != "mixed" || level != 0) { out << "("; }
90  std::list<tree_type>::const_iterator iter = x.hier.begin(), last = x.hier.end();
91  while (iter != last) {
92  tree_dump (*iter, out, level+1);
93  ++iter;
94  if (iter != last) { out << "*"; }
95  }
96  if (x.spec != "mixed" || level != 0) { out << ")"; }
97 }
98 typedef std::list<tree_type> list_type;
99 
100 static tree_type* result_ptr;
101 
102 static family_index_option_type _current_fio;
103 
104 // ================================================================================
105 // part 2 : parser call
106 // ================================================================================
107 typedef int (*parse_type)(void);
108 
109 template<class Lexer>
110 static
111 void
112 space_constitution_get_pass_1_2 (
113  idiststream& ids,
114  parse_type parse,
115  Lexer& input,
116  size_t& line_no,
117  size_t& n_error)
118 {
119  // --------------------------------------------
120  // 1) read from file on io_proc into a string
121  // --------------------------------------------
123  std::istream& is = ids.is();
124  communicator comm = ids.comm();
125  size_type io_proc = odiststream::io_proc();
126  size_type my_proc = comm.rank();
127  std::string str;
128  if (my_proc == io_proc) {
129  std::getline (ids.is(), str);
130  }
131  // then broadcast the string
132 #ifdef _RHEOLEF_HAVE_MPI
133  mpi::broadcast (mpi::communicator(), str, io_proc);
134 #endif // _RHEOLEF_HAVE_MPI
135  // ------------------------------------------------------------------------------------
136  // 2) parse from string on all procs and re-build result_ptr available on all procs
137  // ------------------------------------------------------------------------------------
138  std::istringstream istrstr;
139  istrstr.str (str);
140  input.yyrestart(istrstr);
141  symbol_table.clear();
142  line_no = 1;
143  n_error = 0;
144  if (parse() != 0 || n_error != 0) {
145  is.setstate (std::ios::badbit);
146  delete_macro (result_ptr); result_ptr = 0;
147  error_macro ("internal error in space_constitution io (pass 2)");
148  }
149  symbol_table.clear();
150  // then result_ptr is available on all procs
151 }
152 // ================================================================================
153 // part 2 : space_constitution allocator from tree_type
154 // ================================================================================
155 template<class T, class M>
156 static
157 space_constitution<T,M>
158 build_from_tree (const tree_type& x) {
159  if (! x.is_hier) {
160  geo_basic<T,M> omega (x.basis_geo.geo);
161  basis_option sopt;
162  std::string approx = x.basis_geo.basis + sopt.stamp();
163  return space_constitution<T,M>(omega, approx);
164  }
165  if (x.spec == "vector" || x.spec == "tensor") {
166  assert_macro (x.hier.size() == 1, "unexpected tree");
167  const tree_type& subtree = *(x.hier.begin());
168  assert_macro (! subtree.is_hier, "unexpected tree");
169  geo_basic<T,M> omega (subtree.basis_geo.geo);
170  basis_option sopt;
171  std::string approx = subtree.basis_geo.basis + sopt.stamp();
172  space_constitution<T,M> basis (omega, approx);
173  space_constitution<T,M> constit;
174  constit.set_hierarchy(true);
175  size_t d = omega.dimension();
177  size_t n_comp = space_constant::n_component (valued_tag, d, omega.coordinate_system());
178  constit.get_hierarchy().resize (n_comp);
179  for (size_t i_comp = 0; i_comp < n_comp; i_comp++) {
180  constit.get_hierarchy().operator[] (i_comp) = basis;
181  }
182  constit.set_valued_tag (valued_tag);
183  constit.data().initialize();
184  return constit;
185  }
186  space_constitution<T,M> constit;
187  constit.set_hierarchy(true);
188  size_t n_comp = x.hier.size();
189  constit.get_hierarchy().resize(n_comp);
190  std::list<tree_type>::const_iterator iter = x.hier.begin();
191  for (size_t i_comp = 0; i_comp < n_comp; i_comp++, ++iter) {
192  const tree_type& xi = *iter;
193  constit.get_hierarchy().operator[] (i_comp) = build_from_tree<T,M> (xi); // recursive call
194  }
195  constit.data().initialize();
196  return constit;
197 }
198 
199 } // namespace rheolef
field::size_type size_type
Definition: branch.cc:430
see the basis page for the full documentation
see the geo page for the full documentation
std::allocator< int >::size_type size_type
Definition: distributor.h:74
idiststream: see the diststream page for the full documentation
Definition: diststream.h:336
std::istream & is()
Definition: diststream.h:400
const communicator & comm() const
Definition: diststream.h:356
static size_type io_proc()
Definition: diststream.cc:79
static std::vector< std::string > symbol_table
Definition: basis_get.cc:90
static family_index_option_type _current_fio
Definition: basis_get.cc:50
basis_basic< Float > basis
Definition: basis.h:683
size_t size_type
Definition: basis_get.cc:76
static tree_type * result_ptr
int(* parse_type)(void)
std::list< tree_type > list_type
#define assert_macro(ok_condition, message)
Definition: dis_macros.h:113
#define error_macro(message)
Definition: dis_macros.h:49
valued_type valued_tag(const std::string &name)
size_type n_component(valued_type valued_tag, size_type d, coordinate_type sys_coord)
This file is part of Rheolef.
space_constant::valued_type valued_tag() const
Definition: cavity_dg.h:25
basis_geo_t(std::string b="", std::string g="")
tree_type(const std::string &basis, const std::string &geo)
tree_type(const std::string &s, const std::list< tree_type > &h)
std::list< tree_type > hier