37 #include "MsqVertex.hpp"
38 #include "MsqMeshEntity.hpp"
39 #include "MsqDebug.hpp"
40 #include "MsqTimer.hpp"
41 #include "PatchData.hpp"
43 using namespace Mesquite;
45 #ifdef MSQ_USE_OLD_STD_HEADERS
92 vector<size_t> elem_vtx_indices;
93 vector<size_t>::const_iterator
v;
96 v=elem_vtx_indices.begin();
97 for (i=0; i<num_free_vtx; ++
i) {
98 while ( v!=elem_vtx_indices.end() &&
102 if ( v==elem_vtx_indices.end() ) {
103 MSQ_SETERR(err)(
"free vertices cannot be given in a different"
113 case NUMERICAL_HESSIAN:
114 ret = compute_element_numerical_hessian(pd, el, free_vtces, grad_vec, hessian,
115 num_free_vtx, metric_value, err);
118 case ANALYTICAL_HESSIAN:
119 ret = compute_element_analytical_hessian(pd, el, free_vtces, grad_vec, hessian,
120 num_free_vtx, metric_value, err);
140 double &metric_value,
143 MSQ_PRINT(1)(
"QualityMetric has no analytical gradient defined. "
144 "Defaulting to numerical gradient.\n");
145 set_gradient_type(NUMERICAL_GRADIENT);
146 bool b = compute_vertex_numerical_gradient(pd, vertex, free_vtces, grad_vec,
147 num_free_vtx, metric_value, err);
153 MSQ_SETERR(err)(
"This QualityMetric's MetricType can not be changed.",
167 int num_free_vtx,
double &metric_value,
170 MSQ_PRINT(1)(
"QualityMetric has no analytical gradient defined. "
171 "Defaulting to numerical gradient.\n");
172 set_gradient_type(NUMERICAL_GRADIENT);
173 bool b = compute_element_numerical_gradient(pd, element, free_vtces, grad_vec, num_free_vtx, metric_value, err);
189 int num_free_vtx,
double &metric_value,
192 MSQ_PRINT(1)(
"QualityMetric has no analytical hessian defined. "
193 "Defaulting to numerical hessian.\n");
194 set_hessian_type(NUMERICAL_HESSIAN);
195 bool b = compute_element_numerical_hessian(pd, element, free_vtces, grad_vec,
196 hessian, num_free_vtx, metric_value, err);
210 double &metric_value,
216 ret = compute_element_gradient(pd, el, free_vtces, grad_vec_nz,
217 num_free_vtx, metric_value, err);
219 delete [] grad_vec_nz;
224 gv_i.reserve(num_free_vtx);
226 for (i=0; i<num_free_vtx; ++
i) {
234 vector<size_t>::iterator ev;
235 vector<size_t>::iterator gv;
236 for (ev=ev_i.begin(), e=0; ev!=ev_i.end(); ++ev, ++e) {
239 while (gv!=gv_i.end()) {
247 grad_vec[e] = grad_vec_nz[g];
252 delete []grad_vec_nz;
266 int num_free_vtx,
double &metric_value,
272 MSQ_PRINT(3)(
"Computing Numerical Gradient\n");
274 bool valid=this->evaluate_element(pd, element, metric_value, err);
278 const double delta_C = 10e-6;
279 double delta = delta_C;
280 const double delta_inv_C = 1. / delta;
281 double delta_inv = delta_inv_C;
284 double metric_value1=0;
285 const int reduction_limit = 15;
286 for (
int v=0;
v<num_free_vtx; ++
v)
289 for (
int j=0;
j<3;++
j)
294 delta_inv = delta_inv_C;
299 while(!valid && counter<reduction_limit){
301 pos=(*free_vtces[
v])[
j];
304 (*free_vtces[
v])[
j]+=delta;
306 valid=this->evaluate_element(pd, element, metric_value1, err);
309 grad_vec[
v][
j]=(metric_value1-metric_value)*delta_inv;
311 (*free_vtces[
v])[
j] = pos;
316 if(counter>=reduction_limit){
317 MSQ_SETERR(err)(
"Perturbing vertex by delta caused an inverted element.",
342 int num_free_vtx,
double &metric_value,
346 MSQ_PRINT(3)(
"Computing Numerical Hessian\n");
348 bool valid=this->compute_element_gradient_expanded(pd, element, free_vtces, grad_vec,
349 num_free_vtx, metric_value, err);
353 double delta = 10e-6;
354 double delta_inv = 1./delta;
361 short w,
v,
i,
j, sum_w, mat_index,
k;
366 for (v=0; v<nve; ++
v) {
371 for (k=0; k<num_free_vtx; ++
k) {
379 if (free_vertex==
false) {
380 for (w=0; w<nve; ++w) {
383 mat_index = w*nve+v-sum_w;
384 hessian[mat_index] = 0.;
392 vj_coord = (*free_vtces[fv_ind])[j];
393 (*free_vtces[fv_ind])[j]+=delta;
395 valid = this->compute_element_gradient_expanded(pd, element, free_vtces,
396 grad_vec1, num_free_vtx, metric_value, err);
MSQ_CHKERR(err);
399 for (w=0; w<nve; ++w) {
402 fd = (grad_vec1[w]-grad_vec[w])*delta_inv;
406 mat_index = w*nve+v-sum_w;
409 hessian[mat_index][i][j] = fd[i];
414 (*free_vtces[fv_ind])[j] = vj_coord;
436 double &metric_value,
441 MSQ_PRINT(2)(
"Computing Gradient (QualityMetric's numeric, vertex based.\n");
443 bool valid=this->evaluate_vertex(pd, &(vertex), metric_value, err);
447 const double delta = 10e-6;
448 const double delta_inv = 1./delta;
449 double metric_value1=0;
452 for (v=0; v<num_free_vtx; ++
v)
459 pos=(*free_vtces[
v])[j];
461 (*free_vtces[
v])[j]+=delta;
463 this->evaluate_vertex(pd, &(vertex), metric_value1, err);
MSQ_ERRZERO(err);
465 grad_vec[
v][
j]=(metric_value1-metric_value)*delta_inv;
467 (*free_vtces[
v])[j] = pos;
479 "vertex-version of this metric.",
489 MSQ_SETERR(err)(
"No implementation for a element-version of this "
508 for (i = 1; i < count; ++
i)
509 if (metrics[i] < avg)
513 for (i = 0; i < count; ++
i)
515 if( metrics[i] - avg <=
MSQ_MIN )
527 for (i = 0; i < count; ++
i)
535 for (i = 1; i < count; ++
i)
536 if (metrics[i] > avg)
540 for (i = 0; i < count; ++
i)
542 if( avg - metrics[i] <=
MSQ_MIN )
554 for (i = 0; i < count; ++
i)
561 for (i = 0; i < count; ++
i)
571 for (i = 0; i < count; ++
i)
573 avg += (metrics[
i]*metrics[
i]);
582 for (i = 0; i < count; ++
i)
593 for (i = 0; i < count; ++
i)
594 avg +=
log(metrics[i]);
595 avg =
exp( avg/count );
598 for (i = 0; i < count; ++
i)
599 metrics[i] = f / metrics[i];
605 for (i = 0; i < count; ++
i)
606 avg += metrics[i] * metrics[i];
607 avg =
sqrt( avg / count );
609 f = 1. / (avg*count);
610 for (i = 0; i < count; ++
i)
617 for (i = 0; i < count; ++
i)
618 avg += 1.0 / metrics[i];
621 for (i = 0; i < count; ++
i)
622 metrics[i] = (avg * avg) / (count * metrics[
i] * metrics[
i]);
628 for (i = 0; i < count; ++
i)
629 avg += 1. / (metrics[i] * metrics[i]);
630 avg =
sqrt( count / avg );
632 f = avg*avg*avg / count;
633 for (i = 0; i < count; ++
i)
634 metrics[i] = f / (metrics[i] * metrics[i] * metrics[i]);
#define MSQ_ERRZERO(err)
Return zero/NULL on error.
CImg< _cimg_Tfloat > exp(const CImg< T > &instance)
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...
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)
Used to hold the error state and return it to the application.
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...
void get_vertex_indices(msq_std::vector< msq_stdc::size_t > &vertex_list) const
gets the vertices of the mesh entity
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)
*********************************************************************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...
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_...
CImg< _cimg_Tfloat > log(const CImg< T > &instance)
virtual void change_metric_type(MetricType t, MsqError &err)
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's Error Checking macro.
3*3 Matric class, row-oriented, 0-based [i][j] indexing.
size_t get_vertex_index(MsqVertex *vertex)
#define MSQ_SETERR(err)
Macro to set error - use err.clear() to clear.
void free_vertex(T_Vertex *v)
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.
virtual bool evaluate_vertex(PatchData &, MsqVertex *, double &, MsqError &err)
Evaluate the metric for a vertex.
#define MSQ_PRINT(flag)
Check debug flag and print printf-style formatted output.
bool compute_element_gradient_expanded(PatchData &pd, MsqMeshEntity *element, MsqVertex *free_vtces[], Vector3D grad_vec[], int num_free_vtx, double &metric_value, MsqError &err)
object is in an invalid state
#define MSQ_FUNCTION_TIMER(NAME)
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...
bool compute_vertex_numerical_gradient(PatchData &pd, MsqVertex &vertex, MsqVertex *vertices[], Vector3D grad_vec[], int num_vtx, double &metric_value, MsqError &err)