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

Calculates the L_p objective function raised to the pth power. That is, sums the p_th powers of (the absolute value of) the quality metric values. More...

#include <LPtoPTemplate.hpp>

Inheritance diagram for LPtoPTemplate:
Collaboration diagram for LPtoPTemplate:

Public Member Functions

 LPtoPTemplate (QualityMetric *, short, MsqError &)
 
virtual ~LPtoPTemplate ()
 
virtual bool concrete_evaluate (PatchData &patch, double &fval, MsqError &err)
 
void set_dividing_by_n (bool d_bool)
 
 LPtoPTemplate (QualityMetric *, short, MsqError &)
 
virtual ~LPtoPTemplate ()
 
virtual bool concrete_evaluate (PatchData &patch, double &fval, MsqError &err)
 
void set_dividing_by_n (bool d_bool)
 
- Public Member Functions inherited from ObjectiveFunction
 ObjectiveFunction ()
 
virtual ~ObjectiveFunction ()
 
bool evaluate (PatchData &patch, double &fval, MsqError &err)
 
void set_gradient_type (GRADIENT_TYPE grad)
 Set gradType to either NUMERICAL_GRADIENT or ANALYTICAL_GRADIENT. More...
 
bool compute_gradient (PatchData &patch, Vector3D *const &grad, double &OF_val, MsqError &err, size_t array_size=0)
 Calls either compute_numerical_gradient or compute_analytical_gradient depending on the value of gradType. Function returns 'false' if the patch is not within a required feasible regeion. Otherwise, it returns 'true'. More...
 
bool compute_hessian (PatchData &patch, MsqHessian &hessian, Vector3D *const &grad, double &OF_val, MsqError &err)
 Calls compute_analytical_hessian. Function returns 'false' if the patch is not within a required feasible regeion. Otherwise, it returns 'true'. More...
 
QualityMetricget_quality_metric ()
 
virtual msq_std::list
< QualityMetric * > 
get_quality_metric_list ()
 
void set_quality_metric (QualityMetric *qm)
 Set the value of qMetric. More...
 
void set_negate_flag (int neg)
 Set the value of ObjectiveFunction's negateFlag. Unless composite, concrete ObjectiveFunctions should set this flag to to the value of the associated QualityMetric's negateFLag. More...
 
int get_negate_flag ()
 Returns negateFlag. More...
 
 ObjectiveFunction ()
 
virtual ~ObjectiveFunction ()
 
bool evaluate (PatchData &patch, double &fval, MsqError &err)
 
void set_gradient_type (GRADIENT_TYPE grad)
 Set gradType to either NUMERICAL_GRADIENT or ANALYTICAL_GRADIENT. More...
 
bool compute_gradient (PatchData &patch, Vector3D *const &grad, double &OF_val, MsqError &err, size_t array_size=0)
 Calls either compute_numerical_gradient or compute_analytical_gradient depending on the value of gradType. Function returns 'false' if the patch is not within a required feasible regeion. Otherwise, it returns 'true'. More...
 
bool compute_hessian (PatchData &patch, MsqHessian &hessian, Vector3D *const &grad, double &OF_val, MsqError &err)
 Calls compute_analytical_hessian. Function returns 'false' if the patch is not within a required feasible regeion. Otherwise, it returns 'true'. More...
 
QualityMetricget_quality_metric ()
 
virtual msq_std::list
< QualityMetric * > 
get_quality_metric_list ()
 
void set_quality_metric (QualityMetric *qm)
 Set the value of qMetric. More...
 
void set_negate_flag (int neg)
 Set the value of ObjectiveFunction's negateFlag. Unless composite, concrete ObjectiveFunctions should set this flag to to the value of the associated QualityMetric's negateFLag. More...
 
int get_negate_flag ()
 Returns negateFlag. More...
 

Protected Member Functions

virtual bool compute_analytical_gradient (PatchData &patch, Vector3D *const &grad, double &OF_val, MsqError &err, size_t array_size)
 
virtual bool compute_analytical_hessian (PatchData &patch, MsqHessian &hessian, Vector3D *const &grad, double &OF_val, MsqError &err)
 
virtual bool compute_analytical_gradient (PatchData &patch, Vector3D *const &grad, double &OF_val, MsqError &err, size_t array_size)
 
virtual bool compute_analytical_hessian (PatchData &patch, MsqHessian &hessian, Vector3D *const &grad, double &OF_val, MsqError &err)
 
