Hermes2D  2.0
refmap.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_REFMAP_H
17 #define __H2D_REFMAP_H
18 
19 #include "../global.h"
20 #include "../shapeset/precalc.h"
21 #include "../quadrature/quad_all.h"
22 #include "shapeset/shapeset_h1_all.h"
23 
24 namespace Hermes
25 {
26  namespace Hermes2D
27  {
28  class Element;
29  class Mesh;
30  namespace Views{
31  class Orderizer;
32  class Linearizer;
33  class Vectorizer;
34  };
35 
45  class HERMES_API RefMap : public Transformable
46  {
47  public:
48  RefMap();
49 
50  ~RefMap();
51 
54  void set_quad_2d(Quad2D* quad_2d);
55 
57  Quad2D* get_quad_2d() const;
58 
60  const Quad1D* get_quad_1d() const;
61 
64  virtual void set_active_element(Element* e);
65 
71  double3* get_tangent(int edge, int order = -1);
72 
75  static void untransform(Element* e, double x, double y, double& xi1, double& xi2);
76 
82  static Element* element_on_physical_coordinates(const Mesh* mesh, double x, double y, double* x_reference = NULL, double* y_reference = NULL);
83 
87  double* get_phys_x(int order);
88 
92  double* get_phys_y(int order);
93 
96  bool is_jacobian_const() const;
97 
100  double get_const_jacobian() const;
101 
104  double* get_jacobian(int order);
105 
107  int get_inv_ref_order() const;
108 
112  double2x2* get_inv_ref_map(int order);
113 
116  double2x2* get_const_inv_ref_map();
117 
118  H1ShapesetJacobi ref_map_shapeset;
119  PrecalcShapeset ref_map_pss;
120  private:
122  double3x2* get_second_ref_map(int order);
123 
125  void inv_ref_map_at_point(double xi1, double xi2, double& x, double& y, double2x2& m);
126 
128  void second_ref_map_at_point(double xi1, double xi2, double& x, double& y, double3x2& mm);
129 
131  virtual void push_transform(int son);
132 
134  virtual void pop_transform();
135 
137  void free();
138 
140  void force_transform(uint64_t sub_idx, Trf* ctm)
141  {
142  this->sub_idx = sub_idx;
143  stack[top] = *ctm;
144  this->ctm = stack + top;
145  update_cur_node();
146  if(is_const) calc_const_inv_ref_map();
147  }
148 
149  Quad2D* quad_2d;
150 
151  int num_tables;
152 
153  bool is_const;
154 
155  int inv_ref_order;
156 
157  double const_jacobian;
158 
159  double2x2 const_inv_ref_map;
160 
161  static const int H2D_MAX_TABLES = g_max_quad + 1 + 4 * g_max_quad + 4;
162 
165  struct Node
166  {
167  double* jacobian[H2D_MAX_TABLES];
168  double2x2* inv_ref_map[H2D_MAX_TABLES];
169  double3x2* second_ref_map[H2D_MAX_TABLES];
170  double* phys_x[H2D_MAX_TABLES];
171  double* phys_y[H2D_MAX_TABLES];
172  double3* tan[H2D_MAX_NUMBER_EDGES];
173  };
174 
176  std::map<uint64_t, Node*> nodes;
177 
178  Node* cur_node;
179 
180  Node* overflow;
181 
182  void update_cur_node()
183  {
184  Node* updated_node = new Node;
185 
186  if(sub_idx > H2D_MAX_IDX) {
187  delete updated_node;
188  cur_node = handle_overflow();
189  }
190  else {
191  if(nodes.insert(std::make_pair(sub_idx, updated_node)).second == false)
193  delete updated_node;
194  else
196  init_node(updated_node);
197  cur_node = nodes[sub_idx];
198  }
199  }
200 
201  void calc_inv_ref_map(int order);
202 
205  void calc_const_inv_ref_map();
206 
207  void calc_second_ref_map(int order);
208 
209  static bool is_parallelogram(Element* e);
210 
211  void calc_phys_x(int order);
212 
213  void calc_phys_y(int order);
214 
215  void calc_tangent(int edge, int eo);
216 
219  int calc_inv_ref_order();
220 
221  void init_node(Node* pp);
222 
223  void free_node(Node* node);
224 
225  Node* handle_overflow();
226 
227  Quad1DStd quad_1d;
228 
229  int indices[70];
230 
231  int nc;
232 
233  double2* coeffs;
234 
235  double2 lin_coeffs[H2D_MAX_NUMBER_EDGES];
236  template<typename T> friend class MeshFunction;
237  template<typename T> friend class DiscreteProblem;
238  template<typename T> friend class DiscreteProblemLinear;
239  template<typename T> friend class Solution;
240  template<typename T> friend class ExactSolution;
241  template<typename T> friend class ExactSolutionScalar;
242  template<typename T> friend class ExactSolutionVector;
243  template<typename T> friend class Adapt;
244  template<typename T> friend class KellyTypeAdapt;
245  friend class Views::Orderizer;
246  friend class Views::Vectorizer;
247  friend class Views::Linearizer;
248  template<typename T> friend class Global;
249  friend class VonMisesFilter;
250  template<typename T> friend class Func;
251  template<typename T> friend class Geom;
252  friend Geom<double>* init_geom_vol(RefMap *rm, const int order);
253  friend Geom<double>* init_geom_surf(RefMap *rm, SurfPos* surf_pos, const int order);
254  friend Func<double>* init_fn(PrecalcShapeset *fu, RefMap *rm, const int order);
255  };
256  }
257 }
258 #endif