48 #ifdef MSQ_USE_OLD_C_HEADERS
54 #ifdef MSQ_USE_OLD_IO_HEADERS
55 # include <iostream.h>
63 origin_pd(0), mEntries(0), mRowStart(0), mColIndex(0),
64 mAccumulation(0), mAccumElemStart(0), mSize(0),
65 mPreconditioner(0), precondArraySize(0),
66 mR(0), mZ(0), mP(0), mW(0), cgArraySizes(0), maxCGiter(50)
102 size_t const * vtx_list;
103 size_t e, r,
rs, re, c, cs, ce, nz, nnz, nve,
i,
j;
106 if (num_vertices == 0) {
111 mSize = num_vertices;
116 size_t* col_start =
new size_t[num_vertices + 1];
120 for (i = 0; i < num_vertices; ++
i) {
124 for (e = 0; e < num_elements; ++e) {
129 for (i = 0; i < nve; ++
i) {
132 for (j = i; j < nve; ++
j) {
146 for (i = 0; i < num_vertices; ++
i) {
155 int* row_instr =
new int[5*nz];
156 size_t* row_index =
new size_t[nz];
159 for (e = 0; e < num_elements; ++e) {
163 for (i = 0; i < nve; ++
i) {
166 for (j = i; j < nve; ++
j) {
170 row_index[col_start[c]] = r;
171 row_instr[col_start[c]] = nz;
175 row_index[col_start[r]] = c;
176 row_instr[col_start[r]] = -nz;
185 for (i = num_vertices-1; i > 0; --
i) {
186 col_start[i+1] = col_start[
i];
188 col_start[1] = col_start[0];
208 size_t* row_start =
new size_t[num_vertices + 1];
210 for (i = 0; i < num_vertices; ++
i) {
214 for (i = 0; i < nz; ++
i) {
215 ++row_start[row_index[
i]];
219 for (i = 0; i < num_vertices; ++
i) {
228 size_t* col_index =
new size_t[nz];
229 int* col_instr =
new int[nz];
231 for (i = 0; i < num_vertices; ++
i) {
238 col_index[row_start[r]] =
i;
239 col_instr[row_start[r]] = row_instr[cs];
246 for (i = num_vertices-1; i > 0; --
i) {
247 row_start[i+1] = row_start[
i];
249 row_start[1] = row_start[0];
261 for (i = 0; i <= num_vertices; ++
i) {
266 for (i = 0; i < num_vertices; ++
i) {
272 if (c != col_index[rs]) {
280 if (col_instr[rs] >= 0) {
292 for (i = 0; i < num_vertices; ++
i) {
305 for (i = 0; i < num_vertices; ++
i) {
311 if (c != col_index[rs]) {
322 for (i = num_vertices-1; i > 0; --
i) {
345 if (diag.size() !=
size()) {
346 diag.reserve(
size());
349 for (
size_t i=0;
i<
size(); ++
i) {
371 for (m=0; m<
mSize; ++m) {
374 #if DIAGONAL_PRECONDITIONER
376 sum = (*diag_block)[0][0] + (*diag_block)[1][1] + (*diag_block)[2][2];
395 if ((*diag_block)[0][0] == 0.0) {
400 sum = (*diag_block)[0][0] + (*diag_block)[1][1] + (*diag_block)[2][2];
414 mPreconditioner[m][0][2] = (*diag_block)[0][2] * mPreconditioner[m][0][0];
416 mPreconditioner[m][1][1] =
417 1.0 / ((*diag_block)[1][1] -
418 (*diag_block)[0][1] * mPreconditioner[m][0][1]);
420 tmp = (*diag_block)[1][2] -
421 (*diag_block)[0][2] * mPreconditioner[m][0][1];
423 mPreconditioner[m][1][2] = mPreconditioner[m][1][1] * tmp;
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);
458 double alpha_, alpha, beta;
459 double cg_tol = 1e-2;
461 double norm_r = norm_g;
467 for (i=0; i<
mSize; ++
i) x[i] = 0. ;
468 for (i=0; i<
mSize; ++
i)
mR[i] = -b[i] ;
476 while ((norm_r > norm_g) && (cg_iter <
maxCGiter)) {
479 axpy(
mW, mSize, *
this,
mP, mSize, 0,0,err);
484 for (i=0; i<
mSize; ++
i) x[i] +=
mP[i];
489 alpha = rzm1 / alpha_;
491 for (i=0; i<
mSize; ++
i) x[i] += alpha*
mP[i];
510 s <<
"MsqHessian of size: " << h.
mSize <<
"x"<< h.
mSize <<
"\n";
511 for (i=0; i<h.
mSize; ++
i) {
512 s <<
" ROW " << i <<
" ------------------------\n";
514 s <<
" column " << h.
mColIndex[
j] <<
" ----\n";
subroutine rs(nm, n, a, w, matz, z, fv1, fv2, ierr)
Used to hold the error state and return it to the application.
void apply_preconditioner(Vector3D zloc[], Vector3D rloc[], MsqError &err)
size_t * mAccumElemStart
Starting index in mAccumulation for element i, i=1,...
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
double length(Vector3D *const v, int n)
size_t maxCGiter
max nb of iterations of the CG solver.
invalid function argument passed
size_t num_elements() const
number of elements in the Patch.
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's Error Checking macro.
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
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 num_vertices() const
number of vertices in the patch.
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] .
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
#define MSQ_FUNCTION_TIMER(NAME)
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)
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).
double inner(const Vector3D lhs[], const Vector3D rhs[], int n)
void get_diagonal_blocks(msq_std::vector< Matrix3D > &diag, MsqError &err)
returns the diagonal blocks, memory must be allocated before call.
Matrix3D * mPreconditioner
size_t cgArraySizes
size of arrays allocated in the CG solver.
int * mAccumulation
accumulation pattern instructions
Vector3D * mP
array used in the CG solver