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

Class containing the target corner matrices for the context based smoothing. More...

#include <RI_DFT.hpp>

Inheritance diagram for RI_DFT:
Collaboration diagram for RI_DFT:

Public Member Functions

 RI_DFT ()
 
virtual ~RI_DFT ()
 virtual destructor ensures use of polymorphism during destruction More...
 
bool evaluate_element (PatchData &pd, MsqMeshEntity *e, double &m, MsqError &err)
 Evaluate the metric for an element. More...
 
bool compute_element_analytical_gradient (PatchData &pd, MsqMeshEntity *e, MsqVertex *fv[], Vector3D g[], int nfv, double &m, MsqError &err)
 Virtual function that computes the gradient of the QualityMetric analytically. The base class implementation of this function simply prints a warning and calls compute_numerical_gradient to calculate the gradient. This is used by metric which mType is ELEMENT_BASED. For parameters, see compute_element_gradient() . More...
 
bool compute_element_analytical_hessian (PatchData &pd, MsqMeshEntity *e, MsqVertex *fv[], Vector3D g[], Matrix3D h[], int nfv, double &m, MsqError &err)
 
 RI_DFT ()
 
virtual ~RI_DFT ()
 virtual destructor ensures use of polymorphism during destruction More...
 
bool evaluate_element (PatchData &pd, MsqMeshEntity *e, double &m, MsqError &err)
 Evaluate the metric for an element. More...
 
bool compute_element_analytical_gradient (PatchData &pd, MsqMeshEntity *e, MsqVertex *fv[], Vector3D g[], int nfv, double &m, MsqError &err)
 Virtual function that computes the gradient of the QualityMetric analytically. The base class implementation of this function simply prints a warning and calls compute_numerical_gradient to calculate the gradient. This is used by metric which mType is ELEMENT_BASED. For parameters, see compute_element_gradient() . More...
 
bool compute_element_analytical_hessian (PatchData &pd, MsqMeshEntity *e, MsqVertex *fv[], Vector3D g[], Matrix3D h[], int nfv, double &m, MsqError &err)
 
- Public Member Functions inherited from DistanceFromTarget
virtual ~DistanceFromTarget ()
 virtual destructor ensures use of polymorphism during destruction More...
 
virtual ~DistanceFromTarget ()
 virtual destructor ensures use of polymorphism during destruction More...
 
- Public Member Functions inherited from QualityMetric
virtual ~QualityMetric ()
 
MetricType get_metric_type ()
 
void set_element_evaluation_mode (ElementEvaluationMode mode, MsqError &err)
 Sets the evaluation mode for the ELEMENT_BASED metrics. More...
 
ElementEvaluationMode get_element_evaluation_mode ()
 Returns the evaluation mode for the metric. More...
 
void set_averaging_method (AveragingMethod method, MsqError &err)
 
void set_feasible_constraint (int alpha)
 
int get_feasible_constraint ()
 Returns the feasible flag for this metric. More...
 
void set_name (msq_std::string st)
 Sets the name of this metric. More...
 
msq_std::string get_name ()
 Returns the name of this metric (as a string). More...
 
double vertex_barrier_function (double det, double delta)
 Escobar Barrier Function for Shape and Other Metrics. More...
 
virtual bool evaluate_vertex (PatchData &, MsqVertex *, double &, MsqError &err)
 Evaluate the metric for a vertex. More...
 
void set_gradient_type (GRADIENT_TYPE grad)
 Sets gradType for this metric. More...
 
void set_hessian_type (HESSIAN_TYPE ht)
 Sets hessianType for this metric. More...
 
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_analytical_gradient if gradType equals ANALYTICAL_GRADIENT;. More...
 
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_analytical_gradient() for gradType equal NUMERICAL_GRADIENT or ANALYTICAL_GRADIENT, respectively. More...
 
bool compute_element_gradient_expanded (PatchData &pd, MsqMeshEntity *element, MsqVertex *free_vtces[], Vector3D grad_vec[], int num_free_vtx, double &metric_value, MsqError &err)
 
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_analytical_hessian() for hessianType equal NUMERICAL_HESSIAN or ANALYTICAL_HESSIAN, respectively. More...
 
void set_negate_flag (int neg)
 
int get_negate_flag ()
 Returns negateFlag. More...
 
virtual void change_metric_type (MetricType t, MsqError &err)
 
virtual ~QualityMetric ()
 
MetricType get_metric_type ()
 
void set_element_evaluation_mode (ElementEvaluationMode mode, MsqError &err)
 Sets the evaluation mode for the ELEMENT_BASED metrics. More...
 
ElementEvaluationMode get_element_evaluation_mode ()
 Returns the evaluation mode for the metric. More...
 
void set_averaging_method (AveragingMethod method, MsqError &err)
 
void set_feasible_constraint (int alpha)
 
int get_feasible_constraint ()
 Returns the feasible flag for this metric. More...
 
void set_name (msq_std::string st)
 Sets the name of this metric. More...
 
msq_std::string get_name ()
 Returns the name of this metric (as a string). More...
 
double vertex_barrier_function (double det, double delta)
 Escobar Barrier Function for Shape and Other Metrics. More...
 
virtual bool evaluate_vertex (PatchData &, MsqVertex *, double &, MsqError &err)
 Evaluate the metric for a vertex. More...
 
void set_gradient_type (GRADIENT_TYPE grad)
 Sets gradType for this metric. More...
 
void set_hessian_type (HESSIAN_TYPE ht)
 Sets hessianType for this metric. More...
 
bool compute_vertex_gradient (PatchData &pd, MsqVertex &vertex, MsqVertex *vertices[], Vector3D grad_vec[], int num_vtx, double &metric_value, MsqError &err)
 
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_analytical_gradient() for gradType equal NUMERICAL_GRADIENT or ANALYTICAL_GRADIENT, respectively. More...
 
bool compute_element_gradient_expanded (PatchData &pd, MsqMeshEntity *element, MsqVertex *free_vtces[], Vector3D grad_vec[], int num_free_vtx, double &metric_value, MsqError &err)
 
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_analytical_hessian() for hessianType equal NUMERICAL_HESSIAN or ANALYTICAL_HESSIAN, respectively. More...
 
void set_negate_flag (int neg)
 
int get_negate_flag ()
 Returns negateFlag. More...
 
virtual void change_metric_type (MetricType t, MsqError &err)
 

Private Attributes

double a
 
Exponent b
 
Exponent c
 
Vector3D mNormal
 
Vector3D mCoords [4]
 
Vector3D mGrads [4]
 
Vector3D mAccGrads [8]
 
Matrix3D mHessians [10]
 
Matrix3D invW
 

Additional Inherited Members

- Public Types inherited from QualityMetric
enum  MetricType {
  MT_UNDEFINED, VERTEX_BASED, ELEMENT_BASED, VERTEX_BASED_FREE_ONLY,
  MT_UNDEFINED, VERTEX_BASED, ELEMENT_BASED, VERTEX_BASED_FREE_ONLY
}
 
