Improved convergence checking when using newton solver (does not oversolve the problem like before)
This commit is contained in:
parent
eb0d2b7e24
commit
57cf472982
|
@ -78,7 +78,7 @@ module DAMASK_spectral_SolverBasicPETSc
|
||||||
C_volAvgLastInc = 0.0_pReal, & !< previous volume average stiffness
|
C_volAvgLastInc = 0.0_pReal, & !< previous volume average stiffness
|
||||||
C_minMaxAvg = 0.0_pReal, & !< current (min+max)/2 stiffness
|
C_minMaxAvg = 0.0_pReal, & !< current (min+max)/2 stiffness
|
||||||
S = 0.0_pReal !< current compliance (filled up with zeros)
|
S = 0.0_pReal !< current compliance (filled up with zeros)
|
||||||
real(pReal), private :: err_stress, err_div
|
real(pReal), private :: err_stress, err_div, err_divPrev, err_divDummy
|
||||||
logical, private :: ForwardData
|
logical, private :: ForwardData
|
||||||
integer(pInt), private :: &
|
integer(pInt), private :: &
|
||||||
totalIter = 0_pInt !< total iteration in current increment
|
totalIter = 0_pInt !< total iteration in current increment
|
||||||
|
@ -152,6 +152,7 @@ subroutine basicPETSc_init(temperature)
|
||||||
temp33_Real = 0.0_pReal
|
temp33_Real = 0.0_pReal
|
||||||
real(pReal), dimension(3,3,3,3) :: &
|
real(pReal), dimension(3,3,3,3) :: &
|
||||||
temp3333_Real = 0.0_pReal
|
temp3333_Real = 0.0_pReal
|
||||||
|
KSP :: ksp
|
||||||
|
|
||||||
call Utilities_init()
|
call Utilities_init()
|
||||||
write(6,'(/,a)') ' <<<+- DAMASK_spectral_solverBasicPETSc init -+>>>'
|
write(6,'(/,a)') ' <<<+- DAMASK_spectral_solverBasicPETSc init -+>>>'
|
||||||
|
@ -180,6 +181,8 @@ subroutine basicPETSc_init(temperature)
|
||||||
call SNESSetDM(snes,da,ierr); CHKERRQ(ierr)
|
call SNESSetDM(snes,da,ierr); CHKERRQ(ierr)
|
||||||
call SNESSetConvergenceTest(snes,BasicPETSC_converged,dummy,PETSC_NULL_FUNCTION,ierr)
|
call SNESSetConvergenceTest(snes,BasicPETSC_converged,dummy,PETSC_NULL_FUNCTION,ierr)
|
||||||
CHKERRQ(ierr)
|
CHKERRQ(ierr)
|
||||||
|
call SNESGetKSP(snes,ksp,ierr); CHKERRQ(ierr)
|
||||||
|
call KSPSetConvergenceTest(ksp,BasicPETSC_convergedKSP,dummy,PETSC_NULL_FUNCTION,ierr); CHKERRQ(ierr)
|
||||||
call SNESSetFromOptions(snes,ierr); CHKERRQ(ierr)
|
call SNESSetFromOptions(snes,ierr); CHKERRQ(ierr)
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
@ -482,7 +485,7 @@ if (params%density > 0.0_pReal) then
|
||||||
order=[4,5,1,2,3]) ! field real has a different order
|
order=[4,5,1,2,3]) ! field real has a different order
|
||||||
call Utilities_FFTforward()
|
call Utilities_FFTforward()
|
||||||
field_fourier = field_fourier + inertiaField_fourier
|
field_fourier = field_fourier + inertiaField_fourier
|
||||||
err_div = Utilities_divergenceRMS()
|
err_divDummy = Utilities_divergenceRMS()
|
||||||
call Utilities_fourierConvolution(math_rotate_backward33(F_aim_lastIter-F_aim,params%rotation_BC))
|
call Utilities_fourierConvolution(math_rotate_backward33(F_aim_lastIter-F_aim,params%rotation_BC))
|
||||||
call Utilities_FFTbackward()
|
call Utilities_FFTbackward()
|
||||||
|
|
||||||
|
@ -504,10 +507,6 @@ subroutine BasicPETSc_converged(snes_local,PETScIter,xnorm,snorm,fnorm,reason,du
|
||||||
err_div_tolAbs, &
|
err_div_tolAbs, &
|
||||||
err_stress_tolRel, &
|
err_stress_tolRel, &
|
||||||
err_stress_tolAbs
|
err_stress_tolAbs
|
||||||
use math, only: &
|
|
||||||
math_mul33x33, &
|
|
||||||
math_eigenvalues33, &
|
|
||||||
math_transpose33
|
|
||||||
use FEsolving, only: &
|
use FEsolving, only: &
|
||||||
terminallyIll
|
terminallyIll
|
||||||
|
|
||||||
|
@ -527,8 +526,9 @@ subroutine BasicPETSc_converged(snes_local,PETScIter,xnorm,snorm,fnorm,reason,du
|
||||||
|
|
||||||
divTol = max(maxval(abs(P_av))*err_div_tolRel,err_div_tolAbs)
|
divTol = max(maxval(abs(P_av))*err_div_tolRel,err_div_tolAbs)
|
||||||
stressTol = max(maxval(abs(P_av))*err_stress_tolrel,err_stress_tolabs)
|
stressTol = max(maxval(abs(P_av))*err_stress_tolrel,err_stress_tolabs)
|
||||||
|
err_divPrev = err_div; err_div = err_divDummy
|
||||||
|
|
||||||
converged: if ((totalIter>= itmin .and. &
|
converged: if ((totalIter >= itmin .and. &
|
||||||
all([ err_div/divTol, &
|
all([ err_div/divTol, &
|
||||||
err_stress/stressTol ] < 1.0_pReal)) &
|
err_stress/stressTol ] < 1.0_pReal)) &
|
||||||
.or. terminallyIll) then
|
.or. terminallyIll) then
|
||||||
|
@ -552,6 +552,60 @@ subroutine BasicPETSc_converged(snes_local,PETScIter,xnorm,snorm,fnorm,reason,du
|
||||||
end subroutine BasicPETSc_converged
|
end subroutine BasicPETSc_converged
|
||||||
|
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief convergence check
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
subroutine BasicPETSc_convergedKSP(ksp_local,PETScIter,fnorm,reason,dummy,ierr)
|
||||||
|
use numerics, only: &
|
||||||
|
itmax, &
|
||||||
|
itmin, &
|
||||||
|
err_div_tolRel, &
|
||||||
|
err_div_tolAbs
|
||||||
|
use FEsolving, only: &
|
||||||
|
terminallyIll
|
||||||
|
use DAMASK_spectral_Utilities, only: &
|
||||||
|
wgt
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
KSP :: ksp_local
|
||||||
|
PetscInt :: PETScIter, SNESIter
|
||||||
|
PetscReal :: &
|
||||||
|
fnorm, &
|
||||||
|
SNESfnorm, &
|
||||||
|
estimatedErrDiv
|
||||||
|
KSPConvergedReason :: reason
|
||||||
|
PetscObject :: dummy
|
||||||
|
PetscErrorCode :: ierr
|
||||||
|
real(pReal) :: &
|
||||||
|
divTol, &
|
||||||
|
r_tol
|
||||||
|
|
||||||
|
call SNESGetIterationNumber(snes,SNESIter,ierr); CHKERRQ(ierr)
|
||||||
|
call SNESGetFunctionNorm(snes,SNESfnorm,ierr); CHKERRQ(ierr)
|
||||||
|
|
||||||
|
if (SNESIter == 0_pInt) then ! Eisenstat-Walker calculation of relative tolerance for inexact newton
|
||||||
|
r_tol = 0.3
|
||||||
|
else
|
||||||
|
r_tol = (err_div/err_divPrev)**1.618
|
||||||
|
endif
|
||||||
|
|
||||||
|
divTol = max(maxval(abs(P_av))*err_div_tolRel,err_div_tolAbs)
|
||||||
|
estimatedErrDiv = fnorm*err_div/SNESfnorm ! Estimated error divergence
|
||||||
|
|
||||||
|
converged: if ((PETScIter >= itmin .and. &
|
||||||
|
any([fnorm/snesFnorm/r_tol, &
|
||||||
|
estimatedErrDiv/divTol] < 1.0_pReal)) &
|
||||||
|
.or. terminallyIll) then
|
||||||
|
reason = 1
|
||||||
|
elseif (totalIter >= itmax) then converged
|
||||||
|
reason = -1
|
||||||
|
else converged
|
||||||
|
reason = 0
|
||||||
|
endif converged
|
||||||
|
|
||||||
|
end subroutine BasicPETSc_convergedKSP
|
||||||
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @brief destroy routine
|
!> @brief destroy routine
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
|
Loading…
Reference in New Issue