Rocstar  1.0
Rocstar multiphysics simulation application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
QualityImprover/VertexMover/SteepestDescent/SteepestDescent.cpp
Go to the documentation of this file.
1 /* *****************************************************************
2  MESQUITE -- The Mesh Quality Improvement Toolkit
3 
4  Copyright 2004 Sandia Corporation and Argonne National
5  Laboratory. Under the terms of Contract DE-AC04-94AL85000
6  with Sandia Corporation, the U.S. Government retains certain
7  rights in this software.
8 
9  This library is free software; you can redistribute it and/or
10  modify it under the terms of the GNU Lesser General Public
11  License as published by the Free Software Foundation; either
12  version 2.1 of the License, or (at your option) any later version.
13 
14  This library is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  Lesser General Public License for more details.
18 
19  You should have received a copy of the GNU Lesser General Public License
20  (lgpl.txt) along with this library; if not, write to the Free Software
21  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 
23  diachin2@llnl.gov, djmelan@sandia.gov, mbrewer@sandia.gov,
24  pknupp@sandia.gov, tleurent@mcs.anl.gov, tmunson@mcs.anl.gov
25 
26  ***************************************************************** */
37 #include "SteepestDescent.hpp"
38 #include "MsqFreeVertexIndexIterator.hpp"
39 #include "MsqTimer.hpp"
40 #include "MsqDebug.hpp"
41 
42 namespace Mesquite {
43 
45  VertexMover()
46 {
47  objFunc=of;
48  MsqError err;
49  gradientLessThan=.01;
50  maxIteration=6;
51  this->set_name("SteepestDescent");
53 }
54 
55 
57 {
58 }
59 
61 {
62 }
63 
65  MsqError &err)
66 {
67  MSQ_FUNCTION_TIMER( "SteepestDescent::optimize_vertex_positions" );
68  //PRINT_INFO("\no Performing Steepest Descent optimization.\n");
69  // Get the array of vertices of the patch. Free vertices are first.
70  int num_vertices = pd.num_vertices();
71  msq_std::vector<Vector3D> gradient(num_vertices), dk(num_vertices);
72  int nb_iterations = 0;
73  double norm=10e6;
74  bool sd_bool=true;//bool for OF values
75  double smallest_edge = 0.4; // TODO -- update -- used for step_size
77 
78  // does the steepest descent iteration until stopping is required.
79  while ( (nb_iterations<maxIteration &&
80  norm>gradientLessThan ) && !term_crit->terminate()) {
81 
82  ++nb_iterations;
83  double original_value = 0.0;
84  //get intial objective function value, original_value, and gradient
85  objFunc->compute_gradient(pd, &gradient[0], original_value,
86  err, gradient.size()); MSQ_ERRRTN(err);
87 
88  // Prints out free vertices coordinates.
89  if (MSQ_DBG(3)) {
90  int num_free_vertices = pd.num_free_vertices(err); MSQ_ERRRTN(err);
91  MSQ_DBGOUT(3) << "\n o Free vertices ("<< num_free_vertices <<")original coordinates:\n ";
92  MsqVertex* toto1 = pd.get_vertex_array(err); MSQ_ERRRTN(err);
93  MsqFreeVertexIndexIterator ind1(&pd, err); MSQ_ERRRTN(err);
94  ind1.reset();
95  while (ind1.next()) {
96  MSQ_DBGOUT(3) << "\t\t\t" << toto1[ind1.value()];
97  }
98  }
99 
100  // computes the gradient norm
101  norm=0;
102  for (int n=0; n<num_vertices; ++n)
103  norm += gradient[n] % gradient[n]; // dot product
104  norm = sqrt(norm);
105  MSQ_DBGOUT(3) << " o gradient norm: " << norm << msq_stdio::endl;
106 
107  if (norm <= gradientLessThan) {
108  break;
109  }
110 
111  // ******** Chooses the search direction ********
112  // i.e., -gradient for the steepest descent
113  for (int i=0; i<num_vertices; ++i)
114  for (int j=0; j<3; ++j)
115  dk[i][j] = -gradient[i][j] / norm;
116 
117  // ******* Improve Quality *******
118 
119  //set an error if initial patch is invalid.
120  if(!sd_bool){
121  MSQ_SETERR(err)("SteepestDescent passed invalid initial patch.",
123  return;
124  }
125  MSQ_DBGOUT(3) << " o original_value: " << original_value << msq_stdio::endl;
126 
127  double new_value = original_value+1;
128  // reduces the step size until we get an improvement
129  int nb_iter = 0;
130 
131  // saves the PatchData coordinates in a memento
132  PatchDataVerticesMemento* pd_previous_coords;
133  pd_previous_coords = pd.create_vertices_memento(err);
134  if (MSQ_CHKERR(err)) { delete pd_previous_coords; return; }
135  // Loop to find a step size that improves quality
136  double step_size = smallest_edge;
137  while (new_value > original_value
138  && nb_iter < 10 ) {
139  nb_iter++;
140  // change vertices coordinates in PatchData according to descent
141  //direction.
142  pd.move_free_vertices_constrained(&dk[0], dk.size(), step_size, err);
143  if (MSQ_CHKERR(err)) { delete pd_previous_coords; return; }
144  // and evaluate the objective function with the new node positions.
145  sd_bool=objFunc->evaluate(pd, new_value, err);
146  if (MSQ_CHKERR(err)) { delete pd_previous_coords; return; }
147  if(!sd_bool){
148  MSQ_SETERR(err)("SteepestDescent created invalid patch.",
150  delete pd_previous_coords;
151  return;
152  }
153  MSQ_DBGOUT(3) << " o step_size: " << step_size << msq_stdio::endl;
154  MSQ_DBGOUT(3) << " o new_value: " << new_value << msq_stdio::endl;
155 
156  // if no improvement
157  if (new_value > original_value) {
158  // undoes node movement
159  pd.set_to_vertices_memento( pd_previous_coords, err );
160  if (MSQ_CHKERR(err)) { delete pd_previous_coords; return; }
161  // and reduces step size to try again.
162  step_size /= 2;
163  }
164  }
165 
166  // Prints out free vertices coordinates.
167  if (MSQ_DBG(3)) {
168  MSQ_DBGOUT(3) << " o Free vertices new coordinates: \n";
169  MsqVertex* toto1 = pd.get_vertex_array(err);
170  if (MSQ_CHKERR(err)) { delete pd_previous_coords; return; }
171  MsqFreeVertexIndexIterator ind(&pd, err);
172  if (MSQ_CHKERR(err)) { delete pd_previous_coords; return; }
173  ind.reset();
174  while (ind.next()) {
175  MSQ_DBGOUT(3) << "\t\t\t" << toto1[ind.value()];
176  }
177  }
178 
179  delete pd_previous_coords; // user manages the memento.
180 
181  term_crit->accumulate_inner( pd, err ); MSQ_ERRRTN(err);
182 
183  }
184 }
185 
186 
188 {
189  // cout << "- Executing SteepestDescent::iteration_complete()\n";
190 }
191 
193 {
194  // cout << "- Executing SteepestDescent::iteration_end()\n";
195 }
196 
197 } // namespace Mesquite
#define MSQ_DBG(flag)
Check if a debug flag is activated - evaluates to a bool.
size_t value()
Returns an index corresponding to a free vertex.
virtual void terminate_mesh_iteration(PatchData &pd, MsqError &err)
virtual void optimize_vertex_positions(PatchData &pd, MsqError &err)
virtual void set_patch_type(PatchData::PatchType patch_type, MsqError &err, int param1=0, int param2=0)
Sets the Patch Type.
Used to hold the error state and return it to the application.
bool evaluate(PatchData &patch, double &fval, MsqError &err)
The TerminationCriterion class contains functionality to terminate the VertexMover&#39;s optimization...
void set_name(msq_std::string name)
provides a name to the QualityImprover (use it in constructor).
double sqrt(double d)
Definition: double.h:73
bool terminate()
Check if termination criterion has been met.
void set_to_vertices_memento(PatchDataVerticesMemento *memento, MsqError &err)
Restore the PatchData coordinates to the state contained in the memento.
int num_free_vertices(MsqError &err) const
Returns the number of elements in the current patch who are free to move.
bool next()
Increments the iterator. returns false if there is no more free vertex.
virtual void initialize_mesh_iteration(PatchData &pd, MsqError &err)
T norm(const NVec< DIM, T > &v)
PatchDataVerticesMemento * create_vertices_memento(MsqError &err, bool include_higher_order=false)
Creates a memento that holds the current state of the PatchData coordinates.
invalid function argument passed
#define MSQ_CHKERR(err)
Mesquite&#39;s Error Checking macro.
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 grad...
#define MSQ_SETERR(err)
Macro to set error - use err.clear() to clear.
blockLoc i
Definition: read.cpp:79
const NT & n
size_t num_vertices() const
number of vertices in the patch.
void accumulate_inner(PatchData &pd, MsqError &err)
Accumulate data during inner iteration.
TerminationCriterion * get_inner_termination_criterion()
return the inner termination criterion pointer
void move_free_vertices_constrained(Vector3D dk[], size_t nb_vtx, double step_size, MsqError &err)
Moves free vertices and then snaps the free vertices to the domain.
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
Contains a copy of the coordinates of a PatchData.
#define MSQ_DBGOUT(flag)
Check debug flag and return ostream associated with flag.
iterates over indexes of free vetices in a PatchData.
MsqVertex is the Mesquite object that stores information about the vertices in the mesh...
#define MSQ_ERRRTN(err)
If passed error is true, return from a void function.
Base class for concrete Objective Functions ObjectiveFunction contains a pointer to a QualityMetric...