enum  ElementEvaluationMode {
  EEM_UNDEFINED, ELEMENT_VERTICES, LINEAR_GAUSS_POINTS, QUADRATIC_GAUSS_POINTS,
  CUBIC_GAUSS_POINTS, EEM_UNDEFINED, ELEMENT_VERTICES, LINEAR_GAUSS_POINTS,
  QUADRATIC_GAUSS_POINTS, CUBIC_GAUSS_POINTS
}
 
enum  AveragingMethod {
  NONE, LINEAR, RMS, HMS,
  MINIMUM, MAXIMUM, HARMONIC, GEOMETRIC,
  SUM, SUM_SQUARED, GENERALIZED_MEAN, STANDARD_DEVIATION,
  MAX_OVER_MIN, MAX_MINUS_MIN, SUM_OF_RATIOS_SQUARED, NONE,
  LINEAR, RMS, HMS, MINIMUM,
  MAXIMUM, HARMONIC, GEOMETRIC, SUM,
  SUM_SQUARED, GENERALIZED_MEAN, STANDARD_DEVIATION, MAX_OVER_MIN,
  MAX_MINUS_MIN, SUM_OF_RATIOS_SQUARED
}
 
enum  GRADIENT_TYPE { NUMERICAL_GRADIENT, ANALYTICAL_GRADIENT, NUMERICAL_GRADIENT, ANALYTICAL_GRADIENT }
 
enum  HESSIAN_TYPE { NUMERICAL_HESSIAN, ANALYTICAL_HESSIAN, NUMERICAL_HESSIAN, ANALYTICAL_HESSIAN }
 
enum  MetricType {
  MT_UNDEFINED, VERTEX_BASED, ELEMENT_BASED, VERTEX_BASED_FREE_ONLY,
  MT_UNDEFINED, VERTEX_BASED, ELEMENT_BASED, VERTEX_BASED_FREE_ONLY
}
 
enum  ElementEvaluationMode {
  EEM_UNDEFINED, ELEMENT_VERTICES, LINEAR_GAUSS_POINTS, QUADRATIC_GAUSS_POINTS,
  CUBIC_GAUSS_POINTS, EEM_UNDEFINED, ELEMENT_VERTICES, LINEAR_GAUSS_POINTS,
  QUADRATIC_GAUSS_POINTS, CUBIC_GAUSS_POINTS
}
 
enum  AveragingMethod {
  NONE, LINEAR, RMS, HMS,
  MINIMUM, MAXIMUM, HARMONIC, GEOMETRIC,
  SUM, SUM_SQUARED, GENERALIZED_MEAN, STANDARD_DEVIATION,
  MAX_OVER_MIN, MAX_MINUS_MIN, SUM_OF_RATIOS_SQUARED, NONE,
  LINEAR, RMS, HMS, MINIMUM,
  MAXIMUM, HARMONIC, GEOMETRIC, SUM,
  SUM_SQUARED, GENERALIZED_MEAN, STANDARD_DEVIATION, MAX_OVER_MIN,
  MAX_MINUS_MIN, SUM_OF_RATIOS_SQUARED
}
 
enum  GRADIENT_TYPE { NUMERICAL_GRADIENT, ANALYTICAL_GRADIENT, NUMERICAL_GRADIENT, ANALYTICAL_GRADIENT }
 
enum  HESSIAN_TYPE { NUMERICAL_HESSIAN, ANALYTICAL_HESSIAN, NUMERICAL_HESSIAN, ANALYTICAL_HESSIAN }
 
- Protected Member Functions inherited from DistanceFromTarget
void compute_T_matrices (MsqMeshEntity &elem, PatchData &pd, Matrix3D T[], size_t num_T, double c_k[], MsqError &err)
 For a given element, compute each corner matrix A, and given a target corner matrix W, returns $ T=AW^{-1} $ for each corner. More...
 
bool get_barrier_function (PatchData &pd, const double &tau, double &h, MsqError &err)
 
void compute_T_matrices (MsqMeshEntity &elem, PatchData &pd, Matrix3D T[], size_t num_T, double c_k[], MsqError &err)
 For a given element, compute each corner matrix A, and given a target corner matrix W, returns $ T=AW^{-1} $ for each corner. More...
 
bool get_barrier_function (PatchData &pd, const double &tau, double &h, MsqError &err)
 
- Protected Member Functions inherited from QualityMetric
 QualityMetric ()
 
void set_metric_type (MetricType t)
 This function should be used in the constructor of every concrete quality metric. More...
 
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 data member avgMethod . More...
 
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 and write into the passed metric_values array the the value weight/count to use when averaging gradient vectors for the metric. More...
 
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 contents using averaging method 'method'. More...
 
bool compute_vertex_numerical_gradient (PatchData &pd, MsqVertex &vertex, MsqVertex *vertices[], Vector3D grad_vec[], int num_vtx, double &metric_value, MsqError &err)
 
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 for a given set of free vertices on that element. This is used by metric which mType is ELEMENT_BASED. For parameters, see compute_element_gradient() . More...
 
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 implementation of this function simply prints a warning and calls compute_numerical_gradient to calculate the gradient. This is used by metric which mType is VERTEX_BASED. More...
 
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)
 
 QualityMetric ()
 
void set_metric_type (MetricType t)
 This function should be used in the constructor of every concrete quality metric. More...
 
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 data member avgMethod . More...
 
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 and write into the passed metric_values array the the value weight/count to use when averaging gradient vectors for the metric. More...
 
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 contents using averaging method 'method'. More...
 
bool compute_vertex_numerical_gradient (PatchData &pd, MsqVertex &vertex, MsqVertex *vertices[], Vector3D grad_vec[], int num_vtx, double &metric_value, MsqError &err)
 
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 for a given set of free vertices on that element. This is used by metric which mType is ELEMENT_BASED. For parameters, see compute_element_gradient() . More...
 
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 implementation of this function simply prints a warning and calls compute_numerical_gradient to calculate the gradient. This is used by metric which mType is VERTEX_BASED. More...
 
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)
 
- Protected Attributes inherited from QualityMetric
AveragingMethod avgMethod
 
int feasible
 
msq_std::string metricName
 

Detailed Description

Class containing the target corner matrices for the context based smoothing.

Definition at line 51 of file includeLinks/RI_DFT.hpp.

Constructor & Destructor Documentation

RI_DFT ( )
inline

Definition at line 55 of file includeLinks/RI_DFT.hpp.

References QualityMetric::ELEMENT_BASED, QualityMetric::LINEAR, MSQ_CHKERR, QualityMetric::NUMERICAL_GRADIENT, QualityMetric::NUMERICAL_HESSIAN, QualityMetric::set_averaging_method(), QualityMetric::set_gradient_type(), QualityMetric::set_hessian_type(), and QualityMetric::set_metric_type().

