Rocstar  1.0
Rocstar multiphysics simulation application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
TargetCalculator/TargetCalculator.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  ***************************************************************** */
27 
39 #include "TargetCalculator.hpp"
40 #include "PatchDataUser.hpp"
41 #include "MeshSet.hpp"
42 #include "MsqTimer.hpp"
43 #include "TargetMatrix.hpp"
44 
45 using namespace Mesquite;
46 
48 {
49  if (refMesh)
50  refMesh->reset(err);
51  MSQ_CHKERR(err);
52 }
53 
54 
56 {
57  MSQ_FUNCTION_TIMER( "TargetCalculator::compute_target_matrices_and_check_det" );
58 
59  // Compute the target matrices
60  compute_target_matrices(pd, err); MSQ_ERRRTN(err);
61 
62  //checks that the determinant of each target matrix is positive.
63  MsqMeshEntity* elems=pd.get_element_array(err); MSQ_ERRRTN(err);
64  size_t num_elements=pd.num_elements();
65  for (size_t i=0; i<num_elements; ++i) {
66  const TargetMatrix* matrices = pd.targetMatrices.get_element_corner_tags(&pd, i, err);
67  MSQ_ERRRTN(err);
68  size_t num_corners = elems[i].vertex_count();
69  for (size_t j=0; j<num_corners; ++j) {
70  if ( det(matrices[j]) <= 0 ) {
71  MSQ_SETERR(err)("A Target matrix has a non-positive determinant. "
72  "Please review your target calculator.",
74  return;
75  }
76  }
77  }
78 }
79 
80 
82  MsqError &err)
83 {
84  MSQ_FUNCTION_TIMER( "TargetCalculator::compute_default_target_matrices" );
85 
86  MsqMeshEntity* elems=pd.get_element_array(err); MSQ_ERRRTN(err);
87  size_t num_elements=pd.num_elements();
88 
89  Matrix3D tmp_tri, tmp_quad, tmp_tet, tmp_hex;
90  initialize_default_target_matrices(tmp_tri, tmp_quad, tmp_tet, tmp_hex);
91 
92  TargetMatrix matrices[8];
93 
94  // set the corner matrices to the correct value for each tag.
95  for (size_t i=0; i<num_elements; ++i) {
96 
97  EntityTopology type = elems[i].get_element_type();
98  switch (type)
99  {
100  case TRIANGLE:
101  matrices[0] = tmp_tri;
102  matrices[1] = tmp_tri;
103  matrices[2] = tmp_tri;
104  break;
105  case QUADRILATERAL:
106  matrices[0] = tmp_quad;
107  matrices[1] = tmp_quad;
108  matrices[2] = tmp_quad;
109  matrices[3] = tmp_quad;
110  break;
111  case TETRAHEDRON:
112  matrices[0] = tmp_tet;
113  matrices[1] = tmp_tet;
114  matrices[2] = tmp_tet;
115  matrices[3] = tmp_tet;
116  break;
117  case HEXAHEDRON:
118  matrices[0] = tmp_hex;
119  matrices[1] = tmp_hex;
120  matrices[2] = tmp_hex;
121  matrices[3] = tmp_hex;
122  matrices[4] = tmp_hex;
123  matrices[5] = tmp_hex;
124  matrices[6] = tmp_hex;
125  matrices[7] = tmp_hex;
126  break;
127  default:
128  MSQ_SETERR(err)("Type not implemented.",MsqError::NOT_IMPLEMENTED);
129  return;
130  } //end switch
131 
132  pd.targetMatrices.set_element_corner_tags( &pd, i, matrices, err ); MSQ_ERRRTN(err);
133  } // end loop
134 }
135 
136 
138  MsqError &err)
139 {
140  MSQ_FUNCTION_TIMER( "TargetCalculator::compute_reference_corner_matrices" );
141 
142  PatchData ref_pd;
143  if (refMesh)
144  refMesh->get_next_patch(ref_pd, this->get_all_parameters(), err);
145  else
146  MSQ_SETERR(err)("No reference mesh", MsqError::INVALID_STATE);
147  MSQ_ERRRTN(err);
148 
149  // Make sure topology of ref_pd and pd are equal
150  size_t num_elements=pd.num_elements();
151  assert( num_elements == ref_pd.num_elements() );
152  size_t num_vertices=pd.num_vertices();
153  assert( num_vertices == ref_pd.num_vertices() );
154 
155  // Compute corner matrices for ref_pd and store in pd tags.
156  MsqMeshEntity* elems = pd.get_element_array(err);
157  MsqMeshEntity* elems_ref = ref_pd.get_element_array(err); MSQ_ERRRTN(err);
159  for (size_t i=0; i<num_elements; ++i) {
160  int nve = elems[i].vertex_count();
161  assert( nve = elems_ref[i].vertex_count() );
162  elems_ref[i].compute_corner_matrices(ref_pd, A, nve, err); MSQ_ERRRTN(err);
163  pd.targetMatrices.set_element_corner_tags( &pd, i, A, err ); MSQ_ERRRTN(err);
164  }
165 }
166 
167 
168  void TargetCalculator::compute_guide_matrices(enum guide_type type, PatchData &ref_pd, size_t elem_ind,
169  Matrix3D W_k[], int num, MsqError &err)
170  {
171 
172 
173  MsqMeshEntity* elems = ref_pd.get_element_array(err); MSQ_ERRRTN(err);
174  size_t nve = elems[elem_ind].vertex_count();
175  int i;
176 
177  switch(type) {
178  case Ad:
179  {
180  Matrix3D tmp_tri, tmp_quad, tmp_tet, tmp_hex;
181  initialize_default_target_matrices(tmp_tri, tmp_quad, tmp_tet, tmp_hex);
182  EntityTopology elem_type = elems[elem_ind].get_element_type();
183  switch (elem_type) {
184  case TRIANGLE:
185  for (i=0; i<3; ++i) W_k[i] = tmp_tri;
186  break;
187  case QUADRILATERAL:
188  for (i=0; i<4; ++i) W_k[i] = tmp_quad;
189  break;
190  case TETRAHEDRON:
191  for (i=0; i<4; ++i) W_k[i] = tmp_tet;
192  break;
193  case HEXAHEDRON:
194  for (i=0; i<8; ++i) W_k[i] = tmp_hex;
195  break;
196  default:
197  MSQ_SETERR(err)("Element type not implemented.",MsqError::NOT_IMPLEMENTED);
198  return;
199  }
200  }
201  return;
202  case A0:
203  elems[elem_ind].compute_corner_matrices(ref_pd, W_k, nve, err); MSQ_ERRRTN(err);
204  return;
205  case Ar:
206  elems[elem_ind].compute_corner_matrices(ref_pd, W_k, nve, err); MSQ_ERRRTN(err);
207  return;
208  default:
209  MSQ_SETERR(err)("Element type not implemented.",MsqError::NOT_IMPLEMENTED);
210  return;
211  }
212 
213  }
214 
217  {
218  Vector3D a1(A[0][0], A[1][0], A[2][0]);
219  Vector3D a2(A[0][1], A[1][1], A[2][1]);
220  Vector3D a3(A[0][2], A[1][2], A[2][2]);
221 
222  double a1_norm = A.column_length(0);
223  Vector3D a1_x_a2 = a1 * a2;
224  double a1_x_a2_norm = a1_x_a2.length();
225 
226  Matrix3D V;
227  Vector3D v1, v2, v3;
228 
229  double a1_norm_inv = 1./a1_norm;
230  double a1_x_a2_norm_inv = 1./a1_x_a2_norm;
231  if (!finite(a1_norm_inv) || !finite(a1_x_a2_norm_inv)) {
232  MSQ_SETERR(err)("Numerical error", MsqError::INVALID_STATE);
233  }
234 
235  // note : % is the dot product
236  v1 = a1_norm_inv * a1;
237  v2 = ((-(a1%a2) * a1) + (a1_norm*a1_norm)*a2) * a1_norm_inv * a1_x_a2_norm_inv;
238  v3 = a1_x_a2_norm_inv * a1_x_a2;
239 
240  V.set_column(0, v1);
241  V.set_column(1, v2);
242  V.set_column(2, v3);
243 
244  return V;
245  }
246 
247  msq_std::string TargetCalculator::get_name()
248  { return "Target Calculator"; }
249 
252 
254  {
255  // Currently, target calculators only work with global patches.
256  // The constructor for TargetCalculator sets the patch type
257  // to global, so if we don't have a global patch here something is
258  // really messed up.
259  PatchData* pd = get_global_patch();
260  if (get_patch_type() != PatchData::GLOBAL_PATCH || NULL == pd)
261  {
263  return 0.0;
264  }
265 
266  // Compute the target matrices.
268  return MSQ_CHKERR(err);
269  }
270 
271 
void compute_default_target_matrices(PatchData &pd, MsqError &err)
Compute the default &quot;isotropic&quot; target matrices that are often used in the computation of reference-b...
virtual AlgorithmType get_algorithm_type()
Return the algorithm type (to avoid RTTI use).
virtual msq_std::string get_name()
Returns the algorithm name.
CornerTag< TargetMatrix > targetMatrices
Target matrix data.
Used to hold the error state and return it to the application.
EntityTopology
Definition: Mesquite.hpp:92
PatchDataParameters & get_all_parameters()
Returns the PatchDataParameters object.
void compute_guide_matrices(enum guide_type type, PatchData &ref_pd, size_t elem_ind, Matrix3D A[], int num, MsqError &err)
Computes the guide corner matrices A for a given element index in the reference patch.
requested functionality is not (yet) implemented
MsqMeshEntity is the Mesquite object that stores information about the elements in the mesh...
Vector3D is the object that effeciently stores information about about three-deminsional vectors...
Matrix3D compute_V_3D(const Matrix3D &A, MsqError &err)
const int MSQ_MAX_NUM_VERT_PER_ENT
Definition: Mesquite.hpp:120
static void initialize_default_target_matrices(Matrix3D &tri_M3D, Matrix3D &quad_M3D, Matrix3D &tet_M3D, Matrix3D &hex_M3D)
rational * A
Definition: vinci_lass.c:67
size_t num_elements() const
number of elements in the Patch.
void compute_reference_corner_matrices(PatchData &pd, MsqError &err)
Compute the corner matrices for the reference mesh refMesh.
msq_stdc::size_t vertex_count() const
Returns the number of vertices in this element, based on its element type.
#define MSQ_CHKERR(err)
Mesquite&#39;s Error Checking macro.
3*3 Matric class, row-oriented, 0-based [i][j] indexing.
#define MSQ_SETERR(err)
Macro to set error - use err.clear() to clear.
double column_length(int i) const
returns the column length – i is 0-based.
blockLoc i
Definition: read.cpp:79
PatchData::PatchType get_patch_type()
Returns the Patch Type.
size_t num_vertices() const
number of vertices in the patch.
void compute_target_matrices_and_check_det(PatchData &pd, MsqError &err)
This function wraps compute_target_matrices and checks that the determinant of each target is positiv...
double det(const Matrix3D &A)
void set_column(int j, const Vector3D &c)
Sets column j (0, 1 or 2) to Vector3D c.
PatchData * get_global_patch()
Returns the Global Patch.
j indices j
Definition: Indexing.h:6
Class containing the target corner matrices for the context based smoothing.
EntityTopology get_element_type() const
Returns element type.
object is in an invalid state
const MsqMeshEntity * get_element_array(MsqError &err) const
Returns a pointer to the start of the element array.
void compute_corner_matrices(PatchData &pd, Matrix3D A[], int num_m3d, MsqError &err)
Compute matrices which column are the vectors issued from a corner.
void reset_reference_meshset(MsqError &err)
Reset the reference mesh so it starts from the first vertex again.
#define MSQ_ERRRTN(err)
If passed error is true, return from a void function.
The MeshSet class stores one or more Mesquite::Mesh pointers and manages access to the mesh informati...
void reset(MsqError &err)
Resets the MeshSet object so that get_next_patch() will restart its iterations at the first vertex...
bool get_next_patch(PatchData &pd, PatchDataUser *pd_user, MsqError &err)
Gets the next PatchData.
virtual void compute_target_matrices(PatchData &pd, MsqError &err)=0
This function provides the corner matrices for all elements on the Patch.
virtual double loop_over_mesh(MeshSet &ms, MsqError &err)
This is the &quot;run&quot; function of PatchDataUser. It can do anything really.