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

Vector3D is the object that effeciently stores the objective function Hessian each entry is a Matrix3D object (i.e. a vertex Hessian). More...

#include <MsqHessian.hpp>

Collaboration diagram for MsqHessian:

Public Member Functions

 MsqHessian ()
 
 ~MsqHessian ()
 
void initialize (PatchData &pd, MsqError &err)
 creates a sparse structure for a Hessian, based on the connectivity information contained in the PatchData. Only the upper triangular part of the Hessian is stored. More...
 
void zero_out ()
 
size_t size ()
 
void get_diagonal_blocks (msq_std::vector< Matrix3D > &diag, MsqError &err)
 returns the diagonal blocks, memory must be allocated before call. More...
 
Matrix3Dget_block (size_t i, size_t j)
 
void accumulate_entries (PatchData &pd, const size_t &elem_index, Matrix3D *const &mat3d_array, MsqError &err)
 
void compute_preconditioner (MsqError &err)
 
void apply_preconditioner (Vector3D zloc[], Vector3D rloc[], MsqError &err)
 
void cg_solver (Vector3D x[], Vector3D b[], MsqError &err)
 
 MsqHessian ()
 
 ~MsqHessian ()
 
void initialize (PatchData &pd, MsqError &err)
 
void zero_out ()
 
size_t size ()
 
void get_diagonal_blocks (msq_std::vector< Matrix3D > &diag, MsqError &err)
 returns the diagonal blocks, memory must be allocated before call. More...
 
Matrix3Dget_block (size_t i, size_t j)
 
void accumulate_entries (PatchData &pd, const size_t &elem_index, Matrix3D *const &mat3d_array, MsqError &err)
 
void compute_preconditioner (MsqError &err)
 
void apply_preconditioner (Vector3D zloc[], Vector3D rloc[], MsqError &err)
 
void cg_solver (Vector3D x[], Vector3D b[], MsqError &err)
 

Protected Attributes

PatchDataorigin_pd
 
MsqMeshEntitypatchElemArray
 stored once during initialization for More...
 
Matrix3DmEntries
 CSR block entries. size: nb of nonzero blocks, i.e. mRowStart[mSize] . More...
 
size_t * mRowStart
 start of each row in mEntries. size: nb of vertices (mSize). More...
 
size_t * mColIndex
 CSR block structure: column indexes of the row entries. More...
 
int * mAccumulation
 accumulation pattern instructions More...
 
size_t * mAccumElemStart
 Starting index in mAccumulation for element i, i=1,... More...
 
size_t mSize
 number of rows (or number of columns, this is a square matrix). More...
 
Matrix3DmPreconditioner
 
size_t precondArraySize
 
Vector3DmR
 array used in the CG solver More...
 
Vector3DmZ
 array used in the CG solver More...
 
Vector3DmP
 array used in the CG solver More...
 
Vector3DmW
 array used in the CG solver More...
 
size_t cgArraySizes
 size of arrays allocated in the CG solver. More...
 
size_t maxCGiter
 max nb of iterations of the CG solver. More...
 

Friends

class ObjectiveFunction
 
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). More...
 
msq_stdio::ostream & operator<< (msq_stdio::ostream &, const MsqHessian &)
 Prints out the MsqHessian blocks. More...
 
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). More...
 
msq_stdio::ostream & operator<< (msq_stdio::ostream &, const MsqHessian &)
 Prints out the MsqHessian blocks. More...
 

Detailed Description

Vector3D is the object that effeciently stores the objective function Hessian each entry is a Matrix3D object (i.e. a vertex Hessian).

Definition at line 75 of file includeLinks/MsqHessian.hpp.

Constructor & Destructor Documentation

Definition at line 62 of file Misc/MsqHessian.cpp.

62  :
63  origin_pd(0), mEntries(0), mRowStart(0), mColIndex(0),
66  mR(0), mZ(0), mP(0), mW(0), cgArraySizes(0), maxCGiter(50)
67 { }
size_t * mAccumElemStart
Starting index in mAccumulation for element i, i=1,...
Vector3D * mZ
array used in the CG solver
size_t maxCGiter
max nb of iterations of the CG solver.
size_t mSize
number of rows (or number of columns, this is a square matrix).
Vector3D * mR
array used in the CG solver
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] .
size_t * mRowStart
start of each row in mEntries. size: nb of vertices (mSize).
size_t cgArraySizes
size of arrays allocated in the CG solver.
int * mAccumulation
accumulation pattern instructions
Vector3D * mP
array used in the CG solver
~MsqHessian ( )