56  : a(pow(2.0, MSQ_ONE_THIRD)), b(1.0), c(-4.0/3.0)
57  {
58  MsqError err;
63  }
void set_averaging_method(AveragingMethod method, MsqError &err)
static const double MSQ_ONE_THIRD
Definition: Mesquite.hpp:128
void set_hessian_type(HESSIAN_TYPE ht)
Sets hessianType for this metric.
#define MSQ_CHKERR(err)
Mesquite&#39;s Error Checking macro.
void set_gradient_type(GRADIENT_TYPE grad)
Sets gradType for this metric.
void set_metric_type(MetricType t)
This function should be used in the constructor of every concrete quality metric. ...
double pow(double value, const Exponent &exp)

Here is the call graph for this function:

virtual ~RI_DFT ( )
inlinevirtual

virtual destructor ensures use of polymorphism during destruction

Definition at line 66 of file includeLinks/RI_DFT.hpp.

67  {};
RI_DFT ( )
inline

Definition at line 55 of file src/QualityMetric/DFT/RI_DFT.hpp.

References QualityMetric::ELEMENT_BASED, QualityMetric::LINEAR, MSQ_CHKERR, QualityMetric::NUMERICAL_GRADIENT, QualityMetric::NUMERICAL_HESSIAN, QualityMetric::set_averaging_method(), QualityMetric::set_gradient_type(), QualityMetric::set_hessian_type(), and QualityMetric::set_metric_type().

56  : a(pow(2.0, MSQ_ONE_THIRD)), b(1.0), c(-4.0/3.0)
57  {
58  MsqError err;
63  }
void set_averaging_method(AveragingMethod method, MsqError &err)
static const double MSQ_ONE_THIRD
Definition: Mesquite.hpp:128
void set_hessian_type(HESSIAN_TYPE ht)
Sets hessianType for this metric.
#define MSQ_CHKERR(err)
Mesquite&#39;s Error Checking macro.
void set_gradient_type(GRADIENT_TYPE grad)
Sets gradType for this metric.
void set_metric_type(MetricType t)
This function should be used in the constructor of every concrete quality metric. ...
double pow(double value, const Exponent &exp)

Here is the call graph for this function:

virtual ~RI_DFT ( )
inlinevirtual

virtual destructor ensures use of polymorphism during destruction

Definition at line 66 of file src/QualityMetric/DFT/RI_DFT.hpp.

67  {};

Member Function Documentation

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

Virtual function that computes the gradient of the QualityMetric analytically. The base class implementation of this function simply prints a warning and calls compute_numerical_gradient to calculate the gradient. This is used by metric which mType is ELEMENT_BASED. For parameters, see compute_element_gradient() .

If that function is not over-riden in the concrete class, the base

Parameters description, see QualityMetric::compute_element_gradient() .

Returns
true if the element is valid, false otherwise.

Reimplemented from QualityMetric.

Definition at line 1939 of file QualityMetric/DFT/RI_DFT.cpp.

References RI_DFT::a, RI_DFT::b, RI_DFT::c, QualityMetric::compute_element_numerical_gradient(), g_fcn_ridft2(), g_fcn_ridft3(), PatchData::get_barrier_delta(), TargetMatrix::get_cK(), PatchData::get_domain_normal_at_vertex(), PatchData::get_element_index(), MsqMeshEntity::get_element_type(), PatchData::get_vertex_array(), MsqMeshEntity::get_vertex_index_array(), Mesquite::HEXAHEDRON, i, Mesquite::inv(), RI_DFT::invW, j, k, RI_DFT::mAccGrads, RI_DFT::mCoords, RI_DFT::mGrads, RI_DFT::mNormal, Mesquite::MSQ_3RT_2_OVER_6RT_3, MSQ_CHKERR, MSQ_ERRZERO, Mesquite::MSQ_ONE_THIRD, MSQ_SETERR, MsqError::NOT_IMPLEMENTED, Mesquite::QUADRILATERAL, PatchData::targetMatrices, Mesquite::TETRAHEDRON, Mesquite::TRIANGLE, and MsqMeshEntity::vertex_count().

