Flow123d
elements.cc
Go to the documentation of this file.
1 /*!
2  *
3  * Copyright (C) 2007 Technical University of Liberec. All rights reserved.
4  *
5  * Please make a following refer to Flow123d on your project site if you use the program for any purpose,
6  * especially for academic research:
7  * Flow123d, Research Centre: Advanced Remedial Technologies, Technical University of Liberec, Czech Republic
8  *
9  * This program is free software; you can redistribute it and/or modify it under the terms
10  * of the GNU General Public License version 3 as published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
13  * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14  * See the GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License along with this program; if not,
17  * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 021110-1307, USA.
18  *
19  *
20  * $Id$
21  * $Revision$
22  * $LastChangedBy$
23  * $LastChangedDate$
24  *
25  * @file
26  * @brief Various element oriented stuff, should be restricted to purely geometric functions
27  * @ingroup mesh
28  *
29  */
30 
31 #include <vector>
32 #include <string>
33 
34 #include "system/system.hh"
35 #include "mesh/mesh.h"
36 #include "mesh/ref_element.hh"
37 #include "elements.h"
38 #include "element_impls.hh"
39 
40 // following deps. should be removed
41 #include "mesh/boundaries.h"
42 //#include "materials.hh"
43 #include "mesh/accessors.hh"
44 
45 
46 
48 : pid(0),
49 
50  node(NULL),
51 
52 // material(NULL),
53  edge_idx_(NULL),
54  boundary_idx_(NULL),
55  permutation_idx_(NULL),
56 
57  n_neighs_vb(0),
58  neigh_vb(NULL),
59 
60  dim_(0)
61 
62 {
63 }
64 
65 
66 Element::Element(unsigned int dim, Mesh *mesh_in, RegionIdx reg)
67 {
68  init(dim, mesh_in, reg);
69 }
70 
71 
72 
73 void Element::init(unsigned int dim, Mesh *mesh_in, RegionIdx reg) {
74  pid=0;
75 // material=NULL;
76  n_neighs_vb=0;
77  neigh_vb=NULL;
78  dim_=dim;
79  mesh_=mesh_in;
80  region_idx_=reg;
81 
82  node = new Node * [ n_nodes()];
83  edge_idx_ = new unsigned int [ n_sides()];
84  boundary_idx_ = NULL;
85  permutation_idx_ = new unsigned int[n_sides()];
86 
87  FOR_ELEMENT_SIDES(this, si) {
90  }
91 }
92 
93 
95 /*
96  if (node) { delete[] node; node=NULL;}
97  if (edge_idx_) { delete[] edge_idx_; edge_idx_=NULL;}
98  if (permutation_idx_) { delete[] permutation_idx_; permutation_idx_=NULL;}
99  if (boundary_idx_) { delete[] boundary_idx_; boundary_idx_ = NULL; }
100  */
101 
102 }
103 
104 
105 /**
106  * SET THE "METRICS" FIELD IN STRUCT ELEMENT
107  */
108 double Element::measure() const {
109  switch (dim()) {
110  case 0:
111  return 1.0;
112  break;
113  case 1:
114  return arma::norm(*(node[ 1 ]) - *(node[ 0 ]) , 2);
115  break;
116  case 2:
117  return
118  arma::norm(
119  arma::cross(*(node[1]) - *(node[0]), *(node[2]) - *(node[0])),
120  2
121  ) / 2.0 ;
122  break;
123  case 3:
124  return fabs(
125  arma::dot(
126  arma::cross(*node[1] - *node[0], *node[2] - *node[0]),
127  *node[3] - *node[0] )
128  ) / 6.0;
129  break;
130  }
131  return 1.0;
132 }
133 
134 
135 /**
136  * SET THE "CENTRE[]" FIELD IN STRUCT ELEMENT
137  */
138 
140  unsigned int li;
141 
143  centre.zeros();
144 
145  FOR_ELEMENT_NODES(this, li) {
146  centre += node[ li ]->point();
147  }
148  centre /= (double) n_nodes();
149  //DBGMSG("%d: %f %f %f\n",ele.id(),ele->centre[0],ele->centre[1],ele->centre[2]);
150  return centre;
151 }
152 
153 /**
154  * Count element sides of the space dimension @p side_dim.
155  */
156 
157 unsigned int Element::n_sides_by_dim(unsigned int side_dim)
158 {
159  if (side_dim == dim()) return 1;
160 
161  unsigned int n = 0;
162  for (unsigned int i=0; i<n_sides(); i++)
163  if (side(i)->dim() == side_dim) n++;
164  return n;
165 }
166 
167 
169 {
170  return mesh_->element_accessor( mesh_->element.index(this) );
171 }
172 
173 
174 
176  return Region( region_idx_, mesh_->region_db());
177 }
178 
179 
180 unsigned int Element::id() const {
181  mesh_->element.get_id(this);
182 }
183 
185  if (dim_==3) {
186  double sum_faces=0;
187  double face[4];
188  for(unsigned int i=0;i<4;i++) sum_faces+=( face[i]=side(i)->measure());
189 
190  double sum_pairs=0;
191  for(unsigned int i=0;i<3;i++)
192  for(unsigned int j=i+1;j<4;j++) {
193  unsigned int i_line = RefElement<3>::line_between_faces(i,j);
194  arma::vec line = *node[RefElement<3>::line_nodes[i_line][1]] - *node[RefElement<3>::line_nodes[i_line][0]];
195  sum_pairs += face[i]*face[j]*arma::dot(line, line);
196  }
197  double regular = (2.0*sqrt(2.0/3.0)/9.0); // regular tetrahedron
198  return fabs( measure()
199  * pow( sum_faces/sum_pairs, 3.0/4.0))/ regular;
200 
201  }
202  if (dim_==2) {
203  return fabs(
204  measure()/
205  pow(
206  arma::norm(*node[1] - *node[0], 2)
207  *arma::norm(*node[2] - *node[1], 2)
208  *arma::norm(*node[0] - *node[2], 2)
209  , 2.0/3.0)
210  ) / ( sqrt(3.0) / 4.0 ); // regular triangle
211  }
212  return 1.0;
213 }
214 
215 
216 void Element::get_bounding_box(BoundingBox &bounding_box) const
217 {
218  bounding_box = BoundingBox( this->node[0]->point() );
219 
220  for (unsigned int i=1; i<n_nodes(); i++)
221  bounding_box.expand( this->node[i]->point() );
222 }
223 
224 //-----------------------------------------------------------------------------
225 // vim: set cindent: