Hermes2D  2.0
optimum_selector.h
1 // This file is part of Hermes2D.
2 //
3 // Hermes2D is free software: you can redistribute it and/or modify
4 // it under the terms of the GNU General Public License as published by
5 // the Free Software Foundation, either version 2 of the License, or
6 // (at your option) any later version.
7 //
8 // Hermes2D is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 // GNU General Public License for more details.
12 //
13 // You should have received a copy of the GNU General Public License
14 // along with Hermes2D. If not, see <http://www.gnu.org/licenses/>.
15 
16 #ifndef __H2D_REFINEMENT_OPTIMUM_SELECTOR_H
17 #define __H2D_REFINEMENT_OPTIMUM_SELECTOR_H
18 
19 #include <ostream>
20 #include "order_permutator.h"
21 #include "selector.h"
22 #include "../shapeset/shapeset.h"
23 
24 namespace Hermes
25 {
26  namespace Hermes2D
27  {
28  namespace RefinementSelectors {
30  enum CandList {
40  };
41 
43  enum SelOption {
46  };
47 
49 
52  extern HERMES_API const char* get_cand_list_str(const CandList cand_list);
53 
55 
57  extern HERMES_API bool is_hp(const CandList cand_list);
58 
60 
62  extern HERMES_API bool is_p_aniso(const CandList cand_list);
63 
65 
67  template<typename Scalar>
68  class HERMES_API OptimumSelector : public Selector<Scalar> {
69  protected: //options
72  public:
74 
77  virtual void set_option(const SelOption option, bool enable);
78 
80  struct Cand {
81  double error;
82  int dofs;
83  int split;
85  double score;
86 
88 
90  Cand(const int split, const int order_elems[H2D_MAX_ELEMENT_SONS])
91  : dofs(-1), split(split), score(0) {
92  p[0] = order_elems[0];
93  p[1] = order_elems[1];
94  p[2] = order_elems[2];
95  p[3] = order_elems[3];
96  };
97 
99 
104  Cand(const int split, const int order_elem0, const int order_elem1 = 0, const int order_elem2 = 0, const int order_elem3 = 0)
105  : dofs(-1), split(split), score(0) {
106  p[0] = order_elem0;
107  p[1] = order_elem1;
108  p[2] = order_elem2;
109  p[3] = order_elem3;
110  };
111 
113 
114  int get_num_elems() const {
115  switch (split) {
116  case H2D_REFINEMENT_H: return 4;
117  case H2D_REFINEMENT_P: return 1;
118  case H2D_REFINEMENT_ANISO_H:
119  case H2D_REFINEMENT_ANISO_V:
120  return 2;
121  default:
122  throw Hermes::Exceptions::Exception("Invalid refinement type %d.", split);
123  return -1;
124  break;
125  }
126  }
127  };
128 
130 
131  const Hermes::vector<Cand>& get_candidates() const { return candidates; };
132 
138  int ****num_shapes;
139 
140  protected: //candidates
142  struct CandsInfo {
146 
148  CandsInfo() : uniform_orders(true), min_quad_order(-1), max_quad_order(-1) {};
149 
151 
152  bool is_empty() const { return (min_quad_order < 0 || max_quad_order < 0); };
153  };
154 
156  double conv_exp;
157  Hermes::vector<Cand> candidates;
158 
160 
163  void update_cands_info(CandsInfo& info_h, CandsInfo& info_p, CandsInfo& info_aniso) const;
164 
166 
172  void append_candidates_split(const int start_quad_order, const int last_order, const int split, bool iso_p);
173 
175 
182  virtual void create_candidates(Element* e, int quad_order, int max_ha_quad_order, int max_p_quad_order);
183 
185 
189  void evaluate_candidates(Element* e, Solution<Scalar>* rsln, double* avg_error, double* dev_error);
190 
192 
205  virtual void select_best_candidate(Element* e, const double avg_error, const double dev_error, int* selected_cand, int* selected_h_cand);
206 
208 
213  virtual void evaluate_cands_error(Element* e, Solution<Scalar>* rsln, double* avg_error, double* dev_error) = 0;
214 
216 
220  virtual void evaluate_cands_dof(Element* e, Solution<Scalar>* rsln);
221 
223 
231  virtual void evaluate_cands_score(Element* e);
232 
233  private:
235 
238  static bool compare_cand_score(const Cand& a, const Cand& b);
239 
240  protected: //orders and their range
243 
245 
248  virtual void set_current_order_range(Element* element) = 0;
249 
250  protected: //shape functions
252  enum ShapeType {
253  H2DST_VERTEX = 0x01,
254  H2DST_HORIZ_EDGE = 0x02,
255  H2DST_VERT_EDGE = 0x04,
256  H2DST_TRI_EDGE = 0x08,
257  H2DST_BUBBLE = 0x10
258  };
259 
260  enum ShapeTypeInt {
261  H2DSI_VERTEX,
262  H2DSI_HORIZ_EDGE,
263  H2DSI_VERT_EDGE,
264  H2DSI_TRI_EDGE,
265  H2DSI_BUBBLE,
266  H2DSI_ANY
267  };
268 
270 
271  struct ShapeInx {
272  int order_h;
273  int order_v;
274  int inx;
276 
278 
282  ShapeInx(int order_h, int order_v, int inx, ShapeType type) : order_h(order_h), order_v(order_v), inx(inx), type(type) {};
283  };
284 
286  class Range
287  {
288  protected:
291  bool empty_range;
292  Range();
293  Range(const int& lower_bound, const int& upper_bound);
294  bool empty() const;
295  const int& lower() const;
296  const int& upper() const;
297  bool is_in_closed(const Range& range) const;
298  bool is_in_closed(const int& value) const;
299  bool is_in_open(const int& value) const;
300  void enlarge_to_include(const int& value);
301 
302  static Range make_envelope(const Range& a, const Range& b);
303  template<typename T> friend class OptimumSelector;
304  template<typename T> friend class ProjBasedSelector;
305  template<typename T> friend class H1ProjBasedSelector;
306  template<typename T> friend class L2ProjBasedSelector;
307  template<typename T> friend class HcurlProjBasedSelector;
308  };
309 
311 
312  Hermes::vector<ShapeInx> shape_indices[H2D_NUM_MODES];
313  int max_shape_inx[H2D_NUM_MODES];
314  int next_order_shape[H2D_NUM_MODES][H2DRS_MAX_ORDER+1];
315  bool has_vertex_shape[H2D_NUM_MODES];
316  bool has_edge_shape[H2D_NUM_MODES];
317  bool has_bubble_shape[H2D_NUM_MODES];
318 
320 
329  void add_bubble_shape_index(int order_h, int order_v, std::map<int, bool>& used_shape_index, Hermes::vector<ShapeInx>& indices, ElementMode2D mode);
330 
332 
337  void build_shape_indices(const ElementMode2D mode, const Range& vertex_order, const Range& edge_bubble_order);
338 
340 
345  int calc_num_shapes(int mode, int order_h, int order_v, int allowed_type_mask);
346 
348 
355  OptimumSelector(CandList cand_list, double conv_exp, int max_order, Shapeset* shapeset, const Range& vertex_order, const Range& edge_bubble_order);
356 
357  public:
359  virtual ~OptimumSelector();
360  protected:
362 
363  virtual bool select_refinement(Element* element, int quad_order, Solution<Scalar>* rsln, ElementToRefine& refinement);
364 
366 
367  virtual void generate_shared_mesh_orders(const Element* element, const int orig_quad_order, const int refinement, int tgt_quad_orders[H2D_MAX_ELEMENT_SONS], const int* suggested_quad_orders);
368  };
369  }
370  }
371 }
372 
373 #endif