Rocstar  1.0
Rocstar multiphysics simulation application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Geo_Metric_Base_3 Class Reference

3D Geometric Metric Base Class More...

#include <Geometric_Metrics_3.h>

Inheritance diagram for Geo_Metric_Base_3:
Collaboration diagram for Geo_Metric_Base_3:

Public Member Functions

 Geo_Metric_Base_3 ()
 
virtual ~Geo_Metric_Base_3 ()
 
virtual void initialize (Vector_3< double > n[], int type)
 Initialize a 3D Geometric Metric by nodal coords and element type. More...
 
virtual void initialize (Element_node_enumerator &ene)
 Initialize a 3D Geometric Metric by Element_node_enumerator. More...
 
virtual double maxValue () const
 The maximum value for this metric. More...
 
virtual double minValue () const
 The minimum value for this metric. More...
 
- Public Member Functions inherited from Metric
 Metric ()
 
virtual ~Metric ()
 
virtual void compute (double atts[]) const =0
 Compute the value of this metric. More...
 

Protected Member Functions

void compute_angles (double &min, double &max) const
 Compute min and max dihedral angles. More...
 
void compute_aspects (double &R, double &r, double &l) const
 Compute circumradius, inradius, and shortest edge length. More...
 

Protected Attributes

std::vector< Vector_3< double > > v
 
int _type
 
const COM::Pane * _ene_pane
 
int _ene_i
 

Detailed Description

3D Geometric Metric Base Class

This class is the base class for the implementation of various 3D geometric element quality metrics.

Definition at line 43 of file Geometric_Metrics_3.h.

Constructor & Destructor Documentation

Geo_Metric_Base_3 ( )
inline

Definition at line 48 of file Geometric_Metrics_3.h.

48 : _ene_pane(NULL), _ene_i(0){;}
const COM::Pane * _ene_pane
virtual ~Geo_Metric_Base_3 ( )
inlinevirtual

Definition at line 50 of file Geometric_Metrics_3.h.

50 {;}

Member Function Documentation

void compute_angles ( double &  min,
double &  max 
) const
protected

Compute min and max dihedral angles.

Definition at line 100 of file Geometric_Metrics_3.C.

References angle(), f_angle(), i, j, max(), min(), min_max12(), min_max6(), n, ni, nj, swap(), unit_normal(), and v.

