DAMASK_EICMD/src/mesh/discretization_mesh.f90

275 lines
10 KiB
Fortran
Raw Normal View History

!--------------------------------------------------------------------------------------------------
!> @author Pratheek Shanthraj, Max-Planck-Institut für Eisenforschung GmbH
!> @author Martin Diehl, Max-Planck-Institut für Eisenforschung GmbH
!> @author Philip Eisenlohr, Max-Planck-Institut für Eisenforschung GmbH
!> @author Franz Roters, Max-Planck-Institut für Eisenforschung GmbH
!--------------------------------------------------------------------------------------------------
2020-03-20 19:38:07 +05:30
module discretization_mesh
2018-08-30 15:25:13 +05:30
#include <petsc/finclude/petscdmplex.h>
#include <petsc/finclude/petscis.h>
#include <petsc/finclude/petscdmda.h>
use PETScDMplex
use PETScDMDA
use PETScIS
#if (PETSC_VERSION_MAJOR==3 && PETSC_VERSION_MINOR>14) && !defined(PETSC_HAVE_MPI_F90MODULE_VISIBILITY)
use MPI_f08
#endif
2020-06-16 16:57:21 +05:30
use DAMASK_interface
2020-09-13 13:49:38 +05:30
use parallelization
2020-06-16 16:57:21 +05:30
use IO
2020-08-15 19:32:10 +05:30
use config
2020-06-16 16:57:21 +05:30
use discretization
use results
2020-06-16 16:57:21 +05:30
use FEM_quadrature
2020-06-25 18:45:48 +05:30
use YAML_types
2020-06-16 16:57:21 +05:30
use prec
implicit none
private
integer, public, protected :: &
mesh_Nboundaries, &
mesh_NcpElemsGlobal
2021-01-06 18:54:02 +05:30
integer, public, protected :: &
2020-06-16 16:57:21 +05:30
mesh_NcpElems !< total number of CP elements in mesh
2020-01-21 04:09:24 +05:30
!!!! BEGIN DEPRECATED !!!!!
2020-06-16 16:57:21 +05:30
integer, public, protected :: &
mesh_maxNips !< max number of IPs in any CP element
!!!! BEGIN DEPRECATED !!!!!
2021-07-22 11:18:01 +05:30
DM, public :: geomMesh
PetscInt, dimension(:), allocatable, public, protected :: &
mesh_boundaries
2020-06-16 16:57:21 +05:30
real(pReal), dimension(:,:), allocatable :: &
mesh_ipVolume, & !< volume associated with IP (initially!)
mesh_node0 !< node x,y,z coordinates (initially!)
real(pReal), pointer, dimension(:) :: &
mesh_node0_temp
2020-06-16 16:57:21 +05:30
real(pReal), dimension(:,:,:), allocatable :: &
mesh_ipCoordinates !< IP x,y,z coordinates (after deformation!)
2020-06-16 16:57:21 +05:30
public :: &
discretization_mesh_init, &
mesh_FEM_build_ipVolumes, &
mesh_FEM_build_ipCoordinates
contains
!--------------------------------------------------------------------------------------------------
!> @brief initializes the mesh by calling all necessary private routines the mesh module
!! Order and routines strongly depend on type of solver
!--------------------------------------------------------------------------------------------------
subroutine discretization_mesh_init(restart)
2020-05-07 01:45:09 +05:30
logical, intent(in) :: restart
2019-06-09 19:57:05 +05:30
2020-01-21 01:06:21 +05:30
integer :: dimPlex, &
2020-02-05 04:15:34 +05:30
mesh_Nnodes, & !< total number of nodes in mesh
2021-07-22 03:13:55 +05:30
j, &
2020-07-02 02:09:44 +05:30
debug_element, debug_ip
2020-01-21 01:06:21 +05:30
PetscSF :: sf
DM :: globalMesh
2020-01-21 01:36:08 +05:30
PetscInt :: nFaceSets
2020-01-27 00:26:30 +05:30
PetscInt, pointer, dimension(:) :: pFaceSets
2020-06-16 16:57:21 +05:30
IS :: faceSetIS
PetscErrorCode :: err_PETSc
integer(MPI_INTEGER_KIND) :: err_MPI
2020-06-16 17:29:59 +05:30
integer, dimension(:), allocatable :: &
2020-10-01 16:13:05 +05:30
materialAt
2020-06-16 22:45:01 +05:30
class(tNode), pointer :: &
2020-06-18 00:16:03 +05:30
num_mesh
integer :: p_i !< integration order (quadrature rule)
2021-07-22 03:13:55 +05:30
type(tvec) :: coords_node0
2020-06-16 22:45:01 +05:30
print'(/,1x,a)', '<<<+- discretization_mesh init -+>>>'
2020-06-18 21:22:25 +05:30
!--------------------------------------------------------------------------------
! read numerics parameter
2020-09-13 14:47:49 +05:30
num_mesh => config_numerics%get('mesh',defaultVal=emptyDict)
p_i = num_mesh%get_asInt('p_i',defaultVal = 2)
2020-06-16 22:45:01 +05:30
2020-06-18 21:22:25 +05:30
!---------------------------------------------------------------------------------
! read debug parameters
2020-09-13 14:47:49 +05:30
debug_element = config_debug%get_asInt('element',defaultVal=1)
debug_ip = config_debug%get_asInt('integrationpoint',defaultVal=1)
2020-01-21 01:06:21 +05:30
call DMPlexCreateFromFile(PETSC_COMM_WORLD,interface_geomFile,PETSC_TRUE,globalMesh,err_PETSc)
CHKERRQ(err_PETSc)
call DMGetDimension(globalMesh,dimPlex,err_PETSc)
CHKERRQ(err_PETSc)
call DMGetStratumSize(globalMesh,'depth',dimPlex,mesh_NcpElemsGlobal,err_PETSc)
CHKERRQ(err_PETSc)
print'()'
call DMView(globalMesh, PETSC_VIEWER_STDOUT_WORLD,err_PETSc)
CHKERRQ(err_PETSc)
2020-01-21 01:06:21 +05:30
! get number of IDs in face sets (for boundary conditions?)
call DMGetLabelSize(globalMesh,'Face Sets',mesh_Nboundaries,err_PETSc)
CHKERRQ(err_PETSc)
call MPI_Bcast(mesh_Nboundaries,1_MPI_INTEGER_KIND,MPI_INTEGER,0_MPI_INTEGER_KIND,MPI_COMM_WORLD,err_MPI)
if (err_MPI /= 0_MPI_INTEGER_KIND) error stop 'MPI error'
call MPI_Bcast(mesh_NcpElemsGlobal,1_MPI_INTEGER_KIND,MPI_INTEGER,0_MPI_INTEGER_KIND,MPI_COMM_WORLD,err_MPI)
if (err_MPI /= 0_MPI_INTEGER_KIND) error stop 'MPI error'
call MPI_Bcast(dimPlex,1_MPI_INTEGER_KIND,MPI_INTEGER,0_MPI_INTEGER_KIND,MPI_COMM_WORLD,err_MPI)
if (err_MPI /= 0_MPI_INTEGER_KIND) error stop 'MPI error'
2020-01-21 01:06:21 +05:30
if (worldrank == 0) then
call DMClone(globalMesh,geomMesh,err_PETSc)
else
call DMPlexDistribute(globalMesh,0_pPETSCINT,sf,geomMesh,err_PETSc)
endif
CHKERRQ(err_PETSc)
2020-01-21 01:06:21 +05:30
allocate(mesh_boundaries(mesh_Nboundaries), source = 0)
call DMGetLabelSize(globalMesh,'Face Sets',nFaceSets,err_PETSc)
CHKERRQ(err_PETSc)
call DMGetLabelIdIS(globalMesh,'Face Sets',faceSetIS,err_PETSc)
CHKERRQ(err_PETSc)
2020-01-22 00:03:22 +05:30
if (nFaceSets > 0) then
call ISGetIndicesF90(faceSetIS,pFaceSets,err_PETSc)
CHKERRQ(err_PETSc)
2020-01-22 00:03:22 +05:30
mesh_boundaries(1:nFaceSets) = pFaceSets
CHKERRQ(err_PETSc)
call ISRestoreIndicesF90(faceSetIS,pFaceSets,err_PETSc)
2020-01-22 00:03:22 +05:30
endif
call MPI_Bcast(mesh_boundaries,mesh_Nboundaries,MPI_INTEGER,0_MPI_INTEGER_KIND,MPI_COMM_WORLD,err_MPI)
if (err_MPI /= 0_MPI_INTEGER_KIND) error stop 'MPI error'
2020-01-21 01:06:21 +05:30
call DMDestroy(globalMesh,err_PETSc); CHKERRQ(err_PETSc)
2020-06-16 16:57:21 +05:30
call DMGetStratumSize(geomMesh,'depth',dimPlex,mesh_NcpElems,err_PETSc)
CHKERRQ(err_PETSc)
call DMGetStratumSize(geomMesh,'depth',0_pPETSCINT,mesh_Nnodes,err_PETSc)
CHKERRQ(err_PETSc)
2020-01-21 01:06:21 +05:30
! Get initial nodal coordinates
call DMGetCoordinates(geomMesh,coords_node0,err_PETSc)
CHKERRQ(err_PETSc)
call VecGetArrayF90(coords_node0, mesh_node0_temp,err_PETSc)
CHKERRQ(err_PETSc)
mesh_maxNips = FEM_nQuadrature(dimPlex,p_i)
2020-06-16 16:57:21 +05:30
call mesh_FEM_build_ipCoordinates(dimPlex,FEM_quadrature_points(dimPlex,p_i)%p)
2020-01-21 01:06:21 +05:30
call mesh_FEM_build_ipVolumes(dimPlex)
2020-06-16 16:57:21 +05:30
2020-10-01 16:13:05 +05:30
allocate(materialAt(mesh_NcpElems))
2020-01-21 01:06:21 +05:30
do j = 1, mesh_NcpElems
call DMGetLabelValue(geomMesh,'Cell Sets',j-1,materialAt(j),err_PETSc)
CHKERRQ(err_PETSc)
2021-07-16 14:00:45 +05:30
enddo
materialAt = materialAt + 1
2020-06-16 16:57:21 +05:30
2020-07-02 02:09:44 +05:30
if (debug_element < 1 .or. debug_element > mesh_NcpElems) call IO_error(602,ext_msg='element')
if (debug_ip < 1 .or. debug_ip > mesh_maxNips) call IO_error(602,ext_msg='IP')
2020-06-16 16:57:21 +05:30
allocate(mesh_node0(3,mesh_Nnodes),source=0.0_pReal)
mesh_node0(1:dimPlex,:) = reshape(mesh_node0_temp,[dimPlex,mesh_Nnodes])
2020-01-21 01:06:21 +05:30
2020-10-01 16:13:05 +05:30
call discretization_init(materialAt,&
reshape(mesh_ipCoordinates,[3,mesh_maxNips*mesh_NcpElems]), &
2019-06-07 09:37:00 +05:30
mesh_node0)
2020-06-16 16:57:21 +05:30
call writeGeometry(reshape(mesh_ipCoordinates,[3,mesh_maxNips*mesh_NcpElems]),mesh_node0)
2020-03-20 19:38:07 +05:30
end subroutine discretization_mesh_init
!--------------------------------------------------------------------------------------------------
!> @brief Calculates IP volume. Allocates global array 'mesh_ipVolume'
!--------------------------------------------------------------------------------------------------
subroutine mesh_FEM_build_ipVolumes(dimPlex)
2020-06-16 16:57:21 +05:30
2020-01-21 04:16:48 +05:30
PetscInt,intent(in):: dimPlex
2019-06-16 00:19:48 +05:30
PetscReal :: vol
2020-01-21 04:16:48 +05:30
PetscReal, pointer,dimension(:) :: pCent, pNorm
2019-06-16 00:19:48 +05:30
PetscInt :: cellStart, cellEnd, cell
PetscErrorCode :: err_PETSc
2020-06-16 16:57:21 +05:30
2020-01-21 04:16:48 +05:30
allocate(mesh_ipVolume(mesh_maxNips,mesh_NcpElems),source=0.0_pReal)
2020-06-16 16:57:21 +05:30
call DMPlexGetHeightStratum(geomMesh,0_pPETSCINT,cellStart,cellEnd,err_PETSc)
CHKERRQ(err_PETSc)
2020-01-21 04:16:48 +05:30
allocate(pCent(dimPlex))
allocate(pNorm(dimPlex))
2019-06-16 00:19:48 +05:30
do cell = cellStart, cellEnd-1
call DMPlexComputeCellGeometryFVM(geomMesh,cell,vol,pCent,pNorm,err_PETSc)
CHKERRQ(err_PETSc)
2019-06-16 00:19:48 +05:30
mesh_ipVolume(:,cell+1) = vol/real(mesh_maxNips,pReal)
2020-06-16 16:57:21 +05:30
enddo
end subroutine mesh_FEM_build_ipVolumes
!--------------------------------------------------------------------------------------------------
!> @brief Calculates IP Coordinates. Allocates global array 'mesh_ipCoordinates'
!--------------------------------------------------------------------------------------------------
subroutine mesh_FEM_build_ipCoordinates(dimPlex,qPoints)
2019-06-16 00:19:48 +05:30
PetscInt, intent(in) :: dimPlex
PetscReal, intent(in) :: qPoints(mesh_maxNips*dimPlex)
2020-06-16 16:57:21 +05:30
2020-01-21 04:16:48 +05:30
PetscReal, pointer,dimension(:) :: pV0, pCellJ, pInvcellJ
2019-06-16 00:19:48 +05:30
PetscReal :: detJ
PetscInt :: cellStart, cellEnd, cell, qPt, dirI, dirJ, qOffset
PetscErrorCode :: err_PETSc
2020-06-16 16:57:21 +05:30
allocate(mesh_ipCoordinates(3,mesh_maxNips,mesh_NcpElems),source=0.0_pReal)
2020-06-16 16:57:21 +05:30
2020-01-21 04:16:48 +05:30
allocate(pV0(dimPlex))
allocatE(pCellJ(dimPlex**2))
allocatE(pinvCellJ(dimPlex**2))
call DMPlexGetHeightStratum(geomMesh,0_pPETSCINT,cellStart,cellEnd,err_PETSc)
CHKERRQ(err_PETSc)
2020-06-16 16:57:21 +05:30
do cell = cellStart, cellEnd-1 !< loop over all elements
call DMPlexComputeCellGeometryAffineFEM(geomMesh,cell,pV0,pCellJ,pInvcellJ,detJ,err_PETSc)
CHKERRQ(err_PETSc)
2019-06-16 00:19:48 +05:30
qOffset = 0
do qPt = 1, mesh_maxNips
do dirI = 1, dimPlex
mesh_ipCoordinates(dirI,qPt,cell+1) = pV0(dirI)
do dirJ = 1, dimPlex
mesh_ipCoordinates(dirI,qPt,cell+1) = mesh_ipCoordinates(dirI,qPt,cell+1) + &
pCellJ((dirI-1)*dimPlex+dirJ)*(qPoints(qOffset+dirJ) + 1.0)
enddo
enddo
qOffset = qOffset + dimPlex
enddo
2020-06-16 16:57:21 +05:30
enddo
end subroutine mesh_FEM_build_ipCoordinates
!--------------------------------------------------------------------------------------------------
!> @brief Write all information needed for the DADF5 geometry
!--------------------------------------------------------------------------------------------------
subroutine writeGeometry(coordinates_points,coordinates_nodes)
real(pReal), dimension(:,:), intent(in) :: &
coordinates_nodes, &
coordinates_points
call results_openJobFile
call results_closeGroup(results_addGroup('geometry'))
2021-06-02 17:38:12 +05:30
call results_writeDataset(coordinates_nodes,'geometry','x_n', &
'initial coordinates of the nodes','m')
2021-06-02 17:38:12 +05:30
call results_writeDataset(coordinates_points,'geometry','x_p', &
'initial coordinates of the materialpoints (cell centers)','m')
call results_closeJobFile
end subroutine writeGeometry
2020-03-20 19:38:07 +05:30
end module discretization_mesh