- Protected Member Functions inherited from ObjectiveFunction
bool compute_numerical_gradient (PatchData &patch, Vector3D *const &grad, double &OF_val, MsqError &err, size_t array_size)
 Non-virtual function which numerically computes the gradient of the Objective Function. Function returns 'false' if the patch is not within a required feasible regeion. Otherwise, it returns 'true'. More...
 
double get_eps (PatchData &pd, double &local_val, int k, MsqVertex *vertex, MsqError &err)
 Returns eps used in the numerical gradient calculation. More...
 
void set_use_local_gradient (bool new_bool)
 Sets useLocalGradient This variable determines whether compute_numercial_gradient can use the most efficient gradient calculation. More...
 
bool compute_numerical_gradient (PatchData &patch, Vector3D *const &grad, double &OF_val, MsqError &err, size_t array_size)
 Non-virtual function which numerically computes the gradient of the Objective Function. Function returns 'false' if the patch is not within a required feasible regeion. Otherwise, it returns 'true'. More...
 
double get_eps (PatchData &pd, double &local_val, int k, MsqVertex *vertex, MsqError &err)
 Returns eps used in the numerical gradient calculation. More...
 
void set_use_local_gradient (bool new_bool)
 Sets useLocalGradient This variable determines whether compute_numercial_gradient can use the most efficient gradient calculation. More...
 

Private Member Functions

double compute_function (double metric_values[], size_t total_num, MsqError &err)
 
double compute_function (double metric_values[], size_t total_num, MsqError &err)
 

Private Attributes

short pVal
 The metric value entries are raised to the pVal power. More...
 
bool dividingByN
 dividingByN is true if we are dividing the objective function by the number of metric values. More...
 

Additional Inherited Members

- Public Types inherited from ObjectiveFunction
enum  GRADIENT_TYPE { NUMERICAL_GRADIENT, ANALYTICAL_GRADIENT, NUMERICAL_GRADIENT, ANALYTICAL_GRADIENT }
 
enum  GRADIENT_TYPE { NUMERICAL_GRADIENT, ANALYTICAL_GRADIENT, NUMERICAL_GRADIENT, ANALYTICAL_GRADIENT }
 

Detailed Description

Calculates the L_p objective function raised to the pth power. That is, sums the p_th powers of (the absolute value of) the quality metric values.

Todo:
MB. Suggestions made by Todd Munson: a) There is an inconsistent use of fabs. The hessian evaluation when using the one norm does not take the absolute value, while the gradient does. b) The analytic gradient and hessian evaluations are incorrect when the quality metric changes sign due to taking the absolute value. The negative of the element gradient and hessian also needs to be taken. c) Done. The analytic gradient and hessian evaluations are incorrect when the negate flag is set to -1. The negative of the element gradient and hessian also needs to be taken in this case. d) The malloc in the concrete_eval routine should be removed.
Todo:
MB. Suggestions made by Todd Munson: a) There is an inconsistent use of fabs. The hessian evaluation when using the one norm does not take the absolute value, while the gradient does. b) The analytic gradient and hessian evaluations are incorrect when the quality metric changes sign due to taking the absolute value. The negative of the element gradient and hessian also needs to be taken. c) Done. The analytic gradient and hessian evaluations are incorrect when the negate flag is set to -1. The negative of the element gradient and hessian also needs to be taken in this case. d) The malloc in the concrete_eval routine should be removed.

Definition at line 68 of file includeLinks/LPtoPTemplate.hpp.

Constructor & Destructor Documentation

LPtoPTemplate ( QualityMetric qualitymetric,
short  Pinput,
MsqError err 
)

Definition at line 46 of file ObjectiveFunction/LPtoPTemplate.cpp.

References ObjectiveFunction::ANALYTICAL_GRADIENT, LPtoPTemplate::dividingByN, QualityMetric::get_negate_flag(), MsqError::INVALID_ARG, MSQ_SETERR, LPtoPTemplate::pVal, ObjectiveFunction::set_gradient_type(), ObjectiveFunction::set_negate_flag(), and ObjectiveFunction::set_quality_metric().