100  {
101  if (_type == COM::Connectivity::TET4){
102  double a12,a13,a14,a23,a24,a34;
103  Vector_3<double> n1,n2,n3,n4;
104  unit_normal(v[2],v[3],n1); unit_normal(v[5],v[2],n2);
105  unit_normal(v[3],v[5],n3); unit_normal(v[0],v[4],n4);
106  a12=f_angle(n1,n2); a13=f_angle(n1,n3); a14=f_angle(n1,n4);
107  a23=f_angle(n2,n3); a24=f_angle(n2,n4); a34=f_angle(n3,n4);
108  min_max6(a12,a13,a14,a23,a24,a34,min,max);
109  }
110  else if (_type == COM::Connectivity::HEX8){
111  double a12,a14,a25,a34,a26,a46,a13,a15,a23,a45,a36,a56;
112  Vector_3<double> n1,n2,n3,n4,n5,n6;
113 
114  unit_normal(v[1],v[0],n1); unit_normal(v[0],v[4],n2);
115  unit_normal(v[4],v[2],n3); unit_normal(v[3],v[5],n4);
116  unit_normal(v[5],v[1],n5); unit_normal(v[6],v[7],n6);
117 
118  a12= f_angle(n1,n2); a13= f_angle(n1,n3); a14= f_angle(n1,n4);
119  a15= f_angle(n1,n5); a25= f_angle(n2,n5); a23= f_angle(n2,n3);
120  a34= f_angle(n3,n4); a45= f_angle(n4,n5); a26= f_angle(n2,n6);
121  a36= f_angle(n3,n6); a46= f_angle(n4,n6); a56= f_angle(n5,n6);
122 
123  min_max12(a12,a15,a34,a36,a13,a25,a45,a46,a14,a23,a26,a56,min,max);
124  }
125  else {
126 
127  const int face_node_lists_pyra[5][8] =
128  { {0,3,2,1,8,7,6,5}, {0,1,4,5,10,9,-1,-1}, {1,2,4,6,11,10,-1,-1},
129  {2,3,4,7,12,11,-1,-1}, {3,0,4,8,9,12,-1,-1}};
130 
131  const int face_node_lists_pris[5][9] =
132  { {0,1,4,3,6,10,12,9,15}, {1,2,5,4,7,11,13,10,16}, {2,0,3,5,8,9,14,11,17},
133  {0,2,1,8,7,6,-1,-1,-1}, {3,4,5,12,13,14,-1,-1,-1}};
134 
135  // Create an element node enumerator for handling this element
136  Element_node_enumerator ene(_ene_pane,
137  _ene_i);
138  // Loop over faces,
139  // a) determining which share an edge and
140  // b) face normals
141 
142  std::vector<Vector_3<double> > fnormals(ene.size_of_faces());
143  Element_node_vectors_k_const<double> n;
144  n.set(ene.pane()->attribute("nc"),ene);
145  // map from edges to faces
146  std::map<std::pair<int,int>,int> e2f;
147  std::map<std::pair<int,int>,int>::iterator e2f_it;
148  // set of adjacent faces
149  std::set<std::pair<int,int> > afs;
150  std::set<std::pair<int,int> >::iterator afs_it;
151  for(int i=0, ni = ene.size_of_faces(); i<ni; ++i){
152 
153  Facet_node_enumerator fne( &ene, i);
154 
155  const int *fn_list = (_type == COM::Connectivity::PYRIMID5) ?
156  face_node_lists_pyra[i] : face_node_lists_pris[i];
157 
158  int i0 = fn_list[0];
159  int i1 = fn_list[1];
160  int i2 = fn_list[2];
161 
162  // Find face normal
163  Vector_3<double> e1,e2;
164  e1[0] = n(i1,0)-n(i0,0);
165  e1[1] = n(i1,1)-n(i0,1);
166  e1[2] = n(i1,2)-n(i0,2);
167  e2[0] = n(i2,0)-n(i1,0);
168  e2[1] = n(i2,1)-n(i1,1);
169  e2[2] = n(i2,2)-n(i1,2);
170  unit_normal(e1,e2,fnormals[i]);
171 
172  for(int j=0, nj = fne.size_of_edges();j<nj;++j){
173 
174  // Loop over the edges of this face.
175  // If we there is a matching edge, store the adjacent
176  // faces.
177  int node_id1 = fne[j],node_id2 = fne[(j+1)%nj];
178  if(node_id1>node_id2)
179  std::swap(node_id1, node_id2);
180  e2f_it = e2f.find(std::make_pair<int,int>(node_id1,node_id2));
181  if(e2f_it != e2f.end()){
182  afs.insert(std::make_pair<int,int>(e2f_it->second,i));
183  e2f.erase(e2f_it);
184  }
185  else{
186  e2f.insert(std::make_pair<std::pair<int,int>,int>(
187  std::make_pair<int,int>(node_id1,node_id2)
188  ,i));
189  }
190  }
191  min = 180.0; max = 0.0;
192  for(afs_it = afs.begin(); afs_it != afs.end(); ++afs_it){
193  int ind1 = afs_it->first;
194  int ind2 = afs_it->second;
195  double angle = f_angle(fnormals[ind1],
196  fnormals[ind2]);
197  min = (angle < min) ? angle : min;
198  max = (angle > max) ? angle : max;
199  }
200  }
201  }
202 }
void swap(int &a, int &b)
Definition: buildface.cpp:88
Vector_n max(const Array_n_const &v1, const Array_n_const &v2)
Definition: Vector_n.h:354
std::vector< Vector_3< double > > v
double f_angle(Vector_3< double > v1, Vector_3< double >v2)
Compute the angle between two faces.
Definition: geometry.C:72
blockLoc i
Definition: read.cpp:79
double angle(Vector_3< double > v1, Vector_3< double > v2)
Compute the angle between two vectors.
Definition: geometry.C:61
const NT & n
Vector_n min(const Array_n_const &v1, const Array_n_const &v2)
Definition: Vector_n.h:346
j indices j
Definition: Indexing.h:6
void min_max12(double a1, double a2, double a3, double a4, double a5, double a6, double a7, double a8, double a9, double a10, double a11, double a12, double &min, double &max)
Find minimum and maximum of 12 numbers.
Definition: geometry.C:53
void int int REAL REAL REAL *z blockDim dim * ni
Definition: read.cpp:77
void unit_normal(const Vector_3< double > &v1, const Vector_3< double > &v2, Vector_3< double > &v3)
Compute the unit vector normal to two input vectors.
Definition: geometry.C:80
void int * nj
Definition: read.cpp:74
void min_max6(double a1, double a2, double a3, double a4, double a5, double a6, double &min, double &max)
Find minimum and maximum of 6 numbers.
Definition: geometry.C:46
const COM::Pane * _ene_pane