Definition at line 70 of file Misc/MsqHessian.cpp.

References MsqHessian::mAccumElemStart, MsqHessian::mAccumulation, MsqHessian::mColIndex, MsqHessian::mEntries, MsqHessian::mP, MsqHessian::mPreconditioner, MsqHessian::mR, MsqHessian::mRowStart, MsqHessian::mW, and MsqHessian::mZ.

71 {
72  delete[] mEntries;
73  delete[] mRowStart;
74  delete[] mColIndex;
75 
76  delete[] mAccumulation;
77  delete[] mAccumElemStart;
78 
79  delete[] mPreconditioner;
80 
81  delete[] mR;
82  delete[] mZ;
83  delete[] mP;
84  delete[] mW;
85 }
size_t * mAccumElemStart
Starting index in mAccumulation for element i, i=1,...
Vector3D * mZ
array used in the CG solver
Vector3D * mR
array used in the CG solver
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] .
size_t * mRowStart
start of each row in mEntries. size: nb of vertices (mSize).
int * mAccumulation
accumulation pattern instructions
Vector3D * mP
array used in the CG solver
~MsqHessian ( )

Member Function Documentation

void accumulate_entries ( PatchData pd,
const size_t &  elem_index,
Matrix3D *const &  mat3d_array,
MsqError err 
)
inline

Accumulates entries of an element hessian into an objective function hessian. Make sure to use zero_out() before starting the accumulation process.

Parameters
pd,:PatchData in that contains the element which Hessian we are accumulating in the Hessian matrix. This must be the same PatchData that was used in MsqHessian::initialize().
elem_index,:index of the element in the PatchData.
mat3d_array,:This is the upper triangular part of the element Hessian for all nodes, including fixed nodes, for which the entries must be null Matrix3Ds.
nb_mat3d.The size of the mat3d_array: (n+1)n/2, where n is the number of nodes in the element.

Definition at line 153 of file includeLinks/MsqHessian.hpp.

References PatchData::get_element_array(), i, MsqError::INVALID_ARG, j, MsqHessian::mAccumElemStart, MsqHessian::mAccumulation, MsqHessian::mEntries, MSQ_SETERR, MsqHessian::origin_pd, Matrix3D::plus_transpose_equal(), and MsqMeshEntity::vertex_count().

Referenced by LPtoPTemplate::compute_analytical_hessian().

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  }
size_t * mAccumElemStart
Starting index in mAccumulation for element i, i=1,...
invalid function argument passed
void plus_transpose_equal(const Matrix3D &B)
#define MSQ_SETERR(err)
Macro to set error - use err.clear() to clear.
blockLoc i
Definition: read.cpp:79
Matrix3D * mEntries
CSR block entries. size: nb of nonzero blocks, i.e. mRowStart[mSize] .
j indices j
Definition: Indexing.h:6
int * mAccumulation
accumulation pattern instructions

Here is the call graph for this function:

Here is the caller graph for this function:

void accumulate_entries ( PatchData pd,
const size_t &  elem_index,
Matrix3D *const &  mat3d_array,
MsqError err 
)
inline
void apply_preconditioner ( Vector3D  zloc[],
Vector3D  rloc[],
MsqError err 
)
inline

Computes $ z=M^{-1}r $ .

Definition at line 240 of file includeLinks/MsqHessian.hpp.

References MsqHessian::mPreconditioner, and MsqHessian::mSize.

Referenced by MsqHessian::cg_solver().

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  }
size_t mSize
number of rows (or number of columns, this is a square matrix).

Here is the caller graph for this function:

void apply_preconditioner ( Vector3D  zloc[],
Vector3D  rloc[],
MsqError err 
)
void cg_solver ( Vector3D  x[],
Vector3D  b[],
MsqError err 
)

uses the preconditionned conjugate gradient algebraic solver to find d in $ H * d = -g $ .

Parameters
x: the solution, usually the descent direction d.
b: -b will be the right hand side. Usually b is the gradient.

Definition at line 440 of file Misc/MsqHessian.cpp.

References MsqHessian::apply_preconditioner(), MsqHessian::axpy, MsqHessian::cgArraySizes, MsqHessian::compute_preconditioner(), i, Mesquite::inner(), Mesquite::length(), MsqHessian::maxCGiter, MsqHessian::mP, MsqHessian::mR, MsqHessian::mSize, MSQ_CHKERR, MSQ_FUNCTION_TIMER, MsqHessian::mW, and MsqHessian::mZ.

Referenced by FeasibleNewton::optimize_vertex_positions().

441 {
442  MSQ_FUNCTION_TIMER( "MsqHessian::cg_solver" );
443 
444  // reallocates arrays if size of the Hessian has changed too much.
445  if (mSize > cgArraySizes || mSize < cgArraySizes/10 ) {
446  delete[] mR;
447  delete[] mZ;
448  delete[] mP;
449  delete[] mW;
450  mR = new Vector3D[mSize];
451  mZ = new Vector3D[mSize];
452  mP = new Vector3D[mSize];
453  mW = new Vector3D[mSize];
455  }
456 
457  size_t i;
458  double alpha_, alpha, beta;
459  double cg_tol = 1e-2; // 1e-2 will give a reasonably good solution (~1%).
460  double norm_g = length(b, mSize);
461  double norm_r = norm_g;
462  double rzm1; // r^T_{k-1} z_{k-1}
463  double rzm2; // r^T_{k-2} z_{k-2}
464 
465  this->compute_preconditioner(err); MSQ_CHKERR(err); // get M^{-1} for diagonal blocks
466 
467  for (i=0; i<mSize; ++i) x[i] = 0. ;
468  for (i=0; i<mSize; ++i) mR[i] = -b[i] ; // r = -b because x_0 = 0 and we solve H*x = -b
469  norm_g *= cg_tol;
470 
471  this->apply_preconditioner(mZ, mR, err); // solve Mz = r (computes z = M^-1 r)
472  for (i=0; i<mSize; ++i) mP[i] = mZ[i] ; // p_1 = z_0
473  rzm1 = inner(mZ,mR,mSize); // inner product r_{k-1}^T z_{k-1}
474 
475  size_t cg_iter = 0;
476  while ((norm_r > norm_g) && (cg_iter < maxCGiter)) {
477  ++cg_iter;
478 
479  axpy(mW, mSize, *this, mP, mSize, 0,0,err); // w = A * p_k
480 
481  alpha_ = inner(mP,mW,mSize); // alpha_ = p_k^T A p_k
482  if (alpha_ <= 0.0) {
483  if (1 == cg_iter) {
484  for (i=0; i<mSize; ++i) x[i] += mP[i]; // x_{k+1} = x_k + p_{k+1}
485  }
486  break; // Newton goes on with this direction of negative curvature
487  }
488 
489  alpha = rzm1 / alpha_;
490 
491  for (i=0; i<mSize; ++i) x[i] += alpha*mP[i]; // x_{k+1} = x_k + alpha_{k+1} p_{k+1}
492  for (i=0; i<mSize; ++i) mR[i] -= alpha*mW[i]; // r_{k+1} = r_k - alpha_{k+1} A p_{k+1}
493  norm_r = length(mR, mSize);
494 
495  this->apply_preconditioner(mZ, mR, err); // solve Mz = r (computes z = M^-1 r)
496 
497  rzm2 = rzm1;
498  rzm1 = inner(mZ,mR,mSize); // inner product r_{k-1}^T z_{k-1}
499  beta = rzm1 / rzm2;
500  for (i=0; i<mSize; ++i) mP[i] = mZ[i] + beta*mP[i]; // p_k = z_{k-1} + Beta_k * p_{k-1}
501  }
502 }
void apply_preconditioner(Vector3D zloc[], Vector3D rloc[], MsqError &err)
void compute_preconditioner(MsqError &err)
Vector3D * mZ
array used in the CG solver
double length(Vector3D *const v, int n)
size_t maxCGiter
max nb of iterations of the CG solver.
NVec< 3, double > Vector3D
size_t mSize
number of rows (or number of columns, this is a square matrix).
#define MSQ_CHKERR(err)
Mesquite&#39;s Error Checking macro.
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
double inner(const Vector3D lhs[], const Vector3D rhs[], int n)
size_t cgArraySizes
size of arrays allocated in the CG solver.
Vector3D * mP
array used in the CG solver

Here is the call graph for this function:

Here is the caller graph for this function:

void cg_solver ( Vector3D  x[],
Vector3D  b[],
MsqError err 
)
void compute_preconditioner ( MsqError err)
void compute_preconditioner ( MsqError err)

compute a preconditioner used in the preconditioned conjugate gradient algebraic solver. In fact, this computes $ M^{-1} $ .

Definition at line 358 of file Misc/MsqHessian.cpp.

References MsqHessian::mEntries, MsqHessian::mPreconditioner, MsqHessian::mRowStart, MsqHessian::mSize, and MsqHessian::precondArraySize.

Referenced by MsqHessian::cg_solver().

359 {
360  // reallocates arrays if size of the Hessian has changed too much.
361  if (mSize > precondArraySize || mSize < precondArraySize/10 ) {
362  delete[] mPreconditioner;
363  mPreconditioner = new Matrix3D[mSize];
364  }
365 
366  Matrix3D* diag_block;
367  double sum, tmp;
368  size_t m;
369  // For each diagonal block, the (inverted) preconditioner is
370  // the inverse of the sum of the diagonal entries.
371  for (m=0; m<mSize; ++m) {
372  diag_block = mEntries + mRowStart[m]; // Gets block at position m,m .
373 
374 #if DIAGONAL_PRECONDITIONER
375  // find sum, and computes inverse, or 0 if sum = 0 .
376  sum = (*diag_block)[0][0] + (*diag_block)[1][1] + (*diag_block)[2][2];
377  double inv_sum;
378  if (sum != 0.)
379  inv_sum = 1 / sum;
380  else
381  inv_sum = 0.;
382 
383  mPreconditioner[m][0][0] = inv_sum;
384  mPreconditioner[m][1][1] = inv_sum;
385  mPreconditioner[m][2][2] = inv_sum;
386 #else
387  // calculate LDL^T factorization of the diagonal block
388  // L = [1 pre[0][1] pre[0][2]]
389  // [0 1 pre[1][2]]
390  // [0 0 1 ]
391  // inv(D) = [pre[0][0] 0 0 ]
392  // [0 pre[1][1] 0 ]
393  // [0 0 pre[2][2]]
394 
395  if ((*diag_block)[0][0] == 0.0) {
396  // Either this is a fixed vertex or the diagonal block is not
397  // invertible. Switch to the diagonal preconditioner in this
398  // case.
399 
400  sum = (*diag_block)[0][0] + (*diag_block)[1][1] + (*diag_block)[2][2];
401  if (sum != 0.0)
402  sum = 1 / sum;
403 
404  mPreconditioner[m][0][0] = sum;
405  mPreconditioner[m][0][1] = 0.0;
406  mPreconditioner[m][0][2] = 0.0;
407  mPreconditioner[m][1][1] = sum;
408  mPreconditioner[m][1][2] = 0.0;
409  mPreconditioner[m][2][2] = sum;
410  }
411  else {
412  mPreconditioner[m][0][0] = 1.0 / (*diag_block)[0][0];
413  mPreconditioner[m][0][1] = (*diag_block)[0][1] * mPreconditioner[m][0][0];
414  mPreconditioner[m][0][2] = (*diag_block)[0][2] * mPreconditioner[m][0][0];
415 
416  mPreconditioner[m][1][1] =
417  1.0 / ((*diag_block)[1][1] -
418  (*diag_block)[0][1] * mPreconditioner[m][0][1]);
419 
420  tmp = (*diag_block)[1][2] -
421  (*diag_block)[0][2] * mPreconditioner[m][0][1];
422 
423  mPreconditioner[m][1][2] = mPreconditioner[m][1][1] * tmp;
424 
425  mPreconditioner[m][2][2] =
426  1.0 / ((*diag_block)[2][2] -
427  (*diag_block)[0][2]*mPreconditioner[m][0][2] -
428  mPreconditioner[m][1][2]*tmp);
429  }
430 #endif
431  }
432 }
size_t mSize
number of rows (or number of columns, this is a square matrix).
Matrix3D * mEntries
CSR block entries. size: nb of nonzero blocks, i.e. mRowStart[mSize] .
size_t * mRowStart
start of each row in mEntries. size: nb of vertices (mSize).

Here is the caller graph for this function:

Matrix3D * get_block ( size_t  i,
size_t  j 
)
inline

