Hermes2D  2.0
precalc.cpp
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 #include "global.h"
17 #include "quad_all.h"
18 #include "precalc.h"
19 #include "mesh.h"
20 namespace Hermes
21 {
22  namespace Hermes2D
23  {
25  {
26  if(shapeset == NULL)
27  throw Exceptions::NullException(0);
28  this->shapeset = shapeset;
29  master_pss = NULL;
30  num_components = shapeset->get_num_components();
31  assert(num_components == 1 || num_components == 2);
32  update_max_index();
33  set_quad_2d(&g_quad_2d_std);
34  }
35 
37  {
38  while (pss->is_slave())
39  pss = pss->master_pss;
40  master_pss = pss;
41  shapeset = pss->shapeset;
43  update_max_index();
44  set_quad_2d(&g_quad_2d_std);
45  }
46 
47  void PrecalcShapeset::update_max_index()
48  {
49  max_index[0] = shapeset->get_max_index(HERMES_MODE_TRIANGLE);
50  max_index[1] = shapeset->get_max_index(HERMES_MODE_QUAD);
51  }
52 
53  void PrecalcShapeset::set_quad_2d(Quad2D* quad_2d)
54  {
56  }
57 
58  void PrecalcShapeset::handle_overflow_idx()
59  {
60  if(overflow_nodes != NULL)
61  {
62  for(unsigned int i = 0; i < overflow_nodes->get_size(); i++)
63  if(overflow_nodes->present(i))
64  ::free(overflow_nodes->get(i));
65  delete overflow_nodes;
66  }
67  nodes = new LightArray<Node *>;
69  }
70 
72  {
73  // Key creation.
74  unsigned key = cur_quad | (element->get_mode() << 3) | ((unsigned) (max_index[element->get_mode()] - index) << 4);
75 
76  if(master_pss == NULL)
77  {
78  if(!tables.present(key))
79  tables.add(new std::map<uint64_t, LightArray<Node*>*>, key);
80  sub_tables = tables.get(key);
81  }
82  else
83  {
84  if(!master_pss->tables.present(key))
85  master_pss->tables.add(new std::map<uint64_t, LightArray<Node*>*>, key);
86  sub_tables = master_pss->tables.get(key);
87  }
88 
89  // Update the Node table.
91 
92  this->index = index;
93  order = std::max(H2D_GET_H_ORDER(shapeset->get_order(index, element->get_mode())), H2D_GET_V_ORDER(shapeset->get_order(index, element->get_mode())));
94  }
95 
97  {
99  }
100 
101  void PrecalcShapeset::precalculate(int order, int mask)
102  {
103  int i, j, k;
104 
105  // initialization
106  Quad2D* quad = get_quad_2d();
107  int np = quad->get_num_points(order, this->element->get_mode());
108  double3* pt = quad->get_points(order, this->element->get_mode());
109 
110  int oldmask = (cur_node != NULL) ? cur_node->mask : 0;
111  int newmask = mask | oldmask;
112  Node* node = new_node(newmask, np);
113 
114  // precalculate all required tables
115  for (j = 0; j < num_components; j++)
116  {
117  for (k = 0; k < 6; k++)
118  {
119  if(newmask & idx2mask[k][j])
120  {
121  if(oldmask & idx2mask[k][j])
122  memcpy(node->values[j][k], cur_node->values[j][k], np * sizeof(double));
123  else
124  for (i = 0; i < np; i++)
125  node->values[j][k][i] = shapeset->get_value(k, index, ctm->m[0] * pt[i][0] + ctm->t[0],
126  ctm->m[1] * pt[i][1] + ctm->t[1], j, element->get_mode());
127  }
128  }
129  }
130  if(nodes->present(order))
131  {
132  assert(nodes->get(order) == cur_node);
133  ::free(nodes->get(order));
134  }
135  nodes->add(node, order);
136  cur_node = node;
137  }
138 
139  void PrecalcShapeset::free()
140  {
141  if(master_pss != NULL) return;
142 
143  for(unsigned int i = 0; i < tables.get_size(); i++)
144  if(tables.present(i))
145  {
146  for(std::map<uint64_t, LightArray<Node*>*>::iterator it = tables.get(i)->begin(); it != tables.get(i)->end(); it++)
147  {
148  for(unsigned int k = 0; k < it->second->get_size(); k++)
149  if(it->second->present(k))
150  ::free(it->second->get(k));
151  delete it->second;
152  }
153  delete tables.get(i);
154  }
155 
156  if(overflow_nodes != NULL)
157  {
158  for(unsigned int i = 0; i < overflow_nodes->get_size(); i++)
159  if(overflow_nodes->present(i))
160  ::free(overflow_nodes->get(i));
161  delete overflow_nodes;
162  }
163  }
164 
165  extern PrecalcShapeset ref_map_pss;
166 
168  {
169  free();
170  }
171 
172  void PrecalcShapeset::push_transform(int son)
173  {
175  if(sub_tables != NULL)
177  }
178 
179  void PrecalcShapeset::pop_transform()
180  {
182  if(sub_tables != NULL)
184  }
185 
186  int PrecalcShapeset::get_active_shape() const
187  {
188  return index;
189  };
190 
191  Shapeset* PrecalcShapeset::get_shapeset() const
192  {
193  return shapeset;
194  }
195 
197  {
198  return shapeset->get_space_type();
199  }
200 
201  void PrecalcShapeset::set_master_transform()
202  {
203  assert(master_pss != NULL);
204  sub_idx = master_pss->sub_idx;
205  top = master_pss->top;
206  stack[top] = *(master_pss->ctm);
207  ctm = stack + top;
208  }
209 
210  int PrecalcShapeset::get_edge_fn_order(int edge)
211  {
212  return H2D_MAKE_EDGE_ORDER(element->get_mode(), edge, shapeset->get_order(index, element->get_mode()));
213  }
214 
215  bool PrecalcShapeset::is_slave() const
216  {
217  return master_pss != NULL;
218  }
219 
220  void PrecalcShapeset::force_transform(uint64_t sub_idx, Trf* ctm)
221  {
222  this->sub_idx = sub_idx;
223  this->ctm = ctm;
224  }
225  }
226 }