added kdtree2 source and changed makefile to compile it.

started to implement the nearest neighbor search for regridding
corrected calculation of divergence in real space.
corrected handling of maximum stress deviation (removed mask)
This commit is contained in:
Martin Diehl 2012-01-04 17:43:26 +00:00
parent dd1e968908
commit c54600fd1f
3 changed files with 1975 additions and 47 deletions

View File

@ -21,6 +21,8 @@
!******************************************************************** !********************************************************************
! Material subroutine for BVP solution using spectral method ! Material subroutine for BVP solution using spectral method
! !
! Run 'DAMASK_spectral.exe --help' to get usage hints
!
! written by P. Eisenlohr, ! written by P. Eisenlohr,
! F. Roters, ! F. Roters,
! L. Hantcherli, ! L. Hantcherli,
@ -32,16 +34,6 @@
! !
! MPI fuer Eisenforschung, Duesseldorf ! MPI fuer Eisenforschung, Duesseldorf
! !
!********************************************************************
! Usage:
! - start program with DAMASK_spectral
! -g (--geom, --geometry) PathToGeomFile/NameOfGeom.geom
! -l (--load, --loadcase) PathToLoadFile/NameOfLoadFile.load
! - PathToGeomFile will be the working directory
! - make sure the file "material.config" exists in the working
! directory. For further configuration use "numerics.config" and
! "numerics.config"
!********************************************************************
program DAMASK_spectral program DAMASK_spectral
!******************************************************************** !********************************************************************
@ -50,6 +42,7 @@ program DAMASK_spectral
use IO use IO
use debug, only: spectral_debug_verbosity use debug, only: spectral_debug_verbosity
use math use math
use kdtree2_module
use mesh, only: mesh_ipCenterOfGravity use mesh, only: mesh_ipCenterOfGravity
use CPFEM, only: CPFEM_general, CPFEM_initAll use CPFEM, only: CPFEM_general, CPFEM_initAll
use FEsolving, only: restartWrite, restartReadStep use FEsolving, only: restartWrite, restartReadStep
@ -126,6 +119,13 @@ program DAMASK_spectral
integer(pInt), dimension(3) :: k_s integer(pInt), dimension(3) :: k_s
integer*8, dimension(3) :: fftw_plan ! plans for fftw (forward and backward) integer*8, dimension(3) :: fftw_plan ! plans for fftw (forward and backward)
! variables for regriding
real(pReal), dimension(:,:,:,:) ,allocatable :: deformed_small
real(pReal), dimension(:,:) ,allocatable :: deformed_large
real(pReal), dimension(:,:,:,:) ,allocatable :: new_coordinates
type(kdtree2), pointer :: tree
real(pReal), dimension(3) :: shift
! loop variables, convergence etc. ! loop variables, convergence etc.
real(pReal) :: time = 0.0_pReal, time0 = 0.0_pReal, timeinc ! elapsed time, begin of interval, time interval real(pReal) :: time = 0.0_pReal, time0 = 0.0_pReal, timeinc ! elapsed time, begin of interval, time interval
real(pReal) :: guessmode, err_div, err_stress, err_stress_tol, p_hat_avg real(pReal) :: guessmode, err_div, err_stress, err_stress_tol, p_hat_avg
@ -459,6 +459,7 @@ program DAMASK_spectral
if(totalStepsCounter == restartReadStep) then ! Initialize values if(totalStepsCounter == restartReadStep) then ! Initialize values
if (regrid .eqv. .true. ) then ! 'DeInitialize' the values changing in case of regridding if (regrid .eqv. .true. ) then ! 'DeInitialize' the values changing in case of regridding
regrid = .false. regrid = .false.
call dfftw_destroy_plan(fftw_plan(1)); call dfftw_destroy_plan(fftw_plan(2)) call dfftw_destroy_plan(fftw_plan(1)); call dfftw_destroy_plan(fftw_plan(2))
if(debugDivergence) call dfftw_destroy_plan(fftw_plan(3)) if(debugDivergence) call dfftw_destroy_plan(fftw_plan(3))
deallocate (defgrad) deallocate (defgrad)
@ -492,9 +493,7 @@ program DAMASK_spectral
divergence,(/res(1)/2_pInt+1_pInt,res(2),res(3)/),1,(res(1)/2_pInt+1_pInt)*res(2)*res(3),& divergence,(/res(1)/2_pInt+1_pInt,res(2),res(3)/),1,(res(1)/2_pInt+1_pInt)*res(2)*res(3),&
divergence,(/res(1) +2_pInt,res(2),res(3)/),1,(res(1) +2_pInt)*res(2)*res(3),fftw_planner_flag) divergence,(/res(1) +2_pInt,res(2),res(3)/),1,(res(1) +2_pInt)*res(2)*res(3),fftw_planner_flag)
if (debugGeneral) then if (debugGeneral) then
!$OMP CRITICAL (write2out)
write (6,*) 'FFTW initialized' write (6,*) 'FFTW initialized'
!$OMP END CRITICAL (write2out)
endif endif
if (restartReadStep==1_pInt) then ! not restarting, no deformation at the beginning if (restartReadStep==1_pInt) then ! not restarting, no deformation at the beginning
@ -527,9 +526,7 @@ program DAMASK_spectral
c0_reference = c_current * wgt ! linear reference material stiffness c0_reference = c_current * wgt ! linear reference material stiffness
if (debugGeneral) then if (debugGeneral) then
!$OMP CRITICAL (write2out)
write (6,*) 'first call to CPFEM_general finished' write (6,*) 'first call to CPFEM_general finished'
!$OMP END CRITICAL (write2out)
endif endif
do k = 1_pInt, res(3) ! calculation of discrete angular frequencies, ordered as in FFTW (wrap around) do k = 1_pInt, res(3) ! calculation of discrete angular frequencies, ordered as in FFTW (wrap around)
@ -751,33 +748,35 @@ program DAMASK_spectral
p_hat_avg = sqrt(maxval (math_eigenvalues3x3(math_mul33x33(workfft(1,1,1,1:3,1:3),& ! L_2 norm of average stress (freq 0,0,0) in fourier space, p_hat_avg = sqrt(maxval (math_eigenvalues3x3(math_mul33x33(workfft(1,1,1,1:3,1:3),& ! L_2 norm of average stress (freq 0,0,0) in fourier space,
math_transpose3x3(workfft(1,1,1,1:3,1:3)))))) ! ignore imaginary part as it is always zero for real only input math_transpose3x3(workfft(1,1,1,1:3,1:3)))))) ! ignore imaginary part as it is always zero for real only input
err_div_avg_complex = 0.0_pReal err_div_avg_complex = 0.0_pReal
err_div_max = 0.0_pReal ! only if debugDivergence == .true. of importance err_div_max = 0.0_pReal ! only important if debugDivergence == .true.
divergence = 0.0_pReal ! - '' - divergence = 0.0_pReal ! - '' -
do k = 1_pInt, res(3); do j = 1_pInt, res(2); do i = 1_pInt, res(1)/2_pInt+1_pInt do k = 1_pInt, res(3); do j = 1_pInt, res(2); do i = 1_pInt, res(1)/2_pInt+1_pInt
divergence_complex = math_mul33x3_complex(workfft(i*2_pInt-1_pInt,j,k,1:3,1:3)& ! calculate divergence out of the real and imaginary part of the stress divergence_complex = math_mul33x3_complex(workfft(i*2_pInt-1_pInt,j,k,1:3,1:3)& ! calculate divergence out of the real and imaginary part of the stress
+ workfft(i*2_pInt ,j,k,1:3,1:3)*img,xi(1:3,i,j,k)) + workfft(i*2_pInt ,j,k,1:3,1:3)*img,xi(1:3,i,j,k))
if(debugDivergence) then ! need divergence NOT squared
divergence(i*2_pInt-1_pInt,j,k,1:3) = -aimag(divergence_complex) ! real part at i*2-1, imaginary part at i*2, multiply by i
divergence(i*2_pInt ,j,k,1:3) = real(divergence_complex) ! ==> switch order and change sign of img part
endif
divergence_complex = divergence_complex**2.0_pReal ! all criteria need divergence squared
if(i==1_pInt .or. i == res(1)/2_pInt + 1_pInt) then ! We are on one of the two slides without conjg. complex counterpart if(i==1_pInt .or. i == res(1)/2_pInt + 1_pInt) then ! We are on one of the two slides without conjg. complex counterpart
err_div_avg_complex = err_div_avg_complex + sum(divergence_complex**2.0_pReal) ! Avg of L_2 norm of div(stress) in fourier space (Suquet small strain) err_div_avg_complex = err_div_avg_complex + sum(divergence_complex) ! RMS of L_2 norm of div(stress) in fourier space (Suquet small strain)
else ! Has somewhere a conj. complex counterpart. Therefore count it twice. else ! Has somewhere a conj. complex counterpart. Therefore count it twice.
err_div_avg_complex = err_div_avg_complex +2.0*real(sum(divergence_complex**2.0_pReal)) ! Ignore img part (conjg. complex sum will end up 0). This and the different order err_div_avg_complex = err_div_avg_complex +2.0*real(sum(divergence_complex)) ! Ignore img part (conjg. complex sum will end up 0). This and the different order
endif ! compared to c2c transform results in slight numerical deviations. endif ! compared to c2c transform results in slight numerical deviations.
if(debugDivergence) then if(debugDivergence) then
err_div_max = max(err_div_max,abs(sqrt(sum(divergence_complex**2.0_pReal)))) ! maximum of L two norm of div(stress) in fourier space (Suquet large strain) err_div_max = max(err_div_max,abs(sqrt(sum(divergence_complex)))) ! maximum of L two norm of div(stress) in fourier space (Suquet large strain)
divergence(i*2_pInt-1_pInt,j,k,1:3) = -aimag(divergence_complex)*pi*2.0_pReal ! real part at i*2-1, imaginary part at i*2, multiply by i
divergence(i*2_pInt ,j,k,1:3) = real(divergence_complex)*pi*2.0_pReal ! ==> switch order and change sign of img part
endif endif
enddo; enddo; enddo enddo; enddo; enddo
err_div = abs(sqrt (err_div_avg_complex*wgt)) ! weighting by and taking square root. abs(...) because result is a complex number err_div = abs(sqrt (err_div_avg_complex*wgt)) ! weighting by and taking square root (RMS). abs(...) because result is a complex number
err_div = err_div *correctionFactor/p_hat_avg ! weighting by average stress and multiplying with correction factor err_div = err_div *correctionFactor/p_hat_avg ! weighting by average stress and multiplying with correction factor
err_div_max = err_div_max*correctionFactor/p_hat_avg ! - '' - only if debugDivergence == .true. of importance err_div_max = err_div_max*correctionFactor/p_hat_avg ! - '' - only if debugDivergence == .true. of importance
! calculate additional divergence criteria and report ------------- ! calculate additional divergence criteria and report -------------
if(debugDivergence) then if(debugDivergence) then
call dfftw_execute_dft_c2r(fftw_plan(3),divergence,divergence) call dfftw_execute_dft_c2r(fftw_plan(3),divergence,divergence)
divergence = divergence * wgt divergence = divergence *pi*2.0_pReal* wgt !pointwise factor 2*pi from differentation and weighting from FT
err_real_div_avg = 0.0_pReal err_real_div_avg = 0.0_pReal
err_real_div_max = 0.0_pReal err_real_div_max = 0.0_pReal
do k = 1_pInt, res(3); do j = 1_pInt, res(2); do i = 1_pInt, res(1) do k = 1_pInt, res(3); do j = 1_pInt, res(2); do i = 1_pInt, res(1)
@ -786,8 +785,8 @@ program DAMASK_spectral
enddo; enddo; enddo enddo; enddo; enddo
p_real_avg = sqrt(maxval (math_eigenvalues3x3(math_mul33x33(pstress_av_lab,& ! L_2 norm of average stress in real space, p_real_avg = sqrt(maxval (math_eigenvalues3x3(math_mul33x33(pstress_av_lab,& ! L_2 norm of average stress in real space,
math_transpose3x3(pstress_av_lab))))) math_transpose3x3(pstress_av_lab)))))
err_real_div_avg = sqrt(wgt*err_real_div_avg)*correctionFactor/p_hat_avg err_real_div_avg = sqrt(wgt*err_real_div_avg)*correctionFactor/p_real_avg ! RMS in real space
err_real_div_max = err_real_div_max *correctionFactor/p_hat_avg err_real_div_max = err_real_div_max *correctionFactor/p_real_avg
print '(a,es10.4,a,f6.2)', 'error divergence FT avg = ',err_div, ', ', err_div/err_div_tol print '(a,es10.4,a,f6.2)', 'error divergence FT avg = ',err_div, ', ', err_div/err_div_tol
print '(a,es10.4)', 'error divergence FT max = ',err_div_max print '(a,es10.4)', 'error divergence FT max = ',err_div_max
@ -847,7 +846,7 @@ program DAMASK_spectral
if(size_reduced > 0_pInt) then ! calculate stress BC if applied if(size_reduced > 0_pInt) then ! calculate stress BC if applied
err_stress = maxval(abs(mask_stress * (pstress_av - bc(loadcase)%stress))) ! maximum deviaton (tensor norm not applicable) err_stress = maxval(abs(mask_stress * (pstress_av - bc(loadcase)%stress))) ! maximum deviaton (tensor norm not applicable)
err_stress_tol = maxval(abs(mask_defgrad * pstress_av)) * err_stress_tolrel ! don't use any tensor norm because the comparison should be coherent err_stress_tol = maxval(abs(pstress_av)) * err_stress_tolrel ! don't use any tensor norm because the comparison should be coherent
print '(a)', '' print '(a)', ''
print '(a,es10.4,a,f6.2)', 'error stress = ',err_stress, ', ', err_stress/err_stress_tol print '(a,es10.4,a,f6.2)', 'error stress = ',err_stress, ', ', err_stress/err_stress_tol
print '(a)', '... correcting deformation gradient to fulfill BCs ..........' print '(a)', '... correcting deformation gradient to fulfill BCs ..........'
@ -899,6 +898,47 @@ program DAMASK_spectral
write(538), materialpoint_results(1_pInt:materialpoint_sizeResults,1,1_pInt:Npoints) ! write result to file write(538), materialpoint_results(1_pInt:materialpoint_sizeResults,1,1_pInt:Npoints) ! write result to file
endif endif
!$OMP END CRITICAL (write2out) !$OMP END CRITICAL (write2out)
! ##################################################
! # test of regridding
! allocate(deformed_small(res(1) ,res(2) ,res(3) ,3)); deformed_small = 0.0_pReal
! allocate(deformed_large(3,Npoints*27_pInt)); deformed_large = 0.0_pReal !ToDo: make it smaller (small corona only)
! call deformed_fft(res,geomdimension,defgrad_av_lab,1.0_pReal,defgrad,deformed_small) ! calculate deformed coordinates
! shift = math_mul33x3(defgrad_av_lab,geomdimension)
! print*, 'defgrad'
! do k = 1_pInt, res(3); do j = 1_pInt, res(2); do i = 1_pInt, res(1)
! print*, defgrad(i,j,k,1:3,1:3)
! enddo; enddo; enddo
! print*, 'deformed_small'
! do k = 1_pInt, res(3); do j = 1_pInt, res(2); do i = 1_pInt, res(1)
! print*, deformed_small(i,j,k,1:3)
! enddo; enddo; enddo
! print*, 'shift', shift
! ielem = 0_pInt
! do k = 1_pInt, res(3); do j = 1_pInt, res(2); do i = 1_pInt, res(1)
! do n = -1, 1
! do m = -1, 1
! do l = -1, 1
! ielem = ielem +1_pInt
! deformed_large(1:3,ielem) = deformed_small(i,j,k,1:3)+ real((/l,m,n/),pReal)*shift
! enddo; enddo; enddo
! enddo; enddo; enddo
! print*, 'deformed_large'
! print*, deformed_large
! tree => kdtree2_create(deformed_large,sort=.true.,rearrange=.true.)
! allocate(new_coordinates(res(1),res(2),res(3),3)); new_coordinates = 0.0_pReal !fluctuation free new coordinates
! do k = 1_pInt, res(3); do j = 1_pInt, res(2); do i = 1_pInt, res(1)
! new_coordinates(i,j,k,1:3) = math_mul33x3(defgrad_av_lab,coordinates(1:3,i,j,k))
! enddo; enddo; enddo
! pause
! ##################################################
! # end test of regridding
endif ! end calculation/forwarding endif ! end calculation/forwarding
enddo ! end looping over steps in current loadcase enddo ! end looping over steps in current loadcase
deallocate(c_reduced) deallocate(c_reduced)

