void initComponentGeneral() { static bool first = true; if (first) { first = false; } initValidation(); initExporter(); initEngine(); initGraphComponent(); initTopologyMapping(); initBoundaryCondition(); initUserInteraction(); initConstraint(); initHaptics(); initDenseSolver(); #ifdef SOFA_HAVE_CSPARSE initSparseSolver(); #endif initPreconditioner(); initOpenGLVisual(); }
/* * This routine performs a preconditioned conjugate-gradient * iteration in order to solve the newton equations for a search * direction for a truncated-newton algorithm. * When the value of the quadratic model is sufficiently reduced, * the iteration is terminated. */ static int tnc_direction(double *zsol, double *diagb, double *x, double g[], int n, int maxCGit, int maxnfeval, int *nfeval, logical upd1, double yksk, double yrsr, double *sk, double *yk, double *sr, double *yr, logical lreset, tnc_function *function, void *state, double xscale[], double xoffset[], double fscale, int *pivot, double accuracy, double gnorm, double xnorm, double low[], double up[]) { double alpha, beta, qold, qnew, rhsnrm, tol, vgv, rz, rzold, qtest, pr, gtp; int i, k, frc; /* Temporary vectors */ double *r = NULL, *zk = NULL, *v = NULL, *emat = NULL, *gv = NULL; /* No CG it. => dir = -grad */ if (maxCGit == 0) { dcopy1(n, g, zsol); dneg1(n, zsol); project(n, zsol, pivot); return 0; } /* General initialization */ rhsnrm = gnorm; tol = 1e-12; qold = 0.0; rzold = 0.0; /* Uneeded */ frc = -1; /* ENOMEM here */ r = malloc(sizeof(*r)*n); /* Residual */ if (r == NULL) goto cleanup; v = malloc(sizeof(*v)*n); if (v == NULL) goto cleanup; zk = malloc(sizeof(*zk)*n); if (zk == NULL) goto cleanup; emat = malloc(sizeof(*emat)*n); /* Diagonal preconditoning matrix */ if (emat == NULL) goto cleanup; gv = malloc(sizeof(*gv)*n); /* hessian times v */ if (gv == NULL) goto cleanup; /* Initialization for preconditioned conjugate-gradient algorithm */ frc = initPreconditioner(diagb, emat, n, lreset, yksk, yrsr, sk, yk, sr, yr, upd1); if (frc) goto cleanup; for (i = 0; i < n; i++) { r[i] = -g[i]; v[i] = 0.0; zsol[i] = 0.0; /* Computed search direction */ } /* Main iteration */ for (k = 0; k < maxCGit; k++) { /* CG iteration to solve system of equations */ project(n, r, pivot); frc = msolve(r, zk, n, sk, yk, diagb, sr, yr, upd1, yksk, yrsr, lreset); if (frc) goto cleanup; project(n, zk, pivot); rz = ddot1(n, r, zk); if ((rz / rhsnrm < tol) || ((*nfeval) >= (maxnfeval-1))) { /* Truncate algorithm in case of an emergency or too many function evaluations */ if (k == 0) { dcopy1(n, g, zsol); dneg1(n, zsol); project(n, zsol, pivot); } break; } if (k == 0) beta = 0.0; else beta = rz / rzold; for (i = 0; i < n; i++) v[i] = zk[i] + beta * v[i]; project(n, v, pivot); frc = hessianTimesVector(v, gv, n, x, g, function, state, xscale, xoffset, fscale, accuracy, xnorm, low, up); ++(*nfeval); if (frc) goto cleanup; project(n, gv, pivot); vgv = ddot1(n, v, gv); if (vgv / rhsnrm < tol) { /* Truncate algorithm in case of an emergency */ if (k == 0) { frc = msolve(g, zsol, n, sk, yk, diagb, sr, yr, upd1, yksk, yrsr, lreset); if (frc) goto cleanup; dneg1(n, zsol); project(n, zsol, pivot); } break; } diagonalScaling(n, emat, v, gv, r); /* Compute linear step length */ alpha = rz / vgv; /* Compute current solution and related vectors */ daxpy1(n, alpha, v, zsol); daxpy1(n, -alpha, gv, r); /* Test for convergence */ gtp = ddot1(n, zsol, g); pr = ddot1(n, r, zsol); qnew = (gtp + pr) * 0.5; qtest = (k + 1) * (1.0 - qold / qnew); if (qtest <= 0.5) break; /* Perform cautionary test */ if (gtp > 0.0) { /* Truncate algorithm in case of an emergency */ daxpy1(n, -alpha, v, zsol); break; } qold = qnew; rzold = rz; } /* Terminate algorithm */ /* Store (or restore) diagonal preconditioning */ dcopy1(n, emat, diagb); cleanup: if (r) free(r); if (v) free(v); if (zk) free(zk); if (emat) free(emat); if (gv) free(gv); return frc; }