46  {
47  set_quality_metric(qualitymetric);
48  pVal=Pinput;
49  if(pVal<1){
50  MSQ_SETERR(err)("P_VALUE must be greater than 0.", MsqError::INVALID_ARG);
51  return;
52  }
54  //set_use_local_gradient(true);
55  set_negate_flag(qualitymetric->get_negate_flag());
56  dividingByN=false;
57 }
void set_gradient_type(GRADIENT_TYPE grad)
Set gradType to either NUMERICAL_GRADIENT or ANALYTICAL_GRADIENT.
short pVal
The metric value entries are raised to the pVal power.
void set_quality_metric(QualityMetric *qm)
Set the value of qMetric.
int get_negate_flag()
Returns negateFlag.
every differentiable function should have an analytical gradient implemented.
invalid function argument passed
#define MSQ_SETERR(err)
Macro to set error - use err.clear() to clear.
void set_negate_flag(int neg)
Set the value of ObjectiveFunction&#39;s negateFlag. Unless composite, concrete ObjectiveFunctions should...
bool dividingByN
dividingByN is true if we are dividing the objective function by the number of metric values...

Here is the call graph for this function:

~LPtoPTemplate ( )
virtual

Definition at line 60 of file ObjectiveFunction/LPtoPTemplate.cpp.

60  {
61 
62 }
LPtoPTemplate ( QualityMetric ,
short  ,
MsqError  
)
virtual ~LPtoPTemplate ( )
virtual

Member Function Documentation

bool compute_analytical_gradient ( PatchData patch,
Vector3D *const &  grad,
double &  OF_val,
MsqError err,
size_t  array_size 
)
protectedvirtual

Fills an array of Vector3D, grad, with the gradient of the objective function computed using the gradient of the quality metric. If the function has not been over-riden in the concrete Objective Function, the base class implementation prints a warning and then defaults to numerical gradient. Function returns 'false' if the patch is not within a required feasible regeion. Otherwise, it returns 'true'.

Parameters
patchThe PatchData object for which the objective function gradient is computed.
gradAn array of Vector3D, at least the size of the number of vertices in the patch.
OF_valis set to the value of the objective function.
array_sizeis the size of the grad Vector3D[] array and must correspond to the number of vertices in the patch.

Reimplemented from ObjectiveFunction.

Definition at line 139 of file ObjectiveFunction/LPtoPTemplate.cpp.

References QualityMetric::compute_element_gradient(), QualityMetric::compute_vertex_gradient(), LPtoPTemplate::dividingByN, QualityMetric::ELEMENT_BASED, PatchData::get_adjacent_vertex_indices(), PatchData::get_element_array(), QualityMetric::get_metric_type(), ObjectiveFunction::get_negate_flag(), ObjectiveFunction::get_quality_metric(), PatchData::get_vertex_array(), PatchData::get_vertex_index(), MsqMeshEntity::get_vertex_index_array(), i, MsqError::INVALID_ARG, MsqError::INVALID_MESH, MsqError::INVALID_STATE, MSQ_CHKERR, MSQ_ERRZERO, MSQ_FUNCTION_TIMER, Mesquite::MSQ_MAX_NUM_VERT_PER_ENT, MSQ_SETERR, PatchData::num_elements(), PatchData::num_vertices(), p1, LPtoPTemplate::pVal, QualityMetric::VERTEX_BASED, and MsqMeshEntity::vertex_count().