Here is the call graph for this function:

void compute_aspects ( double &  R,
double &  r,
double &  l 
) const
protected

Compute circumradius, inradius, and shortest edge length.

Definition at line 204 of file Geometric_Metrics_3.C.

References edge_length(), p1, sqrt(), tet_vol(), tri_area(), and v.

Referenced by Aspect_Metric_3::getAspects().

204  {
205 
206  // This metric is only defined for tetrahedrons
207  if (_type == COM::Connectivity::TET4){
208 
209  // Use formulas from mathworld to find circumradius (R),
210  // inradius (r), and shortest edge length (l)
211 
212  double a1 = tri_area(v[0],v[2],v[3]);
213  double a2 = tri_area(v[0],v[4],v[6]);
214  double a3 = tri_area(v[2],v[5],v[6]);
215  double a4 = tri_area(v[3],v[4],v[5]);
216  double a_sum = a1+a2+a3+a4;
217 
218 
219  double len_a = edge_length(v[0]);
220  double len_b = edge_length(v[2]);
221  double len_c = edge_length(v[3]);
222  double len_ap = edge_length(v[5]);
223  double len_bp = edge_length(v[4]);
224  double len_cp = edge_length(v[6]);
225 
226  double p1 = len_a * len_ap;
227  double p2 = len_b * len_bp;
228  double p3 = len_c * len_cp;
229  double p_prod = sqrt((p1+p2+p3)*(p1+p2-p3)*(p1-p2+p3)*(p2+p3-p1));
230 
231  double vol = tet_vol(v[5],v[4],v[6]);
232 
233  R= p_prod/(24.0*vol);
234  r = (3.0*vol)/a_sum;
235  l = len_a;
236  if( len_b < l ){ l = len_b;}
237  if( len_c < l ){ l = len_c;}
238  if( len_ap < l ){ l = len_ap;}
239  if( len_bp < l ){ l = len_bp;}
240  if( len_cp < l ){ l = len_cp;}
241  }
242  else{
243  R = 1.0;
244  r = 1.0;
245  l = 1.0;
246  }
247 }
NT p1
std::vector< Vector_3< double > > v
double sqrt(double d)
Definition: double.h:73
double tet_vol(const Vector_3< double > &a, const Vector_3< double > &b, const Vector_3< double > &c)
Compute the volume of a tetrahedron given three edges from a point as vectors.
Definition: geometry.C:103
double tri_area(const Vector_3< double > &v1, const Vector_3< double > &v2, const Vector_3< double > &v3)
Compute the area of a triangle defined by its three sides as vectors.
Definition: geometry.C:93
double edge_length(const Vector_3< double > &v)
Compute the edge length of a vector.
Definition: geometry.C:89

Here is the call graph for this function:

Here is the caller graph for this function:

void initialize ( Vector_3< double >  n[],
int  type 
)
virtual

Initialize a 3D Geometric Metric by nodal coords and element type.

Parameters
n[]Ordered set of nodal coordinates.
typeElement type: TET or HEX

Implements Metric.

Definition at line 47 of file Geometric_Metrics_3.C.

References v.

Referenced by Rocmop::add_aspect_ratios(), Rocmop::check_all_elem_quality(), Rocmop::check_marked_elem_quality(), main(), Rocmop::obtain_extremal_dihedrals(), Rocmop::perturb_stationary(), Rocmop::print_extremal_dihedrals(), Rocmop::print_mquality(), Rocmop::print_quality(), and Rocmop::smooth_vol_mesq_ng().

47  {
48  _type = type;
49  if (_type == COM::Connectivity::TET4){
50  v.resize(7);
51  v[0]= n[2]-n[1]; v[1]= n[1]-n[2]; v[2]= n[2]-n[0];
52  v[3]= n[1]-n[0]; v[4]= n[3]-n[1]; v[5]= n[3]-n[0];
53  v[6]= n[3]-n[2];
54  }
55  else if (_type == COM::Connectivity::HEX8){
56  v.resize(8);
57  v[0]= n[1]-n[0]; v[1]= n[3]-n[0]; v[2]= n[1]-n[2]; v[3]= n[3]-n[2];
58  v[4]= n[5]-n[1]; v[5]= n[7]-n[3]; v[6]= n[5]-n[4]; v[7]= n[7]-n[4];
59  }
60 }
std::vector< Vector_3< double > > v

Here is the caller graph for this function:

void initialize ( Element_node_enumerator ene)
virtual

Initialize a 3D Geometric Metric by Element_node_enumerator.