1946 {
1947  // Only works with the weighted average
1948 
1949  MsqVertex *vertices = pd.get_vertex_array(err); MSQ_ERRZERO(err);
1950 
1951  EntityTopology topo = e->get_element_type();
1952 
1953  const size_t nv = e->vertex_count();
1954  const size_t *v_i = e->get_vertex_index_array();
1955 
1956  size_t idx = pd.get_element_index(e);
1957  const TargetMatrix *W = pd.targetMatrices.get_element_corner_tags(&pd, idx, err );
1958  MSQ_ERRZERO(err);
1959 
1960  // Initialize constants for the metric
1961  const double delta = pd.get_barrier_delta(err); MSQ_ERRZERO(err);
1962 
1963  const int tetInd[4][4] = {{0, 1, 2, 3}, {1, 2, 0, 3},
1964  {2, 0, 1, 3}, {3, 2, 1, 0}};
1965  const int hexInd[8][4] = {{0, 1, 3, 4}, {1, 2, 0, 5},
1966  {2, 3, 1, 6}, {3, 0, 2, 7},
1967  {4, 7, 5, 0}, {5, 4, 6, 1},
1968  {6, 5, 7, 2}, {7, 6, 4, 3}};
1969 
1970  // Variables used for computing the metric
1971  double mMetric; // Metric value
1972  bool mValid; // Validity of the metric
1973  int i, j;
1974 
1975  m = 0.0;
1976  switch(topo) {
1977  case TRIANGLE:
1978  assert(3 == nv);
1979 
1980 #ifndef ANALYTIC
1981  mValid = compute_element_numerical_gradient(pd, e, fv, g, nfv, m, err);
1982  return !MSQ_CHKERR(err) && mValid;
1983 #else
1984 
1985  // The following analytic calculation only works correctly if the
1986  // normal is constant. If the normal is not constaint, you need
1987  // to get the gradient of the normal with respect to the vertex
1988  // positions to obtain the correct values.
1989 
1990  for (i = 0; i < 3; ++i) {
1991  mAccGrads[i] = 0.0;
1992  }
1993 
1994  for (i = 0; i < 3; ++i) {
1995  for (j = 0; j < 3; ++j) {
1996  mCoords[j] = vertices[v_i[tetInd[i][j]]];
1997  }
1998 
1999  pd.get_domain_normal_at_vertex(v_i[tetInd[i][0]], true, mNormal, err);
2000  MSQ_ERRZERO(err);
2002 
2003  inv(invW, W[i]);
2004 
2005  mValid = g_fcn_ridft2(mMetric, mGrads, mCoords, mNormal,
2006  invW, a, b, c, delta);
2007  if (!mValid) return false;
2008  m += W[i].get_cK() * mMetric;
2009 
2010  for (j = 0; j < 3; ++j) {
2011  mAccGrads[tetInd[i][j]] += W[i].get_cK() * mGrads[j];
2012  }
2013  }
2014 
2015  m *= MSQ_ONE_THIRD;
2016  for (i = 0; i < 3; ++i) {
2018  }
2019 
2020  // This is not very efficient, but is one way to select correct gradients.
2021  // For gradients, info is returned only for free vertices, in the order
2022  // of fv[].
2023 
2024  for (i = 0; i < 3; ++i) {
2025  for (j = 0; j < nfv; ++j) {
2026  if (vertices + v_i[i] == fv[j]) {
2027  g[j] = mAccGrads[i];
2028  }
2029  }
2030  }
2031 #endif
2032 
2033  break;
2034 
2035  case QUADRILATERAL:
2036 
2037 #ifndef ANALYTIC
2038  mValid = compute_element_numerical_gradient(pd, e, fv, g, nfv, m, err);
2039  return !MSQ_CHKERR(err) && mValid;
2040 #else
2041 
2042  // The following analytic calculation only works correctly if the
2043  // normal is constant. If the normal is not constaint, you need
2044  // to get the gradient of the normal with respect to the vertex
2045  // positions to obtain the correct values.
2046 
2047  for (i = 0; i < 4; ++i) {
2048  mAccGrads[i] = 0.0;
2049  }
2050 
2051  for (i = 0; i < 4; ++i) {
2052  for (j = 0; j < 3; ++j) {
2053  mCoords[j] = vertices[v_i[hexInd[i][j]]];
2054  }
2055 
2056  pd.get_domain_normal_at_vertex(v_i[hexInd[i][0]], true, mNormal, err);
2057  MSQ_ERRZERO(err);
2058 
2059  inv(invW, W[i]);
2060 
2061  mValid = g_fcn_ridft2(mMetric, mGrads, mCoords, mNormal,
2062  invW, a, b, c, delta);
2063  if (!mValid) return false;
2064  m += W[i].get_cK() * mMetric;
2065 
2066  for (j = 0; j < 3; ++j) {
2067  mAccGrads[hexInd[i][j]] += W[i].get_cK() * mGrads[j];
2068  }
2069  }
2070 
2071  m *= 0.25;
2072  for (i = 0; i < 4; ++i) {
2073  mAccGrads[i] *= 0.25;
2074  }
2075 
2076  // This is not very efficient, but is one way to select correct gradients
2077  // For gradients, info is returned only for free vertices, in the order
2078  // of fv[].
2079 
2080  for (i = 0; i < 4; ++i) {
2081  for (j = 0; j < nfv; ++j) {
2082  if (vertices + v_i[i] == fv[j]) {
2083  g[j] = mAccGrads[i];
2084  }
2085  }
2086  }
2087 #endif
2088 
2089  break;
2090 
2091  case TETRAHEDRON:
2092 
2093  for (i = 0; i < 4; ++i) {
2094  mAccGrads[i] = 0.0;
2095  }
2096 
2097  for (i = 0; i < 4; ++i) {
2098  for (j = 0; j < 4; ++j) {
2099  mCoords[j] = vertices[v_i[tetInd[i][j]]];
2100  }
2101 
2102  inv(invW, W[i]);
2103 
2104  mValid = g_fcn_ridft3(mMetric, mGrads, mCoords, invW, a, b, c, delta);
2105  if (!mValid) return false;
2106  m += W[i].get_cK() * mMetric;
2107 
2108  for (j = 0; j < 4; ++j) {
2109  mAccGrads[tetInd[i][j]] += W[i].get_cK() * mGrads[j];
2110  }
2111  }
2112 
2113  m *= 0.25;
2114  for (i = 0; i < 4; ++i) {
2115  mAccGrads[i] *= 0.25;
2116  }
2117 
2118  // This is not very efficient, but is one way to select correct gradients.
2119  // For gradients, info is returned only for free vertices, in the order
2120  // of fv[].
2121 
2122  for (i = 0; i < 4; ++i) {
2123  for (size_t k = 0; k < nv; ++k) {
2124  if (vertices + v_i[i] == fv[k]) {
2125  g[k] = mAccGrads[i];
2126  }
2127  }
2128  }
2129  break;
2130 
2131  case HEXAHEDRON:
2132 
2133  for (i = 0; i < 8; ++i) {
2134  mAccGrads[i] = 0.0;
2135  }
2136 
2137  for (i = 0; i < 8; ++i) {
2138  for (j = 0; j < 4; ++j) {
2139  mCoords[j] = vertices[v_i[hexInd[i][j]]];
2140  }
2141 
2142  inv(invW, W[i]);
2143 
2144  mValid = g_fcn_ridft3(mMetric, mGrads, mCoords, invW, a, b, c, delta);
2145  if (!mValid) return false;
2146  m += W[i].get_cK() * mMetric;
2147 
2148  for (j = 0; j < 4; ++j) {
2149  mAccGrads[hexInd[i][j]] += W[i].get_cK() * mGrads[j];
2150  }
2151  }
2152 
2153  m *= 0.125;
2154  for (i = 0; i < 8; ++i) {
2155  mAccGrads[i] *= 0.125;
2156  }
2157 
2158  // This is not very efficient, but is one way to select correct gradients
2159  // For gradients, info is returned only for free vertices, in the order
2160  // of fv[].
2161 
2162  for (i = 0; i < 8; ++i) {
2163  for (j = 0; j < nfv; ++j) {
2164  if (vertices + v_i[i] == fv[j]) {
2165  g[j] = mAccGrads[i];
2166  }
2167  }
2168  }
2169  break;
2170 
2171  default:
2172  MSQ_SETERR(err)("element type not implemented.",MsqError::NOT_IMPLEMENTED);
2173  return false;
2174  }
2175 
2176  return true;
2177 }
#define MSQ_ERRZERO(err)
Return zero/NULL on error.
static const double MSQ_ONE_THIRD
Definition: Mesquite.hpp:128
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...
CornerTag< TargetMatrix > targetMatrices
Target matrix data.
j indices k indices k
Definition: Indexing.h:6
EntityTopology
Definition: Mesquite.hpp:92
requested functionality is not (yet) implemented
double get_barrier_delta(MsqError &err)
Returns delta based on the minimum and maximum corner determinant over all elements in the patch This...
#define MSQ_CHKERR(err)
Mesquite&#39;s Error Checking macro.
size_t get_element_index(MsqMeshEntity *element)
#define MSQ_SETERR(err)
Macro to set error - use err.clear() to clear.
blockLoc i
Definition: read.cpp:79
bool g_fcn_ridft2(double &obj, Vector3D g_obj[3], const Vector3D x[3], const Vector3D &n, const Matrix3D &invW, const double a, const Exponent b, const Exponent c, const double delta)
const MsqVertex * get_vertex_array(MsqError &err) const
Returns a pointer to the start of the vertex array.
j indices j
Definition: Indexing.h:6
void get_domain_normal_at_vertex(size_t vertex_index, bool normalize, Vector3D &surf_norm, MsqError &err)
Class containing the target corner matrices for the context based smoothing.
void inv(Matrix3D &Ainv, const Matrix3D &A)
MsqVertex is the Mesquite object that stores information about the vertices in the mesh...
static const double MSQ_3RT_2_OVER_6RT_3
Definition: Mesquite.hpp:130
bool g_fcn_ridft3(double &obj, Vector3D g_obj[4], const Vector3D x[4], const Matrix3D &invW, const double a, const Exponent b, const Exponent c, const double delta)

