Merge branch 'polishing' into 'development'
forall is deprecated See merge request damask/DAMASK!478
This commit is contained in:
commit
6e36c4c303
|
@ -48,17 +48,17 @@ jobs:
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v2
|
||||||
with:
|
with:
|
||||||
path: download
|
path: download
|
||||||
key: petsc-3.16.0.tar.gz
|
key: petsc-3.16.2.tar.gz
|
||||||
|
|
||||||
- name: PETSc - Download
|
- name: PETSc - Download
|
||||||
if: steps.petsc-download.outputs.cache-hit != 'true'
|
if: steps.petsc-download.outputs.cache-hit != 'true'
|
||||||
run: |
|
run: |
|
||||||
wget -q https://ftp.mcs.anl.gov/pub/petsc/release-snapshots/petsc-3.16.0.tar.gz -P download
|
wget -q https://ftp.mcs.anl.gov/pub/petsc/release-snapshots/petsc-3.16.2.tar.gz -P download
|
||||||
|
|
||||||
- name: PETSc - Prepare
|
- name: PETSc - Prepare
|
||||||
run: |
|
run: |
|
||||||
tar -xf download/petsc-3.16.0.tar.gz -C .
|
tar -xf download/petsc-3.16.2.tar.gz -C .
|
||||||
export PETSC_DIR=${PWD}/petsc-3.16.0
|
export PETSC_DIR=${PWD}/petsc-3.16.2
|
||||||
export PETSC_ARCH=gcc${GCC_V}
|
export PETSC_ARCH=gcc${GCC_V}
|
||||||
printenv >> $GITHUB_ENV
|
printenv >> $GITHUB_ENV
|
||||||
|
|
||||||
|
@ -66,13 +66,13 @@ jobs:
|
||||||
id: petsc-install
|
id: petsc-install
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v2
|
||||||
with:
|
with:
|
||||||
path: petsc-3.16.0
|
path: petsc-3.16.2
|
||||||
key: petsc-3.16.0-${{ matrix.os }}-gcc${{ matrix.gcc_v }}-${{ hashFiles('**/petscversion.h') }}
|
key: petsc-3.16.2-${{ matrix.os }}-gcc${{ matrix.gcc_v }}-${{ hashFiles('**/petscversion.h') }}
|
||||||
|
|
||||||
- name: PETSc - Install (Linux)
|
- name: PETSc - Install (Linux)
|
||||||
if: contains( matrix.os, 'ubuntu')
|
if: contains( matrix.os, 'ubuntu')
|
||||||
run: |
|
run: |
|
||||||
cd petsc-3.16.0
|
cd petsc-3.16.2
|
||||||
./configure --with-fc=gfortran --with-cc=gcc --with-cxx=g++ \
|
./configure --with-fc=gfortran --with-cc=gcc --with-cxx=g++ \
|
||||||
--download-mpich --download-fftw --download-hdf5 --download-hdf5-fortran-bindings=1 --download-zlib \
|
--download-mpich --download-fftw --download-hdf5 --download-hdf5-fortran-bindings=1 --download-zlib \
|
||||||
--with-mpi-f90module-visibility=0
|
--with-mpi-f90module-visibility=0
|
||||||
|
@ -81,7 +81,7 @@ jobs:
|
||||||
- name: PETSc - Install (macOS)
|
- name: PETSc - Install (macOS)
|
||||||
if: contains( matrix.os, 'macos')
|
if: contains( matrix.os, 'macos')
|
||||||
run: |
|
run: |
|
||||||
cd petsc-3.16.0
|
cd petsc-3.16.2
|
||||||
./configure --with-fc=gfortran-${GCC_V} --with-cc=gcc-${GCC_V} --with-cxx=g++-${GCC_V} \
|
./configure --with-fc=gfortran-${GCC_V} --with-cc=gcc-${GCC_V} --with-cxx=g++-${GCC_V} \
|
||||||
--download-openmpi --download-fftw --download-hdf5 --download-hdf5-fortran-bindings=1 --download-zlib
|
--download-openmpi --download-fftw --download-hdf5 --download-hdf5-fortran-bindings=1 --download-zlib
|
||||||
make all
|
make all
|
||||||
|
@ -132,17 +132,17 @@ jobs:
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v2
|
||||||
with:
|
with:
|
||||||
path: download
|
path: download
|
||||||
key: petsc-3.16.0.tar.gz
|
key: petsc-3.16.2.tar.gz
|
||||||
|
|
||||||
- name: PETSc - Download
|
- name: PETSc - Download
|
||||||
if: steps.petsc-download.outputs.cache-hit != 'true'
|
if: steps.petsc-download.outputs.cache-hit != 'true'
|
||||||
run: |
|
run: |
|
||||||
wget -q https://ftp.mcs.anl.gov/pub/petsc/release-snapshots/petsc-3.16.0.tar.gz -P download
|
wget -q https://ftp.mcs.anl.gov/pub/petsc/release-snapshots/petsc-3.16.2.tar.gz -P download
|
||||||
|
|
||||||
- name: PETSc - Prepare
|
- name: PETSc - Prepare
|
||||||
run: |
|
run: |
|
||||||
tar -xf download/petsc-3.16.0.tar.gz -C .
|
tar -xf download/petsc-3.16.2.tar.gz -C .
|
||||||
export PETSC_DIR=${PWD}/petsc-3.16.0
|
export PETSC_DIR=${PWD}/petsc-3.16.2
|
||||||
export PETSC_ARCH=intel-${INTEL_V}
|
export PETSC_ARCH=intel-${INTEL_V}
|
||||||
printenv >> $GITHUB_ENV
|
printenv >> $GITHUB_ENV
|
||||||
|
|
||||||
|
@ -150,13 +150,13 @@ jobs:
|
||||||
id: petsc-install
|
id: petsc-install
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v2
|
||||||
with:
|
with:
|
||||||
path: petsc-3.16.0
|
path: petsc-3.16.2
|
||||||
key: petsc-3.16.0-intel-${{ matrix.intel_v }}-${{ hashFiles('**/petscversion.h') }}
|
key: petsc-3.16.2-intel-${{ matrix.intel_v }}-${{ hashFiles('**/petscversion.h') }}
|
||||||
|
|
||||||
- name: PETSc - Install (classic)
|
- name: PETSc - Install (classic)
|
||||||
if: contains( matrix.intel_v, 'classic')
|
if: contains( matrix.intel_v, 'classic')
|
||||||
run: |
|
run: |
|
||||||
cd petsc-3.16.0
|
cd petsc-3.16.2
|
||||||
./configure --with-fc=mpiifort --with-cc=mpiicc --with-cxx=mpiicpc \
|
./configure --with-fc=mpiifort --with-cc=mpiicc --with-cxx=mpiicpc \
|
||||||
--download-fftw --download-hdf5 --download-hdf5-fortran-bindings=1 --download-zlib
|
--download-fftw --download-hdf5 --download-hdf5-fortran-bindings=1 --download-zlib
|
||||||
make all
|
make all
|
||||||
|
@ -164,7 +164,7 @@ jobs:
|
||||||
- name: PETSc - Install (LLVM)
|
- name: PETSc - Install (LLVM)
|
||||||
if: contains( matrix.intel_v, 'llvm')
|
if: contains( matrix.intel_v, 'llvm')
|
||||||
run: |
|
run: |
|
||||||
cd petsc-3.16.0
|
cd petsc-3.16.2
|
||||||
./configure --with-fc=mpiifort --with-cc="mpiicc -cc=icx" --with-cxx="mpiicpc -cxx=icpx" \
|
./configure --with-fc=mpiifort --with-cc="mpiicc -cc=icx" --with-cxx="mpiicpc -cxx=icpx" \
|
||||||
--download-fftw --download-hdf5 --download-hdf5-fortran-bindings=1 --download-zlib
|
--download-fftw --download-hdf5 --download-hdf5-fortran-bindings=1 --download-zlib
|
||||||
make all
|
make all
|
||||||
|
|
|
@ -43,6 +43,15 @@ program DAMASK_grid
|
||||||
logical :: estimate_rate !< follow trajectory of former loadcase
|
logical :: estimate_rate !< follow trajectory of former loadcase
|
||||||
end type tLoadCase
|
end type tLoadCase
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
! field labels information
|
||||||
|
enum, bind(c); enumerator :: &
|
||||||
|
FIELD_UNDEFINED_ID, &
|
||||||
|
FIELD_MECH_ID, &
|
||||||
|
FIELD_THERMAL_ID, &
|
||||||
|
FIELD_DAMAGE_ID
|
||||||
|
end enum
|
||||||
|
|
||||||
integer(kind(FIELD_UNDEFINED_ID)), allocatable :: ID(:)
|
integer(kind(FIELD_UNDEFINED_ID)), allocatable :: ID(:)
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -167,7 +167,7 @@ function grid_damage_spectral_solution(Delta_t) result(solution)
|
||||||
integer :: i, j, k, ce
|
integer :: i, j, k, ce
|
||||||
type(tSolutionState) :: solution
|
type(tSolutionState) :: solution
|
||||||
PetscInt :: devNull
|
PetscInt :: devNull
|
||||||
PetscReal :: phi_min, phi_max, stagNorm, solnNorm
|
PetscReal :: phi_min, phi_max, stagNorm
|
||||||
|
|
||||||
PetscErrorCode :: ierr
|
PetscErrorCode :: ierr
|
||||||
SNESConvergedReason :: reason
|
SNESConvergedReason :: reason
|
||||||
|
@ -189,9 +189,8 @@ function grid_damage_spectral_solution(Delta_t) result(solution)
|
||||||
solution%iterationsNeeded = totalIter
|
solution%iterationsNeeded = totalIter
|
||||||
end if
|
end if
|
||||||
stagNorm = maxval(abs(phi_current - phi_stagInc))
|
stagNorm = maxval(abs(phi_current - phi_stagInc))
|
||||||
solnNorm = maxval(abs(phi_current))
|
|
||||||
call MPI_Allreduce(MPI_IN_PLACE,stagNorm,1,MPI_DOUBLE,MPI_MAX,MPI_COMM_WORLD,ierr)
|
call MPI_Allreduce(MPI_IN_PLACE,stagNorm,1,MPI_DOUBLE,MPI_MAX,MPI_COMM_WORLD,ierr)
|
||||||
solution%stagConverged = stagNorm < max(num%eps_damage_atol, num%eps_damage_rtol*solnNorm)
|
solution%stagConverged = stagNorm < max(num%eps_damage_atol, num%eps_damage_rtol*maxval(phi_current))
|
||||||
call MPI_Allreduce(MPI_IN_PLACE,solution%stagConverged,1,MPI_LOGICAL,MPI_LAND,MPI_COMM_WORLD,ierr)
|
call MPI_Allreduce(MPI_IN_PLACE,solution%stagConverged,1,MPI_LOGICAL,MPI_LAND,MPI_COMM_WORLD,ierr)
|
||||||
phi_stagInc = phi_current
|
phi_stagInc = phi_current
|
||||||
|
|
||||||
|
|
|
@ -162,7 +162,7 @@ function grid_thermal_spectral_solution(Delta_t) result(solution)
|
||||||
integer :: i, j, k, ce
|
integer :: i, j, k, ce
|
||||||
type(tSolutionState) :: solution
|
type(tSolutionState) :: solution
|
||||||
PetscInt :: devNull
|
PetscInt :: devNull
|
||||||
PetscReal :: T_min, T_max, stagNorm, solnNorm
|
PetscReal :: T_min, T_max, stagNorm
|
||||||
|
|
||||||
PetscErrorCode :: ierr
|
PetscErrorCode :: ierr
|
||||||
SNESConvergedReason :: reason
|
SNESConvergedReason :: reason
|
||||||
|
@ -184,9 +184,8 @@ function grid_thermal_spectral_solution(Delta_t) result(solution)
|
||||||
solution%iterationsNeeded = totalIter
|
solution%iterationsNeeded = totalIter
|
||||||
end if
|
end if
|
||||||
stagNorm = maxval(abs(T_current - T_stagInc))
|
stagNorm = maxval(abs(T_current - T_stagInc))
|
||||||
solnNorm = maxval(abs(T_current))
|
|
||||||
call MPI_Allreduce(MPI_IN_PLACE,stagNorm,1,MPI_DOUBLE,MPI_MAX,MPI_COMM_WORLD,ierr)
|
call MPI_Allreduce(MPI_IN_PLACE,stagNorm,1,MPI_DOUBLE,MPI_MAX,MPI_COMM_WORLD,ierr)
|
||||||
solution%stagConverged = stagNorm < max(num%eps_thermal_atol, num%eps_thermal_rtol*solnNorm)
|
solution%stagConverged = stagNorm < max(num%eps_thermal_atol, num%eps_thermal_rtol*maxval(T_current))
|
||||||
call MPI_Allreduce(MPI_IN_PLACE,solution%stagConverged,1,MPI_LOGICAL,MPI_LAND,MPI_COMM_WORLD,ierr)
|
call MPI_Allreduce(MPI_IN_PLACE,solution%stagConverged,1,MPI_LOGICAL,MPI_LAND,MPI_COMM_WORLD,ierr)
|
||||||
T_stagInc = T_current
|
T_stagInc = T_current
|
||||||
|
|
||||||
|
|
|
@ -28,15 +28,6 @@ module spectral_utilities
|
||||||
|
|
||||||
include 'fftw3-mpi.f03'
|
include 'fftw3-mpi.f03'
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
! field labels information
|
|
||||||
enum, bind(c); enumerator :: &
|
|
||||||
FIELD_UNDEFINED_ID, &
|
|
||||||
FIELD_MECH_ID, &
|
|
||||||
FIELD_THERMAL_ID, &
|
|
||||||
FIELD_DAMAGE_ID
|
|
||||||
end enum
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! grid related information information
|
! grid related information information
|
||||||
real(pReal), protected, public :: wgt !< weighting factor 1/Nelems
|
real(pReal), protected, public :: wgt !< weighting factor 1/Nelems
|
||||||
|
@ -139,11 +130,7 @@ module spectral_utilities
|
||||||
utilities_calculateRate, &
|
utilities_calculateRate, &
|
||||||
utilities_forwardField, &
|
utilities_forwardField, &
|
||||||
utilities_updateCoords, &
|
utilities_updateCoords, &
|
||||||
utilities_saveReferenceStiffness, &
|
utilities_saveReferenceStiffness
|
||||||
FIELD_UNDEFINED_ID, &
|
|
||||||
FIELD_MECH_ID, &
|
|
||||||
FIELD_THERMAL_ID, &
|
|
||||||
FIELD_DAMAGE_ID
|
|
||||||
|
|
||||||
contains
|
contains
|
||||||
|
|
||||||
|
@ -388,21 +375,24 @@ subroutine utilities_updateGamma(C)
|
||||||
gamma_hat = cmplx(0.0_pReal,0.0_pReal,pReal) ! for the singular point and any non invertible A
|
gamma_hat = cmplx(0.0_pReal,0.0_pReal,pReal) ! for the singular point and any non invertible A
|
||||||
do k = grid3Offset+1, grid3Offset+grid3; do j = 1, grid(2); do i = 1, grid1Red
|
do k = grid3Offset+1, grid3Offset+grid3; do j = 1, grid(2); do i = 1, grid1Red
|
||||||
if (any([i,j,k] /= 1)) then ! singular point at xi=(0.0,0.0,0.0) i.e. i=j=k=1
|
if (any([i,j,k] /= 1)) then ! singular point at xi=(0.0,0.0,0.0) i.e. i=j=k=1
|
||||||
forall(l = 1:3, m = 1:3) &
|
do concurrent (l = 1:3, m = 1:3)
|
||||||
xiDyad_cmplx(l,m) = conjg(-xi1st(l,i,j,k-grid3Offset))*xi1st(m,i,j,k-grid3Offset)
|
xiDyad_cmplx(l,m) = conjg(-xi1st(l,i,j,k-grid3Offset))*xi1st(m,i,j,k-grid3Offset)
|
||||||
forall(l = 1:3, m = 1:3) &
|
end do
|
||||||
|
do concurrent(l = 1:3, m = 1:3)
|
||||||
temp33_complex(l,m) = sum(cmplx(C_ref(l,1:3,m,1:3),0.0_pReal)*xiDyad_cmplx)
|
temp33_complex(l,m) = sum(cmplx(C_ref(l,1:3,m,1:3),0.0_pReal)*xiDyad_cmplx)
|
||||||
|
end do
|
||||||
A(1:3,1:3) = temp33_complex%re; A(4:6,4:6) = temp33_complex%re
|
A(1:3,1:3) = temp33_complex%re; A(4:6,4:6) = temp33_complex%re
|
||||||
A(1:3,4:6) = temp33_complex%im; A(4:6,1:3) = -temp33_complex%im
|
A(1:3,4:6) = temp33_complex%im; A(4:6,1:3) = -temp33_complex%im
|
||||||
if (abs(math_det33(A(1:3,1:3))) > 1e-16) then
|
if (abs(math_det33(A(1:3,1:3))) > 1e-16) then
|
||||||
call math_invert(A_inv, err, A)
|
call math_invert(A_inv, err, A)
|
||||||
temp33_complex = cmplx(A_inv(1:3,1:3),A_inv(1:3,4:6),pReal)
|
temp33_complex = cmplx(A_inv(1:3,1:3),A_inv(1:3,4:6),pReal)
|
||||||
forall(l=1:3, m=1:3, n=1:3, o=1:3) &
|
do concurrent(l=1:3, m=1:3, n=1:3, o=1:3)
|
||||||
gamma_hat(l,m,n,o,i,j,k-grid3Offset) = temp33_complex(l,n)* &
|
gamma_hat(l,m,n,o,i,j,k-grid3Offset) = temp33_complex(l,n)* &
|
||||||
conjg(-xi1st(o,i,j,k-grid3Offset))*xi1st(m,i,j,k-grid3Offset)
|
conjg(-xi1st(o,i,j,k-grid3Offset))*xi1st(m,i,j,k-grid3Offset)
|
||||||
endif
|
end do
|
||||||
endif
|
end if
|
||||||
enddo; enddo; enddo
|
end if
|
||||||
|
end do; end do; end do
|
||||||
endif
|
endif
|
||||||
|
|
||||||
end subroutine utilities_updateGamma
|
end subroutine utilities_updateGamma
|
||||||
|
@ -505,32 +495,37 @@ subroutine utilities_fourierGammaConvolution(fieldAim)
|
||||||
memoryEfficient: if (num%memory_efficient) then
|
memoryEfficient: if (num%memory_efficient) then
|
||||||
do k = 1, grid3; do j = 1, grid(2); do i = 1, grid1Red
|
do k = 1, grid3; do j = 1, grid(2); do i = 1, grid1Red
|
||||||
if (any([i,j,k+grid3Offset] /= 1)) then ! singular point at xi=(0.0,0.0,0.0) i.e. i=j=k=1
|
if (any([i,j,k+grid3Offset] /= 1)) then ! singular point at xi=(0.0,0.0,0.0) i.e. i=j=k=1
|
||||||
forall(l = 1:3, m = 1:3) &
|
do concurrent(l = 1:3, m = 1:3)
|
||||||
xiDyad_cmplx(l,m) = conjg(-xi1st(l,i,j,k))*xi1st(m,i,j,k)
|
xiDyad_cmplx(l,m) = conjg(-xi1st(l,i,j,k))*xi1st(m,i,j,k)
|
||||||
forall(l = 1:3, m = 1:3) &
|
end do
|
||||||
|
do concurrent(l = 1:3, m = 1:3)
|
||||||
temp33_complex(l,m) = sum(cmplx(C_ref(l,1:3,m,1:3),0.0_pReal)*xiDyad_cmplx)
|
temp33_complex(l,m) = sum(cmplx(C_ref(l,1:3,m,1:3),0.0_pReal)*xiDyad_cmplx)
|
||||||
|
end do
|
||||||
A(1:3,1:3) = temp33_complex%re; A(4:6,4:6) = temp33_complex%re
|
A(1:3,1:3) = temp33_complex%re; A(4:6,4:6) = temp33_complex%re
|
||||||
A(1:3,4:6) = temp33_complex%im; A(4:6,1:3) = -temp33_complex%im
|
A(1:3,4:6) = temp33_complex%im; A(4:6,1:3) = -temp33_complex%im
|
||||||
if (abs(math_det33(A(1:3,1:3))) > 1e-16) then
|
if (abs(math_det33(A(1:3,1:3))) > 1e-16) then
|
||||||
call math_invert(A_inv, err, A)
|
call math_invert(A_inv, err, A)
|
||||||
temp33_complex = cmplx(A_inv(1:3,1:3),A_inv(1:3,4:6),pReal)
|
temp33_complex = cmplx(A_inv(1:3,1:3),A_inv(1:3,4:6),pReal)
|
||||||
forall(l=1:3, m=1:3, n=1:3, o=1:3) &
|
do concurrent(l=1:3, m=1:3, n=1:3, o=1:3)
|
||||||
gamma_hat(l,m,n,o,1,1,1) = temp33_complex(l,n)*conjg(-xi1st(o,i,j,k))*xi1st(m,i,j,k)
|
gamma_hat(l,m,n,o,1,1,1) = temp33_complex(l,n)*conjg(-xi1st(o,i,j,k))*xi1st(m,i,j,k)
|
||||||
|
end do
|
||||||
else
|
else
|
||||||
gamma_hat(1:3,1:3,1:3,1:3,1,1,1) = cmplx(0.0_pReal,0.0_pReal,pReal)
|
gamma_hat(1:3,1:3,1:3,1:3,1,1,1) = cmplx(0.0_pReal,0.0_pReal,pReal)
|
||||||
endif
|
end if
|
||||||
forall(l = 1:3, m = 1:3) &
|
do concurrent(l = 1:3, m = 1:3)
|
||||||
temp33_Complex(l,m) = sum(gamma_hat(l,m,1:3,1:3,1,1,1)*tensorField_fourier(1:3,1:3,i,j,k))
|
temp33_Complex(l,m) = sum(gamma_hat(l,m,1:3,1:3,1,1,1)*tensorField_fourier(1:3,1:3,i,j,k))
|
||||||
|
end do
|
||||||
tensorField_fourier(1:3,1:3,i,j,k) = temp33_Complex
|
tensorField_fourier(1:3,1:3,i,j,k) = temp33_Complex
|
||||||
endif
|
end if
|
||||||
enddo; enddo; enddo
|
end do; end do; end do
|
||||||
else memoryEfficient
|
else memoryEfficient
|
||||||
do k = 1, grid3; do j = 1, grid(2); do i = 1,grid1Red
|
do k = 1, grid3; do j = 1, grid(2); do i = 1,grid1Red
|
||||||
forall(l = 1:3, m = 1:3) &
|
do concurrent(l = 1:3, m = 1:3)
|
||||||
temp33_Complex(l,m) = sum(gamma_hat(l,m,1:3,1:3,i,j,k) * tensorField_fourier(1:3,1:3,i,j,k))
|
temp33_Complex(l,m) = sum(gamma_hat(l,m,1:3,1:3,i,j,k) * tensorField_fourier(1:3,1:3,i,j,k))
|
||||||
|
end do
|
||||||
tensorField_fourier(1:3,1:3,i,j,k) = temp33_Complex
|
tensorField_fourier(1:3,1:3,i,j,k) = temp33_Complex
|
||||||
enddo; enddo; enddo
|
end do; end do; end do
|
||||||
endif memoryEfficient
|
end if memoryEfficient
|
||||||
|
|
||||||
if (grid3Offset == 0) tensorField_fourier(1:3,1:3,1,1,1) = cmplx(fieldAim/wgt,0.0_pReal,pReal)
|
if (grid3Offset == 0) tensorField_fourier(1:3,1:3,1,1,1) = cmplx(fieldAim/wgt,0.0_pReal,pReal)
|
||||||
|
|
||||||
|
|
|
@ -5,17 +5,17 @@ submodule(phase) mechanical
|
||||||
|
|
||||||
|
|
||||||
enum, bind(c); enumerator :: &
|
enum, bind(c); enumerator :: &
|
||||||
PLASTICITY_UNDEFINED_ID, &
|
PLASTIC_UNDEFINED_ID, &
|
||||||
PLASTICITY_NONE_ID, &
|
PLASTIC_NONE_ID, &
|
||||||
PLASTICITY_ISOTROPIC_ID, &
|
PLASTIC_ISOTROPIC_ID, &
|
||||||
PLASTICITY_PHENOPOWERLAW_ID, &
|
PLASTIC_PHENOPOWERLAW_ID, &
|
||||||
PLASTICITY_KINEHARDENING_ID, &
|
PLASTIC_KINEHARDENING_ID, &
|
||||||
PLASTICITY_DISLOTWIN_ID, &
|
PLASTIC_DISLOTWIN_ID, &
|
||||||
PLASTICITY_DISLOTUNGSTEN_ID, &
|
PLASTIC_DISLOTUNGSTEN_ID, &
|
||||||
PLASTICITY_NONLOCAL_ID, &
|
PLASTIC_NONLOCAL_ID, &
|
||||||
KINEMATICS_UNDEFINED_ID, &
|
EIGEN_UNDEFINED_ID, &
|
||||||
KINEMATICS_CLEAVAGE_OPENING_ID, &
|
EIGEN_CLEAVAGE_OPENING_ID, &
|
||||||
KINEMATICS_THERMAL_EXPANSION_ID
|
EIGEN_THERMAL_EXPANSION_ID
|
||||||
end enum
|
end enum
|
||||||
|
|
||||||
type(tTensorContainer), dimension(:), allocatable :: &
|
type(tTensorContainer), dimension(:), allocatable :: &
|
||||||
|
@ -37,7 +37,7 @@ submodule(phase) mechanical
|
||||||
phase_mechanical_S0
|
phase_mechanical_S0
|
||||||
|
|
||||||
|
|
||||||
integer(kind(PLASTICITY_undefined_ID)), dimension(:), allocatable :: &
|
integer(kind(PLASTIC_undefined_ID)), dimension(:), allocatable :: &
|
||||||
phase_plasticity !< plasticity of each phase
|
phase_plasticity !< plasticity of each phase
|
||||||
|
|
||||||
integer :: phase_plasticity_maxSizeDotState
|
integer :: phase_plasticity_maxSizeDotState
|
||||||
|
@ -291,7 +291,7 @@ module subroutine mechanical_init(phases)
|
||||||
call elastic_init(phases)
|
call elastic_init(phases)
|
||||||
|
|
||||||
allocate(plasticState(phases%length))
|
allocate(plasticState(phases%length))
|
||||||
allocate(phase_plasticity(phases%length),source = PLASTICITY_undefined_ID)
|
allocate(phase_plasticity(phases%length),source = PLASTIC_UNDEFINED_ID)
|
||||||
call plastic_init()
|
call plastic_init()
|
||||||
do ph = 1,phases%length
|
do ph = 1,phases%length
|
||||||
plasticState(ph)%state0 = plasticState(ph)%state
|
plasticState(ph)%state0 = plasticState(ph)%state
|
||||||
|
@ -340,22 +340,22 @@ module subroutine mechanical_results(group,ph)
|
||||||
|
|
||||||
select case(phase_plasticity(ph))
|
select case(phase_plasticity(ph))
|
||||||
|
|
||||||
case(PLASTICITY_ISOTROPIC_ID)
|
case(PLASTIC_ISOTROPIC_ID)
|
||||||
call plastic_isotropic_results(ph,group//'mechanical/')
|
call plastic_isotropic_results(ph,group//'mechanical/')
|
||||||
|
|
||||||
case(PLASTICITY_PHENOPOWERLAW_ID)
|
case(PLASTIC_PHENOPOWERLAW_ID)
|
||||||
call plastic_phenopowerlaw_results(ph,group//'mechanical/')
|
call plastic_phenopowerlaw_results(ph,group//'mechanical/')
|
||||||
|
|
||||||
case(PLASTICITY_KINEHARDENING_ID)
|
case(PLASTIC_KINEHARDENING_ID)
|
||||||
call plastic_kinehardening_results(ph,group//'mechanical/')
|
call plastic_kinehardening_results(ph,group//'mechanical/')
|
||||||
|
|
||||||
case(PLASTICITY_DISLOTWIN_ID)
|
case(PLASTIC_DISLOTWIN_ID)
|
||||||
call plastic_dislotwin_results(ph,group//'mechanical/')
|
call plastic_dislotwin_results(ph,group//'mechanical/')
|
||||||
|
|
||||||
case(PLASTICITY_DISLOTUNGSTEN_ID)
|
case(PLASTIC_DISLOTUNGSTEN_ID)
|
||||||
call plastic_dislotungsten_results(ph,group//'mechanical/')
|
call plastic_dislotungsten_results(ph,group//'mechanical/')
|
||||||
|
|
||||||
case(PLASTICITY_NONLOCAL_ID)
|
case(PLASTIC_NONLOCAL_ID)
|
||||||
call plastic_nonlocal_results(ph,group//'mechanical/')
|
call plastic_nonlocal_results(ph,group//'mechanical/')
|
||||||
|
|
||||||
end select
|
end select
|
||||||
|
|
|
@ -3,9 +3,9 @@ submodule(phase:mechanical) eigen
|
||||||
integer, dimension(:), allocatable :: &
|
integer, dimension(:), allocatable :: &
|
||||||
Nmodels
|
Nmodels
|
||||||
|
|
||||||
integer(kind(KINEMATICS_UNDEFINED_ID)), dimension(:,:), allocatable :: &
|
integer(kind(EIGEN_UNDEFINED_ID)), dimension(:,:), allocatable :: &
|
||||||
model
|
model
|
||||||
integer(kind(KINEMATICS_UNDEFINED_ID)), dimension(:), allocatable :: &
|
integer(kind(EIGEN_UNDEFINED_ID)), dimension(:), allocatable :: &
|
||||||
model_damage
|
model_damage
|
||||||
|
|
||||||
interface
|
interface
|
||||||
|
@ -57,15 +57,15 @@ module subroutine eigen_init(phases)
|
||||||
Nmodels(ph) = kinematics%length
|
Nmodels(ph) = kinematics%length
|
||||||
end do
|
end do
|
||||||
|
|
||||||
allocate(model(maxval(Nmodels),phases%length), source = KINEMATICS_undefined_ID)
|
allocate(model(maxval(Nmodels),phases%length), source = EIGEN_undefined_ID)
|
||||||
|
|
||||||
if (maxval(Nmodels) /= 0) then
|
if (maxval(Nmodels) /= 0) then
|
||||||
where(thermalexpansion_init(maxval(Nmodels))) model = KINEMATICS_thermal_expansion_ID
|
where(thermalexpansion_init(maxval(Nmodels))) model = EIGEN_thermal_expansion_ID
|
||||||
endif
|
endif
|
||||||
|
|
||||||
allocate(model_damage(phases%length), source = KINEMATICS_UNDEFINED_ID)
|
allocate(model_damage(phases%length), source = EIGEN_UNDEFINED_ID)
|
||||||
|
|
||||||
where(damage_anisobrittle_init()) model_damage = KINEMATICS_cleavage_opening_ID
|
where(damage_anisobrittle_init()) model_damage = EIGEN_cleavage_opening_ID
|
||||||
|
|
||||||
|
|
||||||
end subroutine eigen_init
|
end subroutine eigen_init
|
||||||
|
@ -173,7 +173,7 @@ module subroutine phase_LiAndItsTangents(Li, dLi_dS, dLi_dFi, &
|
||||||
|
|
||||||
|
|
||||||
plasticType: select case (phase_plasticity(ph))
|
plasticType: select case (phase_plasticity(ph))
|
||||||
case (PLASTICITY_isotropic_ID) plasticType
|
case (PLASTIC_isotropic_ID) plasticType
|
||||||
call plastic_isotropic_LiAndItsTangent(my_Li, my_dLi_dS, S ,ph,en)
|
call plastic_isotropic_LiAndItsTangent(my_Li, my_dLi_dS, S ,ph,en)
|
||||||
Li = Li + my_Li
|
Li = Li + my_Li
|
||||||
dLi_dS = dLi_dS + my_dLi_dS
|
dLi_dS = dLi_dS + my_dLi_dS
|
||||||
|
@ -182,7 +182,7 @@ module subroutine phase_LiAndItsTangents(Li, dLi_dS, dLi_dFi, &
|
||||||
|
|
||||||
KinematicsLoop: do k = 1, Nmodels(ph)
|
KinematicsLoop: do k = 1, Nmodels(ph)
|
||||||
kinematicsType: select case (model(k,ph))
|
kinematicsType: select case (model(k,ph))
|
||||||
case (KINEMATICS_thermal_expansion_ID) kinematicsType
|
case (EIGEN_thermal_expansion_ID) kinematicsType
|
||||||
call thermalexpansion_LiAndItsTangent(my_Li, my_dLi_dS, ph,en)
|
call thermalexpansion_LiAndItsTangent(my_Li, my_dLi_dS, ph,en)
|
||||||
Li = Li + my_Li
|
Li = Li + my_Li
|
||||||
dLi_dS = dLi_dS + my_dLi_dS
|
dLi_dS = dLi_dS + my_dLi_dS
|
||||||
|
@ -191,7 +191,7 @@ module subroutine phase_LiAndItsTangents(Li, dLi_dS, dLi_dFi, &
|
||||||
end do KinematicsLoop
|
end do KinematicsLoop
|
||||||
|
|
||||||
select case (model_damage(ph))
|
select case (model_damage(ph))
|
||||||
case (KINEMATICS_cleavage_opening_ID)
|
case (EIGEN_cleavage_opening_ID)
|
||||||
call damage_anisobrittle_LiAndItsTangent(my_Li, my_dLi_dS, S, ph, en)
|
call damage_anisobrittle_LiAndItsTangent(my_Li, my_dLi_dS, S, ph, en)
|
||||||
Li = Li + my_Li
|
Li = Li + my_Li
|
||||||
dLi_dS = dLi_dS + my_dLi_dS
|
dLi_dS = dLi_dS + my_dLi_dS
|
||||||
|
|
|
@ -223,7 +223,7 @@ module function phase_homogenizedC66(ph,en) result(C)
|
||||||
|
|
||||||
|
|
||||||
plasticType: select case (phase_plasticity(ph))
|
plasticType: select case (phase_plasticity(ph))
|
||||||
case (PLASTICITY_DISLOTWIN_ID) plasticType
|
case (PLASTIC_DISLOTWIN_ID) plasticType
|
||||||
C = plastic_dislotwin_homogenizedC(ph,en)
|
C = plastic_dislotwin_homogenizedC(ph,en)
|
||||||
case default plasticType
|
case default plasticType
|
||||||
C = elastic_C66(ph,en)
|
C = elastic_C66(ph,en)
|
||||||
|
|
|
@ -224,15 +224,15 @@ module subroutine plastic_init
|
||||||
|
|
||||||
print'(/,1x,a)', '<<<+- phase:mechanical:plastic init -+>>>'
|
print'(/,1x,a)', '<<<+- phase:mechanical:plastic init -+>>>'
|
||||||
|
|
||||||
where(plastic_none_init()) phase_plasticity = PLASTICITY_NONE_ID
|
where(plastic_none_init()) phase_plasticity = PLASTIC_NONE_ID
|
||||||
where(plastic_isotropic_init()) phase_plasticity = PLASTICITY_ISOTROPIC_ID
|
where(plastic_isotropic_init()) phase_plasticity = PLASTIC_ISOTROPIC_ID
|
||||||
where(plastic_phenopowerlaw_init()) phase_plasticity = PLASTICITY_PHENOPOWERLAW_ID
|
where(plastic_phenopowerlaw_init()) phase_plasticity = PLASTIC_PHENOPOWERLAW_ID
|
||||||
where(plastic_kinehardening_init()) phase_plasticity = PLASTICITY_KINEHARDENING_ID
|
where(plastic_kinehardening_init()) phase_plasticity = PLASTIC_KINEHARDENING_ID
|
||||||
where(plastic_dislotwin_init()) phase_plasticity = PLASTICITY_DISLOTWIN_ID
|
where(plastic_dislotwin_init()) phase_plasticity = PLASTIC_DISLOTWIN_ID
|
||||||
where(plastic_dislotungsten_init()) phase_plasticity = PLASTICITY_DISLOTUNGSTEN_ID
|
where(plastic_dislotungsten_init()) phase_plasticity = PLASTIC_DISLOTUNGSTEN_ID
|
||||||
where(plastic_nonlocal_init()) phase_plasticity = PLASTICITY_NONLOCAL_ID
|
where(plastic_nonlocal_init()) phase_plasticity = PLASTIC_NONLOCAL_ID
|
||||||
|
|
||||||
if (any(phase_plasticity == PLASTICITY_undefined_ID)) call IO_error(201)
|
if (any(phase_plasticity == PLASTIC_undefined_ID)) call IO_error(201)
|
||||||
|
|
||||||
end subroutine plastic_init
|
end subroutine plastic_init
|
||||||
|
|
||||||
|
@ -262,7 +262,7 @@ module subroutine plastic_LpAndItsTangents(Lp, dLp_dS, dLp_dFi, &
|
||||||
i, j
|
i, j
|
||||||
|
|
||||||
|
|
||||||
if (phase_plasticity(ph) == PLASTICITY_NONE_ID) then
|
if (phase_plasticity(ph) == PLASTIC_NONE_ID) then
|
||||||
Lp = 0.0_pReal
|
Lp = 0.0_pReal
|
||||||
dLp_dFi = 0.0_pReal
|
dLp_dFi = 0.0_pReal
|
||||||
dLp_dS = 0.0_pReal
|
dLp_dS = 0.0_pReal
|
||||||
|
@ -272,22 +272,22 @@ module subroutine plastic_LpAndItsTangents(Lp, dLp_dS, dLp_dFi, &
|
||||||
|
|
||||||
plasticType: select case (phase_plasticity(ph))
|
plasticType: select case (phase_plasticity(ph))
|
||||||
|
|
||||||
case (PLASTICITY_ISOTROPIC_ID) plasticType
|
case (PLASTIC_ISOTROPIC_ID) plasticType
|
||||||
call isotropic_LpAndItsTangent(Lp,dLp_dMp,Mp,ph,en)
|
call isotropic_LpAndItsTangent(Lp,dLp_dMp,Mp,ph,en)
|
||||||
|
|
||||||
case (PLASTICITY_PHENOPOWERLAW_ID) plasticType
|
case (PLASTIC_PHENOPOWERLAW_ID) plasticType
|
||||||
call phenopowerlaw_LpAndItsTangent(Lp,dLp_dMp,Mp,ph,en)
|
call phenopowerlaw_LpAndItsTangent(Lp,dLp_dMp,Mp,ph,en)
|
||||||
|
|
||||||
case (PLASTICITY_KINEHARDENING_ID) plasticType
|
case (PLASTIC_KINEHARDENING_ID) plasticType
|
||||||
call kinehardening_LpAndItsTangent(Lp,dLp_dMp,Mp,ph,en)
|
call kinehardening_LpAndItsTangent(Lp,dLp_dMp,Mp,ph,en)
|
||||||
|
|
||||||
case (PLASTICITY_NONLOCAL_ID) plasticType
|
case (PLASTIC_NONLOCAL_ID) plasticType
|
||||||
call nonlocal_LpAndItsTangent(Lp,dLp_dMp,Mp, thermal_T(ph,en),ph,en)
|
call nonlocal_LpAndItsTangent(Lp,dLp_dMp,Mp, thermal_T(ph,en),ph,en)
|
||||||
|
|
||||||
case (PLASTICITY_DISLOTWIN_ID) plasticType
|
case (PLASTIC_DISLOTWIN_ID) plasticType
|
||||||
call dislotwin_LpAndItsTangent(Lp,dLp_dMp,Mp, thermal_T(ph,en),ph,en)
|
call dislotwin_LpAndItsTangent(Lp,dLp_dMp,Mp, thermal_T(ph,en),ph,en)
|
||||||
|
|
||||||
case (PLASTICITY_DISLOTUNGSTEN_ID) plasticType
|
case (PLASTIC_DISLOTUNGSTEN_ID) plasticType
|
||||||
call dislotungsten_LpAndItsTangent(Lp,dLp_dMp,Mp, thermal_T(ph,en),ph,en)
|
call dislotungsten_LpAndItsTangent(Lp,dLp_dMp,Mp, thermal_T(ph,en),ph,en)
|
||||||
|
|
||||||
end select plasticType
|
end select plasticType
|
||||||
|
@ -321,28 +321,28 @@ module function plastic_dotState(subdt,co,ip,el,ph,en) result(broken)
|
||||||
logical :: broken
|
logical :: broken
|
||||||
|
|
||||||
|
|
||||||
if (phase_plasticity(ph) /= PLASTICITY_NONE_ID) then
|
if (phase_plasticity(ph) /= PLASTIC_NONE_ID) then
|
||||||
Mp = matmul(matmul(transpose(phase_mechanical_Fi(ph)%data(1:3,1:3,en)),&
|
Mp = matmul(matmul(transpose(phase_mechanical_Fi(ph)%data(1:3,1:3,en)),&
|
||||||
phase_mechanical_Fi(ph)%data(1:3,1:3,en)),phase_mechanical_S(ph)%data(1:3,1:3,en))
|
phase_mechanical_Fi(ph)%data(1:3,1:3,en)),phase_mechanical_S(ph)%data(1:3,1:3,en))
|
||||||
|
|
||||||
plasticType: select case (phase_plasticity(ph))
|
plasticType: select case (phase_plasticity(ph))
|
||||||
|
|
||||||
case (PLASTICITY_ISOTROPIC_ID) plasticType
|
case (PLASTIC_ISOTROPIC_ID) plasticType
|
||||||
call isotropic_dotState(Mp,ph,en)
|
call isotropic_dotState(Mp,ph,en)
|
||||||
|
|
||||||
case (PLASTICITY_PHENOPOWERLAW_ID) plasticType
|
case (PLASTIC_PHENOPOWERLAW_ID) plasticType
|
||||||
call phenopowerlaw_dotState(Mp,ph,en)
|
call phenopowerlaw_dotState(Mp,ph,en)
|
||||||
|
|
||||||
case (PLASTICITY_KINEHARDENING_ID) plasticType
|
case (PLASTIC_KINEHARDENING_ID) plasticType
|
||||||
call plastic_kinehardening_dotState(Mp,ph,en)
|
call plastic_kinehardening_dotState(Mp,ph,en)
|
||||||
|
|
||||||
case (PLASTICITY_DISLOTWIN_ID) plasticType
|
case (PLASTIC_DISLOTWIN_ID) plasticType
|
||||||
call dislotwin_dotState(Mp,thermal_T(ph,en),ph,en)
|
call dislotwin_dotState(Mp,thermal_T(ph,en),ph,en)
|
||||||
|
|
||||||
case (PLASTICITY_DISLOTUNGSTEN_ID) plasticType
|
case (PLASTIC_DISLOTUNGSTEN_ID) plasticType
|
||||||
call dislotungsten_dotState(Mp,thermal_T(ph,en),ph,en)
|
call dislotungsten_dotState(Mp,thermal_T(ph,en),ph,en)
|
||||||
|
|
||||||
case (PLASTICITY_NONLOCAL_ID) plasticType
|
case (PLASTIC_NONLOCAL_ID) plasticType
|
||||||
call nonlocal_dotState(Mp,thermal_T(ph,en),subdt,ph,en,ip,el)
|
call nonlocal_dotState(Mp,thermal_T(ph,en),subdt,ph,en,ip,el)
|
||||||
end select plasticType
|
end select plasticType
|
||||||
end if
|
end if
|
||||||
|
@ -372,13 +372,13 @@ module subroutine plastic_dependentState(co, ip, el)
|
||||||
|
|
||||||
plasticType: select case (phase_plasticity(ph))
|
plasticType: select case (phase_plasticity(ph))
|
||||||
|
|
||||||
case (PLASTICITY_DISLOTWIN_ID) plasticType
|
case (PLASTIC_DISLOTWIN_ID) plasticType
|
||||||
call dislotwin_dependentState(thermal_T(ph,en),ph,en)
|
call dislotwin_dependentState(thermal_T(ph,en),ph,en)
|
||||||
|
|
||||||
case (PLASTICITY_DISLOTUNGSTEN_ID) plasticType
|
case (PLASTIC_DISLOTUNGSTEN_ID) plasticType
|
||||||
call dislotungsten_dependentState(ph,en)
|
call dislotungsten_dependentState(ph,en)
|
||||||
|
|
||||||
case (PLASTICITY_NONLOCAL_ID) plasticType
|
case (PLASTIC_NONLOCAL_ID) plasticType
|
||||||
call nonlocal_dependentState(ph,en,ip,el)
|
call nonlocal_dependentState(ph,en,ip,el)
|
||||||
|
|
||||||
end select plasticType
|
end select plasticType
|
||||||
|
@ -406,7 +406,7 @@ module function plastic_deltaState(ph, en) result(broken)
|
||||||
broken = .false.
|
broken = .false.
|
||||||
|
|
||||||
select case (phase_plasticity(ph))
|
select case (phase_plasticity(ph))
|
||||||
case (PLASTICITY_NONLOCAL_ID,PLASTICITY_KINEHARDENING_ID)
|
case (PLASTIC_NONLOCAL_ID,PLASTIC_KINEHARDENING_ID)
|
||||||
|
|
||||||
Mp = matmul(matmul(transpose(phase_mechanical_Fi(ph)%data(1:3,1:3,en)),&
|
Mp = matmul(matmul(transpose(phase_mechanical_Fi(ph)%data(1:3,1:3,en)),&
|
||||||
phase_mechanical_Fi(ph)%data(1:3,1:3,en)),&
|
phase_mechanical_Fi(ph)%data(1:3,1:3,en)),&
|
||||||
|
@ -414,10 +414,10 @@ module function plastic_deltaState(ph, en) result(broken)
|
||||||
|
|
||||||
plasticType: select case (phase_plasticity(ph))
|
plasticType: select case (phase_plasticity(ph))
|
||||||
|
|
||||||
case (PLASTICITY_KINEHARDENING_ID) plasticType
|
case (PLASTIC_KINEHARDENING_ID) plasticType
|
||||||
call plastic_kinehardening_deltaState(Mp,ph,en)
|
call plastic_kinehardening_deltaState(Mp,ph,en)
|
||||||
|
|
||||||
case (PLASTICITY_NONLOCAL_ID) plasticType
|
case (PLASTIC_NONLOCAL_ID) plasticType
|
||||||
call plastic_nonlocal_deltaState(Mp,ph,en)
|
call plastic_nonlocal_deltaState(Mp,ph,en)
|
||||||
|
|
||||||
end select plasticType
|
end select plasticType
|
||||||
|
|
|
@ -1277,7 +1277,7 @@ function rhoDotFlux(timestep,ph,en,ip,el)
|
||||||
!* The entering flux from my neighbor will be distributed on my slip systems according to the
|
!* The entering flux from my neighbor will be distributed on my slip systems according to the
|
||||||
!* compatibility
|
!* compatibility
|
||||||
if (neighbor_n > 0) then
|
if (neighbor_n > 0) then
|
||||||
if (phase_plasticity(material_phaseAt(1,neighbor_el)) == PLASTICITY_NONLOCAL_ID .and. &
|
if (phase_plasticity(material_phaseAt(1,neighbor_el)) == PLASTIC_NONLOCAL_ID .and. &
|
||||||
any(compatibility(:,:,:,n,ip,el) > 0.0_pReal)) then
|
any(compatibility(:,:,:,n,ip,el) > 0.0_pReal)) then
|
||||||
|
|
||||||
forall (s = 1:ns, t = 1:4)
|
forall (s = 1:ns, t = 1:4)
|
||||||
|
@ -1323,7 +1323,7 @@ function rhoDotFlux(timestep,ph,en,ip,el)
|
||||||
!* In case of reduced transmissivity, part of the leaving flux is stored as dead dislocation density.
|
!* In case of reduced transmissivity, part of the leaving flux is stored as dead dislocation density.
|
||||||
!* That means for an interface of zero transmissivity the leaving flux is fully converted to dead dislocations.
|
!* That means for an interface of zero transmissivity the leaving flux is fully converted to dead dislocations.
|
||||||
if (opposite_n > 0) then
|
if (opposite_n > 0) then
|
||||||
if (phase_plasticity(material_phaseAt(1,opposite_el)) == PLASTICITY_NONLOCAL_ID) then
|
if (phase_plasticity(material_phaseAt(1,opposite_el)) == PLASTIC_NONLOCAL_ID) then
|
||||||
|
|
||||||
normal_me2neighbor_defConf = math_det33(Favg) &
|
normal_me2neighbor_defConf = math_det33(Favg) &
|
||||||
* matmul(math_inv33(transpose(Favg)),IPareaNormal(1:3,n,ip,el)) ! normal of the interface in (average) deformed configuration (pointing en => neighbor)
|
* matmul(math_inv33(transpose(Favg)),IPareaNormal(1:3,n,ip,el)) ! normal of the interface in (average) deformed configuration (pointing en => neighbor)
|
||||||
|
|
Loading…
Reference in New Issue