Parameters
eneElement_node_enumerator

Implements Metric.

Definition at line 62 of file Geometric_Metrics_3.C.

References COM_assertion_msg, n, and v.

62  {
63  _type = ene.type();
64  if(ene.type() == COM::Connectivity::TET4){
65  v.resize(7);
66  const std::string nc("nc");
67  Element_node_vectors_k_const<double> n;
68  n.set(ene.pane()->attribute(nc),ene);
69  v[0][0]=n(2,0)-n(1,0); v[0][1]=n(2,1)-n(1,1); v[0][2]=n(2,2)-n(1,2);
70  v[1][0]=n(1,0)-n(2,0); v[1][1]=n(1,1)-n(2,1); v[1][2]=n(1,2)-n(2,2);
71  v[2][0]=n(2,0)-n(0,0); v[2][1]=n(2,1)-n(0,1); v[2][2]=n(2,2)-n(0,2);
72  v[3][0]=n(1,0)-n(0,0); v[3][1]=n(1,1)-n(0,1); v[3][2]=n(1,2)-n(0,2);
73  v[4][0]=n(3,0)-n(1,0); v[4][1]=n(3,1)-n(1,1); v[4][2]=n(3,2)-n(1,2);
74  v[5][0]=n(3,0)-n(0,0); v[5][1]=n(3,1)-n(0,1); v[5][2]=n(3,2)-n(0,2);
75  v[6][0]=n(3,0)-n(2,0); v[6][1]=n(3,1)-n(2,1); v[6][2]=n(3,2)-n(2,2);
76  }
77  else if (ene.type() == COM::Connectivity::HEX8){
78  v.resize(8);
79  const std::string nc("nc");
80  Element_node_vectors_k_const<double> n;
81  n.set(ene.pane()->attribute(nc),ene);
82  v[0][0]=n(1,0)-n(0,0); v[0][1]=n(1,1)-n(0,1); v[0][2]=n(1,2)-n(0,2);
83  v[1][0]=n(3,0)-n(0,0); v[1][1]=n(3,1)-n(0,1); v[1][2]=n(3,2)-n(0,2);
84  v[2][0]=n(1,0)-n(2,0); v[2][1]=n(1,1)-n(2,1); v[2][2]=n(1,2)-n(2,2);
85  v[3][0]=n(3,0)-n(2,0); v[3][1]=n(3,1)-n(2,1); v[3][2]=n(3,2)-n(2,2);
86  v[4][0]=n(5,0)-n(1,0); v[4][1]=n(5,1)-n(1,1); v[4][2]=n(5,2)-n(1,2);
87  v[5][0]=n(7,0)-n(3,0); v[5][1]=n(7,1)-n(3,1); v[5][2]=n(7,2)-n(3,2);
88  v[6][0]=n(5,0)-n(4,0); v[6][1]=n(5,1)-n(4,1); v[6][2]=n(5,2)-n(4,2);
89  v[7][0]=n(7,0)-n(4,0); v[7][1]=n(7,1)-n(4,1); v[7][2]=n(7,2)-n(4,2);
90  }
91  else if (ene.type() == COM::Connectivity::PYRIMID5 ||
92  ene.type() == COM::Connectivity::PRISM6){
93  _type = ene.type();
94  _ene_pane = ene.pane();
95  _ene_i = ene.id();
96  }
97  else COM_assertion_msg(0,"Element type not supported for 3D geometric metrics");
98 }
#define COM_assertion_msg(EX, msg)
std::vector< Vector_3< double > > v
const NT & n
const COM::Pane * _ene_pane
virtual double maxValue ( ) const
inlinevirtual

The maximum value for this metric.

Implements Metric.

Reimplemented in Aspect_Metric_3, and Angle_Metric_3.

Definition at line 66 of file Geometric_Metrics_3.h.

66 { return 1.0; }
virtual double minValue ( ) const
inlinevirtual

The minimum value for this metric.

Implements Metric.

Reimplemented in Aspect_Metric_3, and Angle_Metric_3.

Definition at line 69 of file Geometric_Metrics_3.h.

69 { return 0.0; }

Member Data Documentation

int _ene_i
protected

Definition at line 83 of file Geometric_Metrics_3.h.

const COM::Pane* _ene_pane
protected

Definition at line 82 of file Geometric_Metrics_3.h.

int _type
protected

Definition at line 81 of file Geometric_Metrics_3.h.

std::vector<Vector_3<double> > v
protected

Definition at line 80 of file Geometric_Metrics_3.h.


The documentation for this class was generated from the following files: