std::pair<Real, Real> SlepcEigenSolver<T>::get_eigenpair(unsigned int i, NumericVector<T> &solution_in) { int ierr=0; PetscReal re, im; // Make sure the NumericVector passed in is really a PetscVector PetscVector<T>* solution = libmesh_cast_ptr<PetscVector<T>*>(&solution_in); // real and imaginary part of the ith eigenvalue. PetscScalar kr, ki; solution->close(); ierr = EPSGetEigenpair(_eps, i, &kr, &ki, solution->vec(), PETSC_NULL); LIBMESH_CHKERRABORT(ierr); #ifdef LIBMESH_USE_COMPLEX_NUMBERS re = PetscRealPart(kr); im = PetscImaginaryPart(kr); #else re = kr; im = ki; #endif return std::make_pair(re, im); }
std::pair<unsigned int, Real> PetscDMNonlinearSolver<T>::solve (SparseMatrix<T>& jac_in, // System Jacobian Matrix NumericVector<T>& x_in, // Solution vector NumericVector<T>& r_in, // Residual vector const double, // Stopping tolerance const unsigned int) { START_LOG("solve()", "PetscNonlinearSolver"); this->init (); // Make sure the data passed in are really of Petsc types libmesh_cast_ptr<PetscMatrix<T>*>(&jac_in); libmesh_cast_ptr<PetscVector<T>*>(&r_in); // Extract solution vector PetscVector<T>* x = libmesh_cast_ptr<PetscVector<T>*>(&x_in); int ierr=0; int n_iterations =0; // Should actually be a PetscReal, but I don't know which version of PETSc first introduced PetscReal Real final_residual_norm=0.; if (this->user_presolve) this->user_presolve(this->system()); //Set the preconditioning matrix if (this->_preconditioner) this->_preconditioner->set_matrix(jac_in); ierr = SNESSolve (this->_snes, PETSC_NULL, x->vec()); CHKERRABORT(libMesh::COMM_WORLD,ierr); ierr = SNESGetIterationNumber(this->_snes,&n_iterations); CHKERRABORT(libMesh::COMM_WORLD,ierr); ierr = SNESGetLinearSolveIterations(this->_snes, &this->_n_linear_iterations); CHKERRABORT(libMesh::COMM_WORLD,ierr); ierr = SNESGetFunctionNorm(this->_snes,&final_residual_norm); CHKERRABORT(libMesh::COMM_WORLD,ierr); // Get and store the reason for convergence SNESGetConvergedReason(this->_snes, &this->_reason); //Based on Petsc 2.3.3 documentation all diverged reasons are negative this->converged = (this->_reason >= 0); this->clear(); STOP_LOG("solve()", "PetscNonlinearSolver"); // return the # of its. and the final residual norm. return std::make_pair(n_iterations, final_residual_norm); }
virtual void setupInternal(NumericVector<Number> &X) { PetscVector<Number> *pX = cast_ptr<PetscVector<Number> *>(&X); PetscErrorCode ierr; ierr = TSSetIFunction(this->_ts,PETSC_NULL,this->_computeIFunction,this); CHKERRABORT(libMesh::COMM_WORLD,ierr); PetscMatrix<Number> *mat = cast_ptr<PetscMatrix<Number> *>(this->_fe_problem.getNonlinearSystem().sys().matrix); Mat pmat = mat->mat(); ierr = TSSetIJacobian(this->_ts,pmat,pmat,this->_computeIJacobian,this); CHKERRABORT(libMesh::COMM_WORLD,ierr); ierr = TSSetFromOptions(this->_ts); CHKERRABORT(libMesh::COMM_WORLD,ierr); ierr = TSSetSolution(_ts,pX->vec()); CHKERRABORT(libMesh::COMM_WORLD,ierr); }
std::pair<unsigned int, Real> PetscNonlinearSolver<T>::solve (SparseMatrix<T>& jac_in, // System Jacobian Matrix NumericVector<T>& x_in, // Solution vector NumericVector<T>& r_in, // Residual vector const double, // Stopping tolerance const unsigned int) { START_LOG("solve()", "PetscNonlinearSolver"); this->init (); // Make sure the data passed in are really of Petsc types PetscMatrix<T>* jac = libmesh_cast_ptr<PetscMatrix<T>*>(&jac_in); PetscVector<T>* x = libmesh_cast_ptr<PetscVector<T>*>(&x_in); PetscVector<T>* r = libmesh_cast_ptr<PetscVector<T>*>(&r_in); PetscErrorCode ierr=0; PetscInt n_iterations =0; // Should actually be a PetscReal, but I don't know which version of PETSc first introduced PetscReal Real final_residual_norm=0.; ierr = SNESSetFunction (_snes, r->vec(), __libmesh_petsc_snes_residual, this); LIBMESH_CHKERRABORT(ierr); // Only set the jacobian function if we've been provided with something to call. // This allows a user to set their own jacobian function if they want to if (this->jacobian || this->jacobian_object || this->residual_and_jacobian_object) { ierr = SNESSetJacobian (_snes, jac->mat(), jac->mat(), __libmesh_petsc_snes_jacobian, this); LIBMESH_CHKERRABORT(ierr); } #if !PETSC_VERSION_LESS_THAN(3,3,0) // Only set the nullspace if we have a way of computing it and the result is non-empty. if (this->nullspace || this->nullspace_object) { MatNullSpace msp; this->build_mat_null_space(this->nullspace_object, this->nullspace, &msp); if (msp) { ierr = MatSetNullSpace(jac->mat(), msp); LIBMESH_CHKERRABORT(ierr); ierr = MatNullSpaceDestroy(&msp); LIBMESH_CHKERRABORT(ierr); } } // Only set the nearnullspace if we have a way of computing it and the result is non-empty. if (this->nearnullspace || this->nearnullspace_object) { MatNullSpace msp = PETSC_NULL; this->build_mat_null_space(this->nearnullspace_object, this->nearnullspace, &msp); if(msp) { ierr = MatSetNearNullSpace(jac->mat(), msp); LIBMESH_CHKERRABORT(ierr); ierr = MatNullSpaceDestroy(&msp); LIBMESH_CHKERRABORT(ierr); } } #endif // Have the Krylov subspace method use our good initial guess rather than 0 KSP ksp; ierr = SNESGetKSP (_snes, &ksp); LIBMESH_CHKERRABORT(ierr); // Set the tolerances for the iterative solver. Use the user-supplied // tolerance for the relative residual & leave the others at default values ierr = KSPSetTolerances (ksp, this->initial_linear_tolerance, PETSC_DEFAULT, PETSC_DEFAULT, this->max_linear_iterations); LIBMESH_CHKERRABORT(ierr); // Set the tolerances for the non-linear solver. ierr = SNESSetTolerances(_snes, this->absolute_residual_tolerance, this->relative_residual_tolerance, this->relative_step_tolerance, this->max_nonlinear_iterations, this->max_function_evaluations); LIBMESH_CHKERRABORT(ierr); //Pull in command-line options KSPSetFromOptions(ksp); SNESSetFromOptions(_snes); if (this->user_presolve) this->user_presolve(this->system()); //Set the preconditioning matrix if(this->_preconditioner) { this->_preconditioner->set_matrix(jac_in); this->_preconditioner->init(); } // ierr = KSPSetInitialGuessNonzero (ksp, PETSC_TRUE); // LIBMESH_CHKERRABORT(ierr); // Older versions (at least up to 2.1.5) of SNESSolve took 3 arguments, // the last one being a pointer to an int to hold the number of iterations required. # if PETSC_VERSION_LESS_THAN(2,2,0) ierr = SNESSolve (_snes, x->vec(), &n_iterations); LIBMESH_CHKERRABORT(ierr); // 2.2.x style #elif PETSC_VERSION_LESS_THAN(2,3,0) ierr = SNESSolve (_snes, x->vec()); LIBMESH_CHKERRABORT(ierr); // 2.3.x & newer style #else ierr = SNESSolve (_snes, PETSC_NULL, x->vec()); LIBMESH_CHKERRABORT(ierr); ierr = SNESGetIterationNumber(_snes,&n_iterations); LIBMESH_CHKERRABORT(ierr); ierr = SNESGetLinearSolveIterations(_snes, &_n_linear_iterations); LIBMESH_CHKERRABORT(ierr); ierr = SNESGetFunctionNorm(_snes,&final_residual_norm); LIBMESH_CHKERRABORT(ierr); #endif // Get and store the reason for convergence SNESGetConvergedReason(_snes, &_reason); //Based on Petsc 2.3.3 documentation all diverged reasons are negative this->converged = (_reason >= 0); this->clear(); STOP_LOG("solve()", "PetscNonlinearSolver"); // return the # of its. and the final residual norm. return std::make_pair(n_iterations, final_residual_norm); }
void PetscNonlinearSolver<T>::build_mat_null_space(NonlinearImplicitSystem::ComputeVectorSubspace* computeSubspaceObject, void (*computeSubspace)(std::vector<NumericVector<Number>*>&, sys_type&), MatNullSpace *msp) { PetscErrorCode ierr; std::vector<NumericVector<Number>* > sp; if (computeSubspaceObject) (*computeSubspaceObject)(sp, this->system()); else (*computeSubspace)(sp, this->system()); *msp = PETSC_NULL; if (sp.size()) { Vec *modes; PetscScalar *dots; PetscInt nmodes = sp.size(); ierr = PetscMalloc2(nmodes,Vec,&modes,nmodes,PetscScalar,&dots); LIBMESH_CHKERRABORT(ierr); for (PetscInt i=0; i<nmodes; ++i) { PetscVector<T>* pv = libmesh_cast_ptr<PetscVector<T>*>(sp[i]); Vec v = pv->vec(); ierr = VecDuplicate(v, modes+i); LIBMESH_CHKERRABORT(ierr); ierr = VecCopy(v,modes[i]); LIBMESH_CHKERRABORT(ierr); } // Normalize. ierr = VecNormalize(modes[0],PETSC_NULL); LIBMESH_CHKERRABORT(ierr); for (PetscInt i=1; i<nmodes; i++) { // Orthonormalize vec[i] against vec[0:i-1] ierr = VecMDot(modes[i],i,modes,dots); LIBMESH_CHKERRABORT(ierr); for (PetscInt j=0; j<i; j++) dots[j] *= -1.; ierr = VecMAXPY(modes[i],i,dots,modes); LIBMESH_CHKERRABORT(ierr); ierr = VecNormalize(modes[i],PETSC_NULL); LIBMESH_CHKERRABORT(ierr); } ierr = MatNullSpaceCreate(this->comm().get(), PETSC_FALSE, nmodes, modes, msp); LIBMESH_CHKERRABORT(ierr); for (PetscInt i=0; i<nmodes; ++i) { ierr = VecDestroy(modes+i); LIBMESH_CHKERRABORT(ierr); } ierr = PetscFree2(modes,dots); LIBMESH_CHKERRABORT(ierr); } }
virtual void interpolate(Real time,NumericVector<Number> &X) { PetscVector<Number> *pX = cast_ptr<PetscVector<Number> *>(&X); PetscErrorCode ierr; ierr = TSInterpolate(this->_ts,time,pX->vec()); CHKERRABORT(libMesh::COMM_WORLD,ierr); }
std::pair<unsigned int, Real> PetscDMNonlinearSolver<T>::solve (SparseMatrix<T>& jac_in, // System Jacobian Matrix NumericVector<T>& x_in, // Solution vector NumericVector<T>& r_in, // Residual vector const double, // Stopping tolerance const unsigned int) { START_LOG("solve()", "PetscNonlinearSolver"); this->init (); // Make sure the data passed in are really of Petsc types libmesh_cast_ptr<PetscMatrix<T>*>(&jac_in); libmesh_cast_ptr<PetscVector<T>*>(&r_in); // Extract solution vector PetscVector<T>* x = libmesh_cast_ptr<PetscVector<T>*>(&x_in); PetscErrorCode ierr=0; PetscInt n_iterations =0; PetscReal final_residual_norm=0.; if (this->user_presolve) this->user_presolve(this->system()); //Set the preconditioning matrix if (this->_preconditioner) this->_preconditioner->set_matrix(jac_in); ierr = SNESSolve (this->_snes, PETSC_NULL, x->vec()); LIBMESH_CHKERRABORT(ierr); ierr = SNESGetIterationNumber(this->_snes,&n_iterations); LIBMESH_CHKERRABORT(ierr); ierr = SNESGetLinearSolveIterations(this->_snes, &this->_n_linear_iterations); LIBMESH_CHKERRABORT(ierr); #if PETSC_VERSION_LESS_THAN(3,5,0) // SNESGetFunctionNorm was removed in PETSc 3.5.0 ierr = SNESGetFunctionNorm(this->_snes,&final_residual_norm); LIBMESH_CHKERRABORT(ierr); #else { /* PB: Not sure where r_in is coming from and it's not used here, so we'll just get the residual from PETSc */ Vec r; ierr = SNESGetFunction(this->_snes,&r,NULL,NULL);LIBMESH_CHKERRABORT(ierr); ierr = VecNorm(r,NORM_2,&final_residual_norm);LIBMESH_CHKERRABORT(ierr); } #endif // Get and store the reason for convergence SNESGetConvergedReason(this->_snes, &this->_reason); //Based on Petsc 2.3.3 documentation all diverged reasons are negative this->converged = (this->_reason >= 0); this->clear(); STOP_LOG("solve()", "PetscNonlinearSolver"); // return the # of its. and the final residual norm. return std::make_pair(n_iterations, final_residual_norm); }