Flow123d  intersections_paper-476-gbe68821
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 
116 {
117  OLD_ASSERT(dim_ == 3, "Cannot provide Jacobian for dimension other than 3.");
118  return arma::dot( arma::cross(*node[1] - *node[0],
119  *node[2] - *node[0]),
120  *node[3] - *node[0]
121  );
122 }
123 
124 
125 /**
126  * SET THE "CENTRE[]" FIELD IN STRUCT ELEMENT
127  */
128 
130  unsigned int li;
131 
133  centre.zeros();
134 
135  FOR_ELEMENT_NODES(this, li) {
136  centre += node[ li ]->point();
137  }
138  centre /= (double) n_nodes();
139  return centre;
140 }
141 
142 /**
143  * Count element sides of the space dimension @p side_dim.
144  */
145 
146 unsigned int Element::n_sides_by_dim(unsigned int side_dim)
147 {
148  if (side_dim == dim()) return 1;
149 
150  unsigned int n = 0;
151  for (unsigned int i=0; i<n_sides(); i++)
152  if (side(i)->dim() == side_dim) n++;
153  return n;
154 }
155 
156 
158 {
159  return mesh_->element_accessor( mesh_->element.index(this) );
160 }
161 
162 
163 
165  return Region( region_idx_, mesh_->region_db());
166 }
167 
168 
169 unsigned int Element::id() const {
170  return mesh_->element.get_id(this);
171 }
172 
174  if (dim_==3) {
175  double sum_faces=0;
176  double face[4];
177  for(unsigned int i=0;i<4;i++) sum_faces+=( face[i]=side(i)->measure());
178 
179  double sum_pairs=0;
180  for(unsigned int i=0;i<3;i++)
181  for(unsigned int j=i+1;j<4;j++) {
182  unsigned int i_line = RefElement<3>::line_between_faces(i,j);
184  sum_pairs += face[i]*face[j]*arma::dot(line, line);
185  }
186  double regular = (2.0*sqrt(2.0/3.0)/9.0); // regular tetrahedron
187  return fabs( measure()
188  * pow( sum_faces/sum_pairs, 3.0/4.0))/ regular;
189 
190  }
191  if (dim_==2) {
192  return fabs(
193  measure()/
194  pow(
195  arma::norm(*node[1] - *node[0], 2)
196  *arma::norm(*node[2] - *node[1], 2)
197  *arma::norm(*node[0] - *node[2], 2)
198  , 2.0/3.0)
199  ) / ( sqrt(3.0) / 4.0 ); // regular triangle
200  }
201  return 1.0;
202 }
203 
204 
206 {
207  bounding_box = BoundingBox( this->node[0]->point() );
208 
209  for (unsigned int i=1; i<n_nodes(); i++)
210  bounding_box.expand( this->node[i]->point() );
211 }
212 
214 {
215  ASSERT_GT(mesh_->element_box_.size(), 0);
216  return mesh_->element_box_[mesh_->element.index(this)];
217 }
218 
219 
220 //-----------------------------------------------------------------------------
221 // vim: set cindent:
Bounding box in 3d ambient space.
Definition: bounding_box.hh:45
double measure() const
Computes the measure of the element.
Definition: elements.cc:89
unsigned int n_nodes() const
#define FOR_ELEMENT_NODES(i, j)
Definition: elements.h:155
unsigned int * boundary_idx_
Definition: elements.h:94
int get_id(const T *it) const
Definition: sys_vector.hh:458
Definition: nodes.hh:32
int pid
Definition: elements.h:87
unsigned int * permutation_idx_
Definition: elements.h:103
static const unsigned int undef_idx
Definition: mesh.h:121
#define ASSERT_GT(a, b)
Definition of comparative assert macro (Greater Than)
Definition: asserts.hh:312
void expand(const Point &point)
Definition: mesh.h:95
double tetrahedron_jacobian() const
Definition: elements.cc:115
#define FOR_ELEMENT_SIDES(i, j)
Definition: elements.h:156
static unsigned int line_between_faces(unsigned int f1, unsigned int f2)
Node ** node
Definition: elements.h:90
unsigned int id() const
Definition: elements.cc:169
const RegionDB & region_db() const
Definition: mesh.h:160
ElementAccessor< 3 > element_accessor(unsigned int idx, bool boundary=false)
Definition: mesh.cc:706
Element()
Definition: elements.cc:34
unsigned int dim() const
#define OLD_ASSERT(...)
Definition: global_defs.h:131
BoundingBox & get_bounding_box_fast(BoundingBox &bounding_box) const
Return precomputed bounding box.
Definition: elements.cc:213
unsigned int * edge_idx_
Definition: elements.h:93
unsigned int dim() const
Definition: side_impl.hh:37
~Element()
Definition: elements.cc:80
Neighbour ** neigh_vb
Definition: elements.h:133
Region region() const
Definition: elements.cc:164
unsigned int n_sides() const
static const IdxVector< (InDim >OutDim?InDim+1:dim-InDim) > interact(TInteraction< OutDim, InDim > interaction)
unsigned int index(const T *pointer) const
Definition: sys_vector.hh:373
void get_bounding_box(BoundingBox &bounding_box) const
Definition: elements.cc:205
SideIter side(const unsigned int loc_index)
unsigned int dim_
Definition: elements.h:142
void init(unsigned int dim, Mesh *mesh_in, RegionIdx reg)
Definition: elements.cc:60
Mesh * mesh_
Definition: elements.h:136
RegionIdx region_idx_
Definition: elements.h:141
arma::vec3 centre() const
Computes the barycenter.
Definition: elements.cc:129
unsigned int n_neighs_vb
Definition: elements.h:131
double quality_measure_smooth()
Definition: elements.cc:173
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:157
unsigned int n_sides_by_dim(unsigned int side_dim)
Definition: elements.cc:146
arma::vec3 & point()
Definition: nodes.hh:68
ElementVector element
Vector of elements of the mesh.
Definition: mesh.h:235
std::vector< BoundingBox > element_box_
Auxiliary vector of mesh elements bounding boxes.
Definition: mesh.h:396
BoundingBox bounding_box()
Definition: elements.h:117