Here is the call graph for this function:

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

Virtual function that computes the gradient of the QualityMetric analytically. The base class implementation of this function simply prints a warning and calls compute_numerical_gradient to calculate the gradient. This is used by metric which mType is ELEMENT_BASED. For parameters, see compute_element_gradient() .

If that function is not over-riden in the concrete class, the base

Parameters description, see QualityMetric::compute_element_gradient() .

Returns
true if the element is valid, false otherwise.

Reimplemented from QualityMetric.

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 
)
virtual

If that function is not over-riden in the concrete class, the base class function makes it default to a numerical hessian.

For parameters description, see QualityMetric::compute_element_hessian() .

Returns
true if the element is valid, false otherwise.

Reimplemented from QualityMetric.

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 
)
virtual

If that function is not over-riden in the concrete class, the base class function makes it default to a numerical hessian.

For parameters description, see QualityMetric::compute_element_hessian() .

Returns
true if the element is valid, false otherwise.

Reimplemented from QualityMetric.

Definition at line 2179 of file QualityMetric/DFT/RI_DFT.cpp.

References RI_DFT::a, RI_DFT::b, RI_DFT::c, QualityMetric::compute_element_numerical_hessian(), PatchData::get_barrier_delta(), TargetMatrix::get_cK(), PatchData::get_domain_normal_at_vertex(), PatchData::get_element_index(), MsqMeshEntity::get_element_type(), PatchData::get_vertex_array(), MsqMeshEntity::get_vertex_index_array(), h_fcn_ridft2(), h_fcn_ridft3(), Mesquite::HEXAHEDRON, i, Mesquite::inv(), RI_DFT::invW, j, k, RI_DFT::mCoords, RI_DFT::mGrads, RI_DFT::mHessians, RI_DFT::mNormal, Mesquite::MSQ_3RT_2_OVER_6RT_3, MSQ_CHKERR, MSQ_ERRZERO, Mesquite::MSQ_ONE_THIRD, MSQ_SETERR, MsqError::NOT_IMPLEMENTED, Mesquite::QUADRILATERAL, PatchData::targetMatrices, Mesquite::TETRAHEDRON, Mesquite::transpose(), Mesquite::TRIANGLE, MsqMeshEntity::vertex_count(), and Matrix3D::zero().

