Rocstar  1.0
Rocstar multiphysics simulation application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
includeLinks/MsqHessian.hpp
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  ***************************************************************** */
27 // -*- Mode : c++; tab-width: 3; c-tab-always-indent: t; indent-tabs-mode: nil; c-basic-offset: 3 -*-
28 //
29 // AUTHOR: Todd Munson <tmunson@mcs.anl.gov>
30 // ORG: Argonne National Laboratory
31 // E-MAIL: tmunson@mcs.anl.gov
32 //
33 // ORIG-DATE: 2-Jan-03 at 11:02:19 bu Thomas Leurent
34 // LAST-MOD: 5-Oct-04 by Jason Kraftcheck
35 //
36 // DESCRIPTION:
37 // ============
49 #ifndef MsqHessian_hpp
50 #define MsqHessian_hpp
51 
52 #include "Mesquite.hpp"
53 #include "Matrix3D.hpp"
54 #include "PatchData.hpp"
55 #include "MsqTimer.hpp"
56 
57 
58 
59 #ifdef MSQ_USE_OLD_IO_HEADERS
60 class ostream;
61 #else
62 #include <iosfwd>
63 #endif
64 
65 
66 namespace Mesquite
67 {
68  class ObjectiveFunction;
69 
75  class MsqHessian
76  {
77  protected: // data accessed directly in tests.
80 
83  size_t* mRowStart;
84  size_t* mColIndex;
85 
87  size_t* mAccumElemStart;
88 
89  size_t mSize;
90 
93 
98  size_t cgArraySizes;
99  size_t maxCGiter;
100 
101  public:
102  MsqHessian();
103  ~MsqHessian();
104 
105  void initialize(PatchData &pd, MsqError &err);
106  inline void zero_out();
107  size_t size() {return mSize;}
109  void get_diagonal_blocks(msq_std::vector<Matrix3D> &diag, MsqError &err);
110  Matrix3D* get_block(size_t i, size_t j);
111  inline void accumulate_entries(PatchData &pd, const size_t &elem_index,
112  Matrix3D* const &mat3d_array, MsqError &err);
113  void compute_preconditioner(MsqError &err);
114 
115  void apply_preconditioner(Vector3D zloc[], Vector3D rloc[], MsqError &err);
116  void cg_solver(Vector3D x[], Vector3D b[], MsqError &err);
118  friend void axpy(Vector3D res[], size_t size_r,
119  const MsqHessian &H, const Vector3D x[], size_t size_x,
120  const Vector3D y[], size_t size_y, MsqError &err);
121  friend class ObjectiveFunction;
122  friend msq_stdio::ostream& operator<<( msq_stdio::ostream&, const MsqHessian& );
123  };
124 
125 
129  inline void MsqHessian::zero_out()
130  {
131  if (mSize==0) return; // empty hessian.
132 
133  size_t i;
134  for (i=0; i<mRowStart[mSize]; ++i) {
135  mEntries[i].zero();
136  }
137  }
138 
139 
153  inline void MsqHessian::accumulate_entries(PatchData &pd, const size_t &elem_index,
154  Matrix3D* const &mat3d_array, MsqError &err)
155  {
156  if (&pd != origin_pd) {
157  MSQ_SETERR(err)(
158  "Cannot accumulate elements from a different patch. "
159  "Use MsqHessian::initialize first.",
161  return;
162  }
163 
164  size_t nve = pd.get_element_array(err)[elem_index].vertex_count();
165  const size_t nb_mat3d = (nve+1)*nve/2;
166 
167  size_t e = mAccumElemStart[elem_index];
168  size_t i;
169  int j;
170  for (i = 0; i < nb_mat3d; ++i) {
171  j = mAccumulation[e++];
172  if (j >= 0)
173  mEntries[j] += mat3d_array[i];
174  else
175  mEntries[-j].plus_transpose_equal(mat3d_array[i]);
176  }
177  }
178 
187  inline void axpy(Vector3D res[], size_t size_r,
188  const MsqHessian &H, const Vector3D x[], size_t size_x,
189  const Vector3D y[], size_t size_y, MsqError &/*err*/)
190  {
191  if ((size_r != H.mSize) || (size_x != H.mSize) ||
192  (size_y != H.mSize && size_y != 0)) {
193  // throw an error
194  }
195 
196  Vector3D tmpx, tmpm; // for cache opt.
197  size_t* col = H.mColIndex;
198  const size_t nn = H.mSize;
199  size_t rl; // row length
200  size_t el; // entries index
201  size_t lo;
202  size_t c; // column index
203  size_t i, j;
204 
205  if (y != 0) {
206  for (i = 0; i < nn; ++i) {
207  res[i] = y[i];
208  }
209  }
210  else { // y == 0
211  for (i = 0; i < nn; ++i) {
212  res[i] = 0.;
213  }
214  }
215 
216  el = 0;
217  for (i = 0; i < nn; ++i) {
218  rl = H.mRowStart[i+1] - H.mRowStart[i];
219  lo = *col++;
220 
221  // Diagonal entry
222  tmpx = x[i];
223  eqAx(tmpm, H.mEntries[el], tmpx);
224  ++el;
225 
226  //Non-diagonal entries
227  for (j = 1; j < rl; ++j) {
228  c = *col++;
229  // res[i] += H.mEntries[e] * x[c];
230  plusEqAx(tmpm, H.mEntries[el], x[c]);
231  // res[c] += transpose(H.mEntries[e]) * tmpxi;
232  plusEqTransAx(res[c], H.mEntries[el], tmpx);
233  ++el;
234  }
235  res[lo] += tmpm;
236  }
237  }
238 
241  Vector3D rloc[],
242  MsqError& /*err*/)
243  {
244  size_t m;
245 
246  for (m=0; m<mSize; ++m) {
247 #ifdef DIAGONAL_PRECONDITIONER
248  // preconditioner is identity matrix for now.
249  zloc[m][0] = mPreconditioner[m][0][0] * rloc[m][0];
250  zloc[m][1] = mPreconditioner[m][1][1] * rloc[m][1];
251  zloc[m][2] = mPreconditioner[m][2][2] * rloc[m][2];
252 #else
253  // z = inv(L^T) * r
254  zloc[m][0] = rloc[m][0];
255  zloc[m][1] = rloc[m][1] - mPreconditioner[m][0][1] * zloc[m][0];
256  zloc[m][2] = rloc[m][2] - mPreconditioner[m][0][2] * zloc[m][0] - mPreconditioner[m][1][2] * zloc[m][1];
257 
258  // z = inv(D) * z
259  zloc[m][0] *= mPreconditioner[m][0][0];
260  zloc[m][1] *= mPreconditioner[m][1][1];
261  zloc[m][2] *= mPreconditioner[m][2][2];
262 
263  // z = inv(L) * z
264  zloc[m][2] = zloc[m][2];
265  zloc[m][1] = zloc[m][1] - mPreconditioner[m][1][2] * zloc[m][2];
266  zloc[m][0] = zloc[m][0] - mPreconditioner[m][0][1] * zloc[m][1] - mPreconditioner[m][0][2] * zloc[m][2];
267 #endif
268  }
269  }
270 
271 
276  inline Matrix3D* MsqHessian::get_block(size_t i, size_t j)
277  {
278  size_t c;
279 
280  if (i >= mSize || j >= mSize || j < i)
281  return NULL;
282 
283  for (c=mRowStart[i]; c<mRowStart[i+1]; ++c) {
284  if (mColIndex[c] == j)
285  return ( mEntries + c );
286  }
287 
288  // if there is no block at position i,j (zero entry).
289  return NULL;
290  }
291 
292 
293  /* ------------------ I/O ----------------- */
294 
295  msq_stdio::ostream& operator<<(msq_stdio::ostream &s, const MsqHessian &h);
296 
297 } // namespace
298 
299 #endif // MsqHessian_hpp
void accumulate_entries(PatchData &pd, const size_t &elem_index, Matrix3D *const &mat3d_array, MsqError &err)
void zero()
Sets all entries to zero (more efficient than assignement).
void int int REAL REAL * y
Definition: read.cpp:74
Used to hold the error state and return it to the application.
void apply_preconditioner(Vector3D zloc[], Vector3D rloc[], MsqError &err)
void plusEqAx(Vector3D &v, const Matrix3D &A, const Vector3D &x)
void axpy(Vector3D res[], size_t size_r, const MsqHessian &H, const Vector3D x[], size_t size_x, const Vector3D y[], size_t size_y, MsqError &)
double s
Definition: blastest.C:80
size_t * mAccumElemStart
Starting index in mAccumulation for element i, i=1,...
void plusEqTransAx(Vector3D &v, const Matrix3D &A, const Vector3D &x)
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 compute_preconditioner(MsqError &err)
Vector3D is the object that effeciently stores the objective function Hessian each entry is a Matrix3...
Vector3D * mZ
array used in the CG solver
size_t maxCGiter
max nb of iterations of the CG solver.
invalid function argument passed
void plus_transpose_equal(const Matrix3D &B)
size_t mSize
number of rows (or number of columns, this is a square matrix).
msq_stdc::size_t vertex_count() const
Returns the number of vertices in this element, based on its element type.
3*3 Matric class, row-oriented, 0-based [i][j] indexing.
void cg_solver(Vector3D x[], Vector3D b[], MsqError &err)
#define MSQ_SETERR(err)
Macro to set error - use err.clear() to clear.
Vector3D * mR
array used in the CG solver
blockLoc i
Definition: read.cpp:79
void int int REAL * x
Definition: read.cpp:74
friend void axpy(Vector3D res[], size_t size_r, const MsqHessian &H, const Vector3D x[], size_t size_x, const Vector3D y[], size_t size_y, MsqError &err)
Hessian - vector product, summed with a second vector (optional).
Vector3D * mW
array used in the CG solver
size_t * mColIndex
CSR block structure: column indexes of the row entries.
Matrix3D * mEntries
CSR block entries. size: nb of nonzero blocks, i.e. mRowStart[mSize] .
j indices j
Definition: Indexing.h:6
MsqMeshEntity * patchElemArray
stored once during initialization for
void initialize(PatchData &pd, MsqError &err)
creates a sparse structure for a Hessian, based on the connectivity information contained in the Patc...
msq_stdio::ostream & operator<<(msq_stdio::ostream &s, const Matrix3D &A)
friend msq_stdio::ostream & operator<<(msq_stdio::ostream &, const MsqHessian &)
Prints out the MsqHessian blocks.
const MsqMeshEntity * get_element_array(MsqError &err) const
Returns a pointer to the start of the element array.
size_t * mRowStart
start of each row in mEntries. size: nb of vertices (mSize).
void get_diagonal_blocks(msq_std::vector< Matrix3D > &diag, MsqError &err)
returns the diagonal blocks, memory must be allocated before call.
Base class for concrete Objective Functions ObjectiveFunction contains a pointer to a QualityMetric...
Matrix3D * get_block(size_t i, size_t j)
size_t cgArraySizes
size of arrays allocated in the CG solver.
int * mAccumulation
accumulation pattern instructions
Vector3D * mP
array used in the CG solver
void eqAx(Vector3D &v, const Matrix3D &A, const Vector3D &x)