Flow123d  release_3.0.0-1210-g1d9e2bd
sides.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 sides.cc
15  * @ingroup mesh
16  * @brief Some side related functions - should be made strictly geometric.
17  */
18 
19 #include "system/system.hh"
20 #include "mesh/side_impl.hh"
21 #include "mesh/mesh.h"
22 #include "sides.h"
23 #include "mesh/accessors.hh"
24 
25 
26 //=============================================================================
27 // CALCULATE METRICS OF THE SIDE
28 //=============================================================================
29 
30 double Side::measure() const {
31  switch ( dim() ) {
32  case 0:
33  return 1.0;
34  case 1: {
35  arma::vec3 diff = node(1)->point();
36  diff -= node(0)->point();
37  return arma::norm( diff , 2 );
38  }
39  case 2: {
40  arma::vec3 diff0 = node(1)->point() - node(0)->point();
41  arma::vec3 diff1 = node(2)->point() - node(0)->point();
42  return 0.5*arma::norm( arma::cross(diff0, diff1), 2);
43  }
44  }
45 
46  return 0.0;
47 }
48 
49 //=============================================================================
50 // CALCULATE NORMAL OF THE SIDE
51 //=============================================================================
52 
54  switch ( dim() ) {
55  case 0:
56  return normal_point();
57  case 1:
58  return normal_line();
59  case 2:
60  return normal_triangle();
61  }
62 
63  return arma::vec3("0 0 0");
64 }
65 //=============================================================================
66 //
67 //=============================================================================
68 
71 
72  arma::vec3 normal(ele.node(1)->point());
73  normal -= ele.node(0) ->point();
74 
75  normal /=arma::norm(normal,2);
76  if ( node( 0 ) == ele.node_accessor( 0 ) )
77  return -normal;
78  else
79  return normal;
80 }
81 //=============================================================================
82 //
83 //=============================================================================
84 
87 
88  // At first, we need vector of the normal of the element
89  arma::vec3 elem_normal=arma::cross( ele.node(1)->point() - ele.node(0)->point(),
90  ele.node(2)->point() - ele.node(0)->point() );
91  elem_normal /= norm( elem_normal, 2);
92 
93  // Now we can calculate the "normal" of our side
94  arma::vec3 side_normal = arma::cross( node(1)->point() - node(0)->point() , elem_normal );
95  side_normal /= norm( side_normal, 2);
96 
97  if ( dot( side_normal, ele.centre() - node(0)->point() ) > 0.0)
98  return -side_normal;
99  else
100  return side_normal;
101 }
102 //=============================================================================
103 //
104 //=============================================================================
105 
107  arma::vec3 side_normal=arma::cross( node(1)->point() - node(0)->point(),
108  node(2)->point() - node(0)->point() );
109  side_normal /= norm( side_normal, 2);
110 
111  if ( dot(side_normal, element().centre() - node(0)->point() ) > 0.0)
112  return -side_normal;
113  else
114  return side_normal;
115 }
116 
117 //=============================================================================
118 // CALCULATE CENTRE OF THE SIDE
119 //=============================================================================
120 
122  arma::vec3 barycenter;
123  barycenter.zeros();
124 
125  for(unsigned int i=0; i < n_nodes() ; i++)
126  barycenter += node( i )->point();
127 
128  barycenter /= (double) n_nodes();
129  return barycenter;
130 }
131 
132 
133 //=============================================================================
134 // CALCULATE THE SIDE DIAMETER
135 //=============================================================================
136 
137 double Side::diameter() const {
138  if (dim() == 0)
139  {
140  return 1.0;
141  }
142  else
143  {
144  double h = 0.0;
145  for (unsigned int i=0; i<n_nodes(); i++)
146  for (unsigned int j=i+1; j<n_nodes(); j++)
147  h = max(h, node(i)->distance(*node(j).node()));
148  return h;
149  }
150 }
151 
152 //-----------------------------------------------------------------------------
153 // vim: set cindent:
NodeAccessor< 3 > node_accessor(unsigned int ni) const
Definition: accessors.hh:149
arma::vec3 normal_line() const
Definition: sides.cc:85
arma::vec3 centre() const
Centre of side.
Definition: sides.cc:121
ElementAccessor< 3 > element() const
Definition: side_impl.hh:53
arma::vec3 normal_point() const
This is necessary by current DofHandler, should change this.
Definition: sides.cc:69
arma::vec::fixed< spacedim > centre() const
Computes the barycenter.
Definition: accessors.hh:285
unsigned int dim() const
Definition: side_impl.hh:38
arma::vec3 normal_triangle() const
Definition: sides.cc:106
Type dot(const Mat< Type, nRows, nCols > &a, const Mat< Type, nRows, nCols > &b)
Definition: armor.hh:176
NodeAccessor< 3 > node(unsigned int i) const
Definition: side_impl.hh:47
double measure() const
Calculate metrics of the side.
Definition: sides.cc:30
double diameter() const
Calculate the side diameter.
Definition: sides.cc:137
arma::vec3 normal() const
Vector of (generalized) normal.
Definition: sides.cc:53
arma::vec3 & point()
Definition: nodes.hh:67
unsigned int n_nodes() const
Definition: side_impl.hh:34
const Node * node(unsigned int ni) const
Definition: accessors.hh:145