143 {
144  MSQ_FUNCTION_TIMER( "LPtoPTemplate::compute_analytical_gradient" );
145 
146  //initialize the scaling value
147  double scaling_value=1.0;
148 
149  size_t num_elements=pd.num_elements();
150  size_t num_vertices=pd.num_vertices();
151  if( num_vertices!=array_size && array_size>0)
152  {
153  MSQ_SETERR(err)("Incorrect array size.", MsqError::INVALID_ARG);
154  return false;
155  }
156 
157  MsqMeshEntity* elems=pd.get_element_array(err); MSQ_ERRZERO(err);
158  MsqVertex* vertices=pd.get_vertex_array(err); MSQ_ERRZERO(err);
159  bool qm_bool=true;
160  double QM_val;
161  OF_val = 0.;
162  size_t i;
163  int p1;
164 
165  //Set currentQM to be quality metric (possibly composite) associated with the objective function
166  QualityMetric* currentQM = get_quality_metric();
167  if(currentQM==NULL) {
168  MSQ_SETERR(err)("LPtoPTemplate has NULL QualityMetric pointer.",MsqError::INVALID_STATE);
169  return false;
170  }
171  enum QualityMetric::MetricType qm_type=currentQM->get_metric_type();
172 
173  if (qm_type!=QualityMetric::ELEMENT_BASED &&
174  qm_type!=QualityMetric::VERTEX_BASED) {
175  MSQ_SETERR(err)("Make sure MetricType is initialised"
176  "in concrete QualityMetric constructor.",
178  return false;
179  }
180 
181 
182  // zeros out objective function gradient
183  for (i=0; i<num_vertices; ++i)
184  grad[i] =0;
185 
186  // Computes objective function gradient for an element based metric
187  if(qm_type==QualityMetric::ELEMENT_BASED){
188  //if scaling, divid by num_elements
189  if(dividingByN){
190  if(num_elements<=0) {
191  MSQ_SETERR(err)("The number of elements should not be zero.",MsqError::INVALID_MESH);
192  return false;
193  }
194 
195  scaling_value/=num_elements;
196  }
197  size_t e, ve;
198  size_t nfve; // num free vtx in element
199  size_t nve; // num vtx in element
200  MsqVertex* ele_free_vtces[MSQ_MAX_NUM_VERT_PER_ENT];
201  const size_t *ele_vtces_ind;
202 
203  // loops over all elements.
204  for (e=0; e<num_elements; ++e) {
205  // stores the pointers to the free vertices within the element
206  // (using pointer arithmetic).
207  nfve = 0;
208  nve = elems[e].vertex_count();
209  ele_vtces_ind = elems[e].get_vertex_index_array();
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];
213  ++nfve;
214  }
215  }
216 
217  // Computes q and grad(q)
219  qm_bool = currentQM->compute_element_gradient(
220  pd, &elems[e],
221  ele_free_vtces,
222  grad_vec, nfve, QM_val, err);
223  if(MSQ_CHKERR(err) || !qm_bool) return false;
224 
225  // computes p*|Q(e)|^{p-1}
226  QM_val = fabs(QM_val);
227  double QM_pow=1.0;
228  double factor;
229  if (pVal==1) factor=1;
230  else {
231  QM_pow=QM_val;
232  for (p1=1; p1<pVal-1; ++p1)
233  QM_pow*=QM_val;
234  factor = QM_pow * pVal;
235  }
236  //this scales the gradient
237  factor *= (scaling_value * get_negate_flag());
238 
239  // computes Objective Function value \sum_{i=1}^{N_e} |q_i|^P
240  // possibly scaled by 1/num.
241  OF_val += (scaling_value * QM_pow * QM_val);
242 
243  // For each free vertex in the element ...
244  for (i=0; i<nfve; ++i) {
245  // ... computes p*q^{p-1}*grad(q) ...
246  grad_vec[i] *= factor;
247  // ... and accumulates it in the objective function gradient.
248  grad[pd.get_vertex_index(ele_free_vtces[i])] += grad_vec[i];
249  }
250  }
251  }
252 
253  // Computes objective function gradient for a vertex based metric
254  else if (qm_type==QualityMetric::VERTEX_BASED){
255  //if scaling, divide by the number of vertices
256  if(dividingByN){
257  if(num_elements<=0) {
258  MSQ_SETERR(err)("The number of vertices should not be zero.",MsqError::INVALID_MESH);
259  return false;
260  }
261 
262  scaling_value/=num_vertices;
263  }
264  //vector for storing indices of vertex's connected elems
265  msq_std::vector<size_t> vert_on_vert_ind;
266  //position in pd's vertex array
267  size_t vert_count=0;
268  //position in vertex array
269  size_t vert_pos=0;
270  //loop over the free vertex indices to find the gradient...
271  size_t vfv_array_length=10;//holds the current legth of vert_free_vtces
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){
275  //For now we compute the metric for attached vertices and this
276  //vertex, the above line gives us the attached vertices. Now,
277  //we must add this vertex.
278  pd.get_adjacent_vertex_indices(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();
282 
283  // dynamic memory management if arrays are too small.
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);
288  }
289 
290  size_t vert_num_free_vtces=0;
291  //loop over the vertices connected to this one (vert_count)
292  //and put the free ones into vert_free_vtces
293  while(!vert_on_vert_ind.empty()){
294  vert_pos=(vert_on_vert_ind.back());
295  //clear the vector as we go
296  vert_on_vert_ind.pop_back();
297  //if the vertex is free, add it to ver_free_vtces
298  if(vertices[vert_pos].is_free_vertex()){
299  vert_free_vtces[vert_num_free_vtces]=&vertices[vert_pos];
300  ++vert_num_free_vtces ;
301  }
302  }
303 
304  qm_bool=currentQM->compute_vertex_gradient(pd,
305  vertices[vert_count],
306  &vert_free_vtces[0],
307  &grad_vec[0],
308  vert_num_free_vtces,
309  QM_val, err);
310  if(MSQ_CHKERR(err) || !qm_bool){
311  return false;
312  }
313  // computes p*|Q(e)|^{p-1}
314  QM_val = fabs(QM_val);
315  double QM_pow = 1.0;
316  double factor;
317  if (pVal==1) factor=1;
318  else {
319  QM_pow=QM_val;
320  for (p1=1; p1<pVal-1; ++p1)
321  QM_pow*=QM_val;
322  factor = QM_pow * pVal;
323  }
324  //this scales the gradient
325  factor *= (scaling_value * get_negate_flag());
326 
327  // computes Objective Function value \sum_{i=1}^{N_v} |q_i|^P
328  // possibly scaled by 1/num
329  OF_val += (scaling_value * QM_pow * QM_val);
330  // For each free vertex around the vertex (and the vertex itself if free) ...
331  for (i=0; i < vert_num_free_vtces ; ++i) {
332  // ... computes p*q^{p-1}*grad(q) ...
333  grad_vec[i] *= factor;
334  // ... and accumulates it in the objective function gradient.
335  grad[pd.get_vertex_index(vert_free_vtces[i])] += grad_vec[i];
336  }
337  }
338  }
339 
340  OF_val *= get_negate_flag();
341 
342  return true;
343 
344 }
short pVal
The metric value entries are raised to the pVal power.
#define MSQ_ERRZERO(err)
Return zero/NULL on error.
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...
Base class for concrete quality metrics.
NT p1
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...
const int MSQ_MAX_NUM_VERT_PER_ENT
Definition: Mesquite.hpp:120
invalid function argument passed
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&#39;s Error Checking macro.
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...
#define MSQ_SETERR(err)
Macro to set error - use err.clear() to clear.
blockLoc i
Definition: read.cpp:79
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)...
MsqVertex is the Mesquite object that stores information about the vertices in the mesh...
bool dividingByN
dividingByN is true if we are dividing the objective function by the number of metric values...

Here is the call graph for this function:

virtual bool compute_analytical_gradient ( PatchData patch,
Vector3D *const &  grad,
double &  OF_val,
MsqError err,
size_t  array_size 
)
protectedvirtual

Fills an array of Vector3D, grad, with the gradient of the objective function computed using the gradient of the quality metric. If the function has not been over-riden in the concrete Objective Function, the base class implementation prints a warning and then defaults to numerical gradient. Function returns 'false' if the patch is not within a required feasible regeion. Otherwise, it returns 'true'.

Parameters
patchThe PatchData object for which the objective function gradient is computed.
gradAn array of Vector3D, at least the size of the number of vertices in the patch.
OF_valis set to the value of the objective function.
array_sizeis the size of the grad Vector3D[] array and must correspond to the number of vertices in the patch.

Reimplemented from ObjectiveFunction.

bool compute_analytical_hessian ( PatchData ,
MsqHessian ,
Vector3D *const &  ,
double &  ,
MsqError err 
)
protectedvirtual

Fills a MsqHessian object with the Hessian of the objective function computed using the hessian of the quality metric. If the function has not been over-riden in the concrete Objective Function, the base class implementation prints a warning and returns false. Function returns 'false' if the patch is not within a required feasible regeion. Otherwise, it returns 'true'.

Reimplemented from ObjectiveFunction.

Definition at line 368 of file ObjectiveFunction/LPtoPTemplate.cpp.

References MsqHessian::accumulate_entries(), QualityMetric::compute_element_hessian(), LPtoPTemplate::dividingByN, PatchData::get_element_array(), ObjectiveFunction::get_negate_flag(), ObjectiveFunction::get_quality_metric(), PatchData::get_vertex_array(), MsqMeshEntity::get_vertex_index_array(), i, MsqError::INVALID_MESH, MsqError::INVALID_STATE, MsqVertex::is_free_vertex(), j, MSQ_CHKERR, MSQ_ERRZERO, MSQ_FUNCTION_TIMER, Mesquite::MSQ_MAX_NUM_VERT_PER_ENT, MSQ_SETERR, n, PatchData::num_elements(), PatchData::num_vertices(), LPtoPTemplate::pVal, v, MsqMeshEntity::vertex_count(), and MsqHessian::zero_out().