Returns a pointer to the Matrix3D block at position i,j if it exist. Returns the NULL pointer if position i,j (0-based) is a NULL entry. Note that block i,j must be in the upper triangular part of the (symetric) hessian.

Definition at line 276 of file includeLinks/MsqHessian.hpp.

References MsqHessian::mColIndex, MsqHessian::mEntries, MsqHessian::mRowStart, and MsqHessian::mSize.

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  }
size_t mSize
number of rows (or number of columns, this is a square matrix).
blockLoc i
Definition: read.cpp:79
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
size_t * mRowStart
start of each row in mEntries. size: nb of vertices (mSize).
Matrix3D* get_block ( size_t  i,
size_t  j 
)
void get_diagonal_blocks ( msq_std::vector< Matrix3D > &  diag,
MsqError err 
)

returns the diagonal blocks, memory must be allocated before call.

Parameters
diagis an STL vector of size MsqHessian::size() .

Definition at line 341 of file Misc/MsqHessian.cpp.

References i, MsqHessian::mEntries, MsqHessian::mRowStart, and MsqHessian::size().

343 {
344  // make sure we have enough memory, so that no reallocation is needed later.
345  if (diag.size() != size()) {
346  diag.reserve(size());
347  }
348 
349  for (size_t i=0; i<size(); ++i) {
350  diag[i] = mEntries[mRowStart[i]];
351  }
352 }
blockLoc i
Definition: read.cpp:79
Matrix3D * mEntries
CSR block entries. size: nb of nonzero blocks, i.e. mRowStart[mSize] .
size_t * mRowStart
start of each row in mEntries. size: nb of vertices (mSize).

Here is the call graph for this function:

void get_diagonal_blocks ( msq_std::vector< Matrix3D > &  diag,
MsqError err 
)

returns the diagonal blocks, memory must be allocated before call.

void initialize ( PatchData pd,
MsqError err 
)

creates a sparse structure for a Hessian, based on the connectivity information contained in the PatchData. Only the upper triangular part of the Hessian is stored.

Definition at line 91 of file Misc/MsqHessian.cpp.

References PatchData::get_element_array(), MsqMeshEntity::get_vertex_index_array(), i, MsqError::INVALID_ARG, j, MsqHessian::mAccumElemStart, MsqHessian::mAccumulation, MsqHessian::mColIndex, MsqHessian::mEntries, MsqHessian::mRowStart, MsqHessian::mSize, MSQ_CHKERR, MSQ_FUNCTION_TIMER, MSQ_SETERR, PatchData::num_elements(), PatchData::num_vertices(), MsqHessian::origin_pd, MsqHessian::patchElemArray, rs(), and MsqMeshEntity::vertex_count().

Referenced by FeasibleNewton::optimize_vertex_positions().

