2018-08-17 03:44:25 +05:30
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
!> @author Pratheek Shanthraj, Max-Planck-Institut für Eisenforschung GmbH
|
|
|
|
!> @brief Utilities used by the FEM solver
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
module FEM_utilities
|
2018-08-30 16:08:44 +05:30
|
|
|
#include <petsc/finclude/petscdmplex.h>
|
2018-09-21 11:49:36 +05:30
|
|
|
#include <petsc/finclude/petscdmda.h>
|
|
|
|
#include <petsc/finclude/petscis.h>
|
2018-08-17 14:53:24 +05:30
|
|
|
|
2019-06-11 13:18:07 +05:30
|
|
|
use PETScdmplex
|
|
|
|
use PETScdmda
|
|
|
|
use PETScis
|
|
|
|
|
|
|
|
use prec
|
|
|
|
use FEsolving
|
|
|
|
use homogenization
|
2020-08-15 19:32:10 +05:30
|
|
|
use config
|
2019-06-11 13:18:07 +05:30
|
|
|
use math
|
2020-03-20 19:38:07 +05:30
|
|
|
use discretization_mesh
|
2019-06-11 13:18:07 +05:30
|
|
|
|
|
|
|
implicit none
|
|
|
|
private
|
2018-08-17 03:44:25 +05:30
|
|
|
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
2020-01-21 10:40:19 +05:30
|
|
|
logical, public :: cutBack = .false. !< cut back of BVP solver in case convergence is not achieved or a material point is terminally ill
|
2019-06-11 13:18:07 +05:30
|
|
|
integer, public, parameter :: maxFields = 6
|
|
|
|
integer, public :: nActiveFields = 0
|
2018-08-17 03:44:25 +05:30
|
|
|
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
! grid related information information
|
2019-06-11 13:18:07 +05:30
|
|
|
real(pReal), public :: wgt !< weighting factor 1/Nelems
|
2018-09-19 22:03:37 +05:30
|
|
|
|
2019-05-12 13:35:40 +05:30
|
|
|
|
2018-08-17 03:44:25 +05:30
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
! field labels information
|
2019-06-11 13:18:07 +05:30
|
|
|
character(len=*), parameter, public :: &
|
|
|
|
FIELD_MECH_label = 'mechanical'
|
|
|
|
|
2020-03-17 12:47:14 +05:30
|
|
|
enum, bind(c); enumerator :: &
|
|
|
|
FIELD_UNDEFINED_ID, &
|
|
|
|
FIELD_MECH_ID
|
2019-06-11 13:18:07 +05:30
|
|
|
end enum
|
2020-03-17 12:47:14 +05:30
|
|
|
enum, bind(c); enumerator :: &
|
|
|
|
COMPONENT_UNDEFINED_ID, &
|
|
|
|
COMPONENT_MECH_X_ID, &
|
|
|
|
COMPONENT_MECH_Y_ID, &
|
|
|
|
COMPONENT_MECH_Z_ID
|
2019-06-11 13:18:07 +05:30
|
|
|
end enum
|
2018-08-17 03:44:25 +05:30
|
|
|
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
! variables controlling debugging
|
2019-06-11 13:18:07 +05:30
|
|
|
logical :: &
|
2018-08-17 03:44:25 +05:30
|
|
|
debugPETSc !< use some in debug defined options for more verbose PETSc solution
|
|
|
|
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
! derived types
|
2019-06-11 13:18:07 +05:30
|
|
|
type, public :: tSolutionState !< return type of solution from FEM solver variants
|
2020-01-21 10:40:19 +05:30
|
|
|
logical :: converged = .true.
|
|
|
|
logical :: stagConverged = .true.
|
|
|
|
integer :: iterationsNeeded = 0
|
2019-06-11 13:18:07 +05:30
|
|
|
end type tSolutionState
|
|
|
|
|
|
|
|
type, public :: tComponentBC
|
|
|
|
integer(kind(COMPONENT_UNDEFINED_ID)) :: ID
|
2020-01-21 10:40:19 +05:30
|
|
|
real(pReal), allocatable, dimension(:) :: Value
|
|
|
|
logical, allocatable, dimension(:) :: Mask
|
2019-06-11 13:18:07 +05:30
|
|
|
end type tComponentBC
|
2018-08-17 03:44:25 +05:30
|
|
|
|
2019-06-11 13:18:07 +05:30
|
|
|
type, public :: tFieldBC
|
|
|
|
integer(kind(FIELD_UNDEFINED_ID)) :: ID
|
|
|
|
integer :: nComponents = 0
|
|
|
|
type(tComponentBC), allocatable :: componentBC(:)
|
|
|
|
end type tFieldBC
|
|
|
|
|
|
|
|
type, public :: tLoadCase
|
|
|
|
real(pReal) :: time = 0.0_pReal !< length of increment
|
|
|
|
integer :: incs = 0, & !< number of increments
|
|
|
|
outputfrequency = 1, & !< frequency of result writes
|
|
|
|
logscale = 0 !< linear/logarithmic time inc flag
|
|
|
|
logical :: followFormerTrajectory = .true. !< follow trajectory of former loadcase
|
2020-01-21 10:40:19 +05:30
|
|
|
integer, allocatable, dimension(:) :: faceID
|
|
|
|
type(tFieldBC), allocatable, dimension(:) :: fieldBC
|
2019-06-11 13:18:07 +05:30
|
|
|
end type tLoadCase
|
|
|
|
|
|
|
|
public :: &
|
2020-06-17 21:32:22 +05:30
|
|
|
FEM_utilities_init, &
|
2019-06-11 13:18:07 +05:30
|
|
|
utilities_constitutiveResponse, &
|
|
|
|
utilities_projectBCValues, &
|
|
|
|
FIELD_MECH_ID, &
|
2020-01-21 12:16:32 +05:30
|
|
|
COMPONENT_UNDEFINED_ID, &
|
2019-06-11 13:18:07 +05:30
|
|
|
COMPONENT_MECH_X_ID, &
|
|
|
|
COMPONENT_MECH_Y_ID, &
|
|
|
|
COMPONENT_MECH_Z_ID
|
2018-08-17 03:44:25 +05:30
|
|
|
|
|
|
|
contains
|
|
|
|
|
2020-06-29 18:39:13 +05:30
|
|
|
!ToDo: use functions in variable call
|
2018-08-17 03:44:25 +05:30
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
!> @brief allocates all neccessary fields, sets debug flags
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
2020-06-17 21:32:22 +05:30
|
|
|
subroutine FEM_utilities_init
|
2019-05-12 16:41:30 +05:30
|
|
|
|
2020-01-26 16:54:35 +05:30
|
|
|
character(len=pStringLen) :: petsc_optionsOrder
|
2020-06-16 22:45:01 +05:30
|
|
|
class(tNode), pointer :: &
|
2020-06-18 02:30:03 +05:30
|
|
|
num_mesh, &
|
2020-06-26 23:42:05 +05:30
|
|
|
debug_mesh ! pointer to mesh debug options
|
2020-06-17 20:49:21 +05:30
|
|
|
integer :: structOrder !< order of displacement shape functions
|
2020-07-03 20:15:11 +05:30
|
|
|
character(len=*), parameter :: &
|
2020-06-18 21:44:53 +05:30
|
|
|
PETSCDEBUG = ' -snes_view -snes_monitor '
|
2020-06-28 01:18:26 +05:30
|
|
|
|
2020-01-26 16:54:35 +05:30
|
|
|
PetscErrorCode :: ierr
|
2018-08-17 03:44:25 +05:30
|
|
|
|
2020-09-19 11:50:29 +05:30
|
|
|
print'(/,a)', ' <<<+- FEM_utilities init -+>>>'
|
2018-08-17 03:44:25 +05:30
|
|
|
|
2020-09-13 14:47:49 +05:30
|
|
|
num_mesh => config_numerics%get('mesh',defaultVal=emptyDict)
|
|
|
|
structOrder = num_mesh%get_asInt('structOrder', defaultVal = 2)
|
2020-06-16 22:45:01 +05:30
|
|
|
|
2020-09-13 14:47:49 +05:30
|
|
|
debug_mesh => config_debug%get('mesh',defaultVal=emptyList)
|
|
|
|
debugPETSc = debug_mesh%contains('petsc')
|
2020-07-03 20:15:11 +05:30
|
|
|
|
2020-09-19 11:50:29 +05:30
|
|
|
if(debugPETSc) print'(3(/,a),/)', &
|
2019-06-11 13:18:07 +05:30
|
|
|
' Initializing PETSc with debug options: ', &
|
|
|
|
trim(PETScDebug), &
|
2020-06-29 20:35:11 +05:30
|
|
|
' add more using the PETSc_Options keyword in numerics.yaml '
|
2020-09-22 16:39:12 +05:30
|
|
|
flush(IO_STDOUT)
|
2019-06-11 13:18:07 +05:30
|
|
|
call PetscOptionsClear(PETSC_NULL_OPTIONS,ierr)
|
|
|
|
CHKERRQ(ierr)
|
|
|
|
if(debugPETSc) call PetscOptionsInsertString(PETSC_NULL_OPTIONS,trim(PETSCDEBUG),ierr)
|
|
|
|
CHKERRQ(ierr)
|
2020-03-17 04:40:23 +05:30
|
|
|
call PetscOptionsInsertString(PETSC_NULL_OPTIONS,'-mech_snes_type newtonls &
|
|
|
|
&-mech_snes_linesearch_type cp -mech_snes_ksp_ew &
|
|
|
|
&-mech_snes_ksp_ew_rtol0 0.01 -mech_snes_ksp_ew_rtolmax 0.01 &
|
|
|
|
&-mech_ksp_type fgmres -mech_ksp_max_it 25 &
|
|
|
|
&-mech_pc_type ml -mech_mg_levels_ksp_type chebyshev &
|
|
|
|
&-mech_mg_levels_pc_type sor -mech_pc_ml_nullspace user',ierr)
|
|
|
|
CHKERRQ(ierr)
|
2020-06-29 20:35:11 +05:30
|
|
|
call PetscOptionsInsertString(PETSC_NULL_OPTIONS,num_mesh%get_asString('petsc_options',defaultVal=''),ierr)
|
2019-06-11 13:18:07 +05:30
|
|
|
CHKERRQ(ierr)
|
2020-01-26 16:54:35 +05:30
|
|
|
write(petsc_optionsOrder,'(a,i0)') '-mechFE_petscspace_degree ', structOrder
|
|
|
|
call PetscOptionsInsertString(PETSC_NULL_OPTIONS,trim(petsc_optionsOrder),ierr)
|
2019-06-11 13:18:07 +05:30
|
|
|
CHKERRQ(ierr)
|
|
|
|
|
|
|
|
wgt = 1.0/real(mesh_maxNips*mesh_NcpElemsGlobal,pReal)
|
2018-08-17 03:44:25 +05:30
|
|
|
|
|
|
|
|
2020-06-17 21:32:22 +05:30
|
|
|
end subroutine FEM_utilities_init
|
2018-08-17 03:44:25 +05:30
|
|
|
|
2020-03-17 04:40:23 +05:30
|
|
|
|
2018-08-17 03:44:25 +05:30
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
!> @brief calculates constitutive response
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
subroutine utilities_constitutiveResponse(timeinc,P_av,forwardData)
|
|
|
|
|
2019-06-11 13:18:07 +05:30
|
|
|
real(pReal), intent(in) :: timeinc !< loading time
|
|
|
|
logical, intent(in) :: forwardData !< age results
|
|
|
|
|
|
|
|
real(pReal),intent(out), dimension(3,3) :: P_av !< average PK stress
|
|
|
|
|
|
|
|
PetscErrorCode :: ierr
|
2018-08-17 03:44:25 +05:30
|
|
|
|
2020-09-19 11:50:29 +05:30
|
|
|
print'(/,a)', ' ... evaluating constitutive response ......................................'
|
2018-08-17 03:44:25 +05:30
|
|
|
|
2020-09-30 13:54:24 +05:30
|
|
|
call materialpoint_stressAndItsTangent(timeinc) ! calculate P field
|
2018-08-17 14:53:24 +05:30
|
|
|
|
2019-06-11 13:18:07 +05:30
|
|
|
cutBack = .false. ! reset cutBack status
|
|
|
|
|
2020-10-24 20:56:42 +05:30
|
|
|
P_av = sum(sum(homogenization_P,dim=4),dim=3) * wgt ! average of P
|
2019-06-11 13:18:07 +05:30
|
|
|
call MPI_Allreduce(MPI_IN_PLACE,P_av,9,MPI_DOUBLE,MPI_SUM,PETSC_COMM_WORLD,ierr)
|
2018-08-17 03:44:25 +05:30
|
|
|
|
|
|
|
end subroutine utilities_constitutiveResponse
|
|
|
|
|
2019-03-09 03:53:07 +05:30
|
|
|
|
2018-08-17 03:44:25 +05:30
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
!> @brief Project BC values to local vector
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
subroutine utilities_projectBCValues(localVec,section,field,comp,bcPointsIS,BCValue,BCDotValue,timeinc)
|
|
|
|
|
2019-06-11 13:18:07 +05:30
|
|
|
Vec :: localVec
|
|
|
|
PetscInt :: field, comp, nBcPoints, point, dof, numDof, numComp, offset
|
|
|
|
PetscSection :: section
|
|
|
|
IS :: bcPointsIS
|
|
|
|
PetscInt, pointer :: bcPoints(:)
|
|
|
|
PetscScalar, pointer :: localArray(:)
|
|
|
|
PetscScalar :: BCValue,BCDotValue,timeinc
|
|
|
|
PetscErrorCode :: ierr
|
|
|
|
|
|
|
|
call PetscSectionGetFieldComponents(section,field,numComp,ierr); CHKERRQ(ierr)
|
|
|
|
call ISGetSize(bcPointsIS,nBcPoints,ierr); CHKERRQ(ierr)
|
|
|
|
if (nBcPoints > 0) call ISGetIndicesF90(bcPointsIS,bcPoints,ierr)
|
|
|
|
call VecGetArrayF90(localVec,localArray,ierr); CHKERRQ(ierr)
|
|
|
|
do point = 1, nBcPoints
|
|
|
|
call PetscSectionGetFieldDof(section,bcPoints(point),field,numDof,ierr)
|
|
|
|
CHKERRQ(ierr)
|
|
|
|
call PetscSectionGetFieldOffset(section,bcPoints(point),field,offset,ierr)
|
|
|
|
CHKERRQ(ierr)
|
|
|
|
do dof = offset+comp+1, offset+numDof, numComp
|
|
|
|
localArray(dof) = localArray(dof) + BCValue + BCDotValue*timeinc
|
|
|
|
enddo
|
|
|
|
enddo
|
|
|
|
call VecRestoreArrayF90(localVec,localArray,ierr); CHKERRQ(ierr)
|
|
|
|
call VecAssemblyBegin(localVec, ierr); CHKERRQ(ierr)
|
|
|
|
call VecAssemblyEnd (localVec, ierr); CHKERRQ(ierr)
|
|
|
|
if (nBcPoints > 0) call ISRestoreIndicesF90(bcPointsIS,bcPoints,ierr)
|
2018-08-17 03:44:25 +05:30
|
|
|
|
|
|
|
end subroutine utilities_projectBCValues
|
|
|
|
|
|
|
|
end module FEM_utilities
|