2187 {
2188  // Only works with the weighted average
2189 
2190  MsqVertex *vertices = pd.get_vertex_array(err); MSQ_ERRZERO(err);
2191 
2192  EntityTopology topo = e->get_element_type();
2193 
2194  const size_t nv = e->vertex_count();
2195  const size_t *v_i = e->get_vertex_index_array();
2196 
2197  size_t idx = pd.get_element_index(e);
2198  const TargetMatrix *W = pd.targetMatrices.get_element_corner_tags(&pd, idx, err );
2199  MSQ_ERRZERO(err);
2200 
2201  // Initialize constants for the metric
2202  const double delta = pd.get_barrier_delta(err); MSQ_ERRZERO(err);
2203 
2204  const int tetInd[4][4] = {{0, 1, 2, 3}, {1, 2, 0, 3},
2205  {2, 0, 1, 3}, {3, 2, 1, 0}};
2206  const int hexInd[8][4] = {{0, 1, 3, 4}, {1, 2, 0, 5},
2207  {2, 3, 1, 6}, {3, 0, 2, 7},
2208  {4, 7, 5, 0}, {5, 4, 6, 1},
2209  {6, 5, 7, 2}, {7, 6, 4, 3}};
2210 
2211  // Variables used for computing the metric
2212  double mMetric; // Metric value
2213  bool mValid; // Validity of the metric
2214  int i, j, k, l;
2215  int row, col, loc;
2216 
2217  m = 0.0;
2218  switch(topo) {
2219  case TRIANGLE:
2220  assert(3 == nv);
2221 
2222 #ifndef ANALYTIC
2223  mValid = compute_element_numerical_hessian(pd, e, fv, g, h, nfv, m, err);
2224  return !MSQ_CHKERR(err) && mValid;
2225 #else
2226 
2227  // The following analytic calculation only works correctly if the
2228  // normal is constant. If the normal is not constaint, you need
2229  // to get the gradient of the normal with respect to the vertex
2230  // positions to obtain the correct values.
2231 
2232  // Zero out the hessian and gradient vector
2233  for (i = 0; i < 3; ++i) {
2234  g[i] = 0.0;
2235  }
2236 
2237  for (i = 0; i < 6; ++i) {
2238  h[i].zero();
2239  }
2240 
2241  // Compute the metric and sum them together
2242  for (i = 0; i < 3; ++i) {
2243  for (j = 0; j < 3; ++j) {
2244  mCoords[j] = vertices[v_i[tetInd[i][j]]];
2245  }
2246 
2247  pd.get_domain_normal_at_vertex(v_i[tetInd[i][0]], true, mNormal, err);
2248  MSQ_ERRZERO(err);
2250 
2251  inv(invW, W[i]);
2252 
2253  mValid = h_fcn_ridft2(mMetric, mGrads, mHessians, mCoords, mNormal,
2254  invW, a, b, c, delta);
2255  if (!mValid) return false;
2256 
2257  m += W[i].get_cK() * mMetric;
2258 
2259  for (j = 0; j < 3; ++j) {
2260  g[tetInd[i][j]] += W[i].get_cK() * mGrads[j];
2261  }
2262 
2263  l = 0;
2264  for (j = 0; j < 3; ++j) {
2265  for (k = j; k < 3; ++k) {
2266  row = tetInd[i][j];
2267  col = tetInd[i][k];
2268 
2269  if (row <= col) {
2270  loc = 3*row - (row*(row+1)/2) + col;
2271  h[loc] += W[i].get_cK() * mHessians[l];
2272  }
2273  else {
2274  loc = 3*col - (col*(col+1)/2) + row;
2275  h[loc] += W[i].get_cK() * transpose(mHessians[l]);
2276  }
2277  ++l;
2278  }
2279  }
2280  }
2281 
2282  m *= MSQ_ONE_THIRD;
2283  for (i = 0; i < 3; ++i) {
2284  g[i] *= MSQ_ONE_THIRD;
2285  }
2286 
2287  for (i = 0; i < 6; ++i) {
2288  h[i] *= MSQ_ONE_THIRD;
2289  }
2290 
2291  // zero out fixed elements of g
2292  j = 0;
2293  for (i = 0; i < 3; ++i) {
2294  if (vertices + v_i[i] == fv[j]) {
2295  // if free vertex, see next
2296  ++j;
2297  }
2298  else {
2299  // else zero gradient entry and hessian entries.
2300  g[i] = 0.;
2301 
2302  switch(i) {
2303  case 0:
2304  h[0].zero(); h[1].zero(); h[2].zero();
2305  break;
2306 
2307  case 1:
2308  h[1].zero(); h[3].zero(); h[4].zero();
2309  break;
2310 
2311  case 2:
2312  h[2].zero(); h[4].zero(); h[5].zero();
2313  break;
2314  }
2315  }
2316  }
2317 #endif
2318 
2319  break;
2320 
2321  case QUADRILATERAL:
2322 
2323 #ifndef ANALYTIC
2324  mValid = compute_element_numerical_hessian(pd, e, fv, g, h, nfv, m, err);
2325  return !MSQ_CHKERR(err) && mValid;
2326 #else
2327 
2328  // The following analytic calculation only works correctly if the
2329  // normal is constant. If the normal is not constaint, you need
2330  // to get the gradient of the normal with respect to the vertex
2331  // positions to obtain the correct values.
2332 
2333  // Zero out the hessian and gradient vector
2334  for (i = 0; i < 4; ++i) {
2335  g[i] = 0.0;
2336  }
2337 
2338  for (i = 0; i < 10; ++i) {
2339  h[i].zero();
2340  }
2341 
2342  // Compute the metric and sum them together
2343  for (i = 0; i < 4; ++i) {
2344  for (j = 0; j < 3; ++j) {
2345  mCoords[j] = vertices[v_i[hexInd[i][j]]];
2346  }
2347 
2348  pd.get_domain_normal_at_vertex(v_i[hexInd[i][0]], true, mNormal, err);
2349  MSQ_ERRZERO(err);
2350 
2351  inv(invW, W[i]);
2352 
2353  mValid = h_fcn_ridft2(mMetric, mGrads, mHessians, mCoords, mNormal,
2354  invW, a, b, c, delta);
2355  if (!mValid) return false;
2356 
2357  m += W[i].get_cK() * mMetric;
2358 
2359  for (j = 0; j < 3; ++j) {
2360  g[hexInd[i][j]] += W[i].get_cK() * mGrads[j];
2361  }
2362 
2363  l = 0;
2364  for (j = 0; j < 3; ++j) {
2365  for (k = j; k < 3; ++k) {
2366  row = hexInd[i][j];
2367  col = hexInd[i][k];
2368 
2369  if (row <= col) {
2370  loc = 4*row - (row*(row+1)/2) + col;
2371  h[loc] += W[i].get_cK() * mHessians[l];
2372  }
2373  else {
2374  loc = 4*col - (col*(col+1)/2) + row;
2375  h[loc] += W[i].get_cK() * transpose(mHessians[l]);
2376  }
2377  ++l;
2378  }
2379  }
2380  }
2381 
2382  m *= 0.25;
2383  for (i = 0; i < 4; ++i) {
2384  g[i] *= 0.25;
2385  }
2386 
2387  for (i = 0; i < 10; ++i) {
2388  h[i] *= 0.25;
2389  }
2390 
2391  // zero out fixed elements of gradient and Hessian
2392  j = 0;
2393  for (i = 0; i < 4; ++i) {
2394  if (vertices + v_i[i] == fv[j]) {
2395  // if free vertex, see next
2396  ++j;
2397  }
2398  else {
2399  // else zero gradient entry and hessian entries.
2400  g[i] = 0.;
2401 
2402  switch(i) {
2403  case 0:
2404  h[0].zero(); h[1].zero(); h[2].zero(); h[3].zero();
2405  break;
2406 
2407  case 1:
2408  h[1].zero(); h[4].zero(); h[5].zero(); h[6].zero();
2409  break;
2410 
2411  case 2:
2412  h[2].zero(); h[5].zero(); h[7].zero(); h[8].zero();
2413  break;
2414 
2415  case 3:
2416  h[3].zero(); h[6].zero(); h[8].zero(); h[9].zero();
2417  break;
2418  }
2419  }
2420  }
2421 #endif
2422 
2423  break;
2424 
2425  case TETRAHEDRON:
2426 
2427  // Zero out the hessian and gradient vector
2428  for (i = 0; i < 4; ++i) {
2429  g[i] = 0.0;
2430  }
2431 
2432  for (i = 0; i < 10; ++i) {
2433  h[i].zero();
2434  }
2435 
2436  // Compute the metric and sum them together
2437  for (i = 0; i < 4; ++i) {
2438  for (j = 0; j < 4; ++j) {
2439  mCoords[j] = vertices[v_i[tetInd[i][j]]];
2440  }
2441 
2442  inv(invW, W[i]);
2443 
2444  mValid = h_fcn_ridft3(mMetric, mGrads, mHessians, mCoords,
2445  invW, a, b, c, delta);
2446  if (!mValid) return false;
2447 
2448  m += W[i].get_cK() * mMetric;
2449 
2450  for (j = 0; j < 4; ++j) {
2451  g[tetInd[i][j]] += W[i].get_cK() * mGrads[j];
2452  }
2453 
2454  l = 0;
2455  for (j = 0; j < 4; ++j) {
2456  for (k = j; k < 4; ++k) {
2457  row = tetInd[i][j];
2458  col = tetInd[i][k];
2459 
2460  if (row <= col) {
2461  loc = 4*row - (row*(row+1)/2) + col;
2462  h[loc] += W[i].get_cK() * mHessians[l];
2463  }
2464  else {
2465  loc = 4*col - (col*(col+1)/2) + row;
2466  h[loc] += W[i].get_cK() * transpose(mHessians[l]);
2467  }
2468  ++l;
2469  }
2470  }
2471  }
2472 
2473  m *= 0.25;
2474  for (i = 0; i < 4; ++i) {
2475  g[i] *= 0.25;
2476  }
2477 
2478  for (i = 0; i < 10; ++i) {
2479  h[i] *= 0.25;
2480  }
2481 
2482  // zero out fixed elements of g
2483  j = 0;
2484  for (i = 0; i < 4; ++i) {
2485  if (vertices + v_i[i] == fv[j]) {
2486  // if free vertex, see next
2487  ++j;
2488  }
2489  else {
2490  // else zero gradient entry and hessian entries.
2491  g[i] = 0.;
2492 
2493  switch(i) {
2494  case 0:
2495  h[0].zero(); h[1].zero(); h[2].zero(); h[3].zero();
2496  break;
2497 
2498  case 1:
2499  h[1].zero(); h[4].zero(); h[5].zero(); h[6].zero();
2500  break;
2501 
2502  case 2:
2503  h[2].zero(); h[5].zero(); h[7].zero(); h[8].zero();
2504  break;
2505 
2506  case 3:
2507  h[3].zero(); h[6].zero(); h[8].zero(); h[9].zero();
2508  break;
2509  }
2510  }
2511  }
2512  break;
2513 
2514  case HEXAHEDRON:
2515 
2516  // Zero out the hessian and gradient vector
2517  for (i = 0; i < 8; ++i) {
2518  g[i] = 0.0;
2519  }
2520 
2521  for (i = 0; i < 36; ++i) {
2522  h[i].zero();
2523  }
2524 
2525  // Compute the metric and sum them together
2526  for (i = 0; i < 8; ++i) {
2527  for (j = 0; j < 4; ++j) {
2528  mCoords[j] = vertices[v_i[hexInd[i][j]]];
2529  }
2530 
2531  inv(invW, W[i]);
2532 
2533  mValid = h_fcn_ridft3(mMetric, mGrads, mHessians, mCoords,
2534  invW, a, b, c, delta);
2535  if (!mValid) return false;
2536 
2537  m += W[i].get_cK() * mMetric;
2538 
2539  for (j = 0; j < 4; ++j) {
2540  g[hexInd[i][j]] += W[i].get_cK() * mGrads[j];
2541  }
2542 
2543  l = 0;
2544  for (j = 0; j < 4; ++j) {
2545  for (k = j; k < 4; ++k) {
2546  row = hexInd[i][j];
2547  col = hexInd[i][k];
2548 
2549  if (row <= col) {
2550  loc = 8*row - (row*(row+1)/2) + col;
2551  h[loc] += W[i].get_cK() * mHessians[l];
2552  }
2553  else {
2554  loc = 8*col - (col*(col+1)/2) + row;
2555  h[loc] += W[i].get_cK() * transpose(mHessians[l]);
2556  }
2557  ++l;
2558  }
2559  }
2560  }
2561 
2562  m *= 0.125;
2563  for (i = 0; i < 8; ++i) {
2564  g[i] *= 0.125;
2565  }
2566 
2567  for (i = 0; i < 36; ++i) {
2568  h[i] *= 0.125;
2569  }
2570 
2571  // zero out fixed elements of gradient and Hessian
2572  j = 0;
2573  for (i = 0; i < 8; ++i) {
2574  if (vertices + v_i[i] == fv[j]) {
2575  // if free vertex, see next
2576  ++j;
2577  }
2578  else {
2579  // else zero gradient entry and hessian entries.
2580  g[i] = 0.;
2581 
2582  switch(i) {
2583  case 0:
2584  h[0].zero(); h[1].zero(); h[2].zero(); h[3].zero();
2585  h[4].zero(); h[5].zero(); h[6].zero(); h[7].zero();
2586  break;
2587 
2588  case 1:
2589  h[1].zero(); h[8].zero(); h[9].zero(); h[10].zero();
2590  h[11].zero(); h[12].zero(); h[13].zero(); h[14].zero();
2591  break;
2592 
2593  case 2:
2594  h[2].zero(); h[9].zero(); h[15].zero(); h[16].zero();
2595  h[17].zero(); h[18].zero(); h[19].zero(); h[20].zero();
2596  break;
2597 
2598  case 3:
2599  h[3].zero(); h[10].zero(); h[16].zero(); h[21].zero();
2600  h[22].zero(); h[23].zero(); h[24].zero(); h[25].zero();
2601  break;
2602 
2603  case 4:
2604  h[4].zero(); h[11].zero(); h[17].zero(); h[22].zero();
2605  h[26].zero(); h[27].zero(); h[28].zero(); h[29].zero();
2606  break;
2607 
2608  case 5:
2609  h[5].zero(); h[12].zero(); h[18].zero(); h[23].zero();
2610  h[27].zero(); h[30].zero(); h[31].zero(); h[32].zero();
2611  break;
2612 
2613  case 6:
2614  h[6].zero(); h[13].zero(); h[19].zero(); h[24].zero();
2615  h[28].zero(); h[31].zero(); h[33].zero(); h[34].zero();
2616  break;
2617 
2618  case 7:
2619  h[7].zero(); h[14].zero(); h[20].zero(); h[25].zero();
2620  h[29].zero(); h[32].zero(); h[34].zero(); h[35].zero();
2621  break;
2622  }
2623  }
2624  }
2625  break;
2626 
2627  default:
2628  MSQ_SETERR(err)("element type not implemented.",MsqError::NOT_IMPLEMENTED);
2629  return false;
2630  }
2631 
2632  return true;
2633 }
#define MSQ_ERRZERO(err)
Return zero/NULL on error.
static const double MSQ_ONE_THIRD
Definition: Mesquite.hpp:128
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)
CornerTag< TargetMatrix > targetMatrices
Target matrix data.
j indices k indices k
Definition: Indexing.h:6
EntityTopology
Definition: Mesquite.hpp:92
Matrix3D transpose(const Matrix3D &A)
requested functionality is not (yet) implemented
double get_barrier_delta(MsqError &err)
Returns delta based on the minimum and maximum corner determinant over all elements in the patch This...
#define MSQ_CHKERR(err)
Mesquite&#39;s Error Checking macro.
size_t get_element_index(MsqMeshEntity *element)
#define MSQ_SETERR(err)
Macro to set error - use err.clear() to clear.
blockLoc i
Definition: read.cpp:79
const MsqVertex * get_vertex_array(MsqError &err) const
Returns a pointer to the start of the vertex array.
j indices j
Definition: Indexing.h:6
void get_domain_normal_at_vertex(size_t vertex_index, bool normalize, Vector3D &surf_norm, MsqError &err)
Class containing the target corner matrices for the context based smoothing.
void inv(Matrix3D &Ainv, const Matrix3D &A)
bool h_fcn_ridft2(double &obj, Vector3D g_obj[3], Matrix3D h_obj[6], const Vector3D x[3], const Vector3D &n, const Matrix3D &invW, const double a, const Exponent b, const Exponent c, const double delta)
MsqVertex is the Mesquite object that stores information about the vertices in the mesh...
bool h_fcn_ridft3(double &obj, Vector3D g_obj[4], Matrix3D h_obj[10], const Vector3D x[4], const Matrix3D &invW, const double a, const Exponent b, const Exponent c, const double delta)
static const double MSQ_3RT_2_OVER_6RT_3
Definition: Mesquite.hpp:130

