39 #include "MsqFreeVertexIndexIterator.hpp"
40 #include "MsqTimer.hpp"
41 #include "MsqHessian.hpp"
42 #include "MsqDebug.hpp"
44 using namespace Mesquite;
71 MSQ_SETERR(err)(
"pVal equal zero not allowed. L_0 is not a valid norm.",
82 MSQ_SETERR(err)(
"NULL QualityMetric pointer in LPtoPTemplate",
90 total_num=num_elements;
92 total_num=num_vertices;
94 MSQ_SETERR(err)(
"Make sure MetricType is initialised in concrete "
99 msq_std::vector<double> metric_values(total_num);
102 for (index=0; index<num_elements;index++)
106 metric_values[index], err);
112 metric_values[index]=fabs(metric_values[index]);
113 MSQ_DBGOUT(3) <<
" o Quality metric value for element "
114 << index <<
"\t: " << metric_values[index] <<
"\n";
120 for (index=0; index<num_vertices;index++)
124 metric_values[index], err);
131 metric_values[index]=fabs(metric_values[index]);
147 double scaling_value=1.0;
151 if( num_vertices!=array_size && array_size>0)
167 if(currentQM==NULL) {
175 MSQ_SETERR(err)(
"Make sure MetricType is initialised"
176 "in concrete QualityMetric constructor.",
183 for (i=0; i<num_vertices; ++
i)
190 if(num_elements<=0) {
195 scaling_value/=num_elements;
201 const size_t *ele_vtces_ind;
204 for (e=0; e<num_elements; ++e) {
210 for (ve=0; ve<nve; ++ve) {
211 if (vertices[ele_vtces_ind[ve]].is_free_vertex()) {
212 ele_free_vtces[nfve] = vertices + ele_vtces_ind[ve];
222 grad_vec, nfve, QM_val, err);
226 QM_val = fabs(QM_val);
229 if (
pVal==1) factor=1;
232 for (p1=1; p1<
pVal-1; ++
p1)
234 factor = QM_pow *
pVal;
241 OF_val += (scaling_value * QM_pow * QM_val);
244 for (i=0; i<nfve; ++
i) {
246 grad_vec[
i] *= factor;
257 if(num_elements<=0) {
262 scaling_value/=num_vertices;
265 msq_std::vector<size_t> vert_on_vert_ind;
271 size_t vfv_array_length=10;
272 msq_std::vector<MsqVertex*> vert_free_vtces(vfv_array_length);
273 msq_std::vector<Vector3D> grad_vec(vfv_array_length);
274 for(vert_count=0; vert_count<num_vertices; ++vert_count){
279 vert_on_vert_ind,err);
280 vert_on_vert_ind.push_back(vert_count);
281 size_t vert_num_vtces = vert_on_vert_ind.size();
284 if(vert_num_vtces > vfv_array_length){
285 vfv_array_length=vert_num_vtces+5;
286 vert_free_vtces.resize(vfv_array_length);
287 grad_vec.resize(vfv_array_length);
290 size_t vert_num_free_vtces=0;
293 while(!vert_on_vert_ind.empty()){
294 vert_pos=(vert_on_vert_ind.back());
296 vert_on_vert_ind.pop_back();
298 if(vertices[vert_pos].is_free_vertex()){
299 vert_free_vtces[vert_num_free_vtces]=&vertices[vert_pos];
300 ++vert_num_free_vtces ;
305 vertices[vert_count],
314 QM_val = fabs(QM_val);
317 if (
pVal==1) factor=1;
320 for (p1=1; p1<
pVal-1; ++
p1)
322 factor = QM_pow *
pVal;
329 OF_val += (scaling_value * QM_pow * QM_val);
331 for (i=0; i < vert_num_free_vtces ; ++
i) {
333 grad_vec[
i] *= factor;
374 double scaling_value=1.0;
384 MSQ_SETERR(err)(
"LPtoP is attempting to divide by zero in analytical Hessian.",
388 scaling_value/=num_elems;
405 const size_t* vtx_indices;
412 for (v=0; v<num_vertices; ++
v) grad[v] = 0.;
416 for (e=0; e<num_elems; ++e) {
422 for (i=0; i<nve; ++
i) {
423 if ( vertices[vtx_indices[i]].is_free_vertex() ) {
424 ele_free_vtces[nfve] = vertices + vtx_indices[
i];
431 elements+e, ele_free_vtces,
432 grad_vec, elem_hessian,
434 if (
MSQ_CHKERR(err) || !qm_bool)
return false;
441 for (i=0; i<nve; ++
i) {
442 for (j=i; j<nve; ++
j) {
451 else if (
pVal >= 2) {
453 QM_val = fabs(QM_val);
455 for (i=0; i<
pVal-2; ++
i)
458 fac2 = pVal* (pVal-1) * QM_pow;
461 fac1 = pVal * QM_pow;
467 for (i=0; i<nve; ++
i) {
468 for (j=i; j<nve; ++
j) {
469 if ( vertices[vtx_indices[i]].is_free_vertex() &&
472 elem_outer_product.outer_product(grad_vec[i], grad_vec[j]);
474 elem_outer_product *= fac2;
475 elem_hessian[
n] *= fac1;
476 elem_hessian[
n] += elem_outer_product;
479 elem_hessian[
n] *= fac1;
498 for (i=0; i<nve; ++
i) {
499 if ( vertices[vtx_indices[i]].is_free_vertex() ) {
504 grad[vtx_indices[
i]] += (scaling_value * grad_vec[
i]);
510 OF_val += (scaling_value * QM_pow * QM_val);
void set_gradient_type(GRADIENT_TYPE grad)
Set gradType to either NUMERICAL_GRADIENT or ANALYTICAL_GRADIENT.
virtual bool compute_analytical_hessian(PatchData &patch, MsqHessian &hessian, Vector3D *const &grad, double &OF_val, MsqError &err)
short pVal
The metric value entries are raised to the pVal power.
#define MSQ_ERRZERO(err)
Return zero/NULL on error.
MetricType get_metric_type()
void set_quality_metric(QualityMetric *qm)
Set the value of qMetric.
void accumulate_entries(PatchData &pd, const size_t &elem_index, Matrix3D *const &mat3d_array, MsqError &err)
double compute_function(double metric_values[], size_t total_num, MsqError &err)
int get_negate_flag()
Returns negateFlag.
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.
virtual bool concrete_evaluate(PatchData &patch, double &fval, MsqError &err)
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...
Vector3D is the object that effeciently stores the objective function Hessian each entry is a Matrix3...
const int MSQ_MAX_NUM_VERT_PER_ENT
every differentiable function should have an analytical gradient implemented.
QualityMetric * get_quality_metric()
virtual msq_std::list< QualityMetric * > get_quality_metric_list()
*********************************************************************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
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
size_t num_elements() const
number of elements in the Patch.
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.
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...
size_t get_vertex_index(MsqVertex *vertex)
#define MSQ_SETERR(err)
Macro to set error - use err.clear() to clear.
void get_adjacent_vertex_indices(size_t vertex_index, msq_std::vector< size_t > &vert_indices, MsqError &err)
void set_negate_flag(int neg)
Set the value of ObjectiveFunction's negateFlag. Unless composite, concrete ObjectiveFunctions should...
size_t num_vertices() const
number of vertices in the patch.
int get_negate_flag()
Returns negateFlag.
virtual bool evaluate_element(PatchData &, MsqMeshEntity *, double &, MsqError &err)
Evaluate the metric for an element.
bool is_free_vertex() const
Returns true if vertex is ``free''.
virtual bool evaluate_vertex(PatchData &, MsqVertex *, double &, MsqError &err)
Evaluate the metric for a vertex.
const MsqVertex * get_vertex_array(MsqError &err) const
Returns a pointer to the start of the vertex array.
object is in an invalid state
const msq_stdc::size_t * get_vertex_index_array() const
Very efficient retrieval of vertices indexes (corresponding to the PatchData vertex array)...
#define MSQ_FUNCTION_TIMER(NAME)
#define MSQ_DBGOUT(flag)
Check debug flag and return ostream associated with flag.
const MsqMeshEntity * get_element_array(MsqError &err) const
Returns a pointer to the start of the element array.
LPtoPTemplate(QualityMetric *, short, MsqError &)
MsqVertex is the Mesquite object that stores information about the vertices in the mesh...
virtual bool compute_analytical_gradient(PatchData &patch, Vector3D *const &grad, double &OF_val, MsqError &err, size_t array_size)
bool dividingByN
dividingByN is true if we are dividing the objective function by the number of metric values...