//====================================================================================================================== // processInput = //====================================================================================================================== void Application::processInput() { btVector3 camX; camX = camY.cross(camZ); if(keys[SDLK_ESCAPE]) { exit(0); } if(keys[SDLK_w]) { camPos += camZ * -movingDist; } if(keys[SDLK_a]) { camPos += camX * -movingDist; } if(keys[SDLK_s]) { camPos += camZ * movingDist; } if(keys[SDLK_d]) { camPos += camX * movingDist; } if(keys[SDLK_SPACE]) { camPos += camY * -movingDist; } if(keys[SDLK_LSHIFT]) { camPos += camY * movingDist; } if(keys[SDLK_q]) { float s = sin(-movingAng); float c = cos(-movingAng); camY = camY * c + camX * s; camY.normalize(); } if(keys[SDLK_e]) { float s = sin(movingAng); float c = cos(movingAng); camY = camY * c + camX * s; camY.normalize(); } if(keys[SDLK_LEFT]) { float s = sin(movingAng); float c = cos(movingAng); camZ = camZ * c + camX * s; camZ.normalize(); } if(keys[SDLK_RIGHT]) { float s = sin(-movingAng); float c = cos(-movingAng); camZ = camZ * c + camX * s; camZ.normalize(); } if(keys[SDLK_UP]) { float s = sin(-movingAng); float c = cos(-movingAng); camZ = camZ * c + camY * s; camZ.normalize(); } if(keys[SDLK_DOWN]) { float s = sin(movingAng); float c = cos(movingAng); camZ = camZ * c + camY * s; camZ.normalize(); camY = camZ.cross(camX); } reorthogonalize(); }
NOX::StatusTest::StatusType NOX::Solver::AndersonAcceleration::step() { prePostOperator.runPreIterate(*this); Teuchos::ParameterList lsParams = paramsPtr->sublist("Direction").sublist("Newton").sublist("Linear Solver"); // On the first step, do some initializations if (nIter == 0) { // Compute F of initital guess NOX::Abstract::Group::ReturnType rtype = solnPtr->computeF(); if (rtype != NOX::Abstract::Group::Ok) { utilsPtr->out() << "NOX::Solver::AndersonAcceleration::init - " << "Unable to compute F" << std::endl; throw "NOX Error"; } // Test the initial guess status = testPtr->checkStatus(*this, checkType); if ((status == NOX::StatusTest::Converged) && (utilsPtr->isPrintType(NOX::Utils::Warning))) { utilsPtr->out() << "Warning: NOX::Solver::AndersonAcceleration::init() - " << "The solution passed into the solver (either " << "through constructor or reset method) " << "is already converged! The solver wil not " << "attempt to solve this system since status is " << "flagged as converged." << std::endl; } printUpdate(); // First check status if (status != NOX::StatusTest::Unconverged) { prePostOperator.runPostIterate(*this); printUpdate(); return status; } // Apply preconditioner if enabled if (precond) { if (recomputeJacobian) solnPtr->computeJacobian(); solnPtr->applyRightPreconditioning(false, lsParams, solnPtr->getF(), *oldPrecF); } else *oldPrecF = solnPtr->getF(); // Copy initial guess to old soln *oldSolnPtr = *solnPtr; // Compute step then first iterate with a line search. workVec->update(mixParam,*oldPrecF); bool ok = lineSearchPtr->compute(*solnPtr, stepSize, *workVec, *this); if (!ok) { if (stepSize == 0.0) { utilsPtr->out() << "NOX::Solver::AndersonAcceleratino::iterate - line search failed" << std::endl; status = NOX::StatusTest::Failed; prePostOperator.runPostIterate(*this); printUpdate(); return status; } else if (utilsPtr->isPrintType(NOX::Utils::Warning)) utilsPtr->out() << "NOX::Solver::AndersonAcceleration::iterate - using recovery step for line search" << std::endl; } // Compute F for the first iterate in case it isn't in the line search rtype = solnPtr->computeF(); if (rtype != NOX::Abstract::Group::Ok) { utilsPtr->out() << "NOX::Solver::AndersonAcceleration::iterate - unable to compute F" << std::endl; status = NOX::StatusTest::Failed; prePostOperator.runPostIterate(*this); printUpdate(); return status; } // Evaluate the current status. status = testPtr->checkStatus(*this, checkType); //Update iteration count nIter++; prePostOperator.runPostIterate(*this); printUpdate(); return status; } // First check status if (status != NOX::StatusTest::Unconverged) { prePostOperator.runPostIterate(*this); printUpdate(); return status; } // Apply preconditioner if enabled if (precond) { if (recomputeJacobian) solnPtr->computeJacobian(); solnPtr->applyRightPreconditioning(false, lsParams, solnPtr->getF(), *precF); } else *precF = solnPtr->getF(); // Manage the matrices of past iterates and QR factors if (storeParam > 0) { if (nIter == accelerationStartIteration) { // Initialize nStore = 0; rMat.shape(0,0); oldPrecF->update(1.0, *precF, -1.0); qrAdd(*oldPrecF); xMat[0]->update(1.0, solnPtr->getX(), -1.0, oldSolnPtr->getX(), 0.0); } else if (nIter > accelerationStartIteration) { if (nStore == storeParam) { Teuchos::RCP<NOX::Abstract::Vector> tempPtr = xMat[0]; for (int ii = 0; ii<nStore-1; ii++) xMat[ii] = xMat[ii+1]; xMat[nStore-1] = tempPtr; qrDelete(); } oldPrecF->update(1.0, *precF, -1.0); qrAdd(*oldPrecF); xMat[nStore-1]->update(1.0, solnPtr->getX(), -1.0, oldSolnPtr->getX(), 0.0); } } // Reorthogonalize if ( (nStore > 1) && (orthoFrequency > 0) ) if (nIter % orthoFrequency == 0) reorthogonalize(); // Copy current soln to the old soln. *oldSolnPtr = *solnPtr; *oldPrecF = *precF; // Adjust for condition number if (nStore > 0) { Teuchos::LAPACK<int,double> lapack; char normType = '1'; double invCondNum = 0.0; int info = 0; if ( WORK.size() < static_cast<std::size_t>(4*nStore) ) WORK.resize(4*nStore); if (IWORK.size() < static_cast<std::size_t>(nStore)) IWORK.resize(nStore); lapack.GECON(normType,nStore,rMat.values(),nStore,rMat.normOne(),&invCondNum,&WORK[0],&IWORK[0],&info); if (utilsPtr->isPrintType(Utils::Details)) utilsPtr->out() << " R condition number estimate ("<< nStore << ") = " << 1.0/invCondNum << std::endl; if (adjustForConditionNumber) { while ( (1.0/invCondNum > dropTolerance) && (nStore > 1) ) { Teuchos::RCP<NOX::Abstract::Vector> tempPtr = xMat[0]; for (int ii = 0; ii<nStore-1; ii++) xMat[ii] = xMat[ii+1]; xMat[nStore-1] = tempPtr; qrDelete(); lapack.GECON(normType,nStore,rMat.values(),nStore,rMat.normOne(),&invCondNum,&WORK[0],&IWORK[0],&info); if (utilsPtr->isPrintType(Utils::Details)) utilsPtr->out() << " Adjusted R condition number estimate ("<< nStore << ") = " << 1.0/invCondNum << std::endl; } } } // Solve the least-squares problem. Teuchos::SerialDenseMatrix<int,double> gamma(nStore,1), RHS(nStore,1), Rgamma(nStore,1); for (int ii = 0; ii<nStore; ii++) RHS(ii,0) = precF->innerProduct( *(qMat[ii]) ); //Back-solve for gamma for (int ii = nStore-1; ii>=0; ii--) { gamma(ii,0) = RHS(ii,0); for (int jj = ii+1; jj<nStore; jj++) { gamma(ii,0) -= rMat(ii,jj)*gamma(jj,0); } gamma(ii,0) /= rMat(ii,ii); } if (nStore > 0) Rgamma.multiply(Teuchos::NO_TRANS,Teuchos::NO_TRANS,mixParam,rMat,gamma,0.0); // Compute the step and new solution using the line search. workVec->update(mixParam,*precF); for (int ii=0; ii<nStore; ii++) workVec->update(-gamma(ii,0), *(xMat[ii]), -Rgamma(ii,0),*(qMat[ii]),1.0); bool ok = lineSearchPtr->compute(*solnPtr, stepSize, *workVec, *this); if (!ok) { if (stepSize == 0.0) { utilsPtr->out() << "NOX::Solver::AndersonAcceleratino::iterate - line search failed" << std::endl; status = NOX::StatusTest::Failed; prePostOperator.runPostIterate(*this); printUpdate(); return status; } else if (utilsPtr->isPrintType(NOX::Utils::Warning)) utilsPtr->out() << "NOX::Solver::AndersonAcceleration::iterate - using recovery step for line search" << std::endl; } // Compute F for new current solution in case the line search didn't . NOX::Abstract::Group::ReturnType rtype = solnPtr->computeF(); if (rtype != NOX::Abstract::Group::Ok) { utilsPtr->out() << "NOX::Solver::AndersonAcceleration::iterate - unable to compute F" << std::endl; status = NOX::StatusTest::Failed; prePostOperator.runPostIterate(*this); printUpdate(); return status; } // Update iteration count nIter++; // Evaluate the current status. status = testPtr->checkStatus(*this, checkType); prePostOperator.runPostIterate(*this); printUpdate(); return status; }