373 {
374  double scaling_value=1.0;
375 
376  MSQ_FUNCTION_TIMER( "LPtoPTemplate::compute_analytical_hessian" );
377 
378  MsqMeshEntity* elements = pd.get_element_array(err); MSQ_ERRZERO(err);
379  MsqVertex* vertices = pd.get_vertex_array(err); MSQ_ERRZERO(err);
380  size_t num_elems = pd.num_elements();
381  //if scaling divide by the number of elements.
382  if(dividingByN){
383  if(num_elems<=0) {
384  MSQ_SETERR(err)("LPtoP is attempting to divide by zero in analytical Hessian.",
386  return false;
387  }
388  scaling_value/=num_elems;
389  }
390 
391  size_t num_vertices = pd.num_vertices();
393  Matrix3D elem_outer_product;
395  double QM_val;
396  double fac1, fac2;
397  Matrix3D grad_outprod;
398  bool qm_bool;
399  QualityMetric* currentQM = get_quality_metric();
400 
401  MsqVertex* ele_free_vtces[MSQ_MAX_NUM_VERT_PER_ENT];
402  short i;
403  for (i=0; i<MSQ_MAX_NUM_VERT_PER_ENT; ++i) ele_free_vtces[i]=NULL;
404 
405  const size_t* vtx_indices;
406 
407  size_t e, v;
408  size_t nfve; // number of free vertices in element
409  short j,n;
410 
411  hessian.zero_out();
412  for (v=0; v<num_vertices; ++v) grad[v] = 0.;
413  OF_val = 0.;
414 
415  // Loops over all elements in the patch.
416  for (e=0; e<num_elems; ++e) {
417  short nve = elements[e].vertex_count();
418 
419  // Gets a list of free vertices in the element.
420  vtx_indices = elements[e].get_vertex_index_array();
421  nfve=0;
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];
425  ++nfve;
426  }
427  }
428 
429  // Computes \nabla^2 Q(e). Only the free vertices will have non-zero entries.
430  qm_bool = currentQM->compute_element_hessian(pd,
431  elements+e, ele_free_vtces,
432  grad_vec, elem_hessian,
433  nfve, QM_val, err);
434  if (MSQ_CHKERR(err) || !qm_bool) return false;
435 
436 
437  // **** Computes Hessian ****
438  double QM_pow=1.;
439  if (pVal == 1) {
440  n=0;
441  for (i=0; i<nve; ++i) {
442  for (j=i; j<nve; ++j) {
443  //negate if necessary
444  elem_hessian[n] *= (scaling_value * get_negate_flag());
445  ++n;
446  }
447  }
448  hessian.accumulate_entries(pd, e, elem_hessian, err);
449  fac1 = 1;
450  }
451  else if (pVal >= 2) {
452  // Computes the coefficients:
453  QM_val = fabs(QM_val);
454  QM_pow = 1;
455  for (i=0; i<pVal-2; ++i)
456  QM_pow *= QM_val;
457  // 1 - computes p(p-1)Q(e)^{p-2}
458  fac2 = pVal* (pVal-1) * QM_pow;
459  // 2 - computes pQ(e)^{p-1}
460  QM_pow *= QM_val;
461  fac1 = pVal * QM_pow;
462 
463  //fac1 *= get_negate_flag();
464  //fac2 *= get_negate_flag();
465 
466  n=0;
467  for (i=0; i<nve; ++i) {
468  for (j=i; j<nve; ++j) {
469  if ( vertices[vtx_indices[i]].is_free_vertex() &&
470  vertices[vtx_indices[j]].is_free_vertex() ) {
471  // Computes \nabla Q(e) [\nabla Q(e)]^T
472  elem_outer_product.outer_product(grad_vec[i], grad_vec[j]);
473 
474  elem_outer_product *= fac2;
475  elem_hessian[n] *= fac1;
476  elem_hessian[n] += elem_outer_product;
477  } else {
478  // elem_outer_product is nul
479  elem_hessian[n] *= fac1;
480  }
481  //scale the hessian by the scaling factor
482  elem_hessian[n] *= (scaling_value * get_negate_flag());
483  ++n;
484  }
485  }
486 
487  hessian.accumulate_entries(pd, e, elem_hessian, err); MSQ_ERRZERO(err);
488 
489  } else {
490  MSQ_SETERR(err)(" invalid P value.", MsqError::INVALID_STATE);
491  return false;
492  }
493 
494 
495  // **** Computes Gradient ****
496 
497  // For each vertex in the element ...
498  for (i=0; i<nve; ++i) {
499  if ( vertices[vtx_indices[i]].is_free_vertex() ) {
500  // ... computes p*q^{p-1}*grad(q) ...
501  grad_vec[i] *= fac1*get_negate_flag();
502  // ... and accumulates it in the objective function gradient.
503  //also scale the gradient by the scaling factor
504  grad[vtx_indices[i]] += (scaling_value * grad_vec[i]);
505  }
506  }
507 
508  // **** computes Objective Function value \sum_{i=1}^{N_e} |q_i|^P ****
509  //and scale by 1/num if necessary
510  OF_val += (scaling_value * QM_pow * QM_val);
511 
512  }
513 
514  OF_val *= get_negate_flag();
515 
516  return true;
517 }
short pVal
The metric value entries are raised to the pVal power.
#define MSQ_ERRZERO(err)
Return zero/NULL on error.
Base class for concrete quality metrics.
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...
const int MSQ_MAX_NUM_VERT_PER_ENT
Definition: Mesquite.hpp:120
*********************************************************************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
Definition: roccomf90.h:20
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_...
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&#39;s Error Checking macro.
3*3 Matric class, row-oriented, 0-based [i][j] indexing.
#define MSQ_SETERR(err)
Macro to set error - use err.clear() to clear.
blockLoc i
Definition: read.cpp:79
const NT & n
bool is_free_vertex() const
Returns true if vertex is ``free&#39;&#39;.
j indices j
Definition: Indexing.h:6
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)...
MsqVertex is the Mesquite object that stores information about the vertices in the mesh...
bool dividingByN
dividingByN is true if we are dividing the objective function by the number of metric values...

