36 #ifndef ABSTRACTNONLINEARASSEMBLERSOLVERHYBRID_HPP_ 37 #define ABSTRACTNONLINEARASSEMBLERSOLVERHYBRID_HPP_ 39 #include "BoundaryConditionsContainer.hpp" 40 #include "AbstractNonlinearEllipticPde.hpp" 41 #include "AbstractNonlinearSolver.hpp" 43 #include "PetscMatTools.hpp" 44 #include "PetscVecTools.hpp" 45 #include "AbstractFeVolumeIntegralAssembler.hpp" 46 #include "LinearSystem.hpp" 47 #include "SimplePetscNonlinearSolver.hpp" 48 #include "NaturalNeumannSurfaceTermAssembler.hpp" 69 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM,
unsigned PROBLEM_DIM>
70 PetscErrorCode AbstractNonlinearAssemblerSolverHybrid_ComputeResidual(SNES snes,
74 #if (PETSC_VERSION_MAJOR==3 && PETSC_VERSION_MINOR>=5) 93 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM,
unsigned PROBLEM_DIM>
95 PetscErrorCode AbstractNonlinearAssemblerSolverHybrid_ComputeJacobian(SNES snes,
117 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM,
unsigned PROBLEM_DIM>
118 PetscErrorCode AbstractNonlinearAssemblerSolverHybrid_ComputeJacobian(SNES snes,
120 Mat* pGlobalJacobian,
121 Mat* pPreconditioner,
122 MatStructure* pMatStructure,
131 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM,
unsigned PROBLEM_DIM>
223 virtual Vec Solve(
Vec initialGuess,
bool useAnalyticalJacobian=
false);
250 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM,
unsigned PROBLEM_DIM>
262 assert(SPACE_DIM==ELEMENT_DIM);
263 assert(pMesh!=
nullptr);
264 assert(pBoundaryConditions!=
nullptr);
269 assert(
mpMesh->GetNumNodes() ==
mpMesh->GetDistributedVectorFactory()->GetProblemSize());
274 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM,
unsigned PROBLEM_DIM>
284 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM,
unsigned PROBLEM_DIM>
291 *(
mpMesh->GetDistributedVectorFactory()));
299 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM,
unsigned PROBLEM_DIM>
320 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM,
unsigned PROBLEM_DIM>
341 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM,
unsigned PROBLEM_DIM>
344 unsigned num_unknowns = PROBLEM_DIM * this->
mpMesh->GetNumNodes();
348 Vec perturbed_residual;
355 Vec current_guess_copy;
356 PETSCEXCEPT( VecDuplicate(currentGuess, ¤t_guess_copy) );
357 PETSCEXCEPT( VecCopy(currentGuess, current_guess_copy) );
364 double near_hsquared = 1e-9;
367 VecGetOwnershipRange(current_guess_copy, &ilo, &ihi);
372 for (
unsigned global_index_outer = 0; global_index_outer < num_unknowns; global_index_outer++)
385 PETSCEXCEPT( VecGetArray(result, &p_result) );
386 for (
unsigned global_index=lo; global_index < hi; global_index++)
388 double result_entry = p_result[ global_index - lo];
394 PETSCEXCEPT( VecRestoreArray(result, &p_result) );
407 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM,
unsigned PROBLEM_DIM>
409 bool useAnalyticalJacobian)
411 assert(initialGuess !=
nullptr);
415 VecGetSize(initialGuess, &size_of_init_guess);
416 PetscInt problem_size = PROBLEM_DIM * this->
mpMesh->GetNumNodes();
417 if (size_of_init_guess != problem_size)
419 EXCEPTION(
"Size of initial guess vector, " << size_of_init_guess
420 <<
", does not match size of problem, " << problem_size);
424 return mpSolver->
Solve(&AbstractNonlinearAssemblerSolverHybrid_ComputeResidual<ELEMENT_DIM, SPACE_DIM, PROBLEM_DIM>,
425 &AbstractNonlinearAssemblerSolverHybrid_ComputeJacobian<ELEMENT_DIM, SPACE_DIM, PROBLEM_DIM>,
427 PROBLEM_DIM * this->
mpMesh->CalculateMaximumNodeConnectivityPerProcess(),
431 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM,
unsigned PROBLEM_DIM>
442 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM,
unsigned PROBLEM_DIM>
445 unsigned size = PROBLEM_DIM * this->
mpMesh->GetNumNodes();
449 Mat analytic_jacobian;
450 Mat numerical_jacobian;
471 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM,
unsigned PROBLEM_DIM>
472 PetscErrorCode AbstractNonlinearAssemblerSolverHybrid_ComputeResidual(SNES snes,
486 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM,
unsigned PROBLEM_DIM>
487 #if (PETSC_VERSION_MAJOR==3 && PETSC_VERSION_MINOR>=5) 488 PetscErrorCode AbstractNonlinearAssemblerSolverHybrid_ComputeJacobian(SNES snes,
503 PetscErrorCode AbstractNonlinearAssemblerSolverHybrid_ComputeJacobian(SNES snes,
505 Mat* pGlobalJacobian,
506 Mat* pPreconditioner,
507 MatStructure* pMatStructure,
void ComputeJacobian(const Vec currentGuess, Mat *pJacobian)
AbstractNonlinearSolver * mpSolver
AbstractNonlinearAssemblerSolverHybrid(AbstractTetrahedralMesh< ELEMENT_DIM, SPACE_DIM > *pMesh, BoundaryConditionsContainer< ELEMENT_DIM, SPACE_DIM, PROBLEM_DIM > *pBoundaryConditions)
NaturalNeumannSurfaceTermAssembler< ELEMENT_DIM, SPACE_DIM, PROBLEM_DIM > * mpNeumannSurfaceTermsAssembler
virtual ~AbstractNonlinearAssemblerSolverHybrid()
virtual Vec Solve(Vec initialGuess, bool useAnalyticalJacobian=false)
#define EXCEPTION(message)
bool mUseAnalyticalJacobian
void SetCurrentSolution(Vec currentSolution)
AbstractTetrahedralMesh< ELEMENT_DIM, SPACE_DIM > * mpMesh
static bool IsNearZero(double number, double tolerance)
BoundaryConditionsContainer< ELEMENT_DIM, SPACE_DIM, PROBLEM_DIM > * mpBoundaryConditions
bool VerifyJacobian(double tol)
void ComputeJacobianNumerically(const Vec currentGuess, Mat *pJacobian)
void SetNonlinearSolver(AbstractNonlinearSolver *pNonlinearSolver)
void ComputeResidual(const Vec currentGuess, Vec residualVector)
bool mWeAllocatedSolverMemory
void SetMatrixToAssemble(Mat &rMatToAssemble, bool zeroMatrixBeforeAssembly=true)
void ApplyDirichletConditions(Vec currentGuess, Vec residual, Mat *pMat)
void SetVectorToAssemble(Vec &rVecToAssemble, bool zeroVectorBeforeAssembly)
virtual Vec Solve(PetscErrorCode(*pComputeResidual)(SNES, Vec, Vec, void *), PetscErrorCode(*pComputeJacobian)(SNES, Vec, Mat *, Mat *, MatStructure *, void *), Vec initialGuess, unsigned fill, void *pContext)=0