Flow123d  release_2.2.0-34-g18a8075
elements.cc
Go to the documentation of this file.
1 /*!
2  *
3  * Copyright (C) 2015 Technical University of Liberec. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it under
6  * the terms of the GNU General Public License version 3 as published by the
7  * Free Software Foundation. (http://www.gnu.org/licenses/gpl-3.0.en.html)
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12  *
13  *
14  * @file elements.cc
15  * @ingroup mesh
16  * @brief Various element oriented stuff, should be restricted to purely geometric functions
17  */
18 
19 #include <vector>
20 #include <string>
21 
22 #include "system/system.hh"
23 #include "mesh/mesh.h"
24 #include "mesh/ref_element.hh"
25 #include "element_impls.hh"
26 
27 // following deps. should be removed
28 #include "mesh/boundaries.h"
29 //#include "materials.hh"
30 #include "mesh/accessors.hh"
31 
32 
33 
35 : pid(0),
36 
37  node(NULL),
38 
39 // material(NULL),
40  edge_idx_(NULL),
41  boundary_idx_(NULL),
42  permutation_idx_(NULL),
43 
44  n_neighs_vb(0),
45  neigh_vb(NULL),
46 
47  dim_(0)
48 
49 {
50 }
51 
52 
53 Element::Element(unsigned int dim, Mesh *mesh_in, RegionIdx reg)
54 {
55  init(dim, mesh_in, reg);
56 }
57 
58 
59 
60 void Element::init(unsigned int dim, Mesh *mesh_in, RegionIdx reg) {
61  pid=0;
62  n_neighs_vb=0;
63  neigh_vb=NULL;
64  dim_=dim;
65  mesh_=mesh_in;
66  region_idx_=reg;
67 
68  node = new Node * [ n_nodes()];
69  edge_idx_ = new unsigned int [ n_sides()];
70  boundary_idx_ = NULL;
71  permutation_idx_ = new unsigned int[n_sides()];
72 
73  FOR_ELEMENT_SIDES(this, si) {
76  }
77 }
78 
79 
81  // Can not make deallocation here since then resize of
82  // vectors of elements deallocates what should be keeped.
83 }
84 
85 
86 /**
87  * SET THE "METRICS" FIELD IN STRUCT ELEMENT
88  */
89 double Element::measure() const {
90  switch (dim()) {
91  case 0:
92  return 1.0;
93  break;
94  case 1:
95  return arma::norm(*(node[ 1 ]) - *(node[ 0 ]) , 2);
96  break;
97  case 2:
98  return
99  arma::norm(
100  arma::cross(*(node[1]) - *(node[0]), *(node[2]) - *(node[0])),
101  2
102  ) / 2.0 ;
103  break;
104  case 3:
105  return fabs(
106  arma::dot(
107  arma::cross(*node[1] - *node[0], *node[2] - *node[0]),
108  *node[3] - *node[0] )
109  ) / 6.0;
110  break;
111  }
112  return 1.0;
113 }
114 
115 
116 /**
117  * SET THE "CENTRE[]" FIELD IN STRUCT ELEMENT
118  */
119 
121  unsigned int li;
122 
124  centre.zeros();
125 
126  FOR_ELEMENT_NODES(this, li) {
127  centre += node[ li ]->point();
128  }
129  centre /= (double) n_nodes();
130  return centre;
131 }
132 
133 /**
134  * Count element sides of the space dimension @p side_dim.
135  */
136 
137 unsigned int Element::n_sides_by_dim(unsigned int side_dim)
138 {
139  if (side_dim == dim()) return 1;
140 
141  unsigned int n = 0;
142  for (unsigned int i=0; i<n_sides(); i++)
143  if (side(i)->dim() == side_dim) n++;
144  return n;
145 }
146 
147 
149 {
150  return mesh_->element_accessor( mesh_->element.index(this) );
151 }
152 
153 
154 
156  return Region( region_idx_, mesh_->region_db());
157 }
158 
159 
160 unsigned int Element::id() const {
161  return mesh_->element.get_id(this);
162 }
163 
165  if (dim_==3) {
166  double sum_faces=0;
167  double face[4];
168  for(unsigned int i=0;i<4;i++) sum_faces+=( face[i]=side(i)->measure());
169 
170  double sum_pairs=0;
171  for(unsigned int i=0;i<3;i++)
172  for(unsigned int j=i+1;j<4;j++) {
173  unsigned int i_line = RefElement<3>::line_between_faces(i,j);
174  arma::vec line = *node[RefElement<3>::line_nodes[i_line][1]] - *node[RefElement<3>::line_nodes[i_line][0]];
175  sum_pairs += face[i]*face[j]*arma::dot(line, line);
176  }
177  double regular = (2.0*sqrt(2.0/3.0)/9.0); // regular tetrahedron
178  return fabs( measure()
179  * pow( sum_faces/sum_pairs, 3.0/4.0))/ regular;
180 
181  }
182  if (dim_==2) {
183  return fabs(
184  measure()/
185  pow(
186  arma::norm(*node[1] - *node[0], 2)
187  *arma::norm(*node[2] - *node[1], 2)
188  *arma::norm(*node[0] - *node[2], 2)
189  , 2.0/3.0)
190  ) / ( sqrt(3.0) / 4.0 ); // regular triangle
191  }
192  return 1.0;
193 }
194 
195 
197 {
198  bounding_box = BoundingBox( this->node[0]->point() );
199 
200  for (unsigned int i=1; i<n_nodes(); i++)
201  bounding_box.expand( this->node[i]->point() );
202 }
203 
204 
205 arma::vec Element::project_point(const arma::vec3 &point, const arma::mat &map) const
206 {
207 
208  if (dim() == 0) return arma::ones(1);
209 
210  arma::mat A=map.cols(0, dim()-1);
211  arma::mat AtA = A.t()*A;
212  arma::vec Atb = A.t()*(point - map.col(dim()));
213  arma::vec bary_coord(dim()+1);
214  bary_coord.rows(0, dim() - 1) = solve(AtA, Atb);
215  bary_coord( dim() ) = 1.0 - arma::sum( bary_coord.rows(0,dim()-1) );
216 
217  return bary_coord;
218 }
219 
220 
221 //-----------------------------------------------------------------------------
222 // vim: set cindent:
arma::vec project_point(const arma::vec3 &point, const arma::mat &map) const
Definition: elements.cc:205
Bounding box in 3d ambient space.
Definition: bounding_box.hh:45
double measure() const
Definition: elements.cc:89
unsigned int n_nodes() const
#define FOR_ELEMENT_NODES(i, j)
Definition: elements.h:187
unsigned int * boundary_idx_
Definition: elements.h:83
int get_id(const T *it) const
Definition: sys_vector.hh:458
Definition: nodes.hh:32
int pid
Definition: elements.h:76
unsigned int * permutation_idx_
Definition: elements.h:92
static const unsigned int undef_idx
Definition: mesh.h:110
void expand(const Point &point)
Definition: mesh.h:97
#define FOR_ELEMENT_SIDES(i, j)
Definition: elements.h:188
static unsigned int line_between_faces(unsigned int f1, unsigned int f2)
Node ** node
Definition: elements.h:79
unsigned int id() const
Definition: elements.cc:160
const RegionDB & region_db() const
Definition: mesh.h:155
ElementAccessor< 3 > element_accessor(unsigned int idx, bool boundary=false)
Definition: mesh.cc:669
Element()
Definition: elements.cc:34
unsigned int dim() const
unsigned int * edge_idx_
Definition: elements.h:82
unsigned int dim() const
Definition: side_impl.hh:37
~Element()
Definition: elements.cc:80
Neighbour ** neigh_vb
Definition: elements.h:166
Region region() const
Definition: elements.cc:155
unsigned int n_sides() const
unsigned int index(const T *pointer) const
Definition: sys_vector.hh:373
void get_bounding_box(BoundingBox &bounding_box) const
Definition: elements.cc:196
SideIter side(const unsigned int loc_index)
unsigned int dim_
Definition: elements.h:175
void init(unsigned int dim, Mesh *mesh_in, RegionIdx reg)
Definition: elements.cc:60
Mesh * mesh_
Definition: elements.h:169
RegionIdx region_idx_
Definition: elements.h:174
arma::vec3 centre() const
Definition: elements.cc:120
unsigned int n_neighs_vb
Definition: elements.h:164
double quality_measure_smooth()
Definition: elements.cc:164
Class RefElement defines numbering of vertices, sides, calculation of normal vectors etc...
ElementAccessor< 3 > element_accessor() const
Gets ElementAccessor of this element.
Definition: elements.cc:148
unsigned int n_sides_by_dim(unsigned int side_dim)
Definition: elements.cc:137
arma::vec3 & point()
Definition: nodes.hh:68
ElementVector element
Vector of elements of the mesh.
Definition: mesh.h:228
BoundingBox bounding_box()
Definition: elements.h:102