92 {
93  MSQ_FUNCTION_TIMER( "MsqHession::initialize" );
94  delete[] mEntries;
95  delete[] mRowStart;
96  delete[] mColIndex;
97  delete[] mAccumulation;
98  delete[] mAccumElemStart;
99 
100  size_t num_vertices = pd.num_vertices();
101  size_t num_elements = pd.num_elements();
102  size_t const * vtx_list;
103  size_t e, r, rs, re, c, cs, ce, nz, nnz, nve, i, j;
104  patchElemArray = pd.get_element_array(err); MSQ_CHKERR(err);
105 
106  if (num_vertices == 0) {
107  MSQ_SETERR( err )( "No vertices in PatchData", MsqError::INVALID_ARG);
108  return;
109  }
110 
111  mSize = num_vertices;
112 
113  // Calculate the offsets for a CSC representation of the accumulation
114  // pattern.
115 
116  size_t* col_start = new size_t[num_vertices + 1];
117  mAccumElemStart = new size_t[num_elements+1];
118  mAccumElemStart[0] = 0;
119 
120  for (i = 0; i < num_vertices; ++i) {
121  col_start[i] = 0;
122  }
123 
124  for (e = 0; e < num_elements; ++e) {
125  nve = patchElemArray[e].vertex_count();
126  vtx_list = patchElemArray[e].get_vertex_index_array();
127  mAccumElemStart[e+1] = mAccumElemStart[e] + (nve+1)*nve/2;
128 
129  for (i = 0; i < nve; ++i) {
130  r = vtx_list[i];
131 
132  for (j = i; j < nve; ++j) {
133  c = vtx_list[j];
134 
135  if (r <= c) {
136  col_start[c]++;
137  }
138  else {
139  col_start[r]++;
140  }
141  }
142  }
143  }
144 
145  nz = 0;
146  for (i = 0; i < num_vertices; ++i) {
147  j = col_start[i];
148  col_start[i] = nz;
149  nz += j;
150  }
151  col_start[i] = nz;
152 
153  // Finished putting matrix into CSC representation
154 
155  int* row_instr = new int[5*nz];
156  size_t* row_index = new size_t[nz];
157 
158  nz = 0;
159  for (e = 0; e < num_elements; ++e) {
160  nve = patchElemArray[e].vertex_count();
161  vtx_list = patchElemArray[e].get_vertex_index_array();
162 
163  for (i = 0; i < nve; ++i) {
164  r = vtx_list[i];
165 
166  for (j = i; j < nve; ++j) {
167  c = vtx_list[j];
168 
169  if (r <= c) {
170  row_index[col_start[c]] = r;
171  row_instr[col_start[c]] = nz;
172  ++col_start[c];
173  }
174  else {
175  row_index[col_start[r]] = c;
176  row_instr[col_start[r]] = -nz;
177  ++col_start[r];
178  }
179 
180  ++nz;
181  }
182  }
183  }
184 
185  for (i = num_vertices-1; i > 0; --i) {
186  col_start[i+1] = col_start[i];
187  }
188  col_start[1] = col_start[0];
189  col_start[0] = 0;
190 
191  // cout << "col_start: ";
192  // for (int t=0; t<num_vertices+1; ++t)
193  // cout << col_start[t] << " ";
194  // cout << endl;
195  // cout << "row_index: ";
196  // for (int t=0; t<nz; ++t)
197  // cout << row_index[t] << " ";
198  // cout << endl;
199  // cout << "row_instr: ";
200  // for (int t=0; t<nz; ++t)
201  // cout << row_instr[t] << " ";
202  // cout << endl;
203 
204 
205  // Convert CSC to CSR
206  // First calculate the offsets in the row
207 
208  size_t* row_start = new size_t[num_vertices + 1];
209 
210  for (i = 0; i < num_vertices; ++i) {
211  row_start[i] = 0;
212  }
213 
214  for (i = 0; i < nz; ++i) {
215  ++row_start[row_index[i]];
216  }
217 
218  nz = 0;
219  for (i = 0; i < num_vertices; ++i) {
220  j = row_start[i];
221  row_start[i] = nz;
222  nz += j;
223  }
224  row_start[i] = nz;
225 
226  // Now calculate the pattern
227 
228  size_t* col_index = new size_t[nz];
229  int* col_instr = new int[nz];
230 
231  for (i = 0; i < num_vertices; ++i) {
232  cs = col_start[i];
233  ce = col_start[i+1];
234 
235  while(cs < ce) {
236  r = row_index[cs];
237 
238  col_index[row_start[r]] = i;
239  col_instr[row_start[r]] = row_instr[cs];
240 
241  ++row_start[r];
242  ++cs;
243  }
244  }
245 
246  for (i = num_vertices-1; i > 0; --i) {
247  row_start[i+1] = row_start[i];
248  }
249  row_start[1] = row_start[0];
250  row_start[0] = 0;
251 
252  delete[] row_index;
253 
254  // Now that the matrix is CSR
255  // Column indices for each row are sorted
256 
257  // Compaction -- count the number of nonzeros
258  mRowStart = col_start; // don't need to reallocate
259  mAccumulation = row_instr; // don't need to reallocate
260 
261  for (i = 0; i <= num_vertices; ++i) {
262  mRowStart[i] = 0;
263  }
264 
265  nnz = 0;
266  for (i = 0; i < num_vertices; ++i) {
267  rs = row_start[i];
268  re = row_start[i+1];
269 
270  c = num_vertices;
271  while(rs < re) {
272  if (c != col_index[rs]) {
273  // This is an unseen nonzero
274 
275  c = col_index[rs];
276  ++mRowStart[i];
277  ++nnz;
278  }
279 
280  if (col_instr[rs] >= 0) {
281  mAccumulation[col_instr[rs]] = nnz - 1;
282  }
283  else {
284  mAccumulation[-col_instr[rs]] = 1 - nnz;
285  }
286 
287  ++rs;
288  }
289  }
290 
291  nnz = 0;
292  for (i = 0; i < num_vertices; ++i) {
293  j = mRowStart[i];
294  mRowStart[i] = nnz;
295  nnz += j;
296  }
297  mRowStart[i] = nnz;
298 
299  delete [] col_instr;
300 
301  // Fill in the compacted hessian matrix
302 
303  mColIndex = new size_t[nnz];
304 
305  for (i = 0; i < num_vertices; ++i) {
306  rs = row_start[i];
307  re = row_start[i+1];
308 
309  c = num_vertices;
310  while(rs < re) {
311  if (c != col_index[rs]) {
312  // This is an unseen nonzero
313 
314  c = col_index[rs];
315  mColIndex[mRowStart[i]] = c;
316  mRowStart[i]++;
317  }
318  ++rs;
319  }
320  }
321 
322  for (i = num_vertices-1; i > 0; --i) {
323  mRowStart[i+1] = mRowStart[i];
324  }
325  mRowStart[1] = mRowStart[0];
326  mRowStart[0] = 0;
327 
328  delete [] row_start;
329  delete [] col_index;
330 
331  mEntries = new Matrix3D[nnz]; // On Solaris, no initializer allowed for new of an array
332  for (i=0;i<nnz;++i) mEntries[i] = 0.; // so we initialize all entries manually.
333 
334  origin_pd = &pd;
335 
336  return;
337 }
subroutine rs(nm, n, a, w, matz, z, fv1, fv2, ierr)
size_t * mAccumElemStart
Starting index in mAccumulation for element i, i=1,...
invalid function argument passed
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.
#define MSQ_CHKERR(err)
Mesquite&#39;s Error Checking macro.
#define MSQ_SETERR(err)
Macro to set error - use err.clear() to clear.
blockLoc i
Definition: read.cpp:79
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
const msq_stdc::size_t * get_vertex_index_array() const
Very efficient retrieval of vertices indexes (corresponding to the PatchData vertex array)...
MsqMeshEntity * patchElemArray
stored once during initialization for
size_t * mRowStart
start of each row in mEntries. size: nb of vertices (mSize).
int * mAccumulation
accumulation pattern instructions

Here is the call graph for this function:

Here is the caller graph for this function:

void initialize ( PatchData pd,
MsqError err 
)
size_t size ( )
inline

Definition at line 107 of file src/Misc/MsqHessian.hpp.

References MsqHessian::mSize.

107 {return mSize;}
size_t mSize
number of rows (or number of columns, this is a square matrix).
size_t size ( )
inline

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

References MsqHessian::mSize.

Referenced by MsqHessian::get_diagonal_blocks().

107 {return mSize;}
size_t mSize
number of rows (or number of columns, this is a square matrix).

Here is the caller graph for this function:

void zero_out ( )
inline
void zero_out ( )
inline

Sets all Hessian entries to zero. This is usually used before starting to accumulate elements hessian in the objective function hessian.

Definition at line 129 of file includeLinks/MsqHessian.hpp.

References i, MsqHessian::mEntries, MsqHessian::mRowStart, MsqHessian::mSize, and Matrix3D::zero().

Referenced by LPtoPTemplate::compute_analytical_hessian().

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  }
void zero()
Sets all entries to zero (more efficient than assignement).
size_t mSize
number of rows (or number of columns, this is a square matrix).
blockLoc i
Definition: read.cpp:79
Matrix3D * mEntries
CSR block entries. size: nb of nonzero blocks, i.e. mRowStart[mSize] .
size_t * mRowStart
start of each row in mEntries. size: nb of vertices (mSize).

Here is the call graph for this function:

Here is the caller graph for this function:

Friends And Related Function Documentation

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 
)
friend

Hessian - vector product, summed with a second vector (optional).

Parameters
res,:array of Vector3D in which the result is stored.
size_r,:size of the res array.
x,:vector multiplied by the Hessian.
size_x,:size of the x array.
y,:vector added to the Hessian vector product. Set to 0 (NULL) if not needed.
size_y,:size of the y array. Set to 0 if not needed.

Definition at line 187 of file includeLinks/MsqHessian.hpp.

