Rocstar  1.0
Rocstar multiphysics simulation application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
includeLinks/QualityMetric.hpp
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 
37 #ifndef QualityMetric_hpp
38 #define QualityMetric_hpp
39 
40 #ifndef MSQ_USE_OLD_C_HEADERS
41 #include <cmath>
42 #include <cstring>
43 #else
44 #include <math.h>
45 #include <string.h>
46 #endif
47 
48 
49 #include "Mesquite.hpp"
50 #include "MsqError.hpp"
51 #include "Vector3D.hpp"
52 #include "Matrix3D.hpp"
53 
54 namespace Mesquite
55 {
56 
60  class MsqVertex;
61  class MsqMeshEntity;
62  class PatchData;
63 
65  {
66  protected:
77  negateFlag(1)
78  {}
79 
80  public:
81  // This is defined in each concrete class. It isn't virtual, so
82  // it doesn't exist in the base class.
83  // static void create_new() = 0;
84 
85  // virtual destructor ensures use of polymorphism during destruction
86  virtual ~QualityMetric()
87  {};
88 
89 
98  {
103  };
104 
106 
112  {
118  };
119 
122 
125  { return evalMode; }
126 
132  {
148  };
149 
168  inline void set_averaging_method(AveragingMethod method, MsqError &err);
169 
173  inline void set_feasible_constraint(int alpha)
174  { feasible=alpha; }
175 
178  { return feasible; }
179 
181  inline void set_name(msq_std::string st)
182  { metricName=st; }
183 
185  inline msq_std::string get_name()
186  { return metricName; }
187 
189  // det = signed determinant of Jacobian Matrix at a Vertex
190  // delta = scaling parameter
191  inline double vertex_barrier_function(double det, double delta)
192  { return 0.5*(det+sqrt(det*det+4*delta*delta)); }
193 
195  virtual bool evaluate_vertex(PatchData& /*pd*/, MsqVertex* /*vertex*/,
196  double& /*value*/, MsqError &err);
197 
199  virtual bool evaluate_element(PatchData& /*pd*/,
200  MsqMeshEntity* /*element*/,
201  double& /*value*/, MsqError &err);
202 
206  {
209  };
210 
213  { gradType=grad; }
214 
218  {
221  };
222 
225  { hessianType=ht; }
226 
235  MsqVertex* vertices[],Vector3D grad_vec[],
236  int num_vtx, double &metric_value,
237  MsqError &err);
238 
245  MsqVertex* free_vtces[], Vector3D grad_vec[],
246  int num_free_vtx, double &metric_value, MsqError &err);
247 
253  MsqVertex* free_vtces[], Vector3D grad_vec[],
254  int num_free_vtx, double &metric_value, MsqError &err);
255 
262  MsqVertex* free_vtces[], Vector3D grad_vec[],
263  Matrix3D hessian[],
264  int num_free_vtx, double &metric_value, MsqError &err);
265 
270  void set_negate_flag(int neg)
271  { negateFlag=neg; }
272 
275  { return negateFlag; }
284  virtual void change_metric_type(MetricType t, MsqError &err);
285 
286 
287  protected:
288 
292 
295  double average_metrics(const double metric_values[], const int& num_values,
296  MsqError &err);
297 
307  double average_metric_and_weights( double metric_values[],
308  int num_metric_values,
309  MsqError& err );
310 
313  double weighted_average_metrics(const double coef[],
314  const double metric_values[],
315  const int& num_values, MsqError &err);
316 
322  MsqVertex &vertex,
323  MsqVertex* vertices[],
324  Vector3D grad_vec[],
325  int num_vtx,
326  double &metric_value,
327  MsqError &err);
328 
329 
336  MsqVertex* free_vtces[], Vector3D grad_vec[],
337  int num_free_vtx, double &metric_value,
338  MsqError &err);
339 
346  MsqVertex &vertex,
347  MsqVertex* vertices[],
348  Vector3D grad_vec[],
349  int num_vtx,
350  double &metric_value,
351  MsqError &err);
352 
353 
361  MsqMeshEntity* element,
362  MsqVertex* free_vtces[],
363  Vector3D grad_vec[],
364  int num_free_vtx,
365  double &metric_value,
366  MsqError &err);
367 
368 
370  MsqMeshEntity* element,
371  MsqVertex* free_vtces[],
372  Vector3D grad_vec[],
373  Matrix3D hessian[],
374  int num_free_vtx,
375  double &metric_value,
376  MsqError &err);
377 
379  MsqMeshEntity* element,
380  MsqVertex* free_vtces[],
381  Vector3D grad_vec[],
382  Matrix3D hessian[],
383  int num_free_vtx,
384  double &metric_value,
385  MsqError &err);
386 
387  friend class MsqMeshEntity;
388 
389  // TODO : pass this private and write protected access fucntions.
391  int feasible;
392  msq_std::string metricName;
393  private:
399  };
400 
401 
403  {
404  if (mType == VERTEX_BASED) {
405  MSQ_SETERR(err)("function must only be used for ELEMENT_BASED metrics.", MsqError::INVALID_STATE);
406  return;
407  }
408 
409  switch(mode)
410  {
411  case(ELEMENT_VERTICES):
412  case(LINEAR_GAUSS_POINTS):
414  case(CUBIC_GAUSS_POINTS):
415  evalMode=mode;
416  break;
417  default:
418  MSQ_SETERR(err)("Requested mode not implemented", MsqError::NOT_IMPLEMENTED);
419  }
420  return;
421  }
422 
423 
425  {
426  switch(method)
427  {
428  case(NONE):
429  case(GEOMETRIC):
430  case(HARMONIC):
431  case(LINEAR):
432  case(MAXIMUM):
433  case(MINIMUM):
434  case(RMS):
435  case(HMS):
436  case(STANDARD_DEVIATION):
437  case(SUM):
438  case(SUM_SQUARED):
439  case(MAX_OVER_MIN):
440  case(MAX_MINUS_MIN):
441  case(SUM_OF_RATIOS_SQUARED):
442  avgMethod=method;
443  break;
444  default:
445  MSQ_SETERR(err)("Requested Averaging Method Not Implemented", MsqError::NOT_IMPLEMENTED);
446  };
447  return;
448  }
449 
450 
457  MsqVertex &vertex,
458  MsqVertex* vertices[],
459  Vector3D grad_vec[],
460  int num_vtx,
461  double &metric_value,
462  MsqError &err)
463  {
464  bool ret=false;;
465  switch(gradType)
466  {
467  case NUMERICAL_GRADIENT:
468  ret = compute_vertex_numerical_gradient(pd, vertex, vertices,
469  grad_vec, num_vtx,
470  metric_value, err);
471  MSQ_CHKERR(err);
472  break;
473  case ANALYTICAL_GRADIENT:
474  ret = compute_vertex_analytical_gradient(pd, vertex, vertices,
475  grad_vec,num_vtx,
476  metric_value, err);
477  MSQ_CHKERR(err);
478  break;
479  }
480  return ret;
481  }
482 
483 
495  MsqMeshEntity* el,
496  MsqVertex* free_vtces[],
497  Vector3D grad_vec[],
498  int num_free_vtx,
499  double &metric_value,
500  MsqError &err)
501  {
502  bool ret=false;
503  switch(gradType)
504  {
505  case NUMERICAL_GRADIENT:
506  ret = compute_element_numerical_gradient(pd, el, free_vtces, grad_vec,
507  num_free_vtx, metric_value, err);
508  MSQ_CHKERR(err);
509  break;
510  case ANALYTICAL_GRADIENT:
511  ret = compute_element_analytical_gradient(pd, el, free_vtces, grad_vec,
512  num_free_vtx, metric_value, err);
513  MSQ_CHKERR(err);
514  break;
515  }
516  return ret;
517  }
518 
519 
524  inline double QualityMetric::average_metrics(const double metric_values[],
525  const int& num_values, MsqError &err)
526  {
527  //MSQ_MAX needs to be made global?
528  //double MSQ_MAX=1e10;
529  double total_value=0.0;
530  double temp_value=0.0;
531  int i=0;
532  int j=0;
533  //if no values, return zero
534  if (num_values<=0){
535  return 0.0;
536  }
537 
538  switch(avgMethod){
539  case GEOMETRIC:
540  total_value=1.0;
541  for (i=0;i<num_values;++i){
542  total_value*=(metric_values[i]);
543  }
544  total_value=pow(total_value, (1/((double) num_values)));
545  break;
546 
547  case HARMONIC:
548  //ensure no divide by zero, return zero
549  for (i=0;i<num_values;++i){
550  if(metric_values[i]<MSQ_MIN){
551  if(metric_values[i]>MSQ_MIN){
552  return 0.0;
553  }
554  }
555  total_value+=(1/metric_values[i]);
556  }
557  //ensure no divide by zero, return MSQ_MAX_CAP
558  if(total_value<MSQ_MIN){
559  if(total_value>MSQ_MIN){
560  return MSQ_MAX_CAP;
561  }
562  }
563  total_value=num_values/total_value;
564  break;
565 
566  case LINEAR:
567  for (i=0;i<num_values;++i){
568  total_value+=metric_values[i];
569  }
570  total_value/= (double) num_values;
571  break;
572 
573  case MAXIMUM:
574  total_value = metric_values[0];
575  for (i = 1; i < num_values; ++i){
576  if (metric_values[i] > total_value){
577  total_value = metric_values[i];
578  }
579  }
580  break;
581 
582  case MINIMUM:
583  total_value = metric_values[0];
584  for (i = 1; i < num_values; ++i){
585  if (metric_values[i] < total_value) {
586  total_value = metric_values[i];
587  }
588  }
589  break;
590 
591  case NONE:
592  MSQ_SETERR(err)("Averaging method set to NONE", MsqError::INVALID_ARG);
593  break;
594 
595  case RMS:
596  for (i=0;i<num_values;++i){
597  total_value+=(metric_values[i]*metric_values[i]);
598  }
599  total_value/= (double) num_values;
600  total_value=sqrt(total_value);
601  break;
602 
603  case HMS:
604  //ensure no divide by zero, return zero
605  for (i=0;i<num_values;++i){
606  if (metric_values[i]*metric_values[i] < MSQ_MIN) {
607  return 0.0;
608  }
609  total_value += (1.0/(metric_values[i]*metric_values[i]));
610  }
611 
612  //ensure no divide by zero, return MSQ_MAX_CAP
613  if (total_value < MSQ_MIN) {
614  return MSQ_MAX_CAP;
615  }
616  total_value = sqrt(num_values/total_value);
617  break;
618 
619  case STANDARD_DEVIATION:
620  total_value=0;
621  temp_value=0;
622  for (i=0;i<num_values;++i){
623  temp_value+=metric_values[i];
624  total_value+=(metric_values[i]*metric_values[i]);
625  }
626  temp_value/= (double) num_values;
627  temp_value*=temp_value;
628  total_value/= (double) num_values;
629  total_value-=temp_value;
630  break;
631 
632  case SUM:
633  for (i=0;i<num_values;++i){
634  total_value+=metric_values[i];
635  }
636  break;
637 
638  case SUM_SQUARED:
639  for (i=0;i<num_values;++i){
640  total_value+= (metric_values[i]*metric_values[i]);
641  }
642  break;
643 
644  case MAX_MINUS_MIN:
645  //total_value used to store the maximum
646  //temp_value used to store the minimum
647  temp_value=MSQ_MAX_CAP;
648  for (i=0;i<num_values;++i){
649  if(metric_values[i]<temp_value){
650  temp_value=metric_values[i];
651  }
652  if(metric_values[i]>total_value){
653  total_value=metric_values[i];
654  }
655  }
656 
657  //ensure no divide by zero, return MSQ_MAX_CAP
658  if (temp_value < MSQ_MIN) {
659  return MSQ_MAX_CAP;
660  }
661  total_value-=temp_value;
662  break;
663 
664  case MAX_OVER_MIN:
665  //total_value used to store the maximum
666  //temp_value used to store the minimum
667  temp_value=MSQ_MAX_CAP;
668  for (i=0;i<num_values;++i){
669  if(metric_values[i]<temp_value){
670  temp_value=metric_values[i];
671  }
672  if(metric_values[i]>total_value){
673  total_value=metric_values[i];
674  }
675  }
676 
677  //ensure no divide by zero, return MSQ_MAX_CAP
678  if (temp_value < MSQ_MIN) {
679  return MSQ_MAX_CAP;
680  }
681  total_value/=temp_value;
682  break;
683 
685  for (j=0;j<num_values;++j){
686  //ensure no divide by zero, return MSQ_MAX_CAP
687  if (metric_values[j] < MSQ_MIN) {
688  return MSQ_MAX_CAP;
689  }
690  for (i=0;i<num_values;++i){
691  total_value+=((metric_values[i]/metric_values[j])*
692  (metric_values[i]/metric_values[j]));
693  }
694  }
695  total_value/=(double)(num_values*num_values);
696  break;
697 
698  default:
699  //Return error saying Averaging Method mode not implemented
700  MSQ_SETERR(err)("Requested Averaging Method Not Implemented", MsqError::NOT_IMPLEMENTED);
701  return 0;
702  }
703  return total_value;
704  }
705 
706 
707 
708  inline double QualityMetric::weighted_average_metrics(const double coef[],
709  const double metric_values[],
710  const int& num_values, MsqError &err)
711  {
712  //MSQ_MAX needs to be made global?
713  //double MSQ_MAX=1e10;
714  double total_value=0.0;
715  int i=0;
716  //if no values, return zero
717  if (num_values<=0){
718  return 0.0;
719  }
720 
721  switch(avgMethod){
722 
723  case LINEAR:
724  for (i=0;i<num_values;++i){
725  total_value += coef[i]*metric_values[i];
726  }
727  total_value /= (double) num_values;
728  break;
729 
730  default:
731  //Return error saying Averaging Method mode not implemented
732  MSQ_SETERR(err)("Requested Averaging Method Not Implemented",MsqError::NOT_IMPLEMENTED);
733  return 0;
734  }
735  return total_value;
736  }
737 
738 
739 } //namespace
740 
741 
742 #endif // QualityMetric_hpp
void set_averaging_method(AveragingMethod method, MsqError &err)
const double MSQ_MAX_CAP
Definition: Mesquite.hpp:173
bool compute_element_numerical_gradient(PatchData &pd, MsqMeshEntity *element, MsqVertex *free_vtces[], Vector3D grad_vec[], int num_free_vtx, double &metric_value, MsqError &err)
Non-virtual function which numerically computes the gradient of a QualityMetric of a given element fo...
int get_negate_flag()
Returns negateFlag.
ElementEvaluationMode get_element_evaluation_mode()
Returns the evaluation mode for the metric.
double vertex_barrier_function(double det, double delta)
Escobar Barrier Function for Shape and Other Metrics.
bool compute_element_numerical_hessian(PatchData &pd, MsqMeshEntity *element, MsqVertex *free_vtces[], Vector3D grad_vec[], Matrix3D hessian[], int num_free_vtx, double &metric_value, MsqError &err)
bool compute_vertex_gradient(PatchData &pd, MsqVertex &vertex, MsqVertex *vertices[], Vector3D grad_vec[], int num_vtx, double &metric_value, MsqError &err)
Calls compute_vertex_numerical_gradient if gradType equals NUMERCIAL_GRADIENT. Calls compute_vertex_a...
Used to hold the error state and return it to the application.
Base class for concrete quality metrics.
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...
double sqrt(double d)
Definition: double.h:73
virtual bool compute_element_analytical_hessian(PatchData &pd, MsqMeshEntity *element, MsqVertex *free_vtces[], Vector3D grad_vec[], Matrix3D hessian[], int num_free_vtx, double &metric_value, MsqError &err)
double average_metric_and_weights(double metric_values[], int num_metric_values, MsqError &err)
Given a list of metric values, calculate the average metric valude according to the current avgMethod...
void set_hessian_type(HESSIAN_TYPE ht)
Sets hessianType for this metric.
bool compute_element_hessian(PatchData &pd, MsqMeshEntity *element, MsqVertex *free_vtces[], Vector3D grad_vec[], Matrix3D hessian[], int num_free_vtx, double &metric_value, MsqError &err)
For MetricType == ELEMENT_BASED. Calls either compute_element_numerical_hessian() or compute_element_...
invalid function argument passed
virtual void change_metric_type(MetricType t, MsqError &err)
void set_element_evaluation_mode(ElementEvaluationMode mode, MsqError &err)
Sets the evaluation mode for the ELEMENT_BASED metrics.
#define MSQ_CHKERR(err)
Mesquite&#39;s Error Checking macro.
3*3 Matric class, row-oriented, 0-based [i][j] indexing.
bool compute_element_gradient(PatchData &pd, MsqMeshEntity *element, MsqVertex *free_vtces[], Vector3D grad_vec[], int num_free_vtx, double &metric_value, MsqError &err)
For MetricType == ELEMENT_BASED. Calls either compute_element_numerical_gradient() or compute_element...
double weighted_average_metrics(const double coef[], const double metric_values[], const int &num_values, MsqError &err)
takes an array of coefficients and an array of metrics (both of length num_value) and averages the co...
#define MSQ_SETERR(err)
Macro to set error - use err.clear() to clear.
blockLoc i
Definition: read.cpp:79
virtual bool compute_element_analytical_gradient(PatchData &pd, MsqMeshEntity *element, MsqVertex *free_vtces[], Vector3D grad_vec[], int num_free_vtx, double &metric_value, MsqError &err)
Virtual function that computes the gradient of the QualityMetric analytically. The base class impleme...
virtual bool evaluate_element(PatchData &, MsqMeshEntity *, double &, MsqError &err)
Evaluate the metric for an element.
double det(const Matrix3D &A)
virtual bool evaluate_vertex(PatchData &, MsqVertex *, double &, MsqError &err)
Evaluate the metric for a vertex.
msq_std::string get_name()
Returns the name of this metric (as a string).
j indices j
Definition: Indexing.h:6
bool compute_element_gradient_expanded(PatchData &pd, MsqMeshEntity *element, MsqVertex *free_vtces[], Vector3D grad_vec[], int num_free_vtx, double &metric_value, MsqError &err)
void set_gradient_type(GRADIENT_TYPE grad)
Sets gradType for this metric.
object is in an invalid state
void set_metric_type(MetricType t)
This function should be used in the constructor of every concrete quality metric. ...
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 ...
MsqVertex is the Mesquite object that stores information about the vertices in the mesh...
virtual bool compute_vertex_analytical_gradient(PatchData &pd, MsqVertex &vertex, MsqVertex *vertices[], Vector3D grad_vec[], int num_vtx, double &metric_value, MsqError &err)
Virtual function that computes the gradient of the QualityMetric analytically. The base class impleme...
int get_feasible_constraint()
Returns the feasible flag for this metric.
void set_name(msq_std::string st)
Sets the name of this metric.
double pow(double value, const Exponent &exp)
bool compute_vertex_numerical_gradient(PatchData &pd, MsqVertex &vertex, MsqVertex *vertices[], Vector3D grad_vec[], int num_vtx, double &metric_value, MsqError &err)
const double MSQ_MIN
Definition: Mesquite.hpp:160