1885
code/kdtree2.f90 Normal file

File diff suppressed because it is too large Load Diff

View File

@ -58,9 +58,9 @@ DEBUG5 =-stand std03/std95
######################################################################################## ########################################################################################
#auto values will be set by setup_code.py #auto values will be set by setup_code.py
FFTWROOT := FFTWROOT := /nethome/m.diehl/DAMASK/lib/fftw
IKMLROOT := IKMLROOT :=
ACMLROOT := ACMLROOT := /opt/acml4.4.0
LAPACKROOT := LAPACKROOT :=
F90 ?= ifort F90 ?= ifort
@ -206,15 +206,18 @@ FEsolving.o: FEsolving.f90 basics.a
basics.a: debug.o math.o basics.a: kdtree2.o
ar rc basics.a debug.o math.o numerics.o IO.o DAMASK_spectral_interface.o prec.o ar rc basics.a kdtree2.o math.o debug.o numerics.o IO.o DAMASK_spectral_interface.o prec.o
kdtree2.o: kdtree2.f90 math.o
$(PREFIX) $(COMPILERNAME) $(COMPILE) kdtree2.f90 $(SUFFIX)
math.o: math.f90 debug.o
$(PREFIX) $(COMPILERNAME) $(COMPILE) math.f90 $(SUFFIX)
debug.o: debug.f90 numerics.o debug.o: debug.f90 numerics.o
$(PREFIX) $(COMPILERNAME) $(COMPILE) debug.f90 $(SUFFIX) $(PREFIX) $(COMPILERNAME) $(COMPILE) debug.f90 $(SUFFIX)
math.o: math.f90 numerics.o
$(PREFIX) $(COMPILERNAME) $(COMPILE) math.f90 $(SUFFIX)
numerics.o: numerics.f90 IO.o numerics.o: numerics.f90 IO.o
$(PREFIX) $(COMPILERNAME) $(COMPILE) numerics.f90 $(SUFFIX) $(PREFIX) $(COMPILERNAME) $(COMPILE) numerics.f90 $(SUFFIX)