Referenced by MsqHessian::cg_solver().

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  }
void int int REAL REAL * y
Definition: read.cpp:74
void plusEqAx(Vector3D &v, const Matrix3D &A, const Vector3D &x)
void plusEqTransAx(Vector3D &v, const Matrix3D &A, const Vector3D &x)
NVec< 3, double > Vector3D
blockLoc i
Definition: read.cpp:79
void int int REAL * x
Definition: read.cpp:74
j indices j
Definition: Indexing.h:6
void eqAx(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 err 
)
friend

Hessian - vector product, summed with a second vector (optional).

Parameters
res,:array of Vector3D in which the result is stored.
size_r,:size of the res array.
x,:vector multiplied by the Hessian.
size_x,:size of the x array.
y,:vector added to the Hessian vector product. Set to 0 (NULL) if not needed.
size_y,:size of the y array. Set to 0 if not needed.

Definition at line 187 of file includeLinks/MsqHessian.hpp.

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  }
void int int REAL REAL * y
Definition: read.cpp:74
void plusEqAx(Vector3D &v, const Matrix3D &A, const Vector3D &x)
void plusEqTransAx(Vector3D &v, const Matrix3D &A, const Vector3D &x)
NVec< 3, double > Vector3D
blockLoc i
Definition: read.cpp:79
void int int REAL * x
Definition: read.cpp:74
j indices j
Definition: Indexing.h:6
void eqAx(Vector3D &v, const Matrix3D &A, const Vector3D &x)

Definition at line 121 of file includeLinks/MsqHessian.hpp.

msq_stdio::ostream& operator<< ( msq_stdio::ostream &  s,
const MsqHessian h 
)
friend

Prints out the MsqHessian blocks.

msq_stdio::ostream& operator<< ( msq_stdio::ostream &  s,
const MsqHessian h 
)
friend

Prints out the MsqHessian blocks.

Member Data Documentation

size_t cgArraySizes
protected

size of arrays allocated in the CG solver.

Definition at line 98 of file includeLinks/MsqHessian.hpp.

Referenced by MsqHessian::cg_solver().

size_t * mAccumElemStart
protected

Starting index in mAccumulation for element i, i=1,...

Definition at line 87 of file includeLinks/MsqHessian.hpp.

Referenced by MsqHessian::accumulate_entries(), MsqHessian::initialize(), and MsqHessian::~MsqHessian().

int * mAccumulation
protected

accumulation pattern instructions

Definition at line 86 of file includeLinks/MsqHessian.hpp.

Referenced by MsqHessian::accumulate_entries(), MsqHessian::initialize(), and MsqHessian::~MsqHessian().

size_t maxCGiter
protected

max nb of iterations of the CG solver.

Definition at line 99 of file includeLinks/MsqHessian.hpp.

Referenced by MsqHessian::cg_solver().

size_t * mColIndex
protected

CSR block structure: column indexes of the row entries.

Definition at line 84 of file includeLinks/MsqHessian.hpp.

Referenced by Mesquite::axpy(), MsqHessian::get_block(), MsqHessian::initialize(), Mesquite::operator<<(), and MsqHessian::~MsqHessian().

Vector3D * mP
protected

array used in the CG solver

Definition at line 96 of file includeLinks/MsqHessian.hpp.

Referenced by MsqHessian::cg_solver(), and MsqHessian::~MsqHessian().

Vector3D * mR
protected

array used in the CG solver

Definition at line 94 of file includeLinks/MsqHessian.hpp.

Referenced by MsqHessian::cg_solver(), and MsqHessian::~MsqHessian().

size_t * mRowStart
protected
Vector3D * mW
protected

array used in the CG solver

Definition at line 97 of file includeLinks/MsqHessian.hpp.

Referenced by MsqHessian::cg_solver(), and MsqHessian::~MsqHessian().

Vector3D * mZ
protected

array used in the CG solver

Definition at line 95 of file includeLinks/MsqHessian.hpp.

Referenced by MsqHessian::cg_solver(), and MsqHessian::~MsqHessian().

PatchData * origin_pd
protected
MsqMeshEntity * patchElemArray
protected

stored once during initialization for

fast access.

Definition at line 79 of file includeLinks/MsqHessian.hpp.

Referenced by MsqHessian::initialize().

size_t precondArraySize
protected

Definition at line 92 of file includeLinks/MsqHessian.hpp.

Referenced by MsqHessian::compute_preconditioner().


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