Here is the call graph for this function:

virtual bool compute_analytical_hessian ( PatchData ,
MsqHessian ,
Vector3D *const &  ,
double &  ,
MsqError err 
)
protectedvirtual

Fills a MsqHessian object with the Hessian of the objective function computed using the hessian of the quality metric. If the function has not been over-riden in the concrete Objective Function, the base class implementation prints a warning and returns false. Function returns 'false' if the patch is not within a required feasible regeion. Otherwise, it returns 'true'.

Reimplemented from ObjectiveFunction.

double compute_function ( double  metric_values[],
size_t  total_num,
MsqError err 
)
private
double compute_function ( double  metric_values[],
size_t  total_num,
MsqError err 
)
inlineprivate

Definition at line 110 of file includeLinks/LPtoPTemplate.hpp.

References LPtoPTemplate::dividingByN, MsqError::INVALID_ARG, MSQ_SETERR, and LPtoPTemplate::pVal.

Referenced by LPtoPTemplate::concrete_evaluate().

113  {
114  double scale_factor=1.0;
115  //if scaling, divide by total_num
116  if(dividingByN){
117  if(total_num<=0) {
119  return 0.0;
120  }
121  scale_factor/=total_num;
122  }
123  size_t ind=0;
124  short jnd=0;
125  double temp_value=1;
126  double total_value=0;
127  for(ind=0;ind<total_num;++ind){
128  temp_value=1;
129  for(jnd=0;jnd<pVal;++jnd){
130  temp_value*=metric_values[ind];
131  }
132  total_value+=(scale_factor*temp_value);
133  }
134  return total_value;
135  }
short pVal
The metric value entries are raised to the pVal power.
invalid function argument passed
#define MSQ_SETERR(err)
Macro to set error - use err.clear() to clear.
bool dividingByN
dividingByN is true if we are dividing the objective function by the number of metric values...

Here is the caller graph for this function:

virtual bool concrete_evaluate ( PatchData patch,
double &  fval,
MsqError err 
)
virtual

Evaluate the objective function on a given patch.

Implements ObjectiveFunction.

bool concrete_evaluate ( PatchData patch,
double &  fval,
MsqError err 
)
virtual

Evaluate the objective function on a given patch.

Implements ObjectiveFunction.

Definition at line 64 of file ObjectiveFunction/LPtoPTemplate.cpp.

References LPtoPTemplate::compute_function(), QualityMetric::ELEMENT_BASED, QualityMetric::evaluate_element(), QualityMetric::evaluate_vertex(), PatchData::get_element_array(), QualityMetric::get_metric_type(), ObjectiveFunction::get_quality_metric(), ObjectiveFunction::get_quality_metric_list(), PatchData::get_vertex_array(), MsqError::INVALID_STATE, MSQ_CHKERR, MSQ_DBGOUT, MSQ_ERRZERO, MSQ_SETERR, PatchData::num_elements(), PatchData::num_vertices(), LPtoPTemplate::pVal, and QualityMetric::VERTEX_BASED.

