Hermes2D  3.0
transformable.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 "transformable.h"
17 #include "mesh.h"
18 namespace Hermes
19 {
20  namespace Hermes2D
21  {
22 #define H2D_IDENTIFY_TRF { 1.0, 1.0 }, { 0.0, 0.0 }
23 
24  Trf tri_trf[H2D_TRF_NUM] =
25  {
26  { { 0.5, 0.5 }, { -0.5, -0.5 } }, // son 0
27  { { 0.5, 0.5 }, { 0.5, -0.5 } }, // son 1
28  { { 0.5, 0.5 }, { -0.5, 0.5 } }, // son 2
29  { { -0.5, -0.5 }, { -0.5, -0.5 } }, // son 3
30  { H2D_IDENTIFY_TRF }, // identity
31  { H2D_IDENTIFY_TRF }, // identity
32  { H2D_IDENTIFY_TRF }, // identity
33  { H2D_IDENTIFY_TRF }, // identity
34  { H2D_IDENTIFY_TRF } // identity
35  };
36 
37  Trf quad_trf[H2D_TRF_NUM] =
38  {
39  { { 0.5, 0.5 }, { -0.5, -0.5 } }, // son 0
40  { { 0.5, 0.5 }, { 0.5, -0.5 } }, // son 1
41  { { 0.5, 0.5 }, { 0.5, 0.5 } }, // son 2
42  { { 0.5, 0.5 }, { -0.5, 0.5 } }, // son 3
43  { { 1.0, 0.5 }, { 0.0, -0.5 } }, // horz son 0
44  { { 1.0, 0.5 }, { 0.0, 0.5 } }, // horz son 1
45  { { 0.5, 1.0 }, { -0.5, 0.0 } }, // vert son 0
46  { { 0.5, 1.0 }, { 0.5, 0.0 } }, // vert son 1
47  { H2D_IDENTIFY_TRF } // identity
48  };
49 
50  Transformable::Transformable()
51  {
52  memset(stack, 0, sizeof(stack));
54  element = nullptr;
55  }
56 
57  Transformable::~Transformable() {}
58 
60  {
61  assert(top > 0);
62  ctm = stack + (--top);
63  sub_idx = (sub_idx - 1) >> 3;
64  }
65 
66  uint64_t Transformable::get_transform() const { return sub_idx; }
67 
69  {
70  stack[0].m[0] = stack[0].m[1] = 1.0;
71  stack[0].t[0] = stack[0].t[1] = 0.0;
72  ctm = stack;
73  sub_idx = top = 0;
74  }
75 
77  {
78  if (e == this->element)
79  return;
80 
81  if (e == nullptr)
82  throw Exceptions::NullException(1);
83 
84  this->element = e;
85 
86  this->reset_transform();
87  }
88 
89  void Transformable::set_transform(uint64_t idx)
90  {
91  int son[25];
92  int i = 0;
93  while (idx > 0)
94  {
95  son[i++] = (idx - 1) & 7;
96  idx = (idx - 1) >> 3;
97  }
99  for (int k = i - 1; k >= 0; k--)
100  push_transform(son[k]);
101  }
102 
103  void Transformable::force_transform(uint64_t sub_idx, Trf* ctm)
104  {
105  this->sub_idx = sub_idx;
106  this->ctm = ctm;
107  }
108 
110  {
111  assert(element != nullptr);
112  if (top >= H2D_MAX_TRN_LEVEL)
113  throw Hermes::Exceptions::Exception("Too deep transform.");
114 
115  Trf* mat = stack + (++top);
116  Trf* tr = (element->is_triangle() ? tri_trf + son : quad_trf + son);
117 
118  mat->m[0] = ctm->m[0] * tr->m[0];
119  mat->m[1] = ctm->m[1] * tr->m[1];
120  mat->t[0] = ctm->m[0] * tr->t[0] + ctm->t[0];
121  mat->t[1] = ctm->m[1] * tr->t[1] + ctm->t[1];
122 
123  ctm = mat;
124  // see traverse.cpp if this changes
125  sub_idx = (sub_idx << 3) + son + 1;
126  }
127 
128  void Transformable::push_transforms(std::set<Transformable *>& transformables, int son)
129  {
130  for (std::set<Transformable *>::iterator it = transformables.begin(); it != transformables.end(); ++it)
131  if (*it != nullptr)
132  (*it)->push_transform(son);
133  }
134  void Transformable::pop_transforms(std::set<Transformable *>& transformables)
135  {
136  for (std::set<Transformable *>::iterator it = transformables.begin(); it != transformables.end(); ++it)
137  if (*it != nullptr)
138  (*it)->pop_transform();
139  }
140  }
141 }
virtual void set_active_element(Element *e)
Definition: adapt.h:24
Trf * ctm
Current sub-element transformation matrix.
virtual void push_transform(int son)
HERMES_API Trf quad_trf[H2D_TRF_NUM]
A table of quad sub-subdomain transforms. Only first ::H2D_TRF_QUAD_NUM transformations are valid...
Stores one element of a mesh.
Definition: element.h:107
virtual void reset_transform()
Empties the stack, loads identity transform.
virtual void force_transform(uint64_t sub_idx, Trf *ctm)
For internal use only.
virtual void set_transform(uint64_t idx)
double2 t
The 2x2 diagonal transformation matrix.
Definition: transformable.h:32
2D transformation.
Definition: transformable.h:29
uint64_t sub_idx
Sub-element transformation index.
HERMES_API Trf tri_trf[H2D_TRF_NUM]
A table of triangle sub-subdomain transforms. Only first ::H2D_TRF_TRI_NUM transformations are valid...
static const unsigned int H2D_MAX_TRN_LEVEL
If this changes, NeighborSearch::H2D_MAX_NEIGHBORS must change too.
Definition: transformable.h:71
Element * element
The active element.
unsigned int top
Stack top.
Trf stack[21]
Transformation matrix stack.