Rocstar  1.0
Rocstar multiphysics simulation application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
QualityMetric/Volume/LocalSizeQualityMetric.cpp
Go to the documentation of this file.
1 /* *****************************************************************
2  MESQUITE -- The Mesh Quality Improvement Toolkit
3 
4  Copyright 2004 Sandia Corporation and Argonne National
5  Laboratory. Under the terms of Contract DE-AC04-94AL85000
6  with Sandia Corporation, the U.S. Government retains certain
7  rights in this software.
8 
9  This library is free software; you can redistribute it and/or
10  modify it under the terms of the GNU Lesser General Public
11  License as published by the Free Software Foundation; either
12  version 2.1 of the License, or (at your option) any later version.
13 
14  This library is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  Lesser General Public License for more details.
18 
19  You should have received a copy of the GNU Lesser General Public License
20  (lgpl.txt) along with this library; if not, write to the Free Software
21  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 
23  diachin2@llnl.gov, djmelan@sandia.gov, mbrewer@sandia.gov,
24  pknupp@sandia.gov, tleurent@mcs.anl.gov, tmunson@mcs.anl.gov
25 
26  ***************************************************************** */
37 #include "Vector3D.hpp"
38 #include "QualityMetric.hpp"
39 #include "MsqVertex.hpp"
40 #include "PatchData.hpp"
41 #include "MsqMeshEntity.hpp"
42 
43 #ifdef MSQ_USE_OLD_STD_HEADERS
44 # include <vector.h>
45 #else
46 # include <vector>
47  using std::vector;
48 #endif
49 
50 
51 using namespace Mesquite;
52 
62  double &fval, MsqError &err)
63 {
64  fval=0.0;
65  //get the element array
66  MsqMeshEntity* elems = pd.get_element_array(err); MSQ_ERRZERO(err);
67  //conver the MsqVertex pointer into an index
68  size_t this_vert = pd.get_vertex_index(vert);
69  //get the vertex to element array and the offset array
70  //const size_t* elem_offset = pd.get_vertex_to_elem_offset(err); MSQ_ERRZERO(err);
71  //const size_t* v_to_e_array = pd.get_vertex_to_elem_array(err); MSQ_ERRZERO(err);
72  //find the offset for this vertex
73  //size_t this_offset = elem_offset[this_vert];
74  //get the number of elements attached to this vertex (given by the
75  //first entry in the vertex to element array)
76  //size_t num_elems = v_to_e_array[this_offset];
77  //PRINT_INFO("\nIN LOCAL SIZE CPP, num_elements = %i",num_elems);
78  size_t num_elems, *v_to_e_array;
79  v_to_e_array = pd.get_vertex_element_adjacencies( this_vert, num_elems, err );
80  MSQ_ERRZERO(err);
81 
82  if(num_elems <= 0){
83  return true;
84  }
85 
86  //create an array to store the local metric values before averaging
87  //Can we remove this dynamic allocatio?
88  double* met_vals = new double[num_elems];
89  //vector to hold the other verts which form a corner.
90  vector<size_t> other_vertices;
91  other_vertices.reserve(4);
92  double total_val=0.0;
93  size_t i=0;
94  //loop over the elements attached to this vertex
95  for(i=0;i<num_elems;++i){
96  //get the vertices which (with this_vert) form the corner of
97  //the ith element.
98  elems[v_to_e_array[i]].get_connected_vertices(this_vert,
99  other_vertices,
100  err); MSQ_ERRZERO(err);
102 
103  switch(other_vertices.size()){
104  //if a surface element, compute the corner area
105  case 2:
106  met_vals[i] = compute_corner_area(pd, this_vert, other_vertices[0],
107  other_vertices[1], err); MSQ_ERRZERO(err);
108  break;
109  //if a volume element, compute the corner volume
110  case 3:
111  met_vals[i] = compute_corner_volume(pd, this_vert, other_vertices[0],
112  other_vertices[1],
113  other_vertices[2], err); MSQ_ERRZERO(err);
114  break;
115  default:
116  //otherwise, there is was an error. Either the wrong number
117  //of vertices were returned fom get_connected_vertices or
118  //the element does not have the correct number of edges
119  //connected to this vertex (possibly a pyramid element).
120  met_vals[i]=0.0;
121  MSQ_SETERR(err)("Incorrect number of vertices returned from "
122  "get_connected_vertices.", MsqError::INTERNAL_ERROR);
123  };
124  //keep track of total so that we can compute the linear average
125  total_val+=met_vals[i];
126  //PRINT_INFO("\nIN LOCAL SIZE CPP, total_val = %f, i = %i",total_val,i);
127  //clear the vector of other_vertices for re-use.
128  other_vertices.clear();
129  //PRINT_INFO("\nIN LOCAL SIZE CPP, after clean size = %f",other_vertices.size());
130 
131  }
132  //calculate the linear average... num_elems is non-zero here.
133  total_val /= (double) num_elems;
134  //PRINT_INFO("\nIN LOCAL SIZE CPP, average = %f",total_val);
135  //if the average is non-zero
136  //divide each entry by the linear average
137  if(total_val!=0){
138  for(i=0;i<num_elems;++i){
139  met_vals[i]/=total_val;
140  }
141  //calculate fval by averaging the corner values
142  fval = average_metrics(met_vals, num_elems, err); MSQ_ERRZERO(err);
143  //PRINT_INFO("\nIN LOCAL SIZE CPP, inside if statement");
144  }
145  //PRINT_INFO("\nIN LOCAL SIZE CPP, fval = %f",fval);
146  //clean up the dynamically allocated array
147  delete []met_vals;
148  //always return true... the vertex position is never invalid
149  return true;
150 
151 }
152 
#define MSQ_ERRZERO(err)
Return zero/NULL on error.
Used to hold the error state and return it to the application.
double compute_corner_area(PatchData &pd, size_t vert_1, size_t vert_2, size_t vert_3, MsqError &err)
Calculate the area of the triangle formed by the three vertices.
MsqMeshEntity is the Mesquite object that stores information about the elements in the mesh...
size_t get_vertex_index(MsqVertex *vertex)
#define MSQ_SETERR(err)
Macro to set error - use err.clear() to clear.
bool evaluate_vertex(PatchData &pd, MsqVertex *vert, double &fval, MsqError &err)
For the given vertex, vert, calculate the local size metric value.
blockLoc i
Definition: read.cpp:79
void get_connected_vertices(msq_stdc::size_t vertex_index, msq_std::vector< msq_stdc::size_t > &vert_indices, MsqError &err)
Fills a vector&lt;size_t&gt; with vertices connected to the given vertex through the edges of this MsqMeshE...
double compute_corner_volume(PatchData &pd, size_t vert_1, size_t vert_2, size_t vert_3, size_t vert_4, MsqError &err)
Calculate the volume of the tetrahedron formed by the four vertices.
double average_metrics(const double metric_values[], const int &num_values, MsqError &err)
average_metrics takes an array of length num_values and averages the contents using averaging method ...
const MsqMeshEntity * get_element_array(MsqError &err) const
Returns a pointer to the start of the element array.
MsqVertex is the Mesquite object that stores information about the vertices in the mesh...
size_t * get_vertex_element_adjacencies(size_t vertex_index, size_t &array_len_out, MsqError &err)