65  {
66  size_t index=0;
67  MsqMeshEntity* elems=pd.get_element_array(err);
68  bool obj_bool=true;
69  //double check for pVal=0;
70  if(pVal==0){
71  MSQ_SETERR(err)("pVal equal zero not allowed. L_0 is not a valid norm.",
73  return false;
74  }
75 
76  //Michael: this may not do what we want
77  //Set currentQM to be the first quality metric* in the list
78  QualityMetric* currentQM = get_quality_metric();
79  if(currentQM==NULL)
80  currentQM=get_quality_metric_list().front();
81  if(currentQM==NULL) {
82  MSQ_SETERR(err)("NULL QualityMetric pointer in LPtoPTemplate",
84  return false;
85  }
86  size_t num_elements=pd.num_elements();
87  size_t num_vertices=pd.num_vertices();
88  size_t total_num=0;
90  total_num=num_elements;
91  else if (currentQM->get_metric_type()==QualityMetric::VERTEX_BASED)
92  total_num=num_vertices;
93  else {
94  MSQ_SETERR(err)("Make sure MetricType is initialised in concrete "
95  "QualityMetric constructor.", MsqError::INVALID_STATE);
96  return false;
97  }
98 
99  msq_std::vector<double> metric_values(total_num);
101  {
102  for (index=0; index<num_elements;index++)
103  {
104  //if invalid return false after clean-up
105  obj_bool=currentQM->evaluate_element(pd, (&elems[index]),
106  metric_values[index], err);
107  if(MSQ_CHKERR(err) || !obj_bool){
108  fval=0.0;
109  return false;
110  }
111 
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";
115  }
116  }
117  else if(currentQM->get_metric_type()==QualityMetric::VERTEX_BASED)
118  {
119  MsqVertex* vertices=pd.get_vertex_array(err); MSQ_ERRZERO(err);
120  for (index=0; index<num_vertices;index++)
121  {
122  //evaluate metric for this vertex
123  obj_bool=currentQM->evaluate_vertex(pd, (&vertices[index]),
124  metric_values[index], err);
125  //if invalid return false after clean-up
126  if(MSQ_CHKERR(err) || !obj_bool){
127  fval=0.0;
128  return false;
129  }
130 
131  metric_values[index]=fabs(metric_values[index]);
132  }
133  }
134  fval=compute_function(&metric_values[0], total_num, err);
135  return !MSQ_CHKERR(err);
136 }
short pVal
The metric value entries are raised to the pVal power.
#define MSQ_ERRZERO(err)
Return zero/NULL on error.
double compute_function(double metric_values[], size_t total_num, MsqError &err)
Base class for concrete quality metrics.
MsqMeshEntity is the Mesquite object that stores information about the elements in the mesh...
virtual msq_std::list< QualityMetric * > get_quality_metric_list()
#define MSQ_CHKERR(err)
Mesquite&#39;s Error Checking macro.
#define MSQ_SETERR(err)
Macro to set error - use err.clear() to clear.
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.
object is in an invalid state
#define MSQ_DBGOUT(flag)
Check debug flag and return ostream associated with flag.
MsqVertex is the Mesquite object that stores information about the vertices in the mesh...

Here is the call graph for this function:

void set_dividing_by_n ( bool  d_bool)
inline

Use set_dividing_by_n to control whether this objective function divides it's final value by the number of metric values used to compute the objective function value. That is, if the associated metric is element based, the obejctive function value is divided by the number of elements. If it is vertex based, the objective function is divided by the number of vertices. If this function is passed 'true', the function value will be scale. If it is passed false, the function value will not be scaled.

Definition at line 85 of file includeLinks/LPtoPTemplate.hpp.

References LPtoPTemplate::dividingByN.

85 {dividingByN=d_bool;}
bool dividingByN
dividingByN is true if we are dividing the objective function by the number of metric values...
void set_dividing_by_n ( bool  d_bool)
inline

Use set_dividing_by_n to control whether this objective function divides it's final value by the number of metric values used to compute the objective function value. That is, if the associated metric is element based, the obejctive function value is divided by the number of elements. If it is vertex based, the objective function is divided by the number of vertices. If this function is passed 'true', the function value will be scale. If it is passed false, the function value will not be scaled.

Definition at line 85 of file src/ObjectiveFunction/LPtoPTemplate.hpp.

References LPtoPTemplate::dividingByN.

85 {dividingByN=d_bool;}
bool dividingByN
dividingByN is true if we are dividing the objective function by the number of metric values...

Member Data Documentation

bool dividingByN
private

dividingByN is true if we are dividing the objective function by the number of metric values.

Definition at line 107 of file includeLinks/LPtoPTemplate.hpp.

Referenced by LPtoPTemplate::compute_analytical_gradient(), LPtoPTemplate::compute_analytical_hessian(), LPtoPTemplate::compute_function(), LPtoPTemplate::LPtoPTemplate(), and LPtoPTemplate::set_dividing_by_n().


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