Here is the call graph for this function:

bool evaluate_element ( PatchData ,
MsqMeshEntity ,
double &  ,
MsqError err 
)
virtual

Evaluate the metric for an element.

Reimplemented from QualityMetric.

bool evaluate_element ( PatchData ,
MsqMeshEntity ,
double &  ,
MsqError err 
)
virtual

Evaluate the metric for an element.

Reimplemented from QualityMetric.

Definition at line 1812 of file QualityMetric/DFT/RI_DFT.cpp.

References RI_DFT::a, RI_DFT::b, RI_DFT::c, PatchData::get_barrier_delta(), TargetMatrix::get_cK(), PatchData::get_domain_normal_at_vertex(), PatchData::get_element_index(), MsqMeshEntity::get_element_type(), PatchData::get_vertex_array(), MsqMeshEntity::get_vertex_index_array(), Mesquite::HEXAHEDRON, i, Mesquite::inv(), RI_DFT::invW, j, Vector3D::length(), m_fcn_ridft2(), m_fcn_ridft3(), RI_DFT::mCoords, RI_DFT::mNormal, Mesquite::MSQ_3RT_2_OVER_6RT_3, MSQ_ERRZERO, Mesquite::MSQ_ONE_THIRD, MSQ_SETERR, Vector3D::normalize(), MsqError::NOT_IMPLEMENTED, Mesquite::QUADRILATERAL, PatchData::targetMatrices, Mesquite::TETRAHEDRON, Mesquite::TRIANGLE, and MsqMeshEntity::vertex_count().

