37 #include "IdealWeightInverseMeanRatio.hpp"
38 #include "MeanRatioFunctions.hpp"
39 #include "MsqTimer.hpp"
40 #include "MsqDebug.hpp"
42 #ifdef MSQ_USE_OLD_STD_HEADERS
83 c3Con=-2.0*pow_dbl/3.0;
94 MsqVertex *vertices = pd.get_vertex_array(err);
MSQ_ERRZERO(err);
95 const size_t *v_i = e->get_vertex_index_array();
100 static const int locs_hex[8][4] = {{0, 1, 3, 4},
109 const Vector3D d_con(1.0, 1.0, 1.0);
114 bool metric_valid =
false;
117 pd.get_domain_normal_at_element(e, n, err);
MSQ_ERRZERO(err);
123 if (!metric_valid)
return false;
127 pd.get_domain_normal_at_element(e, n, err);
MSQ_ERRZERO(err);
129 for (i = 0; i < 4; ++
i) {
130 mCoords[0] = vertices[v_i[locs_hex[
i][0]]];
131 mCoords[1] = vertices[v_i[locs_hex[
i][1]]];
132 mCoords[2] = vertices[v_i[locs_hex[
i][2]]];
135 if (!metric_valid)
return false;
146 if (!metric_valid)
return false;
150 for (i = 0; i < 8; ++
i) {
151 mCoords[0] = vertices[v_i[locs_hex[
i][0]]];
152 mCoords[1] = vertices[v_i[locs_hex[
i][1]]];
153 mCoords[2] = vertices[v_i[locs_hex[
i][2]]];
154 mCoords[3] = vertices[v_i[locs_hex[
i][3]]];
157 if (!metric_valid)
return false;
181 "Minimum and maximum not continuously differentiable.\n"
182 "Element of subdifferential will be returned.\n";
185 MsqVertex *vertices = pd.get_vertex_array(err);
MSQ_ERRZERO(err);
186 const size_t *v_i = e->get_vertex_index_array();
191 static const int locs_hex[8][4] = {{0, 1, 3, 4},
200 const Vector3D d_con(1.0, 1.0, 1.0);
204 bool metric_valid =
false;
205 int vert_per_elem = 0;
211 pd.get_domain_normal_at_element(e, n, err);
MSQ_ERRZERO(err);
222 pd.get_domain_normal_at_element(e, n, err);
MSQ_ERRZERO(err);
224 for (i = 0; i < 4; ++
i) {
227 mCoords[0] = vertices[v_i[locs_hex[
i][0]]];
228 mCoords[1] = vertices[v_i[locs_hex[
i][1]]];
229 mCoords[2] = vertices[v_i[locs_hex[
i][2]]];
235 for (i = 0; i < 4; ++
i) {
250 if (!metric_valid)
return false;
256 for (i = 0; i < 8; ++
i) {
259 mCoords[0] = vertices[v_i[locs_hex[
i][0]]];
260 mCoords[1] = vertices[v_i[locs_hex[
i][1]]];
261 mCoords[2] = vertices[v_i[locs_hex[
i][2]]];
262 mCoords[3] = vertices[v_i[locs_hex[
i][3]]];
268 for (i = 0; i < 8; ++
i) {
285 for (i = 0; i < vert_per_elem; ++
i) {
286 for (j = 0; j < nv; ++
j) {
287 if (vertices + v_i[i] == v[j]) {
312 "Minimum and maximum not continuously differentiable.\n"
313 "Element of subdifferential will be returned.\n"
314 "Who knows what the Hessian is?\n" ;
317 MsqVertex *vertices = pd.get_vertex_array(err);
MSQ_ERRZERO(err);
318 const size_t *v_i = e->get_vertex_index_array();
326 static const int locs_hex[8][4] = {{0, 1, 3, 4},
335 const Vector3D d_con(1.0, 1.0, 1.0);
340 bool metric_valid =
false;
346 pd.get_domain_normal_at_element(e, n, err);
MSQ_ERRZERO(err);
355 for (i = 0; i < 3; ++
i) {
357 if (j<nfv && vertices + v_i[i] == fv[j] )
365 h[0].zero(); h[1].zero(); h[2].zero();
369 h[1].zero(); h[3].zero(); h[4].zero();
373 h[2].zero(); h[4].zero(); h[5].zero();
380 for (i=0; i < 10; ++
i) {
384 pd.get_domain_normal_at_element(e, n, err);
MSQ_ERRZERO(err);
386 for (i = 0; i < 4; ++
i) {
389 mCoords[0] = vertices[v_i[locs_hex[
i][0]]];
390 mCoords[1] = vertices[v_i[locs_hex[
i][1]]];
391 mCoords[2] = vertices[v_i[locs_hex[
i][2]]];
407 for (i = 0; i < 4; ++
i) {
412 for (i = 0; i < 4; ++
i) {
417 for (j = 0; j < 3; ++
j) {
418 for (k = j; k < 3; ++
k) {
423 loc = 4*r - (r*(r+1)/2) + c;
427 loc = 4*c - (c*(c+1)/2) + r;
438 for (i = 0; i < 4; ++
i) {
444 for (i = 0; i < 4; ++
i) {
446 g[locs_hex[
i][1]] +=
mMetrics[
i]*mGradients[3*i+1];
447 g[locs_hex[
i][2]] +=
mMetrics[
i]*mGradients[3*i+2];
449 for (j = 0; j < 3; ++
j) {
450 for (k = j; k < 3; ++
k) {
451 outer = 2.0*outer.outer_product(mGradients[3*i+j],
458 loc = 4*r - (r*(r+1)/2) + c;
462 loc = 4*c - (c*(c+1)/2) + r;
473 for (i = 0; i < 4; ++
i) {
479 for (i = 0; i < 4; ++
i) {
480 g[locs_hex[
i][0]] += 0.25*mGradients[3*i+0];
481 g[locs_hex[
i][1]] += 0.25*mGradients[3*i+1];
482 g[locs_hex[
i][2]] += 0.25*mGradients[3*i+2];
484 for (j = 0; j < 3; ++
j) {
485 for (k = j; k < 3; ++
k) {
490 loc = 4*r - (r*(r+1)/2) + c;
494 loc = 4*c - (c*(c+1)/2) + r;
502 for (i=0; i<10; ++
i) {
531 for (i = 0; i < 4; ++
i) {
542 for (i = 0; i < 4; ++
i) {
543 g[locs_hex[
i][0]] +=
g_factor[
i]*mGradients[3*i+0];
544 g[locs_hex[
i][1]] +=
g_factor[
i]*mGradients[3*i+1];
545 g[locs_hex[
i][2]] +=
g_factor[
i]*mGradients[3*i+2];
547 for (j = 0; j < 3; ++
j) {
548 for (k = j; k < 3; ++
k) {
549 outer =
h_factor[
i] * outer.outer_product(mGradients[3*i+j],
556 loc = 4*r - (r*(r+1)/2) + c;
560 loc = 4*c - (c*(c+1)/2) + r;
568 m =
pow(nm, 1.0 / t);
573 for (i = 0; i < 4; ++
i) {
574 for (j = i; j < 4; ++
j) {
575 outer = outer.outer_product(g[i], g[j]);
586 for (i=0; i<4; ++
i) {
588 if (ind<nfv && vertices+v_i[i] == fv[ind] )
595 h[0].zero(); h[1].zero(); h[2].zero(); h[3].zero();
599 h[1].zero(); h[4].zero(); h[5].zero(); h[6].zero();
603 h[2].zero(); h[5].zero(); h[7].zero(); h[8].zero();
607 h[3].zero(); h[6].zero(); h[8].zero(); h[9].zero();
620 if (!metric_valid)
return false;
624 for (i = 0; i < 4; ++
i) {
626 if (j<nfv && vertices + v_i[i] == fv[j] )
634 h[0].zero(); h[1].zero(); h[2].zero(); h[3].zero();
638 h[1].zero(); h[4].zero(); h[5].zero(); h[6].zero();
642 h[2].zero(); h[5].zero(); h[7].zero(); h[8].zero();
646 h[3].zero(); h[6].zero(); h[8].zero(); h[9].zero();
657 for (i = 0; i < 8; ++
i) {
660 mCoords[0] = vertices[v_i[locs_hex[
i][0]]];
661 mCoords[1] = vertices[v_i[locs_hex[
i][1]]];
662 mCoords[2] = vertices[v_i[locs_hex[
i][2]]];
663 mCoords[3] = vertices[v_i[locs_hex[
i][3]]];
679 for (i = 0; i < 8; ++
i) {
684 for (i = 0; i < 8; ++
i) {
685 g[locs_hex[
i][0]] += mGradients[4*i+0];
686 g[locs_hex[
i][1]] += mGradients[4*i+1];
687 g[locs_hex[
i][2]] += mGradients[4*i+2];
688 g[locs_hex[
i][3]] += mGradients[4*i+3];
690 for (j = 0; j < 4; ++
j) {
691 for (k = j; k < 4; ++
k) {
696 loc = 8*r - (r*(r+1)/2) + c;
700 loc = 8*c - (c*(c+1)/2) + r;
711 for (i = 0; i < 8; ++
i) {
717 for (i = 0; i < 8; ++
i) {
718 g[locs_hex[
i][0]] +=
mMetrics[
i]*mGradients[4*i+0];
719 g[locs_hex[
i][1]] +=
mMetrics[
i]*mGradients[4*i+1];
720 g[locs_hex[
i][2]] +=
mMetrics[
i]*mGradients[4*i+2];
721 g[locs_hex[
i][3]] +=
mMetrics[
i]*mGradients[4*i+3];
723 for (j = 0; j < 4; ++
j) {
724 for (k = j; k < 4; ++
k) {
725 outer = 2.0*outer.outer_product(mGradients[4*i+j],
732 loc = 8*r - (r*(r+1)/2) + c;
736 loc = 8*c - (c*(c+1)/2) + r;
747 for (i = 0; i < 8; ++
i) {
753 for (i = 0; i < 8; ++
i) {
754 g[locs_hex[
i][0]] += 0.125*mGradients[4*i+0];
755 g[locs_hex[
i][1]] += 0.125*mGradients[4*i+1];
756 g[locs_hex[
i][2]] += 0.125*mGradients[4*i+2];
757 g[locs_hex[
i][3]] += 0.125*mGradients[4*i+3];
759 for (j = 0; j < 4; ++
j) {
760 for (k = j; k < 4; ++
k) {
765 loc = 8*r - (r*(r+1)/2) + c;
769 loc = 8*c - (c*(c+1)/2) + r;
805 for (i = 0; i < 8; ++
i) {
816 for (i = 0; i < 8; ++
i) {
817 g[locs_hex[
i][0]] +=
g_factor[
i]*mGradients[4*i+0];
818 g[locs_hex[
i][1]] +=
g_factor[
i]*mGradients[4*i+1];
819 g[locs_hex[
i][2]] +=
g_factor[
i]*mGradients[4*i+2];
820 g[locs_hex[
i][3]] +=
g_factor[
i]*mGradients[4*i+3];
822 for (j = 0; j < 4; ++
j) {
823 for (k = j; k < 4; ++
k) {
824 outer =
h_factor[
i]*outer.outer_product(mGradients[4*i+j],
831 loc = 8*r - (r*(r+1)/2) + c;
835 loc = 8*c - (c*(c+1)/2) + r;
843 m =
pow(nm, 1.0 / t);
848 for (i = 0; i < 8; ++
i) {
849 for (j = i; j < 8; ++
j) {
850 outer = outer.outer_product(g[i], g[j]);
861 for (i=0; i<8; ++
i) {
863 if (ind<nfv && vertices+v_i[i] == fv[ind] )
870 h[0].zero(); h[1].zero(); h[2].zero(); h[3].zero();
871 h[4].zero(); h[5].zero(); h[6].zero(); h[7].zero();
875 h[1].zero(); h[8].zero(); h[9].zero(); h[10].zero();
876 h[11].zero(); h[12].zero(); h[13].zero(); h[14].zero();
880 h[2].zero(); h[9].zero(); h[15].zero(); h[16].zero();
881 h[17].zero(); h[18].zero(); h[19].zero(); h[20].zero();
885 h[3].zero(); h[10].zero(); h[16].zero(); h[21].zero();
886 h[22].zero(); h[23].zero(); h[24].zero(); h[25].zero();
890 h[4].zero(); h[11].zero(); h[17].zero(); h[22].zero();
891 h[26].zero(); h[27].zero(); h[28].zero(); h[29].zero();
895 h[5].zero(); h[12].zero(); h[18].zero(); h[23].zero();
896 h[27].zero(); h[30].zero(); h[31].zero(); h[32].zero();
900 h[6].zero(); h[13].zero(); h[19].zero(); h[24].zero();
901 h[28].zero(); h[31].zero(); h[33].zero(); h[34].zero();
905 h[7].zero(); h[14].zero(); h[20].zero(); h[25].zero();
906 h[29].zero(); h[32].zero(); h[34].zero(); h[35].zero();
int h_fcn_3i(double &obj, Vector3D g_obj[4], Matrix3D h_obj[10], const Vector3D x[4], const double a, const Exponent &b, const Exponent &c, const Vector3D &d)
bool g_fcn_2i(double &obj, Vector3D g_obj[3], const Vector3D x[3], const Vector3D &n, const double a, const Exponent &b, const Exponent &c, const Vector3D &d)
bool m_fcn_3e(double &obj, const Vector3D x[4], const double a, const Exponent &b, const Exponent &c)
#define MSQ_ERRZERO(err)
Return zero/NULL on error.
bool g_fcn_2e(double &obj, Vector3D g_obj[3], const Vector3D x[3], const Vector3D &n, const double a, const Exponent &b, const Exponent &c)
bool g_fcn_3e(double &obj, Vector3D g_obj[4], const Vector3D x[4], const double a, const Exponent &b, const Exponent &c)
bool m_fcn_3i(double &obj, const Vector3D x[4], const double a, const Exponent &b, const Exponent &c, const Vector3D &d)
Matrix3D transpose(const Matrix3D &A)
requested functionality is not (yet) implemented
bool evaluate_element(PatchData &pd, MsqMeshEntity *element, double &fval, MsqError &err)
evaluate using mesquite objects
bool m_fcn_2i(double &obj, const Vector3D x[3], const Vector3D &n, const double a, const Exponent &b, const Exponent &c, const Vector3D &d)
bool g_fcn_3i(double &obj, Vector3D g_obj[4], const Vector3D x[4], const double a, const Exponent &b, const Exponent &c, const Vector3D &d)
*********************************************************************Illinois Open Source License ****University of Illinois NCSA **Open Source License University of Illinois All rights reserved ****Developed free of to any person **obtaining a copy of this software and associated documentation to deal with the Software without including without limitation the rights to and or **sell copies of the and to permit persons to whom the **Software is furnished to do subject to the following this list of conditions and the following disclaimers ****Redistributions in binary form must reproduce the above **copyright this list of conditions and the following **disclaimers in the documentation and or other materials **provided with the distribution ****Neither the names of the Center for Simulation of Advanced the University of nor the names of its **contributors may be used to endorse or promote products derived **from this Software without specific prior written permission ****THE SOFTWARE IS PROVIDED AS WITHOUT WARRANTY OF ANY **EXPRESS OR INCLUDING BUT NOT LIMITED TO THE WARRANTIES **OF FITNESS FOR A PARTICULAR PURPOSE AND **NONINFRINGEMENT IN NO EVENT SHALL THE CONTRIBUTORS OR **COPYRIGHT HOLDERS BE LIABLE FOR ANY DAMAGES OR OTHER WHETHER IN AN ACTION OF TORT OR **ARISING OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE **USE OR OTHER DEALINGS WITH THE SOFTWARE v
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_analytical_hessian(PatchData &pd, MsqMeshEntity *e, MsqVertex *v[], Vector3D g[], Matrix3D h[], int nv, double &m, MsqError &err)
invalid function argument passed
NVec< 3, double > Vector3D
bool h_fcn_3e(double &obj, Vector3D g_obj[4], Matrix3D h_obj[10], const Vector3D x[4], const double a, const Exponent &b, const Exponent &c)
void set_element_evaluation_mode(ElementEvaluationMode mode, MsqError &err)
Sets the evaluation mode for the ELEMENT_BASED metrics.
bool m_fcn_2e(double &obj, const Vector3D x[3], const Vector3D &n, const double a, const Exponent &b, const Exponent &c)
#define MSQ_SETERR(err)
Macro to set error - use err.clear() to clear.
void set_negate_flag(int neg)
bool compute_element_analytical_gradient(PatchData &pd, MsqMeshEntity *element, MsqVertex *free_vtces[], 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...
bool h_fcn_2e(double &obj, Vector3D g_obj[3], Matrix3D h_obj[6], const Vector3D x[3], const Vector3D &n, const double a, const Exponent &b, const Exponent &c)
IdealWeightInverseMeanRatio(MsqError &err, double pow_dbl=1.0)
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 ...
void set_metric_power(double pow_dbl, MsqError &err)
Sets the power value in the metric computation.
#define MSQ_DBGOUT(flag)
Check debug flag and return ostream associated with flag.
AveragingMethod avgMethod
#define MSQ_ERRRTN(err)
If passed error is true, return from a void function.
void set_name(msq_std::string st)
Sets the name of this metric.
bool h_fcn_2i(double &obj, Vector3D g_obj[3], Matrix3D h_obj[6], const Vector3D x[3], const Vector3D &n, const double a, const Exponent &b, const Exponent &c, const Vector3D &d)
double pow(double value, const Exponent &exp)