1816 {
1817  // Only works with the weighted average
1818  MsqError mErr;
1819  MsqVertex *vertices = pd.get_vertex_array(err); MSQ_ERRZERO(err);
1820 
1821  EntityTopology topo = e->get_element_type();
1822 
1823  const size_t nv = e->vertex_count();
1824  const size_t *v_i = e->get_vertex_index_array();
1825 
1826  size_t idx = pd.get_element_index(e);
1827  const TargetMatrix *W = pd.targetMatrices.get_element_corner_tags(&pd, idx, err );
1828  MSQ_ERRZERO(err);
1829 
1830  // Initialize constants for the metric
1831  const double delta = pd.get_barrier_delta(err); MSQ_ERRZERO(err);
1832 
1833  const int tetInd[4][4] = {{0, 1, 2, 3}, {1, 2, 0, 3},
1834  {2, 0, 1, 3}, {3, 2, 1, 0}};
1835  const int hexInd[8][4] = {{0, 1, 3, 4}, {1, 2, 0, 5},
1836  {2, 3, 1, 6}, {3, 0, 2, 7},
1837  {4, 7, 5, 0}, {5, 4, 6, 1},
1838  {6, 5, 7, 2}, {7, 6, 4, 3}};
1839 
1840  // Variables used for computing the metric
1841  double mMetric; // Metric value
1842  bool mValid; // Validity of the metric
1843  int i, j;
1844 
1845  m = 0.0;
1846  switch(topo) {
1847  case TRIANGLE:
1848 
1849  for (i = 0; i < 3; ++i) {
1850  for (j = 0; j < 3; ++j) {
1851  mCoords[j] = vertices[v_i[tetInd[i][j]]];
1852  }
1853 
1854  pd.get_domain_normal_at_vertex(v_i[tetInd[i][0]], true, mNormal, mErr);
1855 
1856  if (mErr || mNormal.length() == 0) {
1857  mNormal = (vertices[v_i[tetInd[i][1]]] - vertices[v_i[tetInd[i][0]]]) *
1858  (vertices[v_i[tetInd[i][2]]] - vertices[v_i[tetInd[i][0]]]);
1859  mNormal.normalize();
1860  }
1862 
1863  inv(invW, W[i]);
1864 
1865  mValid = m_fcn_ridft2(mMetric, mCoords, mNormal, invW, a, b, c, delta);
1866  if (!mValid) return false;
1867  m += W[i].get_cK() * mMetric;
1868  }
1869 
1870  m *= MSQ_ONE_THIRD;
1871  break;
1872 
1873  case QUADRILATERAL:
1874 
1875  for (i = 0; i < 4; ++i) {
1876  for (j = 0; j < 3; ++j) {
1877  mCoords[j] = vertices[v_i[hexInd[i][j]]];
1878  }
1879 
1880  pd.get_domain_normal_at_vertex(v_i[hexInd[i][0]], true, mNormal, mErr);
1881  if (mErr || mNormal.length() == 0) {
1882  mNormal = (vertices[v_i[hexInd[i][1]]] - vertices[v_i[hexInd[i][0]]]) *
1883  (vertices[v_i[hexInd[i][2]]] - vertices[v_i[hexInd[i][0]]]);
1884  mNormal.normalize();
1885  }
1886 
1887  inv(invW, W[i]);
1888 
1889  mValid = m_fcn_ridft2(mMetric, mCoords, mNormal, invW, a, b, c, delta);
1890  if (!mValid) return false;
1891  m += W[i].get_cK() * mMetric;
1892  }
1893 
1894  m *= 0.25;
1895  break;
1896 
1897  case TETRAHEDRON:
1898 
1899  for (i = 0; i < 4; ++i) {
1900  for (j = 0; j < 4; ++j) {
1901  mCoords[j] = vertices[v_i[tetInd[i][j]]];
1902  }
1903 
1904  inv(invW, W[i]);
1905 
1906  mValid = m_fcn_ridft3(mMetric, mCoords, invW, a, b, c, delta);
1907  if (!mValid) return false;
1908  m += W[i].get_cK() * mMetric;
1909  }
1910 
1911  m *= 0.25;
1912  break;
1913 
1914  case HEXAHEDRON:
1915 
1916  for (i = 0; i < 8; ++i) {
1917  for (j = 0; j < 4; ++j) {
1918  mCoords[j] = vertices[v_i[hexInd[i][j]]];
1919  }
1920 
1921  inv(invW, W[i]);
1922 
1923  mValid = m_fcn_ridft3(mMetric, mCoords, invW, a, b, c, delta);
1924  if (!mValid) return false;
1925  m += W[i].get_cK() * mMetric;
1926  }
1927 
1928  m *= 0.125;
1929  break;
1930 
1931  default:
1932  MSQ_SETERR(err)("element type not implemented.", MsqError::NOT_IMPLEMENTED);
1933  return false;
1934  }
1935 
1936  return true;
1937 }
#define MSQ_ERRZERO(err)
Return zero/NULL on error.
static const double MSQ_ONE_THIRD
Definition: Mesquite.hpp:128
Used to hold the error state and return it to the application.
EntityTopology
Definition: Mesquite.hpp:92
requested functionality is not (yet) implemented
#define MSQ_SETERR(err)
Macro to set error - use err.clear() to clear.
blockLoc i
Definition: read.cpp:79
bool m_fcn_ridft3(double &obj, const Vector3D x[4], const Matrix3D &invW, const double a, const Exponent b, const Exponent c, const double delta)
j indices j
Definition: Indexing.h:6
Class containing the target corner matrices for the context based smoothing.
void inv(Matrix3D &Ainv, const Matrix3D &A)
MsqVertex is the Mesquite object that stores information about the vertices in the mesh...
bool m_fcn_ridft2(double &obj, const Vector3D x[3], const Vector3D &n, const Matrix3D &invW, const double a, const Exponent b, const Exponent c, const double delta)
static const double MSQ_3RT_2_OVER_6RT_3
Definition: Mesquite.hpp:130

Here is the call graph for this function:

Member Data Documentation

Vector3D mAccGrads
private
Matrix3D mHessians
private

Definition at line 103 of file includeLinks/RI_DFT.hpp.

Referenced by RI_DFT::compute_element_analytical_hessian().


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