Merge remote-tracking branch 'origin/development' into config_from_dream3D
This commit is contained in:
commit
3b27c64709
|
@ -95,7 +95,7 @@ checkout:
|
||||||
- release
|
- release
|
||||||
|
|
||||||
###################################################################################################
|
###################################################################################################
|
||||||
Pytest_python:
|
pytest_python:
|
||||||
stage: python
|
stage: python
|
||||||
script:
|
script:
|
||||||
- cd $DAMASKROOT/python
|
- cd $DAMASKROOT/python
|
||||||
|
@ -252,7 +252,7 @@ setup_mesh:
|
||||||
- release
|
- release
|
||||||
|
|
||||||
###################################################################################################
|
###################################################################################################
|
||||||
Pytest_grid:
|
pytest_fortran:
|
||||||
stage: grid
|
stage: grid
|
||||||
script:
|
script:
|
||||||
- module load $IntelCompiler $MPI_Intel $PETSc_Intel
|
- module load $IntelCompiler $MPI_Intel $PETSc_Intel
|
||||||
|
@ -287,14 +287,6 @@ J2_plasticBehavior:
|
||||||
- master
|
- master
|
||||||
- release
|
- release
|
||||||
|
|
||||||
Marc_elementLib:
|
|
||||||
stage: marc
|
|
||||||
script:
|
|
||||||
- module load $IntelMarc $HDF5Marc $MSC
|
|
||||||
- Marc_elementLib/test.py
|
|
||||||
except:
|
|
||||||
- master
|
|
||||||
- release
|
|
||||||
|
|
||||||
###################################################################################################
|
###################################################################################################
|
||||||
SpectralRuntime:
|
SpectralRuntime:
|
||||||
|
|
|
@ -84,7 +84,7 @@ for executable in python python3; do
|
||||||
done
|
done
|
||||||
secondLevel "Details on $DEFAULT_PYTHON:"
|
secondLevel "Details on $DEFAULT_PYTHON:"
|
||||||
echo $(ls -la $(which $DEFAULT_PYTHON))
|
echo $(ls -la $(which $DEFAULT_PYTHON))
|
||||||
for module in numpy scipy pandas;do
|
for module in numpy scipy pandas matplotlib yaml h5py;do
|
||||||
thirdLevel $module
|
thirdLevel $module
|
||||||
$DEFAULT_PYTHON -c "import $module; \
|
$DEFAULT_PYTHON -c "import $module; \
|
||||||
print('Version: {}'.format($module.__version__)); \
|
print('Version: {}'.format($module.__version__)); \
|
||||||
|
@ -94,10 +94,6 @@ thirdLevel vtk
|
||||||
$DEFAULT_PYTHON -c "import vtk; \
|
$DEFAULT_PYTHON -c "import vtk; \
|
||||||
print('Version: {}'.format(vtk.vtkVersion.GetVTKVersion())); \
|
print('Version: {}'.format(vtk.vtkVersion.GetVTKVersion())); \
|
||||||
print('Location: {}'.format(vtk.__file__))"
|
print('Location: {}'.format(vtk.__file__))"
|
||||||
thirdLevel h5py
|
|
||||||
$DEFAULT_PYTHON -c "import h5py; \
|
|
||||||
print('Version: {}'.format(h5py.version.version)); \
|
|
||||||
print('Location: {}'.format(h5py.__file__))"
|
|
||||||
|
|
||||||
firstLevel "GNU Compiler Collection"
|
firstLevel "GNU Compiler Collection"
|
||||||
for executable in gcc g++ gfortran ;do
|
for executable in gcc g++ gfortran ;do
|
||||||
|
|
2
LICENSE
2
LICENSE
|
@ -1,4 +1,4 @@
|
||||||
Copyright 2011-20 Max-Planck-Institut für Eisenforschung GmbH
|
Copyright 2011-21 Max-Planck-Institut für Eisenforschung GmbH
|
||||||
|
|
||||||
DAMASK is free software: you can redistribute it and/or modify
|
DAMASK is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|
2
PRIVATE
2
PRIVATE
|
@ -1 +1 @@
|
||||||
Subproject commit 45ef93dbfa3e0e6fa830914b3632e188c308a099
|
Subproject commit 13dfa0ee9d702782f0b7999f3f7fb2384f58d768
|
|
@ -1,5 +1,5 @@
|
||||||
# "set"-syntax needed only for tcsh (but works with bash and zsh)
|
# "set"-syntax needed only for tcsh (but works with bash and zsh)
|
||||||
set DAMASK_NUM_THREADS = 4
|
set OMP_NUM_THREADS = 4
|
||||||
|
|
||||||
set MSC_ROOT = /opt/msc
|
set MSC_ROOT = /opt/msc
|
||||||
set MSC_VERSION = 2020
|
set MSC_VERSION = 2020
|
||||||
|
|
|
@ -1,54 +0,0 @@
|
||||||
# sets up an environment for DAMASK on tcsh
|
|
||||||
# usage: source DAMASK_env.csh
|
|
||||||
|
|
||||||
set CALLED=($_)
|
|
||||||
set ENV_ROOT=`dirname $CALLED[2]`
|
|
||||||
set DAMASK_ROOT=`python3 -c "import os,sys; print(os.path.realpath(os.path.expanduser(sys.argv[1])))" $ENV_ROOT"/../"`
|
|
||||||
|
|
||||||
source $ENV_ROOT/CONFIG
|
|
||||||
|
|
||||||
set path = ($DAMASK_ROOT/bin $path)
|
|
||||||
|
|
||||||
set SOLVER=`which DAMASK_grid`
|
|
||||||
if ( "x$DAMASK_NUM_THREADS" == "x" ) then
|
|
||||||
set DAMASK_NUM_THREADS=1
|
|
||||||
endif
|
|
||||||
|
|
||||||
# currently, there is no information that unlimited stack size causes problems
|
|
||||||
# still, http://software.intel.com/en-us/forums/topic/501500 suggest to fix it
|
|
||||||
# more info https://jblevins.org/log/segfault
|
|
||||||
# https://stackoverflow.com/questions/79923/what-and-where-are-the-stack-and-heap
|
|
||||||
# http://superuser.com/questions/220059/what-parameters-has-ulimit
|
|
||||||
limit stacksize unlimited # maximum stack size (kB)
|
|
||||||
|
|
||||||
# disable output in case of scp
|
|
||||||
if ( $?prompt ) then
|
|
||||||
echo ''
|
|
||||||
echo Düsseldorf Advanced Materials Simulation Kit --- DAMASK
|
|
||||||
echo Max-Planck-Institut für Eisenforschung GmbH, Düsseldorf
|
|
||||||
echo https://damask.mpie.de
|
|
||||||
echo
|
|
||||||
echo Using environment with ...
|
|
||||||
echo "DAMASK $DAMASK_ROOT"
|
|
||||||
echo "Grid Solver $SOLVER"
|
|
||||||
if ( $?PETSC_DIR) then
|
|
||||||
echo "PETSc location $PETSC_DIR"
|
|
||||||
endif
|
|
||||||
if ( $?MSC_ROOT) then
|
|
||||||
echo "MSC.Marc/Mentat $MSC_ROOT"
|
|
||||||
endif
|
|
||||||
echo
|
|
||||||
echo "Multithreading DAMASK_NUM_THREADS=$DAMASK_NUM_THREADS"
|
|
||||||
echo `limit datasize`
|
|
||||||
echo `limit stacksize`
|
|
||||||
echo
|
|
||||||
endif
|
|
||||||
|
|
||||||
setenv DAMASK_NUM_THREADS $DAMASK_NUM_THREADS
|
|
||||||
if ( ! $?PYTHONPATH ) then
|
|
||||||
setenv PYTHONPATH $DAMASK_ROOT/python
|
|
||||||
else
|
|
||||||
setenv PYTHONPATH $DAMASK_ROOT/python:$PYTHONPATH
|
|
||||||
endif
|
|
||||||
setenv MSC_ROOT
|
|
||||||
setenv MSC_VERSION
|
|
|
@ -38,7 +38,7 @@ PATH=${DAMASK_ROOT}/bin:$PATH
|
||||||
SOLVER=$(type -p DAMASK_grid || true 2>/dev/null)
|
SOLVER=$(type -p DAMASK_grid || true 2>/dev/null)
|
||||||
[ "x$SOLVER" == "x" ] && SOLVER=$(blink 'Not found!')
|
[ "x$SOLVER" == "x" ] && SOLVER=$(blink 'Not found!')
|
||||||
|
|
||||||
[ "x$DAMASK_NUM_THREADS" == "x" ] && DAMASK_NUM_THREADS=1
|
[ "x$OMP_NUM_THREADS" == "x" ] && OMP_NUM_THREADS=1
|
||||||
|
|
||||||
# currently, there is no information that unlimited stack size causes problems
|
# currently, there is no information that unlimited stack size causes problems
|
||||||
# still, http://software.intel.com/en-us/forums/topic/501500 suggest to fix it
|
# still, http://software.intel.com/en-us/forums/topic/501500 suggest to fix it
|
||||||
|
@ -66,7 +66,7 @@ if [ ! -z "$PS1" ]; then
|
||||||
echo -n "MSC.Marc/Mentat "
|
echo -n "MSC.Marc/Mentat "
|
||||||
[ -d $MSC_ROOT ] && echo $MSC_ROOT || blink $MSC_ROOT
|
[ -d $MSC_ROOT ] && echo $MSC_ROOT || blink $MSC_ROOT
|
||||||
echo
|
echo
|
||||||
echo "Multithreading DAMASK_NUM_THREADS=$DAMASK_NUM_THREADS"
|
echo "Multithreading OMP_NUM_THREADS=$OMP_NUM_THREADS"
|
||||||
echo -n "heap size "
|
echo -n "heap size "
|
||||||
[[ "$(ulimit -d)" == "unlimited" ]] \
|
[[ "$(ulimit -d)" == "unlimited" ]] \
|
||||||
&& echo "unlimited" \
|
&& echo "unlimited" \
|
||||||
|
@ -86,11 +86,13 @@ if [ ! -z "$PS1" ]; then
|
||||||
echo
|
echo
|
||||||
fi
|
fi
|
||||||
|
|
||||||
export DAMASK_NUM_THREADS
|
export OMP_NUM_THREADS
|
||||||
|
export MSC_ROOT
|
||||||
|
export MSC_VERSION
|
||||||
|
export DAMASK_ROOT
|
||||||
export PYTHONPATH=$DAMASK_ROOT/python:$PYTHONPATH
|
export PYTHONPATH=$DAMASK_ROOT/python:$PYTHONPATH
|
||||||
|
|
||||||
for var in BASE STAT SOLVER BRANCH; do
|
for var in BASE STAT SOLVER BRANCH; do
|
||||||
unset "${var}"
|
unset "${var}"
|
||||||
done
|
done
|
||||||
unset "ENV_ROOT"
|
unset "ENV_ROOT"
|
||||||
unset "DAMASK_ROOT"
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ PATH=${DAMASK_ROOT}/bin:$PATH
|
||||||
SOLVER=$(which DAMASK_grid || true 2>/dev/null)
|
SOLVER=$(which DAMASK_grid || true 2>/dev/null)
|
||||||
[[ "x$SOLVER" == "x" ]] && SOLVER=$(blink 'Not found!')
|
[[ "x$SOLVER" == "x" ]] && SOLVER=$(blink 'Not found!')
|
||||||
|
|
||||||
[[ "x$DAMASK_NUM_THREADS" == "x" ]] && DAMASK_NUM_THREADS=1
|
[[ "x$OMP_NUM_THREADS" == "x" ]] && OMP_NUM_THREADS=1
|
||||||
|
|
||||||
# currently, there is no information that unlimited stack size causes problems
|
# currently, there is no information that unlimited stack size causes problems
|
||||||
# still, http://software.intel.com/en-us/forums/topic/501500 suggest to fix it
|
# still, http://software.intel.com/en-us/forums/topic/501500 suggest to fix it
|
||||||
|
@ -60,7 +60,7 @@ if [ ! -z "$PS1" ]; then
|
||||||
echo -n "MSC.Marc/Mentat "
|
echo -n "MSC.Marc/Mentat "
|
||||||
[ -d $MSC_ROOT ] && echo $MSC_ROOT || blink $MSC_ROOT
|
[ -d $MSC_ROOT ] && echo $MSC_ROOT || blink $MSC_ROOT
|
||||||
echo
|
echo
|
||||||
echo "Multithreading DAMASK_NUM_THREADS=$DAMASK_NUM_THREADS"
|
echo "Multithreading OMP_NUM_THREADS=$OMP_NUM_THREADS"
|
||||||
echo -n "heap size "
|
echo -n "heap size "
|
||||||
[[ "$(ulimit -d)" == "unlimited" ]] \
|
[[ "$(ulimit -d)" == "unlimited" ]] \
|
||||||
&& echo "unlimited" \
|
&& echo "unlimited" \
|
||||||
|
@ -80,11 +80,13 @@ if [ ! -z "$PS1" ]; then
|
||||||
echo
|
echo
|
||||||
fi
|
fi
|
||||||
|
|
||||||
export DAMASK_NUM_THREADS
|
export OMP_NUM_THREADS
|
||||||
|
export MSC_ROOT
|
||||||
|
export MSC_VERSION
|
||||||
|
export DAMASK_ROOT
|
||||||
export PYTHONPATH=$DAMASK_ROOT/python:$PYTHONPATH
|
export PYTHONPATH=$DAMASK_ROOT/python:$PYTHONPATH
|
||||||
|
|
||||||
for var in SOLVER BRANCH; do
|
for var in SOLVER BRANCH; do
|
||||||
unset "${var}"
|
unset "${var}"
|
||||||
done
|
done
|
||||||
unset "ENV_ROOT"
|
unset "ENV_ROOT"
|
||||||
unset "DAMASK_ROOT"
|
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
[SX]
|
|
||||||
type isostrain
|
|
||||||
Ngrains 1
|
|
||||||
{./Homogenization_Damage_NonLocal.config}
|
|
||||||
{./Homogenization_Thermal_Conduction.config}
|
|
||||||
{./Homogenization_VacancyFlux_CahnHilliard.config}
|
|
||||||
{./Homogenization_Porosity_PhaseField.config}
|
|
||||||
{./Homogenization_HydrogenFlux_CahnHilliard.config}
|
|
|
@ -1,4 +0,0 @@
|
||||||
[DP_Steel]
|
|
||||||
crystallite 1
|
|
||||||
(constituent) phase 1 texture 1 fraction 0.82
|
|
||||||
(constituent) phase 2 texture 2 fraction 0.18
|
|
|
@ -1,64 +0,0 @@
|
||||||
[TWIP_Steel_FeMnC]
|
|
||||||
|
|
||||||
elasticity hooke
|
|
||||||
plasticity dislotwin
|
|
||||||
|
|
||||||
(output) rho_mob
|
|
||||||
(output) rho_dip
|
|
||||||
(output) gamma_sl
|
|
||||||
(output) lambda_sl
|
|
||||||
(output) tau_pass
|
|
||||||
(output) f_tw
|
|
||||||
(output) lambda_tw
|
|
||||||
(output) tau_hat_tw
|
|
||||||
(output) f_tr
|
|
||||||
|
|
||||||
|
|
||||||
### Material parameters ###
|
|
||||||
lattice_structure fcc
|
|
||||||
C11 175.0e9 # From Music et al. Applied Physics Letters 91, 191904 (2007)
|
|
||||||
C12 115.0e9
|
|
||||||
C44 135.0e9
|
|
||||||
grainsize 2.0e-5 # Average grain size [m]
|
|
||||||
SolidSolutionStrength 1.5e8 # Strength due to elements in solid solution
|
|
||||||
|
|
||||||
### Dislocation glide parameters ###
|
|
||||||
Nslip 12
|
|
||||||
slipburgers 2.56e-10 # Burgers vector of slip system [m]
|
|
||||||
rhoedgedip0 1.0 # Initial dislocation density [m/m**3]
|
|
||||||
rhoedge0 1.0e12 # Initial dislocation density [m/m**3]
|
|
||||||
v0 1.0e-4 # Initial glide velocity [m/s]
|
|
||||||
Qedge 3.7e-19 # Activation energy for dislocation glide [J]
|
|
||||||
p_slip 1.0 # p-exponent in glide velocity
|
|
||||||
q_slip 1.0 # q-exponent in glide velocity
|
|
||||||
|
|
||||||
# hardening of glide
|
|
||||||
CLambdaSlip 10.0 # Adj. parameter controlling dislocation mean free path
|
|
||||||
D0 4.0e-5 # Vacancy diffusion prefactor [m**2/s]
|
|
||||||
Qsd 4.5e-19 # Activation energy for climb [J]
|
|
||||||
Catomicvolume 1.0 # Adj. parameter controlling the atomic volume [in b^3]
|
|
||||||
Cedgedipmindistance 1.0 # Adj. parameter controlling the minimum dipole distance [in b]
|
|
||||||
interactionSlipSlip 0.122 0.122 0.625 0.07 0.137 0.122 # Interaction coefficients (Kubin et al. 2008)
|
|
||||||
|
|
||||||
### Shearband parameters ###
|
|
||||||
shearbandresistance 180e6
|
|
||||||
shearbandvelocity 0e-4 # set to zero to turn shear banding of
|
|
||||||
QedgePerSbSystem 3.7e-19 # Activation energy for shear banding [J]
|
|
||||||
p_shearband 1.0 # p-exponent in glide velocity
|
|
||||||
q_shearband 1.0 # q-exponent in glide velocity
|
|
||||||
|
|
||||||
### Twinning parameters ###
|
|
||||||
Ntwin 12
|
|
||||||
twinburgers 1.47e-10 # Burgers vector of twin system [m]
|
|
||||||
twinsize 5.0e-8 # Twin stack mean thickness [m]
|
|
||||||
L0_twin 442.0 # Length of twin nuclei in Burgers vectors
|
|
||||||
maxtwinfraction 1.0 # Maximum admissible twin volume fraction
|
|
||||||
xc_twin 1.0e-9 # critical distance for formation of twin nucleus
|
|
||||||
VcrossSlip 1.67e-29 # cross slip volume
|
|
||||||
r_twin 10.0 # r-exponent in twin formation probability
|
|
||||||
Cmfptwin 1.0 # Adj. parameter controlling twin mean free path
|
|
||||||
Cthresholdtwin 1.0 # Adj. parameter controlling twin threshold stress
|
|
||||||
interactionSlipTwin 0.0 1.0 1.0 # Dislocation-Twin interaction coefficients
|
|
||||||
interactionTwinTwin 0.0 1.0 # Twin-Twin interaction coefficients
|
|
||||||
SFE_0K -0.0396 # stacking fault energy at zero K; TWIP steel: -0.0526; Cu: -0.0396
|
|
||||||
dSFE_dT 0.0002 # temperature dependance of stacking fault energy
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
TWIP_Steel_FeMnC:
|
||||||
|
lattice: cF
|
||||||
|
mechanics:
|
||||||
|
elasticity: {type: hooke, C_11: 175.0e9, C_12: 115.0e9, C_44: 135.0e9}
|
||||||
|
plasticity:
|
||||||
|
type: dislotwin
|
||||||
|
output: [rho_mob, rho_dip, gamma_sl, Lambda_sl, tau_pass, f_tw, Lambda_tw, tau_hat_tw, f_tr]
|
||||||
|
D: 2.0e-5
|
||||||
|
N_sl: [12]
|
||||||
|
b_sl: [2.56e-10]
|
||||||
|
rho_mob_0: [1.0e12]
|
||||||
|
rho_dip_0: [1.0]
|
||||||
|
v_0: [1.0e4]
|
||||||
|
Q_s: [3.7e-19]
|
||||||
|
p_sl: [1.0]
|
||||||
|
q_sl: [1.0]
|
||||||
|
tau_0: [1.5e8]
|
||||||
|
i_sl: [10.0] # Adj. parameter controlling dislocation mean free path
|
||||||
|
D_0: 4.0e-5 # Vacancy diffusion prefactor / m^2/s
|
||||||
|
D_a: 1.0 # minimum dipole distance / b
|
||||||
|
Q_cl: 4.5e-19 # Activation energy for climb / J
|
||||||
|
h_sl_sl: [0.122, 0.122, 0.625, 0.07, 0.137, 0.122] # Interaction coefficients (Kubin et al. 2008)
|
||||||
|
# shear band parameters
|
||||||
|
xi_sb: 180.0e6
|
||||||
|
Q_sb: 3.7e-19
|
||||||
|
p_sb: 1.0
|
||||||
|
q_sb: 1.0
|
||||||
|
v_sb: 0.0 # set to 0, to turn it off
|
||||||
|
# twinning parameters
|
||||||
|
N_tw: [12]
|
||||||
|
b_tw: [1.47e-10] # Burgers vector length of twin system / b
|
||||||
|
t_tw: [5.0e-8] # Twin stack mean thickness / m
|
||||||
|
L_tw: 442.0 # Length of twin nuclei / b
|
||||||
|
x_c_tw: 1.0e-9 # critical distance for formation of twin nucleus / m
|
||||||
|
V_cs: 1.67e-29 # cross slip volume / m^3
|
||||||
|
p_tw: [10.0] # r-exponent in twin formation probability
|
||||||
|
i_tw: 1.0 # Adj. parameter controlling twin mean free path
|
||||||
|
h_sl_tw: [0.0, 1.0, 1.0] # dislocation-twin interaction coefficients
|
||||||
|
h_tw_tw: [0.0, 1.0] # twin-twin interaction coefficients
|
||||||
|
Gamma_sf_0K: -0.0396 # stacking fault energy / J/m^2 at zero K; TWIP steel: -0.0526; Cu: -0.0396
|
||||||
|
dGamma_sf_dT: 0.0002 # temperature dependence / J/(m^2 K) of stacking fault energy
|
|
@ -1,36 +0,0 @@
|
||||||
[Tungsten]
|
|
||||||
|
|
||||||
elasticity hooke
|
|
||||||
plasticity dislotwin
|
|
||||||
|
|
||||||
### Material parameters ###
|
|
||||||
lattice_structure bcc
|
|
||||||
C11 523.0e9 # From Marinica et al. Journal of Physics: Condensed Matter(2013)
|
|
||||||
C12 202.0e9
|
|
||||||
C44 161.0e9
|
|
||||||
|
|
||||||
grainsize 2.0e-5 # Average grain size [m]
|
|
||||||
SolidSolutionStrength 1.5e8 # Strength due to elements in solid solution
|
|
||||||
|
|
||||||
### Dislocation glide parameters ###
|
|
||||||
#per family
|
|
||||||
Nslip 12
|
|
||||||
slipburgers 2.72e-10 # Burgers vector of slip system [m]
|
|
||||||
rhoedge0 1.0e12 # Initial edge dislocation density [m/m**3]
|
|
||||||
rhoedgedip0 1.0 # Initial edged dipole dislocation density [m/m**3]
|
|
||||||
v0 1.0e-4 # Initial glide velocity [m/s]
|
|
||||||
Qedge 2.725e-19 # Activation energy for dislocation glide [J]
|
|
||||||
p_slip 0.78 # p-exponent in glide velocity
|
|
||||||
q_slip 1.58 # q-exponent in glide velocity
|
|
||||||
tau_peierls 2.03e9 # peierls stress (for bcc)
|
|
||||||
dipoleformationfactor 0 # to have hardening due to dipole formation off
|
|
||||||
|
|
||||||
#hardening
|
|
||||||
CLambdaSlip 10.0 # Adj. parameter controlling dislocation mean free path
|
|
||||||
D0 4.0e-5 # Vacancy diffusion prefactor [m**2/s]
|
|
||||||
Qsd 4.5e-19 # Activation energy for climb [J]
|
|
||||||
Catomicvolume 1.0 # Adj. parameter controlling the atomic volume [in b]
|
|
||||||
Cedgedipmindistance 1.0 # Adj. parameter controlling the minimum dipole distance [in b]
|
|
||||||
interaction_slipslip 1 1 1.4 1.4 1.4 1.4
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
Tungsten:
|
||||||
|
lattice: cI
|
||||||
|
mechanics:
|
||||||
|
elasticity: {type: hooke, C_11: 523.0e9, C_12: 202.0e9, C_44: 161.0e9} # Marinica et al. Journal of Physics: Condensed Matter(2013)
|
||||||
|
plasticity:
|
||||||
|
type: dislotwin
|
||||||
|
D: 2.0e-5 # Average grain size / m
|
||||||
|
N_sl: [12]
|
||||||
|
b_sl: [2.72e-10] # Burgers vector length of slip families / m
|
||||||
|
rho_mob_0: [1.0e12]
|
||||||
|
rho_dip_0: [1.0]
|
||||||
|
v_0: [1.0e4] # Initial glide velocity / m/s
|
||||||
|
Q_s: [2.725e-19] # Activation energy for dislocation glide / J
|
||||||
|
p_sl: [0.78] # p-exponent in glide velocity
|
||||||
|
q_sl: [1.58] # q-exponent in glide velocity
|
||||||
|
tau_0: [1.5e8] # solid solution strength / Pa
|
||||||
|
i_sl: [10.0] # Adj. parameter controlling dislocation mean free path
|
||||||
|
D_0: 4.0e-5 # Vacancy diffusion prefactor / m^2/s
|
||||||
|
D_a: 1.0 # minimum dipole distance / b
|
||||||
|
Q_cl: 4.5e-19 # Activation energy for climb / J
|
||||||
|
h_sl_sl: [1, 1, 1.4, 1.4, 1.4, 1.4]
|
|
@ -1,3 +0,0 @@
|
||||||
hydrogenflux_diffusion11 1.0
|
|
||||||
hydrogenflux_mobility11 1.0
|
|
||||||
hydrogenVolume 1e-28
|
|
|
@ -1,9 +1,9 @@
|
||||||
# Kuo, J. C., Mikrostrukturmechanik von Bikristallen mit Kippkorngrenzen. Shaker-Verlag 2004. http://edoc.mpg.de/204079
|
# Kuo, J. C., Mikrostrukturmechanik von Bikristallen mit Kippkorngrenzen. Shaker-Verlag 2004. http://edoc.mpg.de/204079
|
||||||
Aluminum:
|
Aluminum:
|
||||||
mechanics:
|
|
||||||
lattice: aP
|
lattice: aP
|
||||||
elasticity: {C_11: 110.9e9, C_12: 58.34e9, type: hooke}
|
mechanics:
|
||||||
output: [F, P, Fe, Fp, Lp]
|
output: [F, P, F_e, F_p, L_p]
|
||||||
|
elasticity: {type: hooke, C_11: 110.9e9, C_12: 58.34e9}
|
||||||
plasticity:
|
plasticity:
|
||||||
type: isotropic
|
type: isotropic
|
||||||
output: [xi]
|
output: [xi]
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
# Maiti and Eisenlohr 2018 Scripta Materialia
|
|
||||||
Air:
|
Air:
|
||||||
mechanics:
|
|
||||||
lattice: aP
|
lattice: aP
|
||||||
elasticity: {C_11: 10e9, C_12: 0.0, type: hooke}
|
mechanics:
|
||||||
output: [F, P, Fe, Fp, Lp]
|
output: [F, P, F_e, F_p, L_p]
|
||||||
|
elasticity: {type: hooke, C_11: 1e8, C_12: 1e6}
|
||||||
plasticity:
|
plasticity:
|
||||||
type: isotropic
|
type: isotropic
|
||||||
output: [xi]
|
output: [xi]
|
||||||
|
@ -14,4 +13,4 @@ Air:
|
||||||
M: 3
|
M: 3
|
||||||
h_0: 1e6
|
h_0: 1e6
|
||||||
a: 2
|
a: 2
|
||||||
dilatation: true
|
dilatation: True
|
||||||
|
|
|
@ -1,21 +0,0 @@
|
||||||
[Aluminum]
|
|
||||||
elasticity hooke
|
|
||||||
plasticity phenopowerlaw
|
|
||||||
|
|
||||||
(output) resistance_slip
|
|
||||||
(output) accumulatedshear_slip
|
|
||||||
|
|
||||||
lattice_structure fcc
|
|
||||||
Nslip 12 # per family
|
|
||||||
|
|
||||||
c11 106.75e9
|
|
||||||
c12 60.41e9
|
|
||||||
c44 28.34e9
|
|
||||||
|
|
||||||
gdot0_slip 0.001
|
|
||||||
n_slip 20
|
|
||||||
tau0_slip 31e6 # per family
|
|
||||||
tausat_slip 63e6 # per family
|
|
||||||
a_slip 2.25
|
|
||||||
h0_slipslip 75e6
|
|
||||||
interaction_slipslip 1 1 1.4 1.4 1.4 1.4
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
Aluminum:
|
||||||
|
lattice: cF
|
||||||
|
mechanics:
|
||||||
|
output: [F, P, F_e, F_p, L_p, O]
|
||||||
|
elasticity: {C_11: 106.75e9, C_12: 60.41e9, C_44: 28.34e9, type: hooke}
|
||||||
|
plasticity:
|
||||||
|
N_sl: [12]
|
||||||
|
a_sl: 2.25
|
||||||
|
dot_gamma_0_sl: 0.001
|
||||||
|
h_0_sl_sl: 75e6
|
||||||
|
h_sl_sl: [1, 1, 1.4, 1.4, 1.4, 1.4]
|
||||||
|
n_sl: 20
|
||||||
|
output: [xi_sl, gamma_sl]
|
||||||
|
type: phenopowerlaw
|
||||||
|
xi_0_sl: [31e6]
|
||||||
|
xi_inf_sl: [63e6]
|
|
@ -2,8 +2,8 @@
|
||||||
# Tasan et.al. 2015 International Journal of Plasticity
|
# Tasan et.al. 2015 International Journal of Plasticity
|
||||||
# Diehl et.al. 2015 Meccanica
|
# Diehl et.al. 2015 Meccanica
|
||||||
Ferrite:
|
Ferrite:
|
||||||
mechanics:
|
|
||||||
lattice: cI
|
lattice: cI
|
||||||
|
mechanics:
|
||||||
elasticity: {C_11: 233.3e9, C_12: 135.5e9, C_44: 118.0e9, type: hooke}
|
elasticity: {C_11: 233.3e9, C_12: 135.5e9, C_44: 118.0e9, type: hooke}
|
||||||
plasticity:
|
plasticity:
|
||||||
N_sl: [12, 12]
|
N_sl: [12, 12]
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
# Tasan et.al. 2015 International Journal of Plasticity
|
# Tasan et.al. 2015 International Journal of Plasticity
|
||||||
# Diehl et.al. 2015 Meccanica
|
# Diehl et.al. 2015 Meccanica
|
||||||
Martensite:
|
Martensite:
|
||||||
mechanics:
|
|
||||||
lattice: cI
|
lattice: cI
|
||||||
|
mechanics:
|
||||||
elasticity: {C_11: 417.4e9, C_12: 242.4e9, C_44: 211.1e9, type: hooke}
|
elasticity: {C_11: 417.4e9, C_12: 242.4e9, C_44: 211.1e9, type: hooke}
|
||||||
plasticity:
|
plasticity:
|
||||||
N_sl: [12, 12]
|
N_sl: [12, 12]
|
||||||
|
|
|
@ -1,27 +0,0 @@
|
||||||
# parameters fitted by D. Ma to:
|
|
||||||
# I. Kovács, G. Vörös
|
|
||||||
# On the mathematical description of the tensile stress-strain curves of polycrystalline face centered cubic metals
|
|
||||||
# International Journal of Plasticity, Volume 12, Issue 1, 1996, Pages 35–43
|
|
||||||
# DOI: 10.1016/S0749-6419(95)00043-7
|
|
||||||
|
|
||||||
[gold_phenopowerlaw]
|
|
||||||
elasticity hooke
|
|
||||||
plasticity phenopowerlaw
|
|
||||||
|
|
||||||
(output) resistance_slip
|
|
||||||
|
|
||||||
lattice_structure fcc
|
|
||||||
Nslip 12 # per family
|
|
||||||
|
|
||||||
c11 191.0e9
|
|
||||||
c12 162.0e9
|
|
||||||
c44 42.20e9
|
|
||||||
|
|
||||||
gdot0_slip 0.001
|
|
||||||
n_slip 83.3
|
|
||||||
tau0_slip 26.25e6 # per family
|
|
||||||
tausat_slip 53.00e6 # per family
|
|
||||||
a_slip 1.0
|
|
||||||
h0_slipslip 75e6
|
|
||||||
interaction_slipslip 1 1 1.4 1.4 1.4 1.4
|
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
# parameters fitted by D. Ma to:
|
||||||
|
# On the mathematical description of the tensile stress-strain curves of polycrystalline face centered cubic metals
|
||||||
|
# International Journal of Plasticity, Volume 12, Issue 1, 1996, Pages 35-43
|
||||||
|
# DOI: 10.1016/S0749-6419(95)00043-7
|
||||||
|
|
||||||
|
Gold:
|
||||||
|
lattice: cF
|
||||||
|
mechanics:
|
||||||
|
output: [F, P, F_e, F_p, L_p, O]
|
||||||
|
elasticity: {type: hooke, C_11: 191e9, C_12: 162e9, C_44: 42.2e9}
|
||||||
|
plasticity:
|
||||||
|
type: phenopowerlaw
|
||||||
|
output: [xi_sl]
|
||||||
|
N_sl: [12]
|
||||||
|
n_sl: 83
|
||||||
|
dot_gamma_0_sl: 0.001
|
||||||
|
h_0_sl_sl: 75e6
|
||||||
|
h_sl_sl: [1, 1, 1.4, 1.4, 1.4, 1.4]
|
||||||
|
a_sl: 1.0
|
||||||
|
xi_0_sl: [26e6]
|
||||||
|
xi_inf_sl: [53e6]
|
|
@ -1,56 +0,0 @@
|
||||||
#-------------------#
|
|
||||||
<phase>
|
|
||||||
#-------------------#
|
|
||||||
/echo/
|
|
||||||
[Mg]
|
|
||||||
plasticity phenopowerlaw
|
|
||||||
elasticity hooke
|
|
||||||
|
|
||||||
(output) resistance_slip
|
|
||||||
(output) resistance_twin
|
|
||||||
|
|
||||||
lattice_structure hex
|
|
||||||
c/a 1.62350 # from Tromans 2011, Elastic Anisotropy of HCP Metal Crystals and Polycrystals
|
|
||||||
c11 59.3e9 # - " -
|
|
||||||
c33 61.5e9 # - " -
|
|
||||||
c44 16.4e9 # - " -
|
|
||||||
c12 25.7e9 # - " -
|
|
||||||
c13 21.4e9 # - " -
|
|
||||||
|
|
||||||
# basal prism prism pyr(a) pyr(c+a) pyr(c+a)
|
|
||||||
Nslip 3 3 0 6 0 6 # from Agnew et al 2006, Validating a polycrystal model for the elastoplastic response of mg alloy AZ32 using in situ neutron diffraction
|
|
||||||
# T1 C1 T2 C2
|
|
||||||
Ntwin 6 0 0 6 # - " -
|
|
||||||
# basal prism prism pyr(a) pyr(c+a) pyr(c+a)
|
|
||||||
tau0_slip 10.0e6 55.0e6 0 60.0e6 0.0 60.0e6 # - " - table 1, pyr(a) set to pyr(c+a)
|
|
||||||
tausat_slip 40.0e6 135.0e6 0 150.0e6 0.0 150.0e6 # - " - table 1, pyr(a) set to pyr(c+a)
|
|
||||||
# T1 C1 T2 C2
|
|
||||||
tau0_twin 40e6 0.0 0.0 60.0e6 # - " - table 1, compressive twin guessed by Steffi, tensile twin modified to match experimental results
|
|
||||||
|
|
||||||
h0_twintwin 50.0e6 # - " - table 1, same range as theta_0
|
|
||||||
h0_slipslip 500.0e6 # - " - table 1, same range as theta_0
|
|
||||||
h0_twinslip 150.0e6 # guessing
|
|
||||||
|
|
||||||
interaction_slipslip 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 # just guessing
|
|
||||||
interaction_twintwin 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 # - " -
|
|
||||||
interaction_sliptwin 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 # - " -
|
|
||||||
interaction_twinslip 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 # - " -
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
####################################################
|
|
||||||
# open for discussion
|
|
||||||
####################################################
|
|
||||||
n_twin 20
|
|
||||||
n_slip 20
|
|
||||||
|
|
||||||
gdot0_twin 0.001
|
|
||||||
gdot0_slip 0.001
|
|
||||||
|
|
||||||
twin_b 0
|
|
||||||
twin_c 0
|
|
||||||
twin_d 20
|
|
||||||
twin_e 20
|
|
||||||
|
|
||||||
a_slip 2.25
|
|
||||||
s_pr 10.0 # push-up factor for slip saturation due to twinning
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
# Tromans 2011, Elastic Anisotropy of HCP Metal Crystals and Polycrystals
|
||||||
|
Magnesium:
|
||||||
|
lattice: hP
|
||||||
|
c/a: 1.62350
|
||||||
|
mechanics:
|
||||||
|
output: [F, P, F_e, F_p, L_p, O]
|
||||||
|
elasticity: {C_11: 59.3e9, C_12: 25.7e9, C_13: 21.4e9, C_33: 61.5e9, C_44: 16.4e9, type: hooke}
|
||||||
|
plasticity:
|
||||||
|
N_sl: [3, 3, 0, 6, 0, 6]
|
||||||
|
N_tw: [6, 0, 0, 6]
|
||||||
|
h_0_tw_tw: 50.0e6
|
||||||
|
h_0_sl_sl: 500.0e6
|
||||||
|
h_0_tw_sl: 150.0e6
|
||||||
|
h_sl_sl: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
|
||||||
|
h_tw_tw: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
|
||||||
|
h_sl_tw: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
|
||||||
|
h_tw_sl: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
|
||||||
|
output: [xi_sl, xi_tw]
|
||||||
|
type: phenopowerlaw
|
||||||
|
xi_0_sl: [10.0e6, 55.0e6, 0, 60.0e6, 0.0, 60.0e6]
|
||||||
|
xi_inf_sl: [40.0e6, 135.0e6, 0, 150.0e6, 0.0, 150.0e6]
|
||||||
|
xi_0_tw: [40e6, 0.0, 0.0, 60.0e6]
|
||||||
|
####################################################
|
||||||
|
# open for discussion
|
||||||
|
####################################################
|
||||||
|
a_sl: 2.25
|
||||||
|
dot_gamma_0_sl: 0.001
|
||||||
|
dot_gamma_0_tw: 0.001
|
||||||
|
n_sl: 20
|
||||||
|
n_tw: 20
|
||||||
|
f_sl_sat_tw: 10.0
|
|
@ -1,23 +0,0 @@
|
||||||
[cpTi-alpha]
|
|
||||||
plasticity phenopowerlaw
|
|
||||||
elasticity hooke
|
|
||||||
|
|
||||||
lattice_structure hex
|
|
||||||
covera_ratio 1.587
|
|
||||||
|
|
||||||
# M. Levy, Handbook of Elastic Properties of Solids, Liquids, and Gases (2001)
|
|
||||||
c11 160.0e9
|
|
||||||
c12 90.0e9
|
|
||||||
c13 66.0e9
|
|
||||||
c33 181.7e9
|
|
||||||
c44 46.5e9
|
|
||||||
# C. Zambaldi, "Orientation informed nanoindentation of a-titanium: Indentation pileup in hexagonal metals deforming by prismatic slip", J. Mater. Res., Vol. 27, No. 1, Jan 14, 2012
|
|
||||||
gdot0_slip 0.001
|
|
||||||
n_slip 20
|
|
||||||
nslip 3 3 0 6
|
|
||||||
tau0_slip 349.3e6 150e6 0 1107.9e6
|
|
||||||
tausat_slip 568.6e6 1502.2e6 0 3420.1e6
|
|
||||||
a_slip 2
|
|
||||||
h0_slipslip 15e6
|
|
||||||
|
|
||||||
interaction_slipslip 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
# M. Levy, Handbook of Elastic Properties of Solids, Liquids, and Gases (2001)
|
||||||
|
# C. Zambaldi, "Orientation informed nanoindentation of a-titanium: Indentation pileup in hexagonal metals deforming by prismatic slip", J. Mater. Res., Vol. 27, No. 1, Jan 14, 2012
|
||||||
|
# Better use values from L. Wang, Z. Zheng, H. Phukan, P. Kenesei, J.-S. Park, J. Lind, R.M. Suter, T.R. Bieler, Direct measurement of critical resolved shear stress of prismatic and basal slip in polycrystalline Ti using high energy X-ray diffraction microscopy, Acta Mater 2017
|
||||||
|
cpTi:
|
||||||
|
lattice: hP
|
||||||
|
c/a: 1.587
|
||||||
|
mechanics:
|
||||||
|
output: [F, P, F_e, F_p, L_p, O]
|
||||||
|
elasticity: {C_11: 160.0e9, C_12: 90.0e9, C_13: 66.0e9, C_33: 181.7e9, C_44: 46.5e9, type: hooke}
|
||||||
|
plasticity:
|
||||||
|
N_sl: [3, 3, 0, 6, 12]
|
||||||
|
a_sl: 2.0
|
||||||
|
dot_gamma_0_sl: 0.001
|
||||||
|
h_0_sl_sl: 200e6
|
||||||
|
h_sl_sl: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
|
||||||
|
n_sl: 20
|
||||||
|
output: [gamma_sl]
|
||||||
|
type: phenopowerlaw
|
||||||
|
xi_0_sl: [0.15e9, 0.09e9, 0, 0.20e9, 0.25e9]
|
||||||
|
xi_inf_sl: [0.24e9, 0.5e9, 0, 0.6e9, 0.8e9]
|
|
@ -1,2 +0,0 @@
|
||||||
[001]
|
|
||||||
(gauss) phi1 0.000 Phi 0.000 phi2 0.000
|
|
|
@ -1,2 +0,0 @@
|
||||||
[101]
|
|
||||||
(gauss) phi1 0.000 Phi 45.000 phi2 90.000
|
|
|
@ -1,2 +0,0 @@
|
||||||
[111]
|
|
||||||
(gauss) phi1 0.000 Phi 54.7356 phi2 45.000
|
|
|
@ -1,2 +0,0 @@
|
||||||
[123]
|
|
||||||
(gauss) phi1 209.805 Phi 29.206 phi2 63.435
|
|
|
@ -1,20 +0,0 @@
|
||||||
# The material.config file needs to specify five parts:
|
|
||||||
# homogenization, microstructure, crystallite, phase, and texture.
|
|
||||||
# You can either put the full text in here or include suited separate files
|
|
||||||
|
|
||||||
<homogenization>
|
|
||||||
{./Homogenization_Isostrain_SX.config}
|
|
||||||
|
|
||||||
<microstructure>
|
|
||||||
[one_only]
|
|
||||||
crystallite 1
|
|
||||||
(constituent) phase 1 texture 1 fraction 1.0
|
|
||||||
|
|
||||||
<crystallite>
|
|
||||||
{./Crystallite_All.config}
|
|
||||||
|
|
||||||
<phase>
|
|
||||||
{./Phase_Phenopowerlaw_Aluminum.config}
|
|
||||||
|
|
||||||
<texture>
|
|
||||||
{./Texture_Gauss_001.config}
|
|
|
@ -1,9 +0,0 @@
|
||||||
step:
|
|
||||||
- mechanics:
|
|
||||||
dot_F: [0, 0, 0,
|
|
||||||
1e-3, 0, 0,
|
|
||||||
0, 0, 0]
|
|
||||||
discretization:
|
|
||||||
t: 60
|
|
||||||
N: 120
|
|
||||||
f_out: 20
|
|
|
@ -1,10 +0,0 @@
|
||||||
---
|
|
||||||
step:
|
|
||||||
- mechanics:
|
|
||||||
dot_F: [0, 0, 1e-3,
|
|
||||||
0, 0, 0,
|
|
||||||
0, 0, 0]
|
|
||||||
discretization:
|
|
||||||
t: 60
|
|
||||||
N: 120
|
|
||||||
f_out: 20
|
|
|
@ -1,25 +0,0 @@
|
||||||
---
|
|
||||||
|
|
||||||
step:
|
|
||||||
- mechanics:
|
|
||||||
dot_F: [1.0e-3, 0, 0,
|
|
||||||
0, x, 0,
|
|
||||||
0, 0, x]
|
|
||||||
P: [x, x, x,
|
|
||||||
x, 0, x,
|
|
||||||
x, x, 0]
|
|
||||||
discretization:
|
|
||||||
t: 10
|
|
||||||
N: 40
|
|
||||||
f_out: 4
|
|
||||||
- mechanics:
|
|
||||||
dot_F: [1.0e-3, 0, 0,
|
|
||||||
0, x, 0,
|
|
||||||
0, 0, x]
|
|
||||||
P: [x, x, x,
|
|
||||||
x, 0, x,
|
|
||||||
x, x, 0]
|
|
||||||
discretization:
|
|
||||||
t: 60
|
|
||||||
N: 60
|
|
||||||
f_out: 4
|
|
|
@ -2,108 +2,108 @@
|
||||||
homogenization:
|
homogenization:
|
||||||
SX:
|
SX:
|
||||||
N_constituents: 1
|
N_constituents: 1
|
||||||
mechanics: {type: none}
|
mechanics: {type: pass}
|
||||||
|
|
||||||
material:
|
material:
|
||||||
- homogenization: SX
|
- homogenization: SX
|
||||||
constituents:
|
constituents:
|
||||||
- phase: Aluminum
|
- phase: Aluminum
|
||||||
fraction: 1.0
|
v: 1.0
|
||||||
O: [1.0, 0.0, 0.0, 0.0]
|
O: [1.0, 0.0, 0.0, 0.0]
|
||||||
- homogenization: SX
|
- homogenization: SX
|
||||||
constituents:
|
constituents:
|
||||||
- phase: Aluminum
|
- phase: Aluminum
|
||||||
fraction: 1.0
|
v: 1.0
|
||||||
O: [0.7936696712125002, -0.28765777461664166, -0.3436487135089419, 0.4113964260949434]
|
O: [0.7936696712125002, -0.28765777461664166, -0.3436487135089419, 0.4113964260949434]
|
||||||
- homogenization: SX
|
- homogenization: SX
|
||||||
constituents:
|
constituents:
|
||||||
- phase: Aluminum
|
- phase: Aluminum
|
||||||
fraction: 1.0
|
v: 1.0
|
||||||
O: [0.3986143167493579, -0.7014883552495493, 0.2154871765709027, 0.5500781677772945]
|
O: [0.3986143167493579, -0.7014883552495493, 0.2154871765709027, 0.5500781677772945]
|
||||||
- homogenization: SX
|
- homogenization: SX
|
||||||
constituents:
|
constituents:
|
||||||
- phase: Aluminum
|
- phase: Aluminum
|
||||||
fraction: 1.0
|
v: 1.0
|
||||||
O: [0.28645844315788244, -0.022571491243423537, -0.467933059311115, -0.8357456192708106]
|
O: [0.28645844315788244, -0.022571491243423537, -0.467933059311115, -0.8357456192708106]
|
||||||
- homogenization: SX
|
- homogenization: SX
|
||||||
constituents:
|
constituents:
|
||||||
- phase: Aluminum
|
- phase: Aluminum
|
||||||
fraction: 1.0
|
v: 1.0
|
||||||
O: [0.33012772942625784, -0.6781865350268957, 0.6494525351030648, 0.09638521992649676]
|
O: [0.33012772942625784, -0.6781865350268957, 0.6494525351030648, 0.09638521992649676]
|
||||||
- homogenization: SX
|
- homogenization: SX
|
||||||
constituents:
|
constituents:
|
||||||
- phase: Aluminum
|
- phase: Aluminum
|
||||||
fraction: 1.0
|
v: 1.0
|
||||||
O: [0.43596817439583935, -0.5982537129781701, 0.046599032277502436, 0.6707106499919265]
|
O: [0.43596817439583935, -0.5982537129781701, 0.046599032277502436, 0.6707106499919265]
|
||||||
- homogenization: SX
|
- homogenization: SX
|
||||||
constituents:
|
constituents:
|
||||||
- phase: Aluminum
|
- phase: Aluminum
|
||||||
fraction: 1.0
|
v: 1.0
|
||||||
O: [0.169734823419553, -0.699615227367322, -0.6059581215838098, -0.33844257746495854]
|
O: [0.169734823419553, -0.699615227367322, -0.6059581215838098, -0.33844257746495854]
|
||||||
- homogenization: SX
|
- homogenization: SX
|
||||||
constituents:
|
constituents:
|
||||||
- phase: Aluminum
|
- phase: Aluminum
|
||||||
fraction: 1.0
|
v: 1.0
|
||||||
O: [0.9698864809294915, 0.1729052643205874, -0.15948307917616958, 0.06315956884687175]
|
O: [0.9698864809294915, 0.1729052643205874, -0.15948307917616958, 0.06315956884687175]
|
||||||
- homogenization: SX
|
- homogenization: SX
|
||||||
constituents:
|
constituents:
|
||||||
- phase: Aluminum
|
- phase: Aluminum
|
||||||
fraction: 1.0
|
v: 1.0
|
||||||
O: [0.46205660912967883, 0.3105054068891252, -0.617849551030653, 0.555294529545738]
|
O: [0.46205660912967883, 0.3105054068891252, -0.617849551030653, 0.555294529545738]
|
||||||
- homogenization: SX
|
- homogenization: SX
|
||||||
constituents:
|
constituents:
|
||||||
- phase: Aluminum
|
- phase: Aluminum
|
||||||
fraction: 1.0
|
v: 1.0
|
||||||
O: [0.4512443497461787, -0.7636045534540555, -0.04739348426715133, -0.45939142396805815]
|
O: [0.4512443497461787, -0.7636045534540555, -0.04739348426715133, -0.45939142396805815]
|
||||||
- homogenization: SX
|
- homogenization: SX
|
||||||
constituents:
|
constituents:
|
||||||
- phase: Aluminum
|
- phase: Aluminum
|
||||||
fraction: 1.0
|
v: 1.0
|
||||||
O: [0.2161856212656443, -0.6581450184826598, -0.5498086209601588, 0.4667112513346289]
|
O: [0.2161856212656443, -0.6581450184826598, -0.5498086209601588, 0.4667112513346289]
|
||||||
- homogenization: SX
|
- homogenization: SX
|
||||||
constituents:
|
constituents:
|
||||||
- phase: Aluminum
|
- phase: Aluminum
|
||||||
fraction: 1.0
|
v: 1.0
|
||||||
O: [0.8753220715350803, -0.4561599367657419, -0.13298279533852678, -0.08969369719975541]
|
O: [0.8753220715350803, -0.4561599367657419, -0.13298279533852678, -0.08969369719975541]
|
||||||
- homogenization: SX
|
- homogenization: SX
|
||||||
constituents:
|
constituents:
|
||||||
- phase: Aluminum
|
- phase: Aluminum
|
||||||
fraction: 1.0
|
v: 1.0
|
||||||
O: [0.11908260752431069, 0.18266024809834172, -0.7144822594012615, -0.664807992845101]
|
O: [0.11908260752431069, 0.18266024809834172, -0.7144822594012615, -0.664807992845101]
|
||||||
- homogenization: SX
|
- homogenization: SX
|
||||||
constituents:
|
constituents:
|
||||||
- phase: Aluminum
|
- phase: Aluminum
|
||||||
fraction: 1.0
|
v: 1.0
|
||||||
O: [0.751104669484278, 0.5585633382623958, -0.34579336397009175, 0.06538900566860861]
|
O: [0.751104669484278, 0.5585633382623958, -0.34579336397009175, 0.06538900566860861]
|
||||||
- homogenization: SX
|
- homogenization: SX
|
||||||
constituents:
|
constituents:
|
||||||
- phase: Aluminum
|
- phase: Aluminum
|
||||||
fraction: 1.0
|
v: 1.0
|
||||||
O: [0.08740438971703973, 0.8991264096610437, -0.4156704205935976, 0.10559485570696363]
|
O: [0.08740438971703973, 0.8991264096610437, -0.4156704205935976, 0.10559485570696363]
|
||||||
- homogenization: SX
|
- homogenization: SX
|
||||||
constituents:
|
constituents:
|
||||||
- phase: Aluminum
|
- phase: Aluminum
|
||||||
fraction: 1.0
|
v: 1.0
|
||||||
O: [0.5584325870096193, 0.6016408353068798, -0.14280340445801173, 0.5529814994483859]
|
O: [0.5584325870096193, 0.6016408353068798, -0.14280340445801173, 0.5529814994483859]
|
||||||
- homogenization: SX
|
- homogenization: SX
|
||||||
constituents:
|
constituents:
|
||||||
- phase: Aluminum
|
- phase: Aluminum
|
||||||
fraction: 1.0
|
v: 1.0
|
||||||
O: [0.4052725440888093, 0.25253073423599154, 0.5693263597910454, -0.669215876471182]
|
O: [0.4052725440888093, 0.25253073423599154, 0.5693263597910454, -0.669215876471182]
|
||||||
- homogenization: SX
|
- homogenization: SX
|
||||||
constituents:
|
constituents:
|
||||||
- phase: Aluminum
|
- phase: Aluminum
|
||||||
fraction: 1.0
|
v: 1.0
|
||||||
O: [0.7570164606888676, 0.15265448024694664, -0.5998021466848317, 0.20942796551297105]
|
O: [0.7570164606888676, 0.15265448024694664, -0.5998021466848317, 0.20942796551297105]
|
||||||
- homogenization: SX
|
- homogenization: SX
|
||||||
constituents:
|
constituents:
|
||||||
- phase: Aluminum
|
- phase: Aluminum
|
||||||
fraction: 1.0
|
v: 1.0
|
||||||
O: [0.6987659297138081, -0.132172211261028, -0.19693254724422338, 0.6748883269678543]
|
O: [0.6987659297138081, -0.132172211261028, -0.19693254724422338, 0.6748883269678543]
|
||||||
- homogenization: SX
|
- homogenization: SX
|
||||||
constituents:
|
constituents:
|
||||||
- phase: Aluminum
|
- phase: Aluminum
|
||||||
fraction: 1.0
|
v: 1.0
|
||||||
O: [0.7729330445886478, 0.21682179052722322, -0.5207379472917645, 0.2905078484066341]
|
O: [0.7729330445886478, 0.21682179052722322, -0.5207379472917645, 0.2905078484066341]
|
||||||
|
|
||||||
phase:
|
phase:
|
|
@ -0,0 +1,15 @@
|
||||||
|
---
|
||||||
|
|
||||||
|
solver:
|
||||||
|
mechanical: spectral_basic
|
||||||
|
|
||||||
|
loadstep:
|
||||||
|
- boundary_conditions:
|
||||||
|
mechanical:
|
||||||
|
dot_F: [0, 0, 0,
|
||||||
|
1e-3, 0, 0,
|
||||||
|
0, 0, 0]
|
||||||
|
discretization:
|
||||||
|
t: 60
|
||||||
|
N: 120
|
||||||
|
f_out: 20
|
|
@ -0,0 +1,15 @@
|
||||||
|
---
|
||||||
|
|
||||||
|
solver:
|
||||||
|
mechanical: spectral_basic
|
||||||
|
|
||||||
|
loadstep:
|
||||||
|
- boundary_conditions:
|
||||||
|
mechanical:
|
||||||
|
dot_F: [0, 0, 1e-3,
|
||||||
|
0, 0, 0,
|
||||||
|
0, 0, 0]
|
||||||
|
discretization:
|
||||||
|
t: 60
|
||||||
|
N: 120
|
||||||
|
f_out: 20
|
|
@ -0,0 +1,30 @@
|
||||||
|
---
|
||||||
|
|
||||||
|
solver:
|
||||||
|
mechanical: spectral_basic
|
||||||
|
|
||||||
|
loadstep:
|
||||||
|
- boundary_conditions:
|
||||||
|
mechanical:
|
||||||
|
dot_F: [1.0e-3, 0, 0,
|
||||||
|
0, x, 0,
|
||||||
|
0, 0, x]
|
||||||
|
P: [x, x, x,
|
||||||
|
x, 0, x,
|
||||||
|
x, x, 0]
|
||||||
|
discretization:
|
||||||
|
t: 10
|
||||||
|
N: 40
|
||||||
|
f_out: 4
|
||||||
|
- boundary_conditions:
|
||||||
|
mechanical:
|
||||||
|
dot_F: [1.0e-3, 0, 0,
|
||||||
|
0, x, 0,
|
||||||
|
0, 0, x]
|
||||||
|
P: [x, x, x,
|
||||||
|
x, 0, x,
|
||||||
|
x, x, 0]
|
||||||
|
discretization:
|
||||||
|
t: 60
|
||||||
|
N: 60
|
||||||
|
f_out: 4
|
|
@ -5,13 +5,9 @@ import glob
|
||||||
import argparse
|
import argparse
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
import damask
|
msc_version = os.environ['MSC_VERSION']
|
||||||
|
msc_root = Path(os.environ['MSC_ROOT'])
|
||||||
msc_version = float(damask.environment.options['MSC_VERSION'])
|
damask_root = Path(os.environ['DAMASK_ROOT'])
|
||||||
if int(msc_version) == msc_version:
|
|
||||||
msc_version = int(msc_version)
|
|
||||||
msc_root = Path(damask.environment.options['MSC_ROOT'])
|
|
||||||
damask_root = damask.environment.root_dir
|
|
||||||
|
|
||||||
parser = argparse.ArgumentParser(
|
parser = argparse.ArgumentParser(
|
||||||
description='Apply DAMASK modification to MSC.Marc/Mentat',
|
description='Apply DAMASK modification to MSC.Marc/Mentat',
|
||||||
|
@ -24,7 +20,7 @@ def copy_and_replace(in_file,dst):
|
||||||
with open(in_file) as f:
|
with open(in_file) as f:
|
||||||
content = f.read()
|
content = f.read()
|
||||||
content = content.replace('%INSTALLDIR%',str(msc_root))
|
content = content.replace('%INSTALLDIR%',str(msc_root))
|
||||||
content = content.replace('%VERSION%',str(msc_version))
|
content = content.replace('%VERSION%', msc_version)
|
||||||
content = content.replace('%EDITOR%', parser.parse_args().editor)
|
content = content.replace('%EDITOR%', parser.parse_args().editor)
|
||||||
with open(dst/Path(in_file).name,'w') as f:
|
with open(dst/Path(in_file).name,'w') as f:
|
||||||
f.write(content)
|
f.write(content)
|
||||||
|
@ -53,8 +49,8 @@ for in_file in glob.glob(str(src/'job_run.ms')):
|
||||||
|
|
||||||
print('compiling Mentat menu binaries...')
|
print('compiling Mentat menu binaries...')
|
||||||
|
|
||||||
executable = str(msc_root/f'mentat{msc_version}/bin/mentat')
|
executable = msc_root/f'mentat{msc_version}/bin/mentat'
|
||||||
menu_file = str(msc_root/f'mentat{msc_version}/menus/linux64/main.msb')
|
menu_file = msc_root/f'mentat{msc_version}/menus/linux64/main.msb'
|
||||||
os.system(f'xvfb-run {executable} -compile {menu_file}')
|
os.system(f'xvfb-run {executable} -compile {menu_file}')
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -3,11 +3,9 @@
|
||||||
# Makes postprocessing routines accessible from everywhere.
|
# Makes postprocessing routines accessible from everywhere.
|
||||||
import sys
|
import sys
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
import os
|
||||||
|
|
||||||
import damask
|
bin_dir = Path(os.environ['DAMASK_ROOT'])/'bin'
|
||||||
|
|
||||||
env = damask.Environment()
|
|
||||||
bin_dir = env.root_dir/Path('bin')
|
|
||||||
|
|
||||||
if not bin_dir.exists():
|
if not bin_dir.exists():
|
||||||
bin_dir.mkdir()
|
bin_dir.mkdir()
|
||||||
|
@ -15,7 +13,7 @@ if not bin_dir.exists():
|
||||||
|
|
||||||
sys.stdout.write('\nsymbolic linking...\n')
|
sys.stdout.write('\nsymbolic linking...\n')
|
||||||
for sub_dir in ['pre','post']:
|
for sub_dir in ['pre','post']:
|
||||||
the_dir = env.root_dir/Path('processing')/Path(sub_dir)
|
the_dir = Path(os.environ['DAMASK_ROOT'])/'processing'/sub_dir
|
||||||
|
|
||||||
for the_file in the_dir.glob('*.py'):
|
for the_file in the_dir.glob('*.py'):
|
||||||
src = the_dir/the_file
|
src = the_dir/the_file
|
||||||
|
|
|
@ -41,15 +41,15 @@ for filename in options.filenames:
|
||||||
table = damask.Table(np.ones(np.product(results.cells),dtype=int)*int(inc[3:]),{'inc':(1,)})\
|
table = damask.Table(np.ones(np.product(results.cells),dtype=int)*int(inc[3:]),{'inc':(1,)})\
|
||||||
.add('pos',coords.reshape(-1,3))
|
.add('pos',coords.reshape(-1,3))
|
||||||
|
|
||||||
results.pick('homogenizations',False)
|
results.view('homogenizations',False)
|
||||||
results.pick('phases',True)
|
results.view('phases',True)
|
||||||
for label in options.con:
|
for label in options.con:
|
||||||
x = results.get_dataset_location(label)
|
x = results.get_dataset_location(label)
|
||||||
if len(x) != 0:
|
if len(x) != 0:
|
||||||
table = table.add(label,results.read_dataset(x,0,plain=True).reshape(results.cells.prod(),-1))
|
table = table.add(label,results.read_dataset(x,0,plain=True).reshape(results.cells.prod(),-1))
|
||||||
|
|
||||||
results.pick('phases',False)
|
results.view('phases',False)
|
||||||
results.pick('homogenizations',True)
|
results.view('homogenizations',True)
|
||||||
for label in options.mat:
|
for label in options.mat:
|
||||||
x = results.get_dataset_location(label)
|
x = results.get_dataset_location(label)
|
||||||
if len(x) != 0:
|
if len(x) != 0:
|
||||||
|
|
|
@ -16,8 +16,6 @@ with open(_Path(__file__).parent/_Path('VERSION')) as _f:
|
||||||
__version__ = version
|
__version__ = version
|
||||||
|
|
||||||
# make classes directly accessible as damask.Class
|
# make classes directly accessible as damask.Class
|
||||||
from ._environment import Environment as _ # noqa
|
|
||||||
environment = _()
|
|
||||||
from . import util # noqa
|
from . import util # noqa
|
||||||
from . import seeds # noqa
|
from . import seeds # noqa
|
||||||
from . import tensor # noqa
|
from . import tensor # noqa
|
||||||
|
@ -38,7 +36,6 @@ from ._result import Result # noqa
|
||||||
|
|
||||||
|
|
||||||
# deprecated
|
# deprecated
|
||||||
Environment = _
|
|
||||||
from ._asciitable import ASCIItable # noqa
|
from ._asciitable import ASCIItable # noqa
|
||||||
from ._test import Test # noqa
|
from ._test import Test # noqa
|
||||||
from .util import extendableOption # noqa
|
from .util import extendableOption # noqa
|
||||||
|
|
|
@ -223,25 +223,46 @@ class Colormap(mpl.colors.ListedColormap):
|
||||||
return Colormap(np.array(rev.colors),rev.name[:-4] if rev.name.endswith('_r_r') else rev.name)
|
return Colormap(np.array(rev.colors),rev.name[:-4] if rev.name.endswith('_r_r') else rev.name)
|
||||||
|
|
||||||
|
|
||||||
|
def _get_file_handle(self,fname,extension):
|
||||||
|
"""
|
||||||
|
Provide file handle.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
fname : file, str, pathlib.Path, or None
|
||||||
|
Filename or filehandle, will be name of the colormap+extension if None.
|
||||||
|
|
||||||
|
extension: str
|
||||||
|
Extension of the filename.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
f
|
||||||
|
File handle
|
||||||
|
|
||||||
|
"""
|
||||||
|
if fname is None:
|
||||||
|
fhandle = open(self.name.replace(' ','_')+'.'+extension,'w',newline='\n')
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
fhandle = open(fname,'w',newline='\n')
|
||||||
|
except TypeError:
|
||||||
|
fhandle = fname
|
||||||
|
|
||||||
|
return fhandle
|
||||||
|
|
||||||
|
|
||||||
def save_paraview(self,fname=None):
|
def save_paraview(self,fname=None):
|
||||||
"""
|
"""
|
||||||
Save as JSON file for use in Paraview.
|
Save as JSON file for use in Paraview.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
fname : file, str, or pathlib.Path, optional.
|
fname : file, str, or pathlib.Path, optional
|
||||||
Filename to store results. If not given, the filename will
|
Filename to store results. If not given, the filename will
|
||||||
consist of the name of the colormap and extension '.json'.
|
consist of the name of the colormap and extension '.json'.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if fname is None:
|
|
||||||
fhandle = None
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
fhandle = open(fname,'w')
|
|
||||||
except TypeError:
|
|
||||||
fhandle = fname
|
|
||||||
|
|
||||||
colors = []
|
colors = []
|
||||||
for i,c in enumerate(np.round(self.colors,6).tolist()):
|
for i,c in enumerate(np.round(self.colors,6).tolist()):
|
||||||
colors+=[i]+c
|
colors+=[i]+c
|
||||||
|
@ -254,8 +275,7 @@ class Colormap(mpl.colors.ListedColormap):
|
||||||
'RGBPoints':colors
|
'RGBPoints':colors
|
||||||
}]
|
}]
|
||||||
|
|
||||||
with open(self.name.replace(' ','_')+'.json', 'w') if fhandle is None else fhandle as f:
|
json.dump(out,self._get_file_handle(fname,'json'),indent=4)
|
||||||
json.dump(out, f,indent=4)
|
|
||||||
|
|
||||||
|
|
||||||
def save_ASCII(self,fname=None):
|
def save_ASCII(self,fname=None):
|
||||||
|
@ -264,24 +284,14 @@ class Colormap(mpl.colors.ListedColormap):
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
fname : file, str, or pathlib.Path, optional.
|
fname : file, str, or pathlib.Path, optional
|
||||||
Filename to store results. If not given, the filename will
|
Filename to store results. If not given, the filename will
|
||||||
consist of the name of the colormap and extension '.txt'.
|
consist of the name of the colormap and extension '.txt'.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if fname is None:
|
|
||||||
fhandle = None
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
fhandle = open(fname,'w')
|
|
||||||
except TypeError:
|
|
||||||
fhandle = fname
|
|
||||||
|
|
||||||
labels = {'RGBA':4} if self.colors.shape[1] == 4 else {'RGB': 3}
|
labels = {'RGBA':4} if self.colors.shape[1] == 4 else {'RGB': 3}
|
||||||
t = Table(self.colors,labels,f'Creator: {util.execution_stamp("Colormap")}')
|
t = Table(self.colors,labels,f'Creator: {util.execution_stamp("Colormap")}')
|
||||||
|
t.save(self._get_file_handle(fname,'txt'))
|
||||||
with open(self.name.replace(' ','_')+'.txt', 'w') if fhandle is None else fhandle as f:
|
|
||||||
t.save(f)
|
|
||||||
|
|
||||||
|
|
||||||
def save_GOM(self,fname=None):
|
def save_GOM(self,fname=None):
|
||||||
|
@ -290,26 +300,19 @@ class Colormap(mpl.colors.ListedColormap):
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
fname : file, str, or pathlib.Path, optional.
|
fname : file, str, or pathlib.Path, optional
|
||||||
Filename to store results. If not given, the filename will
|
Filename to store results. If not given, the filename will
|
||||||
consist of the name of the colormap and extension '.legend'.
|
consist of the name of the colormap and extension '.legend'.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if fname is None:
|
|
||||||
fhandle = None
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
fhandle = open(fname,'w')
|
|
||||||
except TypeError:
|
|
||||||
fhandle = fname
|
|
||||||
# ToDo: test in GOM
|
# ToDo: test in GOM
|
||||||
GOM_str = '1 1 {name} 9 {name} '.format(name=self.name.replace(" ","_")) \
|
GOM_str = '1 1 {name} 9 {name} '.format(name=self.name.replace(" ","_")) \
|
||||||
+ '0 1 0 3 0 0 -1 9 \\ 0 0 0 255 255 255 0 0 255 ' \
|
+ '0 1 0 3 0 0 -1 9 \\ 0 0 0 255 255 255 0 0 255 ' \
|
||||||
+ f'30 NO_UNIT 1 1 64 64 64 255 1 0 0 0 0 0 0 3 0 {len(self.colors)}' \
|
+ f'30 NO_UNIT 1 1 64 64 64 255 1 0 0 0 0 0 0 3 0 {len(self.colors)}' \
|
||||||
+ ' '.join([f' 0 {c[0]} {c[1]} {c[2]} 255 1' for c in reversed((self.colors*255).astype(int))]) \
|
+ ' '.join([f' 0 {c[0]} {c[1]} {c[2]} 255 1' for c in reversed((self.colors*255).astype(int))]) \
|
||||||
+ '\n'
|
+ '\n'
|
||||||
with open(self.name.replace(' ','_')+'.legend', 'w') if fhandle is None else fhandle as f:
|
|
||||||
f.write(GOM_str)
|
self._get_file_handle(fname,'legend').write(GOM_str)
|
||||||
|
|
||||||
|
|
||||||
def save_gmsh(self,fname=None):
|
def save_gmsh(self,fname=None):
|
||||||
|
@ -318,24 +321,16 @@ class Colormap(mpl.colors.ListedColormap):
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
fname : file, str, or pathlib.Path, optional.
|
fname : file, str, or pathlib.Path, optional
|
||||||
Filename to store results. If not given, the filename will
|
Filename to store results. If not given, the filename will
|
||||||
consist of the name of the colormap and extension '.msh'.
|
consist of the name of the colormap and extension '.msh'.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if fname is None:
|
|
||||||
fhandle = None
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
fhandle = open(fname,'w')
|
|
||||||
except TypeError:
|
|
||||||
fhandle = fname
|
|
||||||
# ToDo: test in gmsh
|
# ToDo: test in gmsh
|
||||||
gmsh_str = 'View.ColorTable = {\n' \
|
gmsh_str = 'View.ColorTable = {\n' \
|
||||||
+'\n'.join([f'{c[0]},{c[1]},{c[2]},' for c in self.colors[:,:3]*255]) \
|
+'\n'.join([f'{c[0]},{c[1]},{c[2]},' for c in self.colors[:,:3]*255]) \
|
||||||
+'\n}\n'
|
+'\n}\n'
|
||||||
with open(self.name.replace(' ','_')+'.msh', 'w') if fhandle is None else fhandle as f:
|
self._get_file_handle(fname,'msh').write(gmsh_str)
|
||||||
f.write(gmsh_str)
|
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
|
import copy
|
||||||
from io import StringIO
|
from io import StringIO
|
||||||
|
from collections.abc import Iterable
|
||||||
import abc
|
import abc
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
@ -35,6 +37,50 @@ class Config(dict):
|
||||||
output.seek(0)
|
output.seek(0)
|
||||||
return ''.join(output.readlines())
|
return ''.join(output.readlines())
|
||||||
|
|
||||||
|
|
||||||
|
def __copy__(self):
|
||||||
|
"""Create deep copy."""
|
||||||
|
return copy.deepcopy(self)
|
||||||
|
|
||||||
|
copy = __copy__
|
||||||
|
|
||||||
|
|
||||||
|
def __or__(self,other):
|
||||||
|
"""
|
||||||
|
Update configuration with contents of other.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
other : damask.Config or dict
|
||||||
|
Key-value pairs that update self.
|
||||||
|
|
||||||
|
"""
|
||||||
|
duplicate = self.copy()
|
||||||
|
duplicate.update(other)
|
||||||
|
return duplicate
|
||||||
|
|
||||||
|
|
||||||
|
def __ior__(self,other):
|
||||||
|
"""Update configuration with contents of other."""
|
||||||
|
return self.__or__(other)
|
||||||
|
|
||||||
|
|
||||||
|
def delete(self,keys):
|
||||||
|
"""
|
||||||
|
Remove configuration keys.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
keys : iterable or scalar
|
||||||
|
Label of the key(s) to remove.
|
||||||
|
|
||||||
|
"""
|
||||||
|
duplicate = self.copy()
|
||||||
|
for k in keys if isinstance(keys, Iterable) and not isinstance(keys, str) else [keys]:
|
||||||
|
del duplicate[k]
|
||||||
|
return duplicate
|
||||||
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def load(cls,fname):
|
def load(cls,fname):
|
||||||
"""
|
"""
|
||||||
|
@ -52,6 +98,7 @@ class Config(dict):
|
||||||
fhandle = fname
|
fhandle = fname
|
||||||
return cls(yaml.safe_load(fhandle))
|
return cls(yaml.safe_load(fhandle))
|
||||||
|
|
||||||
|
|
||||||
def save(self,fname,**kwargs):
|
def save(self,fname,**kwargs):
|
||||||
"""
|
"""
|
||||||
Save to yaml file.
|
Save to yaml file.
|
||||||
|
@ -65,7 +112,7 @@ class Config(dict):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
fhandle = open(fname,'w')
|
fhandle = open(fname,'w',newline='\n')
|
||||||
except TypeError:
|
except TypeError:
|
||||||
fhandle = fname
|
fhandle = fname
|
||||||
|
|
||||||
|
@ -95,6 +142,7 @@ class Config(dict):
|
||||||
"""Check for completeness."""
|
"""Check for completeness."""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
def is_valid(self):
|
def is_valid(self):
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import copy
|
|
||||||
from os import path
|
from os import path
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
@ -7,6 +6,7 @@ import h5py
|
||||||
from . import Config
|
from . import Config
|
||||||
from . import Rotation
|
from . import Rotation
|
||||||
from . import Orientation
|
from . import Orientation
|
||||||
|
from . import util
|
||||||
|
|
||||||
class ConfigMaterial(Config):
|
class ConfigMaterial(Config):
|
||||||
"""Material configuration."""
|
"""Material configuration."""
|
||||||
|
@ -15,11 +15,10 @@ class ConfigMaterial(Config):
|
||||||
'homogenization': {},
|
'homogenization': {},
|
||||||
'phase': {}}
|
'phase': {}}
|
||||||
|
|
||||||
def __init__(self,d={}):
|
def __init__(self,d=_defaults):
|
||||||
"""Initialize object with default dictionary keys."""
|
"""Initialize object with default dictionary keys."""
|
||||||
super().__init__(d)
|
super().__init__(d)
|
||||||
for k,v in self._defaults.items():
|
|
||||||
if k not in self: self[k] = v
|
|
||||||
|
|
||||||
def save(self,fname='material.yaml',**kwargs):
|
def save(self,fname='material.yaml',**kwargs):
|
||||||
"""
|
"""
|
||||||
|
@ -51,7 +50,7 @@ class ConfigMaterial(Config):
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def from_table(table,constituents={},**kwargs):
|
def from_table(table,**kwargs):
|
||||||
"""
|
"""
|
||||||
Load from an ASCII table.
|
Load from an ASCII table.
|
||||||
|
|
||||||
|
@ -59,12 +58,9 @@ class ConfigMaterial(Config):
|
||||||
----------
|
----------
|
||||||
table : damask.Table
|
table : damask.Table
|
||||||
Table that contains material information.
|
Table that contains material information.
|
||||||
constituents : dict, optional
|
|
||||||
Entries for 'constituents'. The key is the name and the value specifies
|
|
||||||
the label of the data column in the table
|
|
||||||
**kwargs
|
**kwargs
|
||||||
Keyword arguments where the key is the name and the value specifies
|
Keyword arguments where the key is the name and the value specifies
|
||||||
the label of the data column in the table
|
the label of the data column in the table.
|
||||||
|
|
||||||
Examples
|
Examples
|
||||||
--------
|
--------
|
||||||
|
@ -75,32 +71,30 @@ class ConfigMaterial(Config):
|
||||||
pos pos pos qu qu qu qu phase homog
|
pos pos pos qu qu qu qu phase homog
|
||||||
0 0 0 0 0.19 0.8 0.24 -0.51 Aluminum SX
|
0 0 0 0 0.19 0.8 0.24 -0.51 Aluminum SX
|
||||||
1 1 0 0 0.8 0.19 0.24 -0.51 Steel SX
|
1 1 0 0 0.8 0.19 0.24 -0.51 Steel SX
|
||||||
>>> cm.from_table(t,{'O':'qu','phase':'phase'},homogenization='homog')
|
1 1 1 0 0.8 0.19 0.24 -0.51 Steel SX
|
||||||
|
>>> cm.from_table(t,O='qu',phase='phase',homogenization='homog')
|
||||||
material:
|
material:
|
||||||
- constituents:
|
- constituents:
|
||||||
- O: [0.19, 0.8, 0.24, -0.51]
|
- O: [0.19, 0.8, 0.24, -0.51]
|
||||||
fraction: 1.0
|
v: 1.0
|
||||||
phase: Aluminum
|
phase: Aluminum
|
||||||
homogenization: SX
|
homogenization: SX
|
||||||
- constituents:
|
- constituents:
|
||||||
- O: [0.8, 0.19, 0.24, -0.51]
|
- O: [0.8, 0.19, 0.24, -0.51]
|
||||||
fraction: 1.0
|
v: 1.0
|
||||||
phase: Steel
|
phase: Steel
|
||||||
homogenization: SX
|
homogenization: SX
|
||||||
homogenization: {}
|
homogenization: {}
|
||||||
phase: {}
|
phase: {}
|
||||||
|
|
||||||
"""
|
"""
|
||||||
constituents_ = {k:table.get(v) for k,v in constituents.items()}
|
|
||||||
kwargs_ = {k:table.get(v) for k,v in kwargs.items()}
|
kwargs_ = {k:table.get(v) for k,v in kwargs.items()}
|
||||||
|
|
||||||
_,idx = np.unique(np.hstack(list({**constituents_,**kwargs_}.values())),return_index=True,axis=0)
|
_,idx = np.unique(np.hstack(list(kwargs_.values())),return_index=True,axis=0)
|
||||||
|
|
||||||
idx = np.sort(idx)
|
idx = np.sort(idx)
|
||||||
constituents_ = {k:np.atleast_1d(v[idx].squeeze()) for k,v in constituents_.items()}
|
|
||||||
kwargs_ = {k:np.atleast_1d(v[idx].squeeze()) for k,v in kwargs_.items()}
|
kwargs_ = {k:np.atleast_1d(v[idx].squeeze()) for k,v in kwargs_.items()}
|
||||||
|
|
||||||
return ConfigMaterial().material_add(constituents_,**kwargs_)
|
return ConfigMaterial().material_add(**kwargs_)
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@ -187,7 +181,6 @@ class ConfigMaterial(Config):
|
||||||
"""Check for completeness."""
|
"""Check for completeness."""
|
||||||
ok = True
|
ok = True
|
||||||
for top_level in ['homogenization','phase','material']:
|
for top_level in ['homogenization','phase','material']:
|
||||||
# ToDo: With python 3.8 as prerequisite we can shorten with :=
|
|
||||||
ok &= top_level in self
|
ok &= top_level in self
|
||||||
if top_level not in self: print(f'{top_level} entry missing')
|
if top_level not in self: print(f'{top_level} entry missing')
|
||||||
|
|
||||||
|
@ -238,7 +231,7 @@ class ConfigMaterial(Config):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_valid(self):
|
def is_valid(self):
|
||||||
"""Check for valid file layout."""
|
"""Check for valid content."""
|
||||||
ok = True
|
ok = True
|
||||||
|
|
||||||
if 'phase' in self:
|
if 'phase' in self:
|
||||||
|
@ -247,25 +240,23 @@ class ConfigMaterial(Config):
|
||||||
try:
|
try:
|
||||||
Orientation(lattice=v['lattice'])
|
Orientation(lattice=v['lattice'])
|
||||||
except KeyError:
|
except KeyError:
|
||||||
s = v['lattice']
|
print(f"Invalid lattice '{v['lattice']}' in phase '{k}'")
|
||||||
print(f"Invalid lattice: '{s}' in phase '{k}'")
|
|
||||||
ok = False
|
ok = False
|
||||||
|
|
||||||
if 'material' in self:
|
if 'material' in self:
|
||||||
for i,v in enumerate(self['material']):
|
for i,m in enumerate(self['material']):
|
||||||
if 'constituents' in v:
|
if 'constituents' in m:
|
||||||
f = 0.0
|
v = 0.0
|
||||||
for c in v['constituents']:
|
for c in m['constituents']:
|
||||||
f+= float(c['fraction'])
|
v += float(c['v'])
|
||||||
if 'O' in c:
|
if 'O' in c:
|
||||||
try:
|
try:
|
||||||
Rotation.from_quaternion(c['O'])
|
Rotation.from_quaternion(c['O'])
|
||||||
except ValueError:
|
except ValueError:
|
||||||
o = c['O']
|
print(f"Invalid orientation '{c['O']}' in material '{i}'")
|
||||||
print(f"Invalid orientation: '{o}' in material '{i}'")
|
|
||||||
ok = False
|
ok = False
|
||||||
if not np.isclose(f,1.0):
|
if not np.isclose(v,1.0):
|
||||||
print(f"Invalid total fraction '{f}' in material '{i}'")
|
print(f"Total fraction v = {v} ≠ 1 in material '{i}'")
|
||||||
ok = False
|
ok = False
|
||||||
|
|
||||||
return ok
|
return ok
|
||||||
|
@ -284,10 +275,15 @@ class ConfigMaterial(Config):
|
||||||
constituent: list of ints, optional
|
constituent: list of ints, optional
|
||||||
Limit renaming to selected constituents.
|
Limit renaming to selected constituents.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
cfg : damask.ConfigMaterial
|
||||||
|
Updated material configuration.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
dup = copy.deepcopy(self)
|
dup = self.copy()
|
||||||
for i,m in enumerate(dup['material']):
|
for i,m in enumerate(dup['material']):
|
||||||
if ID and i not in ID: continue
|
if ID is not None and i not in ID: continue
|
||||||
for c in m['constituents']:
|
for c in m['constituents']:
|
||||||
if constituent is not None and c not in constituent: continue
|
if constituent is not None and c not in constituent: continue
|
||||||
try:
|
try:
|
||||||
|
@ -308,10 +304,15 @@ class ConfigMaterial(Config):
|
||||||
ID: list of ints, optional
|
ID: list of ints, optional
|
||||||
Limit renaming to selected homogenization IDs.
|
Limit renaming to selected homogenization IDs.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
cfg : damask.ConfigMaterial
|
||||||
|
Updated material configuration.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
dup = copy.deepcopy(self)
|
dup = self.copy()
|
||||||
for i,m in enumerate(dup['material']):
|
for i,m in enumerate(dup['material']):
|
||||||
if ID and i not in ID: continue
|
if ID is not None and i not in ID: continue
|
||||||
try:
|
try:
|
||||||
m['homogenization'] = mapping[m['homogenization']]
|
m['homogenization'] = mapping[m['homogenization']]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
|
@ -319,93 +320,92 @@ class ConfigMaterial(Config):
|
||||||
return dup
|
return dup
|
||||||
|
|
||||||
|
|
||||||
def material_add(self,constituents=None,**kwargs):
|
def material_add(self,**kwargs):
|
||||||
"""
|
"""
|
||||||
Add material entries.
|
Add material entries.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
constituents : dict, optional
|
|
||||||
Entries for 'constituents' as key-value pair.
|
|
||||||
**kwargs
|
**kwargs
|
||||||
Key-value pairs.
|
Key-value pairs.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
cfg : damask.ConfigMaterial
|
||||||
|
Updated material configuration.
|
||||||
|
|
||||||
Examples
|
Examples
|
||||||
--------
|
--------
|
||||||
|
>>> import numpy as np
|
||||||
>>> import damask
|
>>> import damask
|
||||||
>>> O = damask.Rotation.from_random(3).as_quaternion()
|
>>> m = damask.ConfigMaterial().material_add(phase = ['Aluminum','Steel'],
|
||||||
>>> phase = ['Aluminum','Steel','Aluminum']
|
... O = damask.Rotation.from_random(2),
|
||||||
>>> m = damask.ConfigMaterial().material_add(constituents={'phase':phase,'O':O},
|
|
||||||
... homogenization = 'SX')
|
... homogenization = 'SX')
|
||||||
>>> m
|
>>> m
|
||||||
material:
|
material:
|
||||||
- constituents:
|
- constituents:
|
||||||
- O: [0.577764, -0.146299, -0.617669, 0.513010]
|
- O: [0.577764, -0.146299, -0.617669, 0.513010]
|
||||||
fraction: 1.0
|
v: 1.0
|
||||||
phase: Aluminum
|
phase: Aluminum
|
||||||
homogenization: SX
|
homogenization: SX
|
||||||
- constituents:
|
- constituents:
|
||||||
- O: [0.184176, 0.340305, 0.737247, 0.553840]
|
- O: [0.184176, 0.340305, 0.737247, 0.553840]
|
||||||
fraction: 1.0
|
v: 1.0
|
||||||
phase: Steel
|
phase: Steel
|
||||||
homogenization: SX
|
homogenization: SX
|
||||||
- constituents:
|
homogenization: {}
|
||||||
- O: [0.0886257, -0.144848, 0.615674, -0.769487]
|
phase: {}
|
||||||
fraction: 1.0
|
|
||||||
phase: Aluminum
|
>>> m = damask.ConfigMaterial().material_add(phase = np.array(['Austenite','Martensite']).reshape(1,2),
|
||||||
homogenization: SX
|
... O = damask.Rotation.from_random((2,2)),
|
||||||
|
... v = np.array([0.2,0.8]).reshape(1,2),
|
||||||
|
... homogenization = ['A','B'])
|
||||||
|
>>> m
|
||||||
|
material:
|
||||||
|
- constituents:
|
||||||
|
- phase: Austenite
|
||||||
|
O: [0.659802978293224, 0.6953785848195171, 0.22426295326327111, -0.17554139512785227]
|
||||||
|
v: 0.2
|
||||||
|
- phase: Martensite
|
||||||
|
O: [0.49356745891301596, 0.2841806579193434, -0.7487679215072818, -0.339085707289975]
|
||||||
|
v: 0.8
|
||||||
|
homogenization: A
|
||||||
|
- constituents:
|
||||||
|
- phase: Austenite
|
||||||
|
O: [0.26542221365204055, 0.7268854930702071, 0.4474726435701472, -0.44828201137283735]
|
||||||
|
v: 0.2
|
||||||
|
- phase: Martensite
|
||||||
|
O: [0.6545817158479885, -0.08004812803625233, -0.6226561293931374, 0.4212059104577611]
|
||||||
|
v: 0.8
|
||||||
|
homogenization: B
|
||||||
homogenization: {}
|
homogenization: {}
|
||||||
phase: {}
|
phase: {}
|
||||||
|
|
||||||
"""
|
"""
|
||||||
length = -1
|
N,n,shaped = 1,1,{}
|
||||||
for v in kwargs.values():
|
|
||||||
if hasattr(v,'__len__') and not isinstance(v,str):
|
|
||||||
if length != -1 and len(v) != length:
|
|
||||||
raise ValueError('Cannot add entries of different length')
|
|
||||||
else:
|
|
||||||
length = len(v)
|
|
||||||
length = max(1,length)
|
|
||||||
|
|
||||||
c = [{} for _ in range(length)] if constituents is None else \
|
|
||||||
[{'constituents':u} for u in ConfigMaterial._constituents(**constituents)]
|
|
||||||
|
|
||||||
if len(c) == 1: c = [copy.deepcopy(c[0]) for _ in range(length)]
|
|
||||||
|
|
||||||
if length != 1 and length != len(c):
|
|
||||||
raise ValueError('Cannot add entries of different length')
|
|
||||||
|
|
||||||
for k,v in kwargs.items():
|
for k,v in kwargs.items():
|
||||||
if hasattr(v,'__len__') and not isinstance(v,str):
|
shaped[k] = np.array(v)
|
||||||
for i,vv in enumerate(v):
|
s = shaped[k].shape[:-1] if k=='O' else shaped[k].shape
|
||||||
c[i][k] = vv.item() if isinstance(vv,np.generic) else vv
|
N = max(N,s[0]) if len(s)>0 else N
|
||||||
|
n = max(n,s[1]) if len(s)>1 else n
|
||||||
|
|
||||||
|
mat = [{'constituents':[{} for _ in range(n)]} for _ in range(N)]
|
||||||
|
|
||||||
|
if 'v' not in kwargs:
|
||||||
|
shaped['v'] = np.broadcast_to(1/n,(N,n))
|
||||||
|
|
||||||
|
for k,v in shaped.items():
|
||||||
|
target = (N,n,4) if k=='O' else (N,n)
|
||||||
|
obj = np.broadcast_to(v.reshape(util.shapeshifter(v.shape,target,mode='right')),target)
|
||||||
|
for i in range(N):
|
||||||
|
if k in ['phase','O','v']:
|
||||||
|
for j in range(n):
|
||||||
|
mat[i]['constituents'][j][k] = obj[i,j].item() if isinstance(obj[i,j],np.generic) else obj[i,j]
|
||||||
else:
|
else:
|
||||||
for i in range(len(c)):
|
mat[i][k] = obj[i,0].item() if isinstance(obj[i,0],np.generic) else obj[i,0]
|
||||||
c[i][k] = v
|
|
||||||
dup = copy.deepcopy(self)
|
dup = self.copy()
|
||||||
dup['material'] = dup['material'] + c if 'material' in dup else c
|
dup['material'] = dup['material'] + mat if 'material' in dup else mat
|
||||||
|
|
||||||
return dup
|
return dup
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def _constituents(N=1,**kwargs):
|
|
||||||
"""Construct list of constituents."""
|
|
||||||
N_material=1
|
|
||||||
for v in kwargs.values():
|
|
||||||
if hasattr(v,'__len__') and not isinstance(v,str): N_material = len(v)
|
|
||||||
|
|
||||||
if N == 1:
|
|
||||||
m = [[{'fraction':1.0}] for _ in range(N_material)]
|
|
||||||
for k,v in kwargs.items():
|
|
||||||
if hasattr(v,'__len__') and not isinstance(v,str):
|
|
||||||
if len(v) != N_material:
|
|
||||||
raise ValueError('Cannot add entries of different length')
|
|
||||||
for i,vv in enumerate(np.array(v)):
|
|
||||||
m[i][0][k] = vv.item() if isinstance(vv,np.generic) else vv
|
|
||||||
else:
|
|
||||||
for i in range(N_material):
|
|
||||||
m[i][0][k] = v
|
|
||||||
return m
|
|
||||||
else:
|
|
||||||
raise NotImplementedError
|
|
||||||
|
|
|
@ -1,41 +0,0 @@
|
||||||
import os
|
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
class Environment:
|
|
||||||
|
|
||||||
@property
|
|
||||||
def screen_size(self):
|
|
||||||
try:
|
|
||||||
import wx
|
|
||||||
_ = wx.App(False) # noqa
|
|
||||||
width, height = wx.GetDisplaySize()
|
|
||||||
except ImportError:
|
|
||||||
try:
|
|
||||||
import tkinter
|
|
||||||
tk = tkinter.Tk()
|
|
||||||
width = tk.winfo_screenwidth()
|
|
||||||
height = tk.winfo_screenheight()
|
|
||||||
tk.destroy()
|
|
||||||
except Exception as e:
|
|
||||||
width = 1024
|
|
||||||
height = 768
|
|
||||||
|
|
||||||
return (width,height)
|
|
||||||
|
|
||||||
|
|
||||||
@property
|
|
||||||
def options(self):
|
|
||||||
options = {}
|
|
||||||
for item in ['DAMASK_NUM_THREADS',
|
|
||||||
'MSC_ROOT',
|
|
||||||
'MSC_VERSION',
|
|
||||||
]:
|
|
||||||
options[item] = os.environ[item] if item in os.environ else None
|
|
||||||
|
|
||||||
return options
|
|
||||||
|
|
||||||
|
|
||||||
@property
|
|
||||||
def root_dir(self):
|
|
||||||
"""Return DAMASK root path."""
|
|
||||||
return Path(__file__).parents[2]
|
|
|
@ -1,7 +1,7 @@
|
||||||
import copy
|
import copy
|
||||||
import multiprocessing as mp
|
import multiprocessing as mp
|
||||||
from functools import partial
|
from functools import partial
|
||||||
from os import path
|
import os
|
||||||
import warnings
|
import warnings
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
@ -10,7 +10,6 @@ import h5py
|
||||||
from scipy import ndimage, spatial
|
from scipy import ndimage, spatial
|
||||||
from vtk.util.numpy_support import vtk_to_numpy as vtk_to_np
|
from vtk.util.numpy_support import vtk_to_numpy as vtk_to_np
|
||||||
|
|
||||||
from . import environment
|
|
||||||
from . import VTK
|
from . import VTK
|
||||||
from . import util
|
from . import util
|
||||||
from . import grid_filters
|
from . import grid_filters
|
||||||
|
@ -57,13 +56,10 @@ class Grid:
|
||||||
|
|
||||||
|
|
||||||
def __copy__(self):
|
def __copy__(self):
|
||||||
"""Copy grid."""
|
"""Create deep copy."""
|
||||||
return copy.deepcopy(self)
|
return copy.deepcopy(self)
|
||||||
|
|
||||||
|
copy = __copy__
|
||||||
def copy(self):
|
|
||||||
"""Copy grid."""
|
|
||||||
return self.__copy__()
|
|
||||||
|
|
||||||
|
|
||||||
def diff(self,other):
|
def diff(self,other):
|
||||||
|
@ -126,7 +122,7 @@ class Grid:
|
||||||
|
|
||||||
@size.setter
|
@size.setter
|
||||||
def size(self,size):
|
def size(self,size):
|
||||||
if len(size) != 3 or any(np.array(size) <= 0):
|
if len(size) != 3 or any(np.array(size) < 0):
|
||||||
raise ValueError(f'invalid size {size}')
|
raise ValueError(f'invalid size {size}')
|
||||||
else:
|
else:
|
||||||
self._size = np.array(size)
|
self._size = np.array(size)
|
||||||
|
@ -206,7 +202,7 @@ class Grid:
|
||||||
Geometry file to read.
|
Geometry file to read.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
warnings.warn('Support for ASCII-based geom format will be removed in DAMASK 3.1.0', DeprecationWarning)
|
warnings.warn('Support for ASCII-based geom format will be removed in DAMASK 3.1.0', DeprecationWarning,2)
|
||||||
try:
|
try:
|
||||||
f = open(fname)
|
f = open(fname)
|
||||||
except TypeError:
|
except TypeError:
|
||||||
|
@ -281,14 +277,14 @@ class Grid:
|
||||||
"""
|
"""
|
||||||
root_dir ='DataContainers'
|
root_dir ='DataContainers'
|
||||||
f = h5py.File(fname, 'r')
|
f = h5py.File(fname, 'r')
|
||||||
g = path.join(root_dir,base_group,'_SIMPL_GEOMETRY')
|
g = os.path.join(root_dir,base_group,'_SIMPL_GEOMETRY')
|
||||||
cells = f[path.join(g,'DIMENSIONS')][()]
|
cells = f[os.path.join(g,'DIMENSIONS')][()]
|
||||||
size = f[path.join(g,'SPACING')][()] * cells
|
size = f[os.path.join(g,'SPACING')][()] * cells
|
||||||
origin = f[path.join(g,'ORIGIN')][()]
|
origin = f[os.path.join(g,'ORIGIN')][()]
|
||||||
|
|
||||||
ma = np.arange(cells.prod(),dtype=int) \
|
ma = np.arange(cells.prod(),dtype=int) \
|
||||||
if point_data is None else \
|
if point_data is None else \
|
||||||
np.reshape(f[path.join(root_dir,base_group,point_data,material)],cells.prod())
|
np.reshape(f[os.path.join(root_dir,base_group,point_data,material)],cells.prod())
|
||||||
|
|
||||||
return Grid(ma.reshape(cells,order='F'),size,origin,util.execution_stamp('Grid','load_DREAM3D'))
|
return Grid(ma.reshape(cells,order='F'),size,origin,util.execution_stamp('Grid','load_DREAM3D'))
|
||||||
|
|
||||||
|
@ -307,7 +303,7 @@ class Grid:
|
||||||
Need to be ordered (1./x fast, 3./z slow).
|
Need to be ordered (1./x fast, 3./z slow).
|
||||||
labels : str or list of str
|
labels : str or list of str
|
||||||
Label(s) of the columns containing the material definition.
|
Label(s) of the columns containing the material definition.
|
||||||
Each unique combintation of values results in one material ID.
|
Each unique combination of values results in one material ID.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
cells,size,origin = grid_filters.cellsSizeOrigin_coordinates0_point(table.get(coordinates))
|
cells,size,origin = grid_filters.cellsSizeOrigin_coordinates0_point(table.get(coordinates))
|
||||||
|
@ -358,7 +354,7 @@ class Grid:
|
||||||
seeds_p = seeds
|
seeds_p = seeds
|
||||||
coords = grid_filters.coordinates0_point(cells,size).reshape(-1,3)
|
coords = grid_filters.coordinates0_point(cells,size).reshape(-1,3)
|
||||||
|
|
||||||
pool = mp.Pool(processes = int(environment.options['DAMASK_NUM_THREADS']))
|
pool = mp.Pool(int(os.environ.get('OMP_NUM_THREADS',1)))
|
||||||
result = pool.map_async(partial(Grid._find_closest_seed,seeds_p,weights_p), [coord for coord in coords])
|
result = pool.map_async(partial(Grid._find_closest_seed,seeds_p,weights_p), [coord for coord in coords])
|
||||||
pool.close()
|
pool.close()
|
||||||
pool.join()
|
pool.join()
|
||||||
|
@ -545,7 +541,7 @@ class Grid:
|
||||||
Compress geometry with 'x of y' and 'a to b'.
|
Compress geometry with 'x of y' and 'a to b'.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
warnings.warn('Support for ASCII-based geom format will be removed in DAMASK 3.1.0', DeprecationWarning)
|
warnings.warn('Support for ASCII-based geom format will be removed in DAMASK 3.1.0', DeprecationWarning,2)
|
||||||
header = [f'{len(self.comments)+4} header'] + self.comments \
|
header = [f'{len(self.comments)+4} header'] + self.comments \
|
||||||
+ ['grid a {} b {} c {}'.format(*self.cells),
|
+ ['grid a {} b {} c {}'.format(*self.cells),
|
||||||
'size x {} y {} z {}'.format(*self.size),
|
'size x {} y {} z {}'.format(*self.size),
|
||||||
|
@ -764,26 +760,21 @@ class Grid:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if fill is None: fill = np.nanmax(self.material) + 1
|
if fill is None: fill = np.nanmax(self.material) + 1
|
||||||
dtype = float if np.isnan(fill) or int(fill) != fill or self.material.dtype==np.float else int
|
dtype = float if isinstance(fill,float) or self.material.dtype in np.sctypes['float'] else int
|
||||||
|
|
||||||
Eulers = R.as_Euler_angles(degrees=True)
|
|
||||||
material_in = self.material.copy()
|
|
||||||
|
|
||||||
|
material = self.material
|
||||||
# These rotations are always applied in the reference coordinate system, i.e. (z,x,z) not (z,x',z'')
|
# These rotations are always applied in the reference coordinate system, i.e. (z,x,z) not (z,x',z'')
|
||||||
# see https://www.cs.utexas.edu/~theshark/courses/cs354/lectures/cs354-14.pdf
|
# see https://www.cs.utexas.edu/~theshark/courses/cs354/lectures/cs354-14.pdf
|
||||||
for angle,axes in zip(Eulers[::-1], [(0,1),(1,2),(0,1)]):
|
for angle,axes in zip(R.as_Euler_angles(degrees=True)[::-1], [(0,1),(1,2),(0,1)]):
|
||||||
material_out = ndimage.rotate(material_in,angle,axes,order=0,
|
material_temp = ndimage.rotate(material,angle,axes,order=0,prefilter=False,output=dtype,cval=fill)
|
||||||
prefilter=False,output=dtype,cval=fill)
|
|
||||||
if np.prod(material_in.shape) == np.prod(material_out.shape):
|
|
||||||
# avoid scipy interpolation errors for rotations close to multiples of 90°
|
# avoid scipy interpolation errors for rotations close to multiples of 90°
|
||||||
material_in = np.rot90(material_in,k=np.rint(angle/90.).astype(int),axes=axes)
|
material = material_temp if np.prod(material_temp.shape) != np.prod(material.shape) else \
|
||||||
else:
|
np.rot90(material,k=np.rint(angle/90.).astype(int),axes=axes)
|
||||||
material_in = material_out
|
|
||||||
|
|
||||||
origin = self.origin-(np.asarray(material_in.shape)-self.cells)*.5 * self.size/self.cells
|
origin = self.origin-(np.asarray(material.shape)-self.cells)*.5 * self.size/self.cells
|
||||||
|
|
||||||
return Grid(material = material_in,
|
return Grid(material = material,
|
||||||
size = self.size/self.cells*np.asarray(material_in.shape),
|
size = self.size/self.cells*np.asarray(material.shape),
|
||||||
origin = origin,
|
origin = origin,
|
||||||
comments = self.comments+[util.execution_stamp('Grid','rotate')],
|
comments = self.comments+[util.execution_stamp('Grid','rotate')],
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import inspect
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
from . import Rotation
|
from . import Rotation
|
||||||
|
@ -107,8 +109,7 @@ class Orientation(Rotation):
|
||||||
lattice = None,
|
lattice = None,
|
||||||
a = None,b = None,c = None,
|
a = None,b = None,c = None,
|
||||||
alpha = None,beta = None,gamma = None,
|
alpha = None,beta = None,gamma = None,
|
||||||
degrees = False,
|
degrees = False):
|
||||||
**kwargs):
|
|
||||||
"""
|
"""
|
||||||
Initialize orientation object.
|
Initialize orientation object.
|
||||||
|
|
||||||
|
@ -199,7 +200,7 @@ class Orientation(Rotation):
|
||||||
|
|
||||||
|
|
||||||
def __copy__(self,**kwargs):
|
def __copy__(self,**kwargs):
|
||||||
"""Copy."""
|
"""Create deep copy."""
|
||||||
return self.__class__(rotation=kwargs['rotation'] if 'rotation' in kwargs else self.quaternion,
|
return self.__class__(rotation=kwargs['rotation'] if 'rotation' in kwargs else self.quaternion,
|
||||||
lattice =kwargs['lattice'] if 'lattice' in kwargs else self.lattice
|
lattice =kwargs['lattice'] if 'lattice' in kwargs else self.lattice
|
||||||
if self.lattice is not None else self.family,
|
if self.lattice is not None else self.family,
|
||||||
|
@ -225,96 +226,150 @@ class Orientation(Rotation):
|
||||||
Orientation to check for equality.
|
Orientation to check for equality.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return super().__eq__(other) \
|
matching_type = all([hasattr(other,attr) and getattr(self,attr) == getattr(other,attr)
|
||||||
and hasattr(other, 'family') and self.family == other.family \
|
for attr in ['family','lattice','parameters']])
|
||||||
and hasattr(other, 'lattice') and self.lattice == other.lattice \
|
return np.logical_and(super().__eq__(other),matching_type)
|
||||||
and hasattr(other, 'parameters') and self.parameters == other.parameters
|
|
||||||
|
|
||||||
|
def __ne__(self,other):
|
||||||
def __matmul__(self,other):
|
|
||||||
"""
|
"""
|
||||||
Rotation of vector, second or fourth order tensor, or rotation object.
|
Not equal to other.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
other : numpy.ndarray, Rotation, or Orientation
|
other : Orientation
|
||||||
Vector, second or fourth order tensor, or rotation object that is rotated.
|
Orientation to check for equality.
|
||||||
|
|
||||||
|
"""
|
||||||
|
return np.logical_not(self==other)
|
||||||
|
|
||||||
|
|
||||||
|
def __mul__(self,other):
|
||||||
|
"""
|
||||||
|
Compose this orientation with other.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
other : Rotation or Orientation
|
||||||
|
Object for composition.
|
||||||
|
|
||||||
Returns
|
Returns
|
||||||
-------
|
-------
|
||||||
other_rot : numpy.ndarray or Rotation
|
composition : Orientation
|
||||||
Rotated vector, second or fourth order tensor, or rotation object.
|
Compound rotation self*other, i.e. first other then self rotation.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.copy(rotation=Rotation.__matmul__(self,Rotation(other.quaternion))) \
|
if isinstance(other,Orientation) or isinstance(other,Rotation):
|
||||||
if isinstance(other,self.__class__) else \
|
return self.copy(rotation=Rotation.__mul__(self,Rotation(other.quaternion)))
|
||||||
Rotation.__matmul__(self,other)
|
else:
|
||||||
|
raise TypeError('Use "O@b", i.e. matmul, to apply Orientation "O" to object "b"')
|
||||||
|
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _split_kwargs(kwargs,target):
|
||||||
|
"""
|
||||||
|
Separate keyword arguments in 'kwargs' targeted at 'target' from general keyword arguments of Orientation objects.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
kwargs : dictionary
|
||||||
|
Contains all **kwargs.
|
||||||
|
target: method
|
||||||
|
Function to scan for kwarg signature.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
rot_kwargs: dictionary
|
||||||
|
Valid keyword arguments of 'target' function of Rotation class.
|
||||||
|
ori_kwargs: dictionary
|
||||||
|
Valid keyword arguments of Orientation object.
|
||||||
|
|
||||||
|
"""
|
||||||
|
kws = ()
|
||||||
|
for t in (target,Orientation.__init__):
|
||||||
|
kws += ({key: kwargs[key] for key in set(inspect.signature(t).parameters) & set(kwargs)},)
|
||||||
|
|
||||||
|
invalid_keys = set(kwargs)-(set(kws[0])|set(kws[1]))
|
||||||
|
if invalid_keys:
|
||||||
|
raise TypeError(f"{inspect.stack()[1][3]}() got an unexpected keyword argument '{invalid_keys.pop()}'")
|
||||||
|
|
||||||
|
return kws
|
||||||
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@util.extended_docstring(Rotation.from_random,_parameter_doc)
|
@util.extended_docstring(Rotation.from_random,_parameter_doc)
|
||||||
def from_random(cls,**kwargs):
|
def from_random(cls,**kwargs):
|
||||||
return cls(rotation=Rotation.from_random(**kwargs),**kwargs)
|
kwargs_rot,kwargs_ori = Orientation._split_kwargs(kwargs,Rotation.from_random)
|
||||||
|
return cls(rotation=Rotation.from_random(**kwargs_rot),**kwargs_ori)
|
||||||
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@util.extended_docstring(Rotation.from_quaternion,_parameter_doc)
|
@util.extended_docstring(Rotation.from_quaternion,_parameter_doc)
|
||||||
def from_quaternion(cls,**kwargs):
|
def from_quaternion(cls,**kwargs):
|
||||||
return cls(rotation=Rotation.from_quaternion(**kwargs),**kwargs)
|
kwargs_rot,kwargs_ori = Orientation._split_kwargs(kwargs,Rotation.from_quaternion)
|
||||||
|
return cls(rotation=Rotation.from_quaternion(**kwargs_rot),**kwargs_ori)
|
||||||
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@util.extended_docstring(Rotation.from_Euler_angles,_parameter_doc)
|
@util.extended_docstring(Rotation.from_Euler_angles,_parameter_doc)
|
||||||
def from_Euler_angles(cls,**kwargs):
|
def from_Euler_angles(cls,**kwargs):
|
||||||
return cls(rotation=Rotation.from_Euler_angles(**kwargs),**kwargs)
|
kwargs_rot,kwargs_ori = Orientation._split_kwargs(kwargs,Rotation.from_Euler_angles)
|
||||||
|
return cls(rotation=Rotation.from_Euler_angles(**kwargs_rot),**kwargs_ori)
|
||||||
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@util.extended_docstring(Rotation.from_axis_angle,_parameter_doc)
|
@util.extended_docstring(Rotation.from_axis_angle,_parameter_doc)
|
||||||
def from_axis_angle(cls,**kwargs):
|
def from_axis_angle(cls,**kwargs):
|
||||||
return cls(rotation=Rotation.from_axis_angle(**kwargs),**kwargs)
|
kwargs_rot,kwargs_ori = Orientation._split_kwargs(kwargs,Rotation.from_axis_angle)
|
||||||
|
return cls(rotation=Rotation.from_axis_angle(**kwargs_rot),**kwargs_ori)
|
||||||
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@util.extended_docstring(Rotation.from_basis,_parameter_doc)
|
@util.extended_docstring(Rotation.from_basis,_parameter_doc)
|
||||||
def from_basis(cls,**kwargs):
|
def from_basis(cls,**kwargs):
|
||||||
return cls(rotation=Rotation.from_basis(**kwargs),**kwargs)
|
kwargs_rot,kwargs_ori = Orientation._split_kwargs(kwargs,Rotation.from_basis)
|
||||||
|
return cls(rotation=Rotation.from_basis(**kwargs_rot),**kwargs_ori)
|
||||||
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@util.extended_docstring(Rotation.from_matrix,_parameter_doc)
|
@util.extended_docstring(Rotation.from_matrix,_parameter_doc)
|
||||||
def from_matrix(cls,**kwargs):
|
def from_matrix(cls,**kwargs):
|
||||||
return cls(rotation=Rotation.from_matrix(**kwargs),**kwargs)
|
kwargs_rot,kwargs_ori = Orientation._split_kwargs(kwargs,Rotation.from_matrix)
|
||||||
|
return cls(rotation=Rotation.from_matrix(**kwargs_rot),**kwargs_ori)
|
||||||
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@util.extended_docstring(Rotation.from_Rodrigues_vector,_parameter_doc)
|
@util.extended_docstring(Rotation.from_Rodrigues_vector,_parameter_doc)
|
||||||
def from_Rodrigues_vector(cls,**kwargs):
|
def from_Rodrigues_vector(cls,**kwargs):
|
||||||
return cls(rotation=Rotation.from_Rodrigues_vector(**kwargs),**kwargs)
|
kwargs_rot,kwargs_ori = Orientation._split_kwargs(kwargs,Rotation.from_Rodrigues_vector)
|
||||||
|
return cls(rotation=Rotation.from_Rodrigues_vector(**kwargs_rot),**kwargs_ori)
|
||||||
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@util.extended_docstring(Rotation.from_homochoric,_parameter_doc)
|
@util.extended_docstring(Rotation.from_homochoric,_parameter_doc)
|
||||||
def from_homochoric(cls,**kwargs):
|
def from_homochoric(cls,**kwargs):
|
||||||
return cls(rotation=Rotation.from_homochoric(**kwargs),**kwargs)
|
kwargs_rot,kwargs_ori = Orientation._split_kwargs(kwargs,Rotation.from_homochoric)
|
||||||
|
return cls(rotation=Rotation.from_homochoric(**kwargs_rot),**kwargs_ori)
|
||||||
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@util.extended_docstring(Rotation.from_cubochoric,_parameter_doc)
|
@util.extended_docstring(Rotation.from_cubochoric,_parameter_doc)
|
||||||
def from_cubochoric(cls,**kwargs):
|
def from_cubochoric(cls,**kwargs):
|
||||||
return cls(rotation=Rotation.from_cubochoric(**kwargs),**kwargs)
|
kwargs_rot,kwargs_ori = Orientation._split_kwargs(kwargs,Rotation.from_cubochoric)
|
||||||
|
return cls(rotation=Rotation.from_cubochoric(**kwargs_rot),**kwargs_ori)
|
||||||
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@util.extended_docstring(Rotation.from_spherical_component,_parameter_doc)
|
@util.extended_docstring(Rotation.from_spherical_component,_parameter_doc)
|
||||||
def from_spherical_component(cls,**kwargs):
|
def from_spherical_component(cls,**kwargs):
|
||||||
return cls(rotation=Rotation.from_spherical_component(**kwargs),**kwargs)
|
kwargs_rot,kwargs_ori = Orientation._split_kwargs(kwargs,Rotation.from_spherical_component)
|
||||||
|
return cls(rotation=Rotation.from_spherical_component(**kwargs_rot),**kwargs_ori)
|
||||||
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@util.extended_docstring(Rotation.from_fiber_component,_parameter_doc)
|
@util.extended_docstring(Rotation.from_fiber_component,_parameter_doc)
|
||||||
def from_fiber_component(cls,**kwargs):
|
def from_fiber_component(cls,**kwargs):
|
||||||
return cls(rotation=Rotation.from_fiber_component(**kwargs),**kwargs)
|
kwargs_rot,kwargs_ori = Orientation._split_kwargs(kwargs,Rotation.from_fiber_component)
|
||||||
|
return cls(rotation=Rotation.from_fiber_component(**kwargs_rot),**kwargs_ori)
|
||||||
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
@ -429,7 +484,7 @@ class Orientation(Rotation):
|
||||||
raise ValueError('Missing crystal symmetry')
|
raise ValueError('Missing crystal symmetry')
|
||||||
|
|
||||||
o = self.symmetry_operations.broadcast_to(self.symmetry_operations.shape+self.shape,mode='right')
|
o = self.symmetry_operations.broadcast_to(self.symmetry_operations.shape+self.shape,mode='right')
|
||||||
return self.copy(rotation=o@Rotation(self.quaternion).broadcast_to(o.shape,mode='left'))
|
return self.copy(rotation=o*Rotation(self.quaternion).broadcast_to(o.shape,mode='left'))
|
||||||
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -469,26 +524,26 @@ class Orientation(Rotation):
|
||||||
if self.family is None:
|
if self.family is None:
|
||||||
raise ValueError('Missing crystal symmetry')
|
raise ValueError('Missing crystal symmetry')
|
||||||
|
|
||||||
rho_abs = np.abs(self.as_Rodrigues_vector(compact=True))
|
rho_abs = np.abs(self.as_Rodrigues_vector(compact=True))*(1.-1.e-9)
|
||||||
|
|
||||||
with np.errstate(invalid='ignore'):
|
with np.errstate(invalid='ignore'):
|
||||||
# using '*'/prod for 'and'
|
# using '*'/prod for 'and'
|
||||||
if self.family == 'cubic':
|
if self.family == 'cubic':
|
||||||
return (np.prod(np.sqrt(2)-1. >= rho_abs,axis=-1) *
|
return (np.prod(np.sqrt(2)-1. >= rho_abs,axis=-1) *
|
||||||
(1. >= np.sum(rho_abs,axis=-1))).astype(np.bool)
|
(1. >= np.sum(rho_abs,axis=-1))).astype(bool)
|
||||||
elif self.family == 'hexagonal':
|
elif self.family == 'hexagonal':
|
||||||
return (np.prod(1. >= rho_abs,axis=-1) *
|
return (np.prod(1. >= rho_abs,axis=-1) *
|
||||||
(2. >= np.sqrt(3)*rho_abs[...,0] + rho_abs[...,1]) *
|
(2. >= np.sqrt(3)*rho_abs[...,0] + rho_abs[...,1]) *
|
||||||
(2. >= np.sqrt(3)*rho_abs[...,1] + rho_abs[...,0]) *
|
(2. >= np.sqrt(3)*rho_abs[...,1] + rho_abs[...,0]) *
|
||||||
(2. >= np.sqrt(3) + rho_abs[...,2])).astype(np.bool)
|
(2. >= np.sqrt(3) + rho_abs[...,2])).astype(bool)
|
||||||
elif self.family == 'tetragonal':
|
elif self.family == 'tetragonal':
|
||||||
return (np.prod(1. >= rho_abs[...,:2],axis=-1) *
|
return (np.prod(1. >= rho_abs[...,:2],axis=-1) *
|
||||||
(np.sqrt(2) >= rho_abs[...,0] + rho_abs[...,1]) *
|
(np.sqrt(2) >= rho_abs[...,0] + rho_abs[...,1]) *
|
||||||
(np.sqrt(2) >= rho_abs[...,2] + 1.)).astype(np.bool)
|
(np.sqrt(2) >= rho_abs[...,2] + 1.)).astype(bool)
|
||||||
elif self.family == 'orthorhombic':
|
elif self.family == 'orthorhombic':
|
||||||
return (np.prod(1. >= rho_abs,axis=-1)).astype(np.bool)
|
return (np.prod(1. >= rho_abs,axis=-1)).astype(bool)
|
||||||
elif self.family == 'monoclinic':
|
elif self.family == 'monoclinic':
|
||||||
return (1. >= rho_abs[...,1]).astype(np.bool)
|
return (1. >= rho_abs[...,1]).astype(bool)
|
||||||
else:
|
else:
|
||||||
return np.all(np.isfinite(rho_abs),axis=-1)
|
return np.all(np.isfinite(rho_abs),axis=-1)
|
||||||
|
|
||||||
|
@ -512,28 +567,28 @@ class Orientation(Rotation):
|
||||||
if self.family is None:
|
if self.family is None:
|
||||||
raise ValueError('Missing crystal symmetry')
|
raise ValueError('Missing crystal symmetry')
|
||||||
|
|
||||||
rho = self.as_Rodrigues_vector(compact=True)
|
rho = self.as_Rodrigues_vector(compact=True)*(1.0-1.0e-9)
|
||||||
|
|
||||||
with np.errstate(invalid='ignore'):
|
with np.errstate(invalid='ignore'):
|
||||||
if self.family == 'cubic':
|
if self.family == 'cubic':
|
||||||
return ((rho[...,0] >= rho[...,1]) &
|
return ((rho[...,0] >= rho[...,1]) &
|
||||||
(rho[...,1] >= rho[...,2]) &
|
(rho[...,1] >= rho[...,2]) &
|
||||||
(rho[...,2] >= 0)).astype(np.bool)
|
(rho[...,2] >= 0)).astype(bool)
|
||||||
elif self.family == 'hexagonal':
|
elif self.family == 'hexagonal':
|
||||||
return ((rho[...,0] >= rho[...,1]*np.sqrt(3)) &
|
return ((rho[...,0] >= rho[...,1]*np.sqrt(3)) &
|
||||||
(rho[...,1] >= 0) &
|
(rho[...,1] >= 0) &
|
||||||
(rho[...,2] >= 0)).astype(np.bool)
|
(rho[...,2] >= 0)).astype(bool)
|
||||||
elif self.family == 'tetragonal':
|
elif self.family == 'tetragonal':
|
||||||
return ((rho[...,0] >= rho[...,1]) &
|
return ((rho[...,0] >= rho[...,1]) &
|
||||||
(rho[...,1] >= 0) &
|
(rho[...,1] >= 0) &
|
||||||
(rho[...,2] >= 0)).astype(np.bool)
|
(rho[...,2] >= 0)).astype(bool)
|
||||||
elif self.family == 'orthorhombic':
|
elif self.family == 'orthorhombic':
|
||||||
return ((rho[...,0] >= 0) &
|
return ((rho[...,0] >= 0) &
|
||||||
(rho[...,1] >= 0) &
|
(rho[...,1] >= 0) &
|
||||||
(rho[...,2] >= 0)).astype(np.bool)
|
(rho[...,2] >= 0)).astype(bool)
|
||||||
elif self.family == 'monoclinic':
|
elif self.family == 'monoclinic':
|
||||||
return ((rho[...,1] >= 0) &
|
return ((rho[...,1] >= 0) &
|
||||||
(rho[...,2] >= 0)).astype(np.bool)
|
(rho[...,2] >= 0)).astype(bool)
|
||||||
else:
|
else:
|
||||||
return np.ones_like(rho[...,0],dtype=bool)
|
return np.ones_like(rho[...,0],dtype=bool)
|
||||||
|
|
||||||
|
@ -608,7 +663,7 @@ class Orientation(Rotation):
|
||||||
o,lattice = self.relation_operations(model,return_lattice=True)
|
o,lattice = self.relation_operations(model,return_lattice=True)
|
||||||
target = Orientation(lattice=lattice)
|
target = Orientation(lattice=lattice)
|
||||||
o = o.broadcast_to(o.shape+self.shape,mode='right')
|
o = o.broadcast_to(o.shape+self.shape,mode='right')
|
||||||
return self.copy(rotation=o@Rotation(self.quaternion).broadcast_to(o.shape,mode='left'),
|
return self.copy(rotation=o*Rotation(self.quaternion).broadcast_to(o.shape,mode='left'),
|
||||||
lattice=lattice,
|
lattice=lattice,
|
||||||
b = self.b if target.ratio['b'] is None else self.a*target.ratio['b'],
|
b = self.b if target.ratio['b'] is None else self.a*target.ratio['b'],
|
||||||
c = self.c if target.ratio['c'] is None else self.a*target.ratio['c'],
|
c = self.c if target.ratio['c'] is None else self.a*target.ratio['c'],
|
||||||
|
|
|
@ -80,7 +80,7 @@ class Result:
|
||||||
self.out_type_ho += f['/'.join([self.increments[0],'homogenization',m])].keys()
|
self.out_type_ho += f['/'.join([self.increments[0],'homogenization',m])].keys()
|
||||||
self.out_type_ho = list(set(self.out_type_ho)) # make unique
|
self.out_type_ho = list(set(self.out_type_ho)) # make unique
|
||||||
|
|
||||||
self.selection = {'increments': self.increments,
|
self.visible = {'increments': self.increments,
|
||||||
'phases': self.phases,
|
'phases': self.phases,
|
||||||
'homogenizations': self.homogenizations,
|
'homogenizations': self.homogenizations,
|
||||||
'out_type_ph': self.out_type_ph,
|
'out_type_ph': self.out_type_ph,
|
||||||
|
@ -94,23 +94,23 @@ class Result:
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
"""Show summary of file content."""
|
"""Show summary of file content."""
|
||||||
all_selected_increments = self.selection['increments']
|
visible_increments = self.visible['increments']
|
||||||
|
|
||||||
self.pick('increments',all_selected_increments[0:1])
|
self.view('increments',visible_increments[0:1])
|
||||||
first = self.list_data()
|
first = self.list_data()
|
||||||
|
|
||||||
self.pick('increments',all_selected_increments[-1:])
|
self.view('increments',visible_increments[-1:])
|
||||||
last = '' if len(all_selected_increments) < 2 else self.list_data()
|
last = '' if len(visible_increments) < 2 else self.list_data()
|
||||||
|
|
||||||
self.pick('increments',all_selected_increments)
|
self.view('increments',visible_increments)
|
||||||
|
|
||||||
in_between = '' if len(all_selected_increments) < 3 else \
|
in_between = '' if len(visible_increments) < 3 else \
|
||||||
''.join([f'\n{inc}\n ...\n' for inc in all_selected_increments[1:-2]])
|
''.join([f'\n{inc}\n ...\n' for inc in visible_increments[1:-1]])
|
||||||
|
|
||||||
return util.srepr(first + in_between + last)
|
return util.srepr(first + in_between + last)
|
||||||
|
|
||||||
|
|
||||||
def _manage_selection(self,action,what,datasets):
|
def _manage_view(self,action,what,datasets):
|
||||||
"""
|
"""
|
||||||
Manages the visibility of the groups.
|
Manages the visibility of the groups.
|
||||||
|
|
||||||
|
@ -119,10 +119,10 @@ class Result:
|
||||||
action : str
|
action : str
|
||||||
Select from 'set', 'add', and 'del'.
|
Select from 'set', 'add', and 'del'.
|
||||||
what : str
|
what : str
|
||||||
Attribute to change (must be from self.selection).
|
Attribute to change (must be from self.visible).
|
||||||
datasets : list of str or bool
|
datasets : list of str or bool
|
||||||
Name of datasets as list, supports ? and * wildcards.
|
Name of datasets as list; supports ? and * wildcards.
|
||||||
True is equivalent to [*], False is equivalent to []
|
True is equivalent to [*], False is equivalent to [].
|
||||||
|
|
||||||
"""
|
"""
|
||||||
def natural_sort(key):
|
def natural_sort(key):
|
||||||
|
@ -156,18 +156,18 @@ class Result:
|
||||||
choice.append(self.increments[idx+1])
|
choice.append(self.increments[idx+1])
|
||||||
|
|
||||||
valid = [e for e_ in [glob.fnmatch.filter(getattr(self,what),s) for s in choice] for e in e_]
|
valid = [e for e_ in [glob.fnmatch.filter(getattr(self,what),s) for s in choice] for e in e_]
|
||||||
existing = set(self.selection[what])
|
existing = set(self.visible[what])
|
||||||
|
|
||||||
if action == 'set':
|
if action == 'set':
|
||||||
self.selection[what] = valid
|
self.visible[what] = valid
|
||||||
elif action == 'add':
|
elif action == 'add':
|
||||||
add = existing.union(valid)
|
add = existing.union(valid)
|
||||||
add_sorted = sorted(add, key=natural_sort)
|
add_sorted = sorted(add, key=natural_sort)
|
||||||
self.selection[what] = add_sorted
|
self.visible[what] = add_sorted
|
||||||
elif action == 'del':
|
elif action == 'del':
|
||||||
diff = existing.difference(valid)
|
diff = existing.difference(valid)
|
||||||
diff_sorted = sorted(diff, key=natural_sort)
|
diff_sorted = sorted(diff, key=natural_sort)
|
||||||
self.selection[what] = diff_sorted
|
self.visible[what] = diff_sorted
|
||||||
|
|
||||||
|
|
||||||
def _get_attribute(self,path,attr):
|
def _get_attribute(self,path,attr):
|
||||||
|
@ -200,7 +200,7 @@ class Result:
|
||||||
self._allow_modification = True
|
self._allow_modification = True
|
||||||
|
|
||||||
def disallow_modification(self):
|
def disallow_modification(self):
|
||||||
"""Disllow to overwrite existing data (default case)."""
|
"""Disallow to overwrite existing data (default case)."""
|
||||||
self._allow_modification = False
|
self._allow_modification = False
|
||||||
|
|
||||||
|
|
||||||
|
@ -245,84 +245,84 @@ class Result:
|
||||||
|
|
||||||
def iterate(self,what):
|
def iterate(self,what):
|
||||||
"""
|
"""
|
||||||
Iterate over selection items by setting each one selected.
|
Iterate over visible items and view them independently.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
what : str
|
what : str
|
||||||
Attribute to change (must be from self.selection).
|
Attribute to change (must be from self.visible).
|
||||||
|
|
||||||
"""
|
"""
|
||||||
datasets = self.selection[what]
|
datasets = self.visible[what]
|
||||||
last_selection = datasets.copy()
|
last_view = datasets.copy()
|
||||||
for dataset in datasets:
|
for dataset in datasets:
|
||||||
if last_selection != self.selection[what]:
|
if last_view != self.visible[what]:
|
||||||
self._manage_selection('set',what,datasets)
|
self._manage_view('set',what,datasets)
|
||||||
raise Exception
|
raise Exception
|
||||||
self._manage_selection('set',what,dataset)
|
self._manage_view('set',what,dataset)
|
||||||
last_selection = self.selection[what]
|
last_view = self.visible[what]
|
||||||
yield dataset
|
yield dataset
|
||||||
self._manage_selection('set',what,datasets)
|
self._manage_view('set',what,datasets)
|
||||||
|
|
||||||
|
|
||||||
def pick(self,what,datasets):
|
def view(self,what,datasets):
|
||||||
"""
|
"""
|
||||||
Set selection.
|
Set view.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
what : str
|
what : str
|
||||||
attribute to change (must be from self.selection)
|
Attribute to change (must be from self.visible).
|
||||||
datasets : list of str or bool
|
datasets : list of str or bool
|
||||||
name of datasets as list, supports ? and * wildcards.
|
Name of datasets as list; supports ? and * wildcards.
|
||||||
True is equivalent to [*], False is equivalent to []
|
True is equivalent to [*], False is equivalent to [].
|
||||||
|
|
||||||
"""
|
"""
|
||||||
self._manage_selection('set',what,datasets)
|
self._manage_view('set',what,datasets)
|
||||||
|
|
||||||
|
|
||||||
def pick_more(self,what,datasets):
|
def view_more(self,what,datasets):
|
||||||
"""
|
"""
|
||||||
Add to selection.
|
Add to view.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
what : str
|
what : str
|
||||||
attribute to change (must be from self.selection)
|
Attribute to change (must be from self.visible).
|
||||||
datasets : list of str or bool
|
datasets : list of str or bool
|
||||||
name of datasets as list, supports ? and * wildcards.
|
Name of datasets as list; supports ? and * wildcards.
|
||||||
True is equivalent to [*], False is equivalent to []
|
True is equivalent to [*], False is equivalent to [].
|
||||||
|
|
||||||
"""
|
"""
|
||||||
self._manage_selection('add',what,datasets)
|
self._manage_view('add',what,datasets)
|
||||||
|
|
||||||
|
|
||||||
def pick_less(self,what,datasets):
|
def view_less(self,what,datasets):
|
||||||
"""
|
"""
|
||||||
Delete from selection.
|
Delete from view.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
what : str
|
what : str
|
||||||
attribute to change (must be from self.selection)
|
Attribute to change (must be from self.visible).
|
||||||
datasets : list of str or bool
|
datasets : list of str or bool
|
||||||
name of datasets as list, supports ? and * wildcards.
|
Name of datasets as list; supports ? and * wildcards.
|
||||||
True is equivalent to [*], False is equivalent to []
|
True is equivalent to [*], False is equivalent to [].
|
||||||
|
|
||||||
"""
|
"""
|
||||||
self._manage_selection('del',what,datasets)
|
self._manage_view('del',what,datasets)
|
||||||
|
|
||||||
|
|
||||||
def rename(self,name_old,name_new):
|
def rename(self,name_old,name_new):
|
||||||
"""
|
"""
|
||||||
Rename datasets.
|
Rename dataset.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
name_old : str
|
name_old : str
|
||||||
name of the datasets to be renamed
|
Name of the dataset to be renamed.
|
||||||
name_new : str
|
name_new : str
|
||||||
new name of the datasets
|
New name of the dataset.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if self._allow_modification:
|
if self._allow_modification:
|
||||||
|
@ -353,13 +353,13 @@ class Result:
|
||||||
----------
|
----------
|
||||||
datasets : iterable or str
|
datasets : iterable or str
|
||||||
constituent : int
|
constituent : int
|
||||||
Constituent to consider for phase data
|
Constituent to consider for phase data.
|
||||||
tagged : bool
|
tagged : bool
|
||||||
tag Table.column name with '#constituent'
|
Tag Table.column name with '#constituent'.
|
||||||
defaults to False
|
Defaults to False.
|
||||||
split : bool
|
split : bool
|
||||||
split Table by increment and return dictionary of Tables
|
Split Table by increment and return dictionary of Tables.
|
||||||
defaults to True
|
Defaults to True.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
sets = datasets if hasattr(datasets,'__iter__') and not isinstance(datasets,str) else \
|
sets = datasets if hasattr(datasets,'__iter__') and not isinstance(datasets,str) else \
|
||||||
|
@ -371,7 +371,7 @@ class Result:
|
||||||
with h5py.File(self.fname,'r') as f:
|
with h5py.File(self.fname,'r') as f:
|
||||||
for dataset in sets:
|
for dataset in sets:
|
||||||
for group in self.groups_with_datasets(dataset):
|
for group in self.groups_with_datasets(dataset):
|
||||||
path = os.path.join(group,dataset)
|
path = '/'.join([group,dataset])
|
||||||
inc,prop,name,cat,item = (path.split('/') + ['']*5)[:5]
|
inc,prop,name,cat,item = (path.split('/') + ['']*5)[:5]
|
||||||
key = '/'.join([prop,name+tag])
|
key = '/'.join([prop,name+tag])
|
||||||
if key not in inGeom:
|
if key not in inGeom:
|
||||||
|
@ -388,15 +388,15 @@ class Result:
|
||||||
np.nan,
|
np.nan,
|
||||||
dtype=np.dtype(f[path]))
|
dtype=np.dtype(f[path]))
|
||||||
data[inGeom[key]] = (f[path] if len(shape)>1 else np.expand_dims(f[path],1))[inData[key]]
|
data[inGeom[key]] = (f[path] if len(shape)>1 else np.expand_dims(f[path],1))[inData[key]]
|
||||||
path = (os.path.join(*([prop,name]+([cat] if cat else [])+([item] if item else []))) if split else path)+tag
|
path = ('/'.join([prop,name]+([cat] if cat else [])+([item] if item else [])) if split else path)+tag
|
||||||
if split:
|
if split:
|
||||||
try:
|
try:
|
||||||
tbl[inc].add(path,data)
|
tbl[inc] = tbl[inc].add(path,data)
|
||||||
except KeyError:
|
except KeyError:
|
||||||
tbl[inc] = Table(data.reshape(self.N_materialpoints,-1),{path:data.shape[1:]})
|
tbl[inc] = Table(data.reshape(self.N_materialpoints,-1),{path:data.shape[1:]})
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
tbl.add(path,data)
|
tbl = tbl.add(path,data)
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
tbl = Table(data.reshape(self.N_materialpoints,-1),{path:data.shape[1:]})
|
tbl = Table(data.reshape(self.N_materialpoints,-1),{path:data.shape[1:]})
|
||||||
|
|
||||||
|
@ -415,7 +415,7 @@ class Result:
|
||||||
are considered as they contain user-relevant data.
|
are considered as they contain user-relevant data.
|
||||||
Single strings will be treated as list with one entry.
|
Single strings will be treated as list with one entry.
|
||||||
|
|
||||||
Wild card matching is allowed, but the number of arguments need to fit.
|
Wild card matching is allowed, but the number of arguments needs to fit.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
|
@ -1134,8 +1134,7 @@ class Result:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
chunk_size = 1024**2//8
|
chunk_size = 1024**2//8
|
||||||
num_threads = damask.environment.options['DAMASK_NUM_THREADS']
|
pool = mp.Pool(int(os.environ.get('OMP_NUM_THREADS',1)))
|
||||||
pool = mp.Pool(int(num_threads) if num_threads is not None else None)
|
|
||||||
lock = mp.Manager().Lock()
|
lock = mp.Manager().Lock()
|
||||||
|
|
||||||
groups = self.groups_with_datasets(datasets.values())
|
groups = self.groups_with_datasets(datasets.values())
|
||||||
|
@ -1190,8 +1189,8 @@ class Result:
|
||||||
"""
|
"""
|
||||||
Write XDMF file to directly visualize data in DADF5 file.
|
Write XDMF file to directly visualize data in DADF5 file.
|
||||||
|
|
||||||
This works only for scalar, 3-vector and 3x3-tensor data.
|
The view is not taken into account, i.e. the content of the
|
||||||
Selection is not taken into account.
|
whole file will be included.
|
||||||
"""
|
"""
|
||||||
if self.N_constituents != 1 or len(self.phases) != 1 or not self.structured:
|
if self.N_constituents != 1 or len(self.phases) != 1 or not self.structured:
|
||||||
raise TypeError('XDMF output requires homogeneous grid')
|
raise TypeError('XDMF output requires homogeneous grid')
|
||||||
|
@ -1288,7 +1287,7 @@ class Result:
|
||||||
np.prod(shape))}
|
np.prod(shape))}
|
||||||
data_items[-1].text=f'{os.path.split(self.fname)[1]}:{name}'
|
data_items[-1].text=f'{os.path.split(self.fname)[1]}:{name}'
|
||||||
|
|
||||||
with open(self.fname.with_suffix('.xdmf').name,'w') as f:
|
with open(self.fname.with_suffix('.xdmf').name,'w',newline='\n') as f:
|
||||||
f.write(xml.dom.minidom.parseString(ET.tostring(xdmf).decode()).toprettyxml())
|
f.write(xml.dom.minidom.parseString(ET.tostring(xdmf).decode()).toprettyxml())
|
||||||
|
|
||||||
|
|
||||||
|
@ -1320,10 +1319,10 @@ class Result:
|
||||||
|
|
||||||
N_digits = int(np.floor(np.log10(max(1,int(self.increments[-1][3:])))))+1
|
N_digits = int(np.floor(np.log10(max(1,int(self.increments[-1][3:])))))+1
|
||||||
|
|
||||||
for inc in util.show_progress(self.iterate('increments'),len(self.selection['increments'])):
|
for inc in util.show_progress(self.iterate('increments'),len(self.visible['increments'])):
|
||||||
|
|
||||||
picked_backup_ho = self.selection['homogenizations'].copy()
|
viewed_backup_ho = self.visible['homogenizations'].copy()
|
||||||
self.pick('homogenizations',False)
|
self.view('homogenizations',False)
|
||||||
for label in (labels if isinstance(labels,list) else [labels]):
|
for label in (labels if isinstance(labels,list) else [labels]):
|
||||||
for o in self.iterate('out_type_ph'):
|
for o in self.iterate('out_type_ph'):
|
||||||
for c in range(self.N_constituents):
|
for c in range(self.N_constituents):
|
||||||
|
@ -1343,10 +1342,10 @@ class Result:
|
||||||
ph_name = re.compile(r'(?<=(phase\/))(.*?)(?=(mechanics))') # identify phase name
|
ph_name = re.compile(r'(?<=(phase\/))(.*?)(?=(mechanics))') # identify phase name
|
||||||
dset_name = prefix+re.sub(ph_name,r'',paths[0].split('/',1)[1]) # remove phase name
|
dset_name = prefix+re.sub(ph_name,r'',paths[0].split('/',1)[1]) # remove phase name
|
||||||
v.add(array,dset_name+f' / {self._get_attribute(paths[0],"Unit")}')
|
v.add(array,dset_name+f' / {self._get_attribute(paths[0],"Unit")}')
|
||||||
self.pick('homogenizations',picked_backup_ho)
|
self.view('homogenizations',viewed_backup_ho)
|
||||||
|
|
||||||
picked_backup_ph = self.selection['phases'].copy()
|
viewed_backup_ph = self.visible['phases'].copy()
|
||||||
self.pick('phases',False)
|
self.view('phases',False)
|
||||||
for label in (labels if isinstance(labels,list) else [labels]):
|
for label in (labels if isinstance(labels,list) else [labels]):
|
||||||
for _ in self.iterate('out_type_ho'):
|
for _ in self.iterate('out_type_ho'):
|
||||||
paths = self.get_dataset_location(label)
|
paths = self.get_dataset_location(label)
|
||||||
|
@ -1354,7 +1353,7 @@ class Result:
|
||||||
continue
|
continue
|
||||||
array = self.read_dataset(paths)
|
array = self.read_dataset(paths)
|
||||||
v.add(array,paths[0].split('/',1)[1]+f' / {self._get_attribute(paths[0],"Unit")}')
|
v.add(array,paths[0].split('/',1)[1]+f' / {self._get_attribute(paths[0],"Unit")}')
|
||||||
self.pick('phases',picked_backup_ph)
|
self.view('phases',viewed_backup_ph)
|
||||||
|
|
||||||
u = self.read_dataset(self.get_dataset_location('u_n' if mode.lower() == 'cell' else 'u_p'))
|
u = self.read_dataset(self.get_dataset_location('u_n' if mode.lower() == 'cell' else 'u_p'))
|
||||||
v.add(u,'u')
|
v.add(u,'u')
|
||||||
|
|
|
@ -35,6 +35,11 @@ class Rotation:
|
||||||
- b = Q @ a
|
- b = Q @ a
|
||||||
- b = np.dot(Q.as_matrix(),a)
|
- b = np.dot(Q.as_matrix(),a)
|
||||||
|
|
||||||
|
Compound rotations R1 (first) and R2 (second):
|
||||||
|
|
||||||
|
- R = R2 * R1
|
||||||
|
- R = Rotation.from_matrix(np.dot(R2.as_matrix(),R1.as_matrix())
|
||||||
|
|
||||||
References
|
References
|
||||||
----------
|
----------
|
||||||
D. Rowenhorst et al., Modelling and Simulation in Materials Science and Engineering 23:083501, 2015
|
D. Rowenhorst et al., Modelling and Simulation in Materials Science and Engineering 23:083501, 2015
|
||||||
|
@ -65,22 +70,13 @@ class Rotation:
|
||||||
|
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
"""Represent rotation as unit quaternion, rotation matrix, and Bunge-Euler angles."""
|
"""Represent rotation as unit quaternion(s)."""
|
||||||
if self == Rotation():
|
return f'Quaternion{" " if self.quaternion.shape == (4,) else "s of shape "+str(self.quaternion.shape)+chr(10)}'\
|
||||||
return 'Rotation()'
|
+ str(self.quaternion)
|
||||||
else:
|
|
||||||
return f'Quaternions {self.shape}:\n'+str(self.quaternion) \
|
|
||||||
if self.quaternion.shape != (4,) else \
|
|
||||||
'\n'.join([
|
|
||||||
'Quaternion: (real={:.3f}, imag=<{:+.3f}, {:+.3f}, {:+.3f}>)'.format(*(self.quaternion)),
|
|
||||||
'Matrix:\n{}'.format(np.round(self.as_matrix(),8)),
|
|
||||||
'Bunge Eulers / deg: ({:3.2f}, {:3.2f}, {:3.2f})'.format(*self.as_Euler_angles(degrees=True)),
|
|
||||||
])
|
|
||||||
|
|
||||||
|
|
||||||
# ToDo: Check difference __copy__ vs __deepcopy__
|
|
||||||
def __copy__(self,**kwargs):
|
def __copy__(self,**kwargs):
|
||||||
"""Copy."""
|
"""Create deep copy."""
|
||||||
return self.__class__(rotation=kwargs['rotation'] if 'rotation' in kwargs else self.quaternion)
|
return self.__class__(rotation=kwargs['rotation'] if 'rotation' in kwargs else self.quaternion)
|
||||||
|
|
||||||
copy = __copy__
|
copy = __copy__
|
||||||
|
@ -97,6 +93,26 @@ class Rotation:
|
||||||
"""
|
"""
|
||||||
Equal to other.
|
Equal to other.
|
||||||
|
|
||||||
|
Equality is determined taking limited floating point precision into account.
|
||||||
|
See numpy.allclose for details.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
other : Rotation
|
||||||
|
Rotation to check for equality.
|
||||||
|
|
||||||
|
"""
|
||||||
|
s = self.quaternion
|
||||||
|
o = other.quaternion
|
||||||
|
if self.shape == () == other.shape:
|
||||||
|
return np.allclose(s,o) or (np.isclose(s[0],0.0) and np.allclose(s,-1.0*o))
|
||||||
|
else:
|
||||||
|
return np.all(np.isclose(s,o),-1) + np.all(np.isclose(s,-1.0*o),-1) * np.isclose(s[...,0],0.0)
|
||||||
|
|
||||||
|
def __ne__(self,other):
|
||||||
|
"""
|
||||||
|
Not equal to other.
|
||||||
|
|
||||||
Equality is determined taking limited floating point precision into
|
Equality is determined taking limited floating point precision into
|
||||||
account. See numpy.allclose for details.
|
account. See numpy.allclose for details.
|
||||||
|
|
||||||
|
@ -106,13 +122,21 @@ class Rotation:
|
||||||
Rotation to check for equality.
|
Rotation to check for equality.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return np.prod(self.shape,dtype=int) == np.prod(other.shape,dtype=int) \
|
return np.logical_not(self==other)
|
||||||
and np.allclose(self.quaternion,other.quaternion)
|
|
||||||
|
|
||||||
|
def __array__(self):
|
||||||
|
"""Initializer for numpy."""
|
||||||
|
return self.quaternion
|
||||||
|
|
||||||
|
|
||||||
|
@property
|
||||||
|
def size(self):
|
||||||
|
return self.quaternion[...,0].size
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def shape(self):
|
def shape(self):
|
||||||
return self.quaternion.shape[:-1]
|
return self.quaternion[...,0].shape
|
||||||
|
|
||||||
|
|
||||||
def __len__(self):
|
def __len__(self):
|
||||||
|
@ -127,41 +151,46 @@ class Rotation:
|
||||||
return dup
|
return dup
|
||||||
|
|
||||||
|
|
||||||
def __pow__(self,pwr):
|
def __pow__(self,exp):
|
||||||
"""
|
"""
|
||||||
Raise quaternion to power.
|
Perform the rotation 'exp' times.
|
||||||
|
|
||||||
Equivalent to performing the rotation 'pwr' times.
|
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
pwr : float
|
exp : float
|
||||||
Power to raise quaternion to.
|
Exponent.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
phi = np.arccos(self.quaternion[...,0:1])
|
phi = np.arccos(self.quaternion[...,0:1])
|
||||||
p = self.quaternion[...,1:]/np.linalg.norm(self.quaternion[...,1:],axis=-1,keepdims=True)
|
p = self.quaternion[...,1:]/np.linalg.norm(self.quaternion[...,1:],axis=-1,keepdims=True)
|
||||||
return self.copy(rotation=Rotation(np.block([np.cos(pwr*phi),np.sin(pwr*phi)*p]))._standardize())
|
return self.copy(rotation=Rotation(np.block([np.cos(exp*phi),np.sin(exp*phi)*p]))._standardize())
|
||||||
|
|
||||||
|
def __ipow__(self,exp):
|
||||||
def __mul__(self,other):
|
|
||||||
"""Standard multiplication is not implemented."""
|
|
||||||
raise NotImplementedError('Use "R@b", i.e. matmul, to apply rotation "R" to object "b"')
|
|
||||||
|
|
||||||
|
|
||||||
def __matmul__(self,other):
|
|
||||||
"""
|
"""
|
||||||
Rotation of vector, second or fourth order tensor, or rotation object.
|
Perform the rotation 'exp' times (in-place).
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
other : numpy.ndarray or Rotation
|
exp : float
|
||||||
Vector, second or fourth order tensor, or rotation object that is rotated.
|
Exponent.
|
||||||
|
|
||||||
|
"""
|
||||||
|
return self**exp
|
||||||
|
|
||||||
|
|
||||||
|
def __mul__(self,other):
|
||||||
|
"""
|
||||||
|
Compose this rotation with other.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
other : Rotation of shape(self.shape)
|
||||||
|
Rotation for composition.
|
||||||
|
|
||||||
Returns
|
Returns
|
||||||
-------
|
-------
|
||||||
other_rot : numpy.ndarray or Rotation
|
composition : Rotation
|
||||||
Rotated vector, second or fourth order tensor, or rotation object.
|
Compound rotation self*other, i.e. first other then self rotation.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if isinstance(other,Rotation):
|
if isinstance(other,Rotation):
|
||||||
|
@ -172,8 +201,71 @@ class Rotation:
|
||||||
q = (q_m*q_o - np.einsum('...i,...i',p_m,p_o).reshape(self.shape+(1,)))
|
q = (q_m*q_o - np.einsum('...i,...i',p_m,p_o).reshape(self.shape+(1,)))
|
||||||
p = q_m*p_o + q_o*p_m + _P * np.cross(p_m,p_o)
|
p = q_m*p_o + q_o*p_m + _P * np.cross(p_m,p_o)
|
||||||
return Rotation(np.block([q,p]))._standardize()
|
return Rotation(np.block([q,p]))._standardize()
|
||||||
|
else:
|
||||||
|
raise TypeError('Use "R@b", i.e. matmul, to apply rotation "R" to object "b"')
|
||||||
|
|
||||||
elif isinstance(other,np.ndarray):
|
def __imul__(self,other):
|
||||||
|
"""
|
||||||
|
Compose this rotation with other (in-place).
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
other : Rotation of shape(self.shape)
|
||||||
|
Rotation for composition.
|
||||||
|
|
||||||
|
"""
|
||||||
|
return self*other
|
||||||
|
|
||||||
|
|
||||||
|
def __truediv__(self,other):
|
||||||
|
"""
|
||||||
|
Compose this rotation with inverse of other.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
other : damask.Rotation of shape (self.shape)
|
||||||
|
Rotation to inverse composition.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
composition : Rotation
|
||||||
|
Compound rotation self*(~other), i.e. first inverse of other then self rotation.
|
||||||
|
|
||||||
|
"""
|
||||||
|
if isinstance(other,Rotation):
|
||||||
|
return self*~other
|
||||||
|
else:
|
||||||
|
raise TypeError('Use "R@b", i.e. matmul, to apply rotation "R" to object "b"')
|
||||||
|
|
||||||
|
def __itruediv__(self,other):
|
||||||
|
"""
|
||||||
|
Compose this rotation with inverse of other (in-place).
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
other : Rotation of shape (self.shape)
|
||||||
|
Rotation to inverse composition.
|
||||||
|
|
||||||
|
"""
|
||||||
|
return self/other
|
||||||
|
|
||||||
|
|
||||||
|
def __matmul__(self,other):
|
||||||
|
"""
|
||||||
|
Rotation of vector, second order tensor, or fourth order tensor.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
other : numpy.ndarray of shape (...,3), (...,3,3), or (...,3,3,3,3)
|
||||||
|
Vector or tensor on which to apply the rotation.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
rotated : numpy.ndarray of shape (...,3), (...,3,3), or (...,3,3,3,3)
|
||||||
|
Rotated vector or tensor, i.e. transformed to frame defined by rotation.
|
||||||
|
|
||||||
|
"""
|
||||||
|
if isinstance(other,np.ndarray):
|
||||||
if self.shape + (3,) == other.shape:
|
if self.shape + (3,) == other.shape:
|
||||||
q_m = self.quaternion[...,0]
|
q_m = self.quaternion[...,0]
|
||||||
p_m = self.quaternion[...,1:]
|
p_m = self.quaternion[...,1:]
|
||||||
|
@ -193,9 +285,13 @@ class Rotation:
|
||||||
return np.einsum('...im,...jn,...ko,...lp,...mnop',R,R,R,R,other)
|
return np.einsum('...im,...jn,...ko,...lp,...mnop',R,R,R,R,other)
|
||||||
else:
|
else:
|
||||||
raise ValueError('Can only rotate vectors, 2nd order tensors, and 4th order tensors')
|
raise ValueError('Can only rotate vectors, 2nd order tensors, and 4th order tensors')
|
||||||
|
elif isinstance(other,Rotation):
|
||||||
|
raise TypeError('Use "R1*R2", i.e. multiplication, to compose rotations "R1" and "R2"')
|
||||||
else:
|
else:
|
||||||
raise TypeError(f'Cannot rotate {type(other)}')
|
raise TypeError(f'Cannot rotate {type(other)}')
|
||||||
|
|
||||||
|
apply = __matmul__
|
||||||
|
|
||||||
|
|
||||||
def _standardize(self):
|
def _standardize(self):
|
||||||
"""Standardize quaternion (ensure positive real hemisphere)."""
|
"""Standardize quaternion (ensure positive real hemisphere)."""
|
||||||
|
@ -296,7 +392,7 @@ class Rotation:
|
||||||
Rotation to which the misorientation is computed.
|
Rotation to which the misorientation is computed.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return other@~self
|
return other*~self
|
||||||
|
|
||||||
|
|
||||||
################################################################################################
|
################################################################################################
|
||||||
|
@ -379,15 +475,17 @@ class Rotation:
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
vector : bool, optional
|
compact : bool, optional
|
||||||
Return as actual Rodrigues-Frank vector, i.e. axis
|
Return as actual Rodrigues-Frank vector,
|
||||||
and angle argument are not separated.
|
i.e. axis and angle argument are not separated.
|
||||||
|
|
||||||
Returns
|
Returns
|
||||||
-------
|
-------
|
||||||
rho : numpy.ndarray of shape (...,4) unless vector == True:
|
rho : numpy.ndarray of shape (...,4) containing
|
||||||
numpy.ndarray of shape (...,3)
|
[n_1, n_2, n_3, tan(ω/2)], ǀnǀ = 1 and ω ∈ [0,π]
|
||||||
Rodrigues-Frank vector: [n_1, n_2, n_3, tan(ω/2)], ǀnǀ = 1 and ω ∈ [0,π].
|
unless compact == True:
|
||||||
|
numpy.ndarray of shape (...,3) containing
|
||||||
|
tan(ω/2) [n_1, n_2, n_3], ω ∈ [0,π].
|
||||||
|
|
||||||
"""
|
"""
|
||||||
ro = Rotation._qu2ro(self.quaternion)
|
ro = Rotation._qu2ro(self.quaternion)
|
||||||
|
@ -415,8 +513,8 @@ class Rotation:
|
||||||
|
|
||||||
Returns
|
Returns
|
||||||
-------
|
-------
|
||||||
c : numpy.ndarray of shape (...,3)
|
x : numpy.ndarray of shape (...,3)
|
||||||
Cubochoric vector: (c_1, c_2, c_3), max(c_i) < 1/2*π^(2/3).
|
Cubochoric vector: (x_1, x_2, x_3), max(x_i) < 1/2*π^(2/3).
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return Rotation._qu2cu(self.quaternion)
|
return Rotation._qu2cu(self.quaternion)
|
||||||
|
@ -427,8 +525,7 @@ class Rotation:
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def from_quaternion(q,
|
def from_quaternion(q,
|
||||||
accept_homomorph = False,
|
accept_homomorph = False,
|
||||||
P = -1,
|
P = -1):
|
||||||
**kwargs):
|
|
||||||
"""
|
"""
|
||||||
Initialize from quaternion.
|
Initialize from quaternion.
|
||||||
|
|
||||||
|
@ -463,8 +560,7 @@ class Rotation:
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def from_Euler_angles(phi,
|
def from_Euler_angles(phi,
|
||||||
degrees = False,
|
degrees = False):
|
||||||
**kwargs):
|
|
||||||
"""
|
"""
|
||||||
Initialize from Bunge-Euler angles.
|
Initialize from Bunge-Euler angles.
|
||||||
|
|
||||||
|
@ -491,8 +587,7 @@ class Rotation:
|
||||||
def from_axis_angle(axis_angle,
|
def from_axis_angle(axis_angle,
|
||||||
degrees = False,
|
degrees = False,
|
||||||
normalize = False,
|
normalize = False,
|
||||||
P = -1,
|
P = -1):
|
||||||
**kwargs):
|
|
||||||
"""
|
"""
|
||||||
Initialize from Axis angle pair.
|
Initialize from Axis angle pair.
|
||||||
|
|
||||||
|
@ -529,8 +624,7 @@ class Rotation:
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def from_basis(basis,
|
def from_basis(basis,
|
||||||
orthonormal = True,
|
orthonormal = True,
|
||||||
reciprocal = False,
|
reciprocal = False):
|
||||||
**kwargs):
|
|
||||||
"""
|
"""
|
||||||
Initialize from lattice basis vectors.
|
Initialize from lattice basis vectors.
|
||||||
|
|
||||||
|
@ -564,7 +658,7 @@ class Rotation:
|
||||||
return Rotation(Rotation._om2qu(om))
|
return Rotation(Rotation._om2qu(om))
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def from_matrix(R,**kwargs):
|
def from_matrix(R):
|
||||||
"""
|
"""
|
||||||
Initialize from rotation matrix.
|
Initialize from rotation matrix.
|
||||||
|
|
||||||
|
@ -608,8 +702,7 @@ class Rotation:
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def from_Rodrigues_vector(rho,
|
def from_Rodrigues_vector(rho,
|
||||||
normalize = False,
|
normalize = False,
|
||||||
P = -1,
|
P = -1):
|
||||||
**kwargs):
|
|
||||||
"""
|
"""
|
||||||
Initialize from Rodrigues-Frank vector (angle separated from axis).
|
Initialize from Rodrigues-Frank vector (angle separated from axis).
|
||||||
|
|
||||||
|
@ -640,8 +733,7 @@ class Rotation:
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def from_homochoric(h,
|
def from_homochoric(h,
|
||||||
P = -1,
|
P = -1):
|
||||||
**kwargs):
|
|
||||||
"""
|
"""
|
||||||
Initialize from homochoric vector.
|
Initialize from homochoric vector.
|
||||||
|
|
||||||
|
@ -667,21 +759,20 @@ class Rotation:
|
||||||
return Rotation(Rotation._ho2qu(ho))
|
return Rotation(Rotation._ho2qu(ho))
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def from_cubochoric(c,
|
def from_cubochoric(x,
|
||||||
P = -1,
|
P = -1):
|
||||||
**kwargs):
|
|
||||||
"""
|
"""
|
||||||
Initialize from cubochoric vector.
|
Initialize from cubochoric vector.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
c : numpy.ndarray of shape (...,3)
|
x : numpy.ndarray of shape (...,3)
|
||||||
Cubochoric vector: (c_1, c_2, c_3), max(c_i) < 1/2*π^(2/3).
|
Cubochoric vector: (x_1, x_2, x_3), max(x_i) < 1/2*π^(2/3).
|
||||||
P : int ∈ {-1,1}, optional
|
P : int ∈ {-1,1}, optional
|
||||||
Convention used. Defaults to -1.
|
Convention used. Defaults to -1.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
cu = np.array(c,dtype=float)
|
cu = np.array(x,dtype=float)
|
||||||
if cu.shape[:-2:-1] != (3,):
|
if cu.shape[:-2:-1] != (3,):
|
||||||
raise ValueError('Invalid shape.')
|
raise ValueError('Invalid shape.')
|
||||||
if abs(P) != 1:
|
if abs(P) != 1:
|
||||||
|
@ -697,8 +788,7 @@ class Rotation:
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def from_random(shape = None,
|
def from_random(shape = None,
|
||||||
rng_seed = None,
|
rng_seed = None):
|
||||||
**kwargs):
|
|
||||||
"""
|
"""
|
||||||
Draw random rotation.
|
Draw random rotation.
|
||||||
|
|
||||||
|
@ -791,8 +881,7 @@ class Rotation:
|
||||||
sigma,
|
sigma,
|
||||||
N = 500,
|
N = 500,
|
||||||
degrees = True,
|
degrees = True,
|
||||||
rng_seed = None,
|
rng_seed = None):
|
||||||
**kwargs):
|
|
||||||
"""
|
"""
|
||||||
Calculate set of rotations with Gaussian distribution around center.
|
Calculate set of rotations with Gaussian distribution around center.
|
||||||
|
|
||||||
|
@ -819,7 +908,7 @@ class Rotation:
|
||||||
np.sqrt(1-u**2)*np.sin(Theta),
|
np.sqrt(1-u**2)*np.sin(Theta),
|
||||||
u, omega])
|
u, omega])
|
||||||
|
|
||||||
return Rotation.from_axis_angle(p) @ center
|
return Rotation.from_axis_angle(p) * center
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@ -828,8 +917,7 @@ class Rotation:
|
||||||
sigma = 0.0,
|
sigma = 0.0,
|
||||||
N = 500,
|
N = 500,
|
||||||
degrees = True,
|
degrees = True,
|
||||||
rng_seed = None,
|
rng_seed = None):
|
||||||
**kwargs):
|
|
||||||
"""
|
"""
|
||||||
Calculate set of rotations with Gaussian distribution around direction.
|
Calculate set of rotations with Gaussian distribution around direction.
|
||||||
|
|
||||||
|
@ -870,8 +958,8 @@ class Rotation:
|
||||||
f[::2,:3] *= -1 # flip half the rotation axes to negative sense
|
f[::2,:3] *= -1 # flip half the rotation axes to negative sense
|
||||||
|
|
||||||
return R_align.broadcast_to(N) \
|
return R_align.broadcast_to(N) \
|
||||||
@ Rotation.from_axis_angle(p,normalize=True) \
|
* Rotation.from_axis_angle(p,normalize=True) \
|
||||||
@ Rotation.from_axis_angle(f)
|
* Rotation.from_axis_angle(f)
|
||||||
|
|
||||||
|
|
||||||
####################################################################################################
|
####################################################################################################
|
||||||
|
@ -1060,7 +1148,6 @@ class Rotation:
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _om2ax(om):
|
def _om2ax(om):
|
||||||
"""Rotation matrix to axis angle pair."""
|
"""Rotation matrix to axis angle pair."""
|
||||||
#return Rotation._qu2ax(Rotation._om2qu(om)) # HOTFIX
|
|
||||||
diag_delta = -_P*np.block([om[...,1,2:3]-om[...,2,1:2],
|
diag_delta = -_P*np.block([om[...,1,2:3]-om[...,2,1:2],
|
||||||
om[...,2,0:1]-om[...,0,2:3],
|
om[...,2,0:1]-om[...,0,2:3],
|
||||||
om[...,0,1:2]-om[...,1,0:1]
|
om[...,0,1:2]-om[...,1,0:1]
|
||||||
|
|
|
@ -26,7 +26,7 @@ class Table:
|
||||||
comments_ = [comments] if isinstance(comments,str) else comments
|
comments_ = [comments] if isinstance(comments,str) else comments
|
||||||
self.comments = [] if comments_ is None else [c for c in comments_]
|
self.comments = [] if comments_ is None else [c for c in comments_]
|
||||||
self.data = pd.DataFrame(data=data)
|
self.data = pd.DataFrame(data=data)
|
||||||
self.shapes = { k:(v,) if isinstance(v,(np.int,int)) else v for k,v in shapes.items() }
|
self.shapes = { k:(v,) if isinstance(v,(np.int64,np.int32,int)) else v for k,v in shapes.items() }
|
||||||
self._label_uniform()
|
self._label_uniform()
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
|
@ -42,12 +42,10 @@ class Table:
|
||||||
return len(self.data)
|
return len(self.data)
|
||||||
|
|
||||||
def __copy__(self):
|
def __copy__(self):
|
||||||
"""Copy Table."""
|
"""Create deep copy."""
|
||||||
return copy.deepcopy(self)
|
return copy.deepcopy(self)
|
||||||
|
|
||||||
def copy(self):
|
copy = __copy__
|
||||||
"""Copy Table."""
|
|
||||||
return self.__copy__()
|
|
||||||
|
|
||||||
|
|
||||||
def _label_discrete(self):
|
def _label_discrete(self):
|
||||||
|
@ -191,6 +189,11 @@ class Table:
|
||||||
label : str
|
label : str
|
||||||
Column label.
|
Column label.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
data : numpy.ndarray
|
||||||
|
Array of column data.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if re.match(r'[0-9]*?_',label):
|
if re.match(r'[0-9]*?_',label):
|
||||||
idx,key = label.split('_',1)
|
idx,key = label.split('_',1)
|
||||||
|
@ -214,6 +217,11 @@ class Table:
|
||||||
info : str, optional
|
info : str, optional
|
||||||
Human-readable information about the new data.
|
Human-readable information about the new data.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
table : Table
|
||||||
|
Updated table.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
dup = self.copy()
|
dup = self.copy()
|
||||||
dup._add_comment(label,data.shape[1:],info)
|
dup._add_comment(label,data.shape[1:],info)
|
||||||
|
@ -240,6 +248,11 @@ class Table:
|
||||||
info : str, optional
|
info : str, optional
|
||||||
Human-readable information about the modified data.
|
Human-readable information about the modified data.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
table : Table
|
||||||
|
Updated table.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
dup = self.copy()
|
dup = self.copy()
|
||||||
dup._add_comment(label,data.shape[1:],info)
|
dup._add_comment(label,data.shape[1:],info)
|
||||||
|
@ -263,6 +276,11 @@ class Table:
|
||||||
label : str
|
label : str
|
||||||
Column label.
|
Column label.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
table : Table
|
||||||
|
Updated table.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
dup = self.copy()
|
dup = self.copy()
|
||||||
dup.data.drop(columns=label,inplace=True)
|
dup.data.drop(columns=label,inplace=True)
|
||||||
|
@ -281,6 +299,11 @@ class Table:
|
||||||
label_new : str or iterable of str
|
label_new : str or iterable of str
|
||||||
New column label(s).
|
New column label(s).
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
table : Table
|
||||||
|
Updated table.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
dup = self.copy()
|
dup = self.copy()
|
||||||
columns = dict(zip([old] if isinstance(old,str) else old,
|
columns = dict(zip([old] if isinstance(old,str) else old,
|
||||||
|
@ -302,6 +325,11 @@ class Table:
|
||||||
ascending : bool or list, optional
|
ascending : bool or list, optional
|
||||||
Set sort order.
|
Set sort order.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
table : Table
|
||||||
|
Updated table.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
dup = self.copy()
|
dup = self.copy()
|
||||||
dup._label_discrete()
|
dup._label_discrete()
|
||||||
|
@ -322,6 +350,11 @@ class Table:
|
||||||
other : Table
|
other : Table
|
||||||
Table to append.
|
Table to append.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
table : Table
|
||||||
|
Concatenated table.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if self.shapes != other.shapes or not self.data.columns.equals(other.data.columns):
|
if self.shapes != other.shapes or not self.data.columns.equals(other.data.columns):
|
||||||
raise KeyError('Labels or shapes or order do not match')
|
raise KeyError('Labels or shapes or order do not match')
|
||||||
|
@ -342,6 +375,11 @@ class Table:
|
||||||
other : Table
|
other : Table
|
||||||
Table to join.
|
Table to join.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
table : Table
|
||||||
|
Joined table.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if set(self.shapes) & set(other.shapes) or self.data.shape[0] != other.data.shape[0]:
|
if set(self.shapes) & set(other.shapes) or self.data.shape[0] != other.data.shape[0]:
|
||||||
raise KeyError('Dublicated keys or row count mismatch')
|
raise KeyError('Dublicated keys or row count mismatch')
|
||||||
|
@ -382,7 +420,7 @@ class Table:
|
||||||
[f'# {comment}' for comment in self.comments]
|
[f'# {comment}' for comment in self.comments]
|
||||||
|
|
||||||
try:
|
try:
|
||||||
fhandle = open(fname,'w')
|
fhandle = open(fname,'w',newline='\n')
|
||||||
except TypeError:
|
except TypeError:
|
||||||
fhandle = fname
|
fhandle = fname
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ import logging
|
||||||
import logging.config
|
import logging.config
|
||||||
from collections.abc import Iterable
|
from collections.abc import Iterable
|
||||||
from optparse import OptionParser
|
from optparse import OptionParser
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
|
@ -180,7 +181,7 @@ class Test:
|
||||||
|
|
||||||
def fileInRoot(self,dir,file):
|
def fileInRoot(self,dir,file):
|
||||||
"""Path to a file in the root directory of DAMASK."""
|
"""Path to a file in the root directory of DAMASK."""
|
||||||
return str(damask.environment.root_dir/dir/file)
|
return str(Path(os.environ['DAMASK_ROOT'])/dir/file)
|
||||||
|
|
||||||
|
|
||||||
def fileInReference(self,file):
|
def fileInReference(self,file):
|
||||||
|
@ -282,40 +283,6 @@ class Test:
|
||||||
return out,error
|
return out,error
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def compare_Array(self,File1,File2):
|
|
||||||
|
|
||||||
import numpy as np
|
|
||||||
logging.info('\n '.join(['comparing',File1,File2]))
|
|
||||||
table = damask.Table.load(File1)
|
|
||||||
len1 = len(table.comments)+2
|
|
||||||
table = damask.Table.load(File2)
|
|
||||||
len2 = len(table.comments)+2
|
|
||||||
|
|
||||||
refArray = np.nan_to_num(np.genfromtxt(File1,missing_values='n/a',skip_header = len1,autostrip=True))
|
|
||||||
curArray = np.nan_to_num(np.genfromtxt(File2,missing_values='n/a',skip_header = len2,autostrip=True))
|
|
||||||
|
|
||||||
if len(curArray) == len(refArray):
|
|
||||||
refArrayNonZero = refArray[refArray.nonzero()]
|
|
||||||
curArray = curArray[refArray.nonzero()]
|
|
||||||
max_err = np. max(abs(refArrayNonZero[curArray.nonzero()]/curArray[curArray.nonzero()]-1.))
|
|
||||||
max_loc = np.argmax(abs(refArrayNonZero[curArray.nonzero()]/curArray[curArray.nonzero()]-1.))
|
|
||||||
refArrayNonZero = refArrayNonZero[curArray.nonzero()]
|
|
||||||
curArray = curArray[curArray.nonzero()]
|
|
||||||
print(f' ********\n * maximum relative error {max_err} between {refArrayNonZero[max_loc]} and {curArray[max_loc]}\n ********')
|
|
||||||
return max_err
|
|
||||||
else:
|
|
||||||
raise Exception(f'mismatch in array sizes ({len(refArray)} and {len(curArray)}) to compare')
|
|
||||||
|
|
||||||
|
|
||||||
def compare_ArrayRefCur(self,ref,cur=''):
|
|
||||||
|
|
||||||
if cur == '': cur = ref
|
|
||||||
refName = self.fileInReference(ref)
|
|
||||||
curName = self.fileInCurrent(cur)
|
|
||||||
return self.compare_Array(refName,curName)
|
|
||||||
|
|
||||||
|
|
||||||
def compare_Table(self,headings0,file0,
|
def compare_Table(self,headings0,file0,
|
||||||
headings1,file1,
|
headings1,file1,
|
||||||
normHeadings='',normType=None,
|
normHeadings='',normType=None,
|
||||||
|
@ -468,101 +435,6 @@ class Test:
|
||||||
return (mean < meanTol) & (std < stdTol)
|
return (mean < meanTol) & (std < stdTol)
|
||||||
|
|
||||||
|
|
||||||
def compare_Tables(self,
|
|
||||||
files = [None,None], # list of file names
|
|
||||||
columns = [None], # list of list of column labels (per file)
|
|
||||||
rtol = 1e-5,
|
|
||||||
atol = 1e-8,
|
|
||||||
debug = False):
|
|
||||||
"""Compare multiple tables with np.allclose."""
|
|
||||||
if not (isinstance(files, Iterable) and not isinstance(files, str)): # check whether list of files is requested
|
|
||||||
files = [str(files)]
|
|
||||||
|
|
||||||
if len(files) < 2: return True # single table is always close to itself...
|
|
||||||
|
|
||||||
tables = [damask.Table.load(filename) for filename in files]
|
|
||||||
|
|
||||||
columns += [columns[0]]*(len(files)-len(columns)) # extend to same length as files
|
|
||||||
columns = columns[:len(files)] # truncate to same length as files
|
|
||||||
|
|
||||||
for i,column in enumerate(columns):
|
|
||||||
if column is None: columns[i] = list(tables[i].shapes.keys()) # if no column is given, use all
|
|
||||||
|
|
||||||
logging.info('comparing ASCIItables')
|
|
||||||
for i in range(len(columns)):
|
|
||||||
columns[i] = columns[0] if not columns[i] else \
|
|
||||||
([columns[i]] if not (isinstance(columns[i], Iterable) and not isinstance(columns[i], str)) else \
|
|
||||||
columns[i]
|
|
||||||
)
|
|
||||||
logging.info(files[i]+': '+','.join(columns[i]))
|
|
||||||
|
|
||||||
dimensions = [np.prod(tables[0].shapes[c]) for c in columns[0]] # width of each requested column
|
|
||||||
maximum = np.zeros_like(columns[0],dtype=float) # one magnitude per column entry
|
|
||||||
data = [] # list of feature table extracted from each file (ASCII table)
|
|
||||||
|
|
||||||
for i,(table,labels) in enumerate(zip(tables,columns)):
|
|
||||||
if np.any(dimensions != [np.prod(table.shapes[c]) for c in labels]): # check data object consistency
|
|
||||||
logging.critical(f'Table {files[i]} differs in data layout.')
|
|
||||||
return False
|
|
||||||
data.append(np.hstack(list(table.get(label) for label in labels)).astype(np.float)) # store
|
|
||||||
|
|
||||||
for j,label in enumerate(labels): # iterate over object labels
|
|
||||||
maximum[j] = np.maximum(
|
|
||||||
maximum[j],
|
|
||||||
np.amax(np.linalg.norm(table.get(label),
|
|
||||||
axis=1))
|
|
||||||
) # find maximum Euclidean norm across rows
|
|
||||||
|
|
||||||
maximum = np.where(maximum > 0.0, maximum, 1.0) # avoid div by zero for zero columns
|
|
||||||
maximum = np.repeat(maximum,dimensions) # spread maximum over columns of each object
|
|
||||||
|
|
||||||
for i in range(len(data)):
|
|
||||||
data[i] /= maximum # normalize each table
|
|
||||||
logging.info(f'shape of data {i}: {data[i].shape}')
|
|
||||||
|
|
||||||
if debug:
|
|
||||||
violators = np.absolute(data[0]-data[1]) > atol + rtol*np.absolute(data[1])
|
|
||||||
logging.info(f'shape of violators: {violators.shape}')
|
|
||||||
for j,culprits in enumerate(violators):
|
|
||||||
goodguys = np.logical_not(culprits)
|
|
||||||
if culprits.any():
|
|
||||||
logging.info(f'{j} has {np.sum(culprits)}')
|
|
||||||
logging.info(f'deviation: {np.absolute(data[0][j]-data[1][j])[culprits]}')
|
|
||||||
logging.info(f'data : {np.absolute(data[1][j])[culprits]}')
|
|
||||||
logging.info(f'deviation: {np.absolute(data[0][j]-data[1][j])[goodguys]}')
|
|
||||||
logging.info(f'data : {np.absolute(data[1][j])[goodguys]}')
|
|
||||||
|
|
||||||
allclose = True # start optimistic
|
|
||||||
for i in range(1,len(data)):
|
|
||||||
allclose &= np.allclose(data[i-1],data[i],rtol,atol) # accumulate "pessimism"
|
|
||||||
|
|
||||||
return allclose
|
|
||||||
|
|
||||||
|
|
||||||
def compare_TableRefCur(self,headingsRef,ref,headingsCur='',cur='',
|
|
||||||
normHeadings='',normType=None,
|
|
||||||
absoluteTolerance=False,perLine=False,skipLines=[]):
|
|
||||||
|
|
||||||
return self.compare_Table(headingsRef,
|
|
||||||
self.fileInReference(ref),
|
|
||||||
headingsRef if headingsCur == '' else headingsCur,
|
|
||||||
self.fileInCurrent(ref if cur == '' else cur),
|
|
||||||
normHeadings,normType,
|
|
||||||
absoluteTolerance,perLine,skipLines)
|
|
||||||
|
|
||||||
|
|
||||||
def compare_TableCurCur(self,headingsCur0,Cur0,Cur1,
|
|
||||||
headingsCur1='',
|
|
||||||
normHeadings='',normType=None,
|
|
||||||
absoluteTolerance=False,perLine=False,skipLines=[]):
|
|
||||||
|
|
||||||
return self.compare_Table(headingsCur0,
|
|
||||||
self.fileInCurrent(Cur0),
|
|
||||||
headingsCur0 if headingsCur1 == '' else headingsCur1,
|
|
||||||
self.fileInCurrent(Cur1),
|
|
||||||
normHeadings,normType,absoluteTolerance,perLine,skipLines)
|
|
||||||
|
|
||||||
|
|
||||||
def report_Success(self,culprit):
|
def report_Success(self,culprit):
|
||||||
|
|
||||||
ret = culprit
|
ret = culprit
|
||||||
|
|
|
@ -10,7 +10,6 @@ from vtk.util.numpy_support import numpy_to_vtkIdTypeArray as np_to_vtkIdTypeArr
|
||||||
from vtk.util.numpy_support import vtk_to_numpy as vtk_to_np
|
from vtk.util.numpy_support import vtk_to_numpy as vtk_to_np
|
||||||
|
|
||||||
from . import util
|
from . import util
|
||||||
from . import environment
|
|
||||||
from . import Table
|
from . import Table
|
||||||
|
|
||||||
|
|
||||||
|
@ -247,8 +246,8 @@ class VTK:
|
||||||
raise ValueError('No label defined for numpy.ndarray')
|
raise ValueError('No label defined for numpy.ndarray')
|
||||||
|
|
||||||
N_data = data.shape[0]
|
N_data = data.shape[0]
|
||||||
d = np_to_vtk((data.astype(np.float32) if data.dtype in [np.float64, np.float128]
|
d = np_to_vtk((data.astype(np.single) if data.dtype in [np.double, np.longdouble] else
|
||||||
else data).reshape(N_data,-1),deep=True) # avoid large files
|
data).reshape(N_data,-1),deep=True) # avoid large files
|
||||||
d.SetName(label)
|
d.SetName(label)
|
||||||
|
|
||||||
if N_data == N_points:
|
if N_data == N_points:
|
||||||
|
@ -348,6 +347,21 @@ class VTK:
|
||||||
|
|
||||||
See http://compilatrix.com/article/vtk-1 for further ideas.
|
See http://compilatrix.com/article/vtk-1 for further ideas.
|
||||||
"""
|
"""
|
||||||
|
try:
|
||||||
|
import wx
|
||||||
|
_ = wx.App(False) # noqa
|
||||||
|
width, height = wx.GetDisplaySize()
|
||||||
|
except ImportError:
|
||||||
|
try:
|
||||||
|
import tkinter
|
||||||
|
tk = tkinter.Tk()
|
||||||
|
width = tk.winfo_screenwidth()
|
||||||
|
height = tk.winfo_screenheight()
|
||||||
|
tk.destroy()
|
||||||
|
except Exception as e:
|
||||||
|
width = 1024
|
||||||
|
height = 768
|
||||||
|
|
||||||
mapper = vtk.vtkDataSetMapper()
|
mapper = vtk.vtkDataSetMapper()
|
||||||
mapper.SetInputData(self.vtk_data)
|
mapper.SetInputData(self.vtk_data)
|
||||||
actor = vtk.vtkActor()
|
actor = vtk.vtkActor()
|
||||||
|
@ -361,7 +375,7 @@ class VTK:
|
||||||
ren.AddActor(actor)
|
ren.AddActor(actor)
|
||||||
ren.SetBackground(0.2,0.2,0.2)
|
ren.SetBackground(0.2,0.2,0.2)
|
||||||
|
|
||||||
window.SetSize(environment.screen_size[0],environment.screen_size[1])
|
window.SetSize(width,height)
|
||||||
|
|
||||||
iren = vtk.vtkRenderWindowInteractor()
|
iren = vtk.vtkRenderWindowInteractor()
|
||||||
iren.SetRenderWindow(window)
|
iren.SetRenderWindow(window)
|
||||||
|
|
|
@ -2,14 +2,13 @@ import subprocess
|
||||||
import shlex
|
import shlex
|
||||||
import re
|
import re
|
||||||
import io
|
import io
|
||||||
|
import os
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
from .. import environment
|
|
||||||
|
|
||||||
class Marc:
|
class Marc:
|
||||||
"""Wrapper to run DAMASK with MSCMarc."""
|
"""Wrapper to run DAMASK with MSCMarc."""
|
||||||
|
|
||||||
def __init__(self,version=environment.options['MSC_VERSION']):
|
def __init__(self,version=os.environ['MSC_VERSION']):
|
||||||
"""
|
"""
|
||||||
Create a Marc solver object.
|
Create a Marc solver object.
|
||||||
|
|
||||||
|
@ -25,9 +24,7 @@ class Marc:
|
||||||
@property
|
@property
|
||||||
def library_path(self):
|
def library_path(self):
|
||||||
|
|
||||||
path_MSC = environment.options['MSC_ROOT']
|
path_lib = Path(f'{os.environ["MSC_ROOT"]}/mentat{self.version}/shlib/linux64')
|
||||||
path_lib = Path(f'{path_MSC}/mentat{self.version}/shlib/linux64')
|
|
||||||
|
|
||||||
if not path_lib.is_dir():
|
if not path_lib.is_dir():
|
||||||
raise FileNotFoundError(f'library path "{path_lib}" not found')
|
raise FileNotFoundError(f'library path "{path_lib}" not found')
|
||||||
|
|
||||||
|
@ -37,9 +34,7 @@ class Marc:
|
||||||
@property
|
@property
|
||||||
def tools_path(self):
|
def tools_path(self):
|
||||||
|
|
||||||
path_MSC = environment.options['MSC_ROOT']
|
path_tools = Path(f'{os.environ["MSC_ROOT"]}/marc{self.version}/tools')
|
||||||
path_tools = Path(f'{path_MSC}/marc{self.version}/tools')
|
|
||||||
|
|
||||||
if not path_tools.is_dir():
|
if not path_tools.is_dir():
|
||||||
raise FileNotFoundError(f'tools path "{path_tools}" not found')
|
raise FileNotFoundError(f'tools path "{path_tools}" not found')
|
||||||
|
|
||||||
|
@ -54,7 +49,7 @@ class Marc:
|
||||||
optimization = '',
|
optimization = '',
|
||||||
):
|
):
|
||||||
|
|
||||||
usersub = environment.root_dir/'src/DAMASK_marc'
|
usersub = Path(os.environ['DAMASK_ROOT'])/'src/DAMASK_marc'
|
||||||
usersub = usersub.parent/(usersub.name + ('.f90' if compile else '.marc'))
|
usersub = usersub.parent/(usersub.name + ('.f90' if compile else '.marc'))
|
||||||
if not usersub.is_file():
|
if not usersub.is_file():
|
||||||
raise FileNotFoundError(f'subroutine ({"source" if compile else "binary"}) "{usersub}" not found')
|
raise FileNotFoundError(f'subroutine ({"source" if compile else "binary"}) "{usersub}" not found')
|
||||||
|
@ -71,7 +66,7 @@ class Marc:
|
||||||
|
|
||||||
if logfile is not None:
|
if logfile is not None:
|
||||||
try:
|
try:
|
||||||
f = open(logfile,'w+')
|
f = open(logfile,'w+',newline='\n')
|
||||||
except TypeError:
|
except TypeError:
|
||||||
f = logfile
|
f = logfile
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -133,6 +133,8 @@ def execute(cmd,
|
||||||
stdout = stdout.decode('utf-8').replace('\x08','')
|
stdout = stdout.decode('utf-8').replace('\x08','')
|
||||||
stderr = stderr.decode('utf-8').replace('\x08','')
|
stderr = stderr.decode('utf-8').replace('\x08','')
|
||||||
if process.returncode != 0:
|
if process.returncode != 0:
|
||||||
|
print(stdout)
|
||||||
|
print(stderr)
|
||||||
raise RuntimeError(f"'{cmd}' failed with returncode {process.returncode}")
|
raise RuntimeError(f"'{cmd}' failed with returncode {process.returncode}")
|
||||||
return stdout, stderr
|
return stdout, stderr
|
||||||
|
|
||||||
|
@ -183,7 +185,7 @@ def scale_to_coprime(v):
|
||||||
# Python 3.9 provides math.lcm, see https://stackoverflow.com/questions/51716916.
|
# Python 3.9 provides math.lcm, see https://stackoverflow.com/questions/51716916.
|
||||||
return a * b // np.gcd(a, b)
|
return a * b // np.gcd(a, b)
|
||||||
|
|
||||||
m = (np.array(v) * reduce(lcm, map(lambda x: int(get_square_denominator(x)),v)) ** 0.5).astype(np.int)
|
m = (np.array(v) * reduce(lcm, map(lambda x: int(get_square_denominator(x)),v)) ** 0.5).astype(int)
|
||||||
m = m//reduce(np.gcd,m)
|
m = m//reduce(np.gcd,m)
|
||||||
|
|
||||||
with np.errstate(invalid='ignore'):
|
with np.errstate(invalid='ignore'):
|
||||||
|
@ -193,7 +195,7 @@ def scale_to_coprime(v):
|
||||||
return m
|
return m
|
||||||
|
|
||||||
|
|
||||||
def project_stereographic(vector,normalize=False):
|
def project_stereographic(vector,direction='z',normalize=True,keepdims=False):
|
||||||
"""
|
"""
|
||||||
Apply stereographic projection to vector.
|
Apply stereographic projection to vector.
|
||||||
|
|
||||||
|
@ -201,18 +203,37 @@ def project_stereographic(vector,normalize=False):
|
||||||
----------
|
----------
|
||||||
vector : numpy.ndarray of shape (...,3)
|
vector : numpy.ndarray of shape (...,3)
|
||||||
Vector coordinates to be projected.
|
Vector coordinates to be projected.
|
||||||
|
direction : str
|
||||||
|
Projection direction 'x', 'y', or 'z'.
|
||||||
|
Defaults to 'z'.
|
||||||
normalize : bool
|
normalize : bool
|
||||||
Ensure unit length for vector. Defaults to False.
|
Ensure unit length of input vector. Defaults to True.
|
||||||
|
keepdims : bool
|
||||||
|
Maintain three-dimensional output coordinates.
|
||||||
|
Default two-dimensional output uses right-handed frame spanned by
|
||||||
|
the next and next-next axis relative to the projection direction,
|
||||||
|
e.g. x-y when projecting along z and z-x when projecting along y.
|
||||||
|
|
||||||
Returns
|
Returns
|
||||||
-------
|
-------
|
||||||
coordinates : numpy.ndarray of shape (...,2)
|
coordinates : numpy.ndarray of shape (...,2 | 3)
|
||||||
Projected coordinates.
|
Projected coordinates.
|
||||||
|
|
||||||
|
Examples
|
||||||
|
--------
|
||||||
|
>>> project_stereographic(np.ones(3))
|
||||||
|
[0.3660254, 0.3660254]
|
||||||
|
>>> project_stereographic(np.ones(3),direction='x',normalize=False,keepdims=True)
|
||||||
|
[0, 0.5, 0.5]
|
||||||
|
>>> project_stereographic([0,1,1],direction='y',normalize=True,keepdims=False)
|
||||||
|
[0.41421356, 0]
|
||||||
|
|
||||||
"""
|
"""
|
||||||
v_ = vector/np.linalg.norm(vector,axis=-1,keepdims=True) if normalize else vector
|
shift = 'zyx'.index(direction)
|
||||||
return np.block([v_[...,:2]/(1+np.abs(v_[...,2:3])),
|
v_ = np.roll(vector/np.linalg.norm(vector,axis=-1,keepdims=True) if normalize else vector,
|
||||||
np.zeros_like(v_[...,2:3])])
|
shift,axis=-1)
|
||||||
|
return np.roll(np.block([v_[...,:2]/(1+np.abs(v_[...,2:3])),np.zeros_like(v_[...,2:3])]),
|
||||||
|
-shift if keepdims else 0,axis=-1)[...,:3 if keepdims else 2]
|
||||||
|
|
||||||
|
|
||||||
def execution_stamp(class_name,function_name=None):
|
def execution_stamp(class_name,function_name=None):
|
||||||
|
|
|
@ -6,28 +6,29 @@ with open(Path(__file__).parent/'damask/VERSION') as f:
|
||||||
version = re.sub(r'(-([^-]*)).*$',r'.\2',re.sub(r'^v(\d+\.\d+(\.\d+)?)',r'\1',f.readline().strip()))
|
version = re.sub(r'(-([^-]*)).*$',r'.\2',re.sub(r'^v(\d+\.\d+(\.\d+)?)',r'\1',f.readline().strip()))
|
||||||
|
|
||||||
setuptools.setup(
|
setuptools.setup(
|
||||||
name="damask",
|
name='damask',
|
||||||
version=version,
|
version=version,
|
||||||
author="The DAMASK team",
|
author='The DAMASK team',
|
||||||
author_email="damask@mpie.de",
|
author_email='damask@mpie.de',
|
||||||
description="DAMASK library",
|
description='DAMASK library',
|
||||||
long_description="Python library for pre and post processing of DAMASK simulations",
|
long_description='Python library for pre and post processing of DAMASK simulations',
|
||||||
url="https://damask.mpie.de",
|
url='https://damask.mpie.de',
|
||||||
packages=setuptools.find_packages(),
|
packages=setuptools.find_packages(),
|
||||||
include_package_data=True,
|
include_package_data=True,
|
||||||
|
python_requires = '>=3.6',
|
||||||
install_requires = [
|
install_requires = [
|
||||||
"pandas", # requires numpy
|
'pandas>=0.24', # requires numpy
|
||||||
"scipy",
|
'scipy>=1.2',
|
||||||
"h5py", # requires numpy
|
'h5py>=2.9', # requires numpy
|
||||||
"vtk",
|
'vtk>=8.1',
|
||||||
"matplotlib", # requires numpy, pillow
|
'matplotlib>=3.0', # requires numpy, pillow
|
||||||
"pyaml"
|
'pyaml>=3.12'
|
||||||
],
|
],
|
||||||
classifiers = [
|
classifiers = [
|
||||||
"Intended Audience :: Science/Research",
|
'Intended Audience :: Science/Research',
|
||||||
"Topic :: Scientific/Engineering",
|
'Topic :: Scientific/Engineering',
|
||||||
"Programming Language :: Python :: 3",
|
'Programming Language :: Python :: 3',
|
||||||
"License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)",
|
'License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)',
|
||||||
"Operating System :: OS Independent",
|
'Operating System :: OS Independent',
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,32 +1,32 @@
|
||||||
homogenization:
|
homogenization:
|
||||||
SX:
|
SX:
|
||||||
N_constituents: 1
|
N_constituents: 1
|
||||||
mechanics: {type: none}
|
mechanics: {type: pass}
|
||||||
Taylor:
|
Taylor:
|
||||||
N_constituents: 2
|
N_constituents: 2
|
||||||
mechanics: {type: isostrain}
|
mechanics: {type: isostrain}
|
||||||
|
|
||||||
material:
|
material:
|
||||||
- constituents:
|
- constituents:
|
||||||
- fraction: 1.0
|
- v: 1.0
|
||||||
O: [1.0, 0.0, 0.0, 0.0]
|
O: [1.0, 0.0, 0.0, 0.0]
|
||||||
phase: Aluminum
|
phase: Aluminum
|
||||||
homogenization: SX
|
homogenization: SX
|
||||||
- constituents:
|
- constituents:
|
||||||
- fraction: 1.0
|
- v: 1.0
|
||||||
O: [0.7936696712125002, -0.28765777461664166, -0.3436487135089419, 0.4113964260949434]
|
O: [0.7936696712125002, -0.28765777461664166, -0.3436487135089419, 0.4113964260949434]
|
||||||
phase: Aluminum
|
phase: Aluminum
|
||||||
homogenization: SX
|
homogenization: SX
|
||||||
- constituents:
|
- constituents:
|
||||||
- fraction: 1.0
|
- v: 1.0
|
||||||
O: [0.3986143167493579, -0.7014883552495493, 0.2154871765709027, 0.5500781677772945]
|
O: [0.3986143167493579, -0.7014883552495493, 0.2154871765709027, 0.5500781677772945]
|
||||||
phase: Aluminum
|
phase: Aluminum
|
||||||
homogenization: SX
|
homogenization: SX
|
||||||
- constituents:
|
- constituents:
|
||||||
- fraction: 0.5
|
- v: 0.5
|
||||||
O: [0.28645844315788244, -0.022571491243423537, -0.467933059311115, -0.8357456192708106]
|
O: [0.28645844315788244, -0.022571491243423537, -0.467933059311115, -0.8357456192708106]
|
||||||
phase: Aluminum
|
phase: Aluminum
|
||||||
- fraction: 0.5
|
- v: 0.5
|
||||||
O: [0.3986143167493579, -0.7014883552495493, 0.2154871765709027, 0.5500781677772945]
|
O: [0.3986143167493579, -0.7014883552495493, 0.2154871765709027, 0.5500781677772945]
|
||||||
phase: Steel
|
phase: Steel
|
||||||
homogenization: Taylor
|
homogenization: Taylor
|
||||||
|
|
|
@ -22,6 +22,19 @@ class TestConfig:
|
||||||
with open(tmp_path/'config.yaml') as f:
|
with open(tmp_path/'config.yaml') as f:
|
||||||
assert Config.load(f) == config
|
assert Config.load(f) == config
|
||||||
|
|
||||||
|
def test_add_remove(self):
|
||||||
|
dummy = {'hello':'world','foo':'bar'}
|
||||||
|
config = Config()
|
||||||
|
config |= dummy
|
||||||
|
assert config == Config() | dummy
|
||||||
|
config = config.delete(dummy)
|
||||||
|
assert config == Config()
|
||||||
|
assert (config | dummy ).delete( 'hello' ) == config | {'foo':'bar'}
|
||||||
|
assert (config | dummy ).delete([ 'hello', 'foo' ]) == config
|
||||||
|
assert (config | Config(dummy)).delete({ 'hello':1,'foo':2 }) == config
|
||||||
|
assert (config | Config(dummy)).delete(Config({'hello':1 })) == config | {'foo':'bar'}
|
||||||
|
|
||||||
|
|
||||||
def test_repr(self,tmp_path):
|
def test_repr(self,tmp_path):
|
||||||
config = Config()
|
config = Config()
|
||||||
config['A'] = 1
|
config['A'] = 1
|
||||||
|
|
|
@ -5,6 +5,7 @@ import numpy as np
|
||||||
|
|
||||||
from damask import ConfigMaterial
|
from damask import ConfigMaterial
|
||||||
from damask import Table
|
from damask import Table
|
||||||
|
from damask import Rotation
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def ref_path(ref_path_base):
|
def ref_path(ref_path_base):
|
||||||
|
@ -42,7 +43,7 @@ class TestConfigMaterial:
|
||||||
|
|
||||||
def test_invalid_fraction(self,ref_path):
|
def test_invalid_fraction(self,ref_path):
|
||||||
material_config = ConfigMaterial.load(ref_path/'material.yaml')
|
material_config = ConfigMaterial.load(ref_path/'material.yaml')
|
||||||
material_config['material'][0]['constituents'][0]['fraction']=.9
|
material_config['material'][0]['constituents'][0]['v']=.9
|
||||||
assert not material_config.is_valid
|
assert not material_config.is_valid
|
||||||
|
|
||||||
@pytest.mark.parametrize('item',['homogenization','phase','material'])
|
@pytest.mark.parametrize('item',['homogenization','phase','material'])
|
||||||
|
@ -85,42 +86,25 @@ class TestConfigMaterial:
|
||||||
|
|
||||||
def test_from_table(self):
|
def test_from_table(self):
|
||||||
N = np.random.randint(3,10)
|
N = np.random.randint(3,10)
|
||||||
a = np.vstack((np.hstack((np.arange(N),np.arange(N)[::-1])),np.ones(N*2),np.zeros(N*2),np.ones(N*2))).T
|
a = np.vstack((np.hstack((np.arange(N),np.arange(N)[::-1])),np.ones(N*2),np.zeros(N*2),np.ones(N*2),np.ones(N*2))).T
|
||||||
t = Table(a,{'varying':2,'constant':2})
|
t = Table(a,{'varying':1,'constant':4})
|
||||||
c = ConfigMaterial.from_table(t,constituents={'a':'varying','b':'1_constant'},c='2_constant')
|
c = ConfigMaterial.from_table(t,**{'phase':'varying','O':'constant','homogenization':'4_constant'})
|
||||||
assert len(c['material']) == N
|
assert len(c['material']) == N
|
||||||
for i,m in enumerate(c['material']):
|
for i,m in enumerate(c['material']):
|
||||||
c = m['constituents'][0]
|
assert m['homogenization'] == 1 and (m['constituents'][0]['O'] == [1,0,1,1]).all()
|
||||||
assert m['c'] == 1 and c['b'] == 0 and (c['a'] == [i,1]).all()
|
|
||||||
|
|
||||||
def test_constituents(self):
|
@pytest.mark.parametrize('N,n,kw',[
|
||||||
c = ConfigMaterial._constituents(c=1,v=[2,3])
|
(1,1,{'phase':'Gold',
|
||||||
assert c[0][0]['c'] == c[1][0]['c'] == 1
|
'O':[1,0,0,0],
|
||||||
assert c[0][0]['v'] == c[1][0]['v'] -1 ==2
|
'homogenization':'SX'}),
|
||||||
|
(3,1,{'phase':'Gold',
|
||||||
@pytest.mark.parametrize('constituents',[{'W':1,'X':[2,3]},{'Y':4},{'Z':[5,6]}])
|
'O':Rotation.from_random(3),
|
||||||
@pytest.mark.parametrize('a',[[7.,8.],9.])
|
'homogenization':'SX'}),
|
||||||
@pytest.mark.parametrize('b',['bd',['efg','hi']])
|
(2,3,{'phase':np.broadcast_to(['a','b','c'],(2,3)),
|
||||||
def test_material_add(self,tmp_path,constituents,a,b):
|
'O':Rotation.from_random((2,3)),
|
||||||
len_c = len(ConfigMaterial()._constituents(1,**constituents))
|
'homogenization':['SX','PX']}),
|
||||||
len_a = len(a) if isinstance(a,list) else 1
|
])
|
||||||
len_b = len(b) if isinstance(b,list) else 1
|
def test_material_add(self,kw,N,n):
|
||||||
m = ConfigMaterial().material_add(constituents,a=a,b=b)
|
m = ConfigMaterial().material_add(**kw)
|
||||||
m.save()
|
assert len(m['material']) == N
|
||||||
assert len(m['material']) == np.max([len_a,len_b,len_c])
|
assert len(m['material'][0]['constituents']) == n
|
||||||
|
|
||||||
@pytest.mark.parametrize('constituents',[{'W':1,'X':np.array([2,3])},{'Y':4},{'Z':np.array([5,6])}])
|
|
||||||
@pytest.mark.parametrize('a',[np.array([7,8]),9])
|
|
||||||
def test_material_add_np(self,tmp_path,constituents,a):
|
|
||||||
len_c = len(ConfigMaterial()._constituents(1,**constituents))
|
|
||||||
len_a = len(a) if isinstance(a,np.ndarray) else 1
|
|
||||||
m = ConfigMaterial().material_add(constituents,ld=a)
|
|
||||||
m.save()
|
|
||||||
assert len(m['material']) == np.max([len_a,len_c])
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('constituents',[{'X':np.array([2,3,4,5])},{'Y':4}])
|
|
||||||
@pytest.mark.parametrize('a',[np.array([1,2,3]),[4,5,6]])
|
|
||||||
@pytest.mark.parametrize('b',[np.array([6.,7.]),[8.,9.]])
|
|
||||||
def test_material_add_invalid(self,constituents,a,b):
|
|
||||||
with pytest.raises(ValueError):
|
|
||||||
ConfigMaterial().material_add(constituents,a=a,u=b)
|
|
||||||
|
|
|
@ -347,7 +347,7 @@ class TestGrid:
|
||||||
@pytest.mark.parametrize('approach',['Laguerre','Voronoi'])
|
@pytest.mark.parametrize('approach',['Laguerre','Voronoi'])
|
||||||
def test_tessellate_bicrystal(self,approach):
|
def test_tessellate_bicrystal(self,approach):
|
||||||
cells = np.random.randint(5,10,3)*2
|
cells = np.random.randint(5,10,3)*2
|
||||||
size = cells.astype(np.float)
|
size = cells.astype(float)
|
||||||
seeds = np.vstack((size*np.array([0.5,0.25,0.5]),size*np.array([0.5,0.75,0.5])))
|
seeds = np.vstack((size*np.array([0.5,0.25,0.5]),size*np.array([0.5,0.75,0.5])))
|
||||||
material = np.zeros(cells)
|
material = np.zeros(cells)
|
||||||
material[:,cells[1]//2:,:] = 1
|
material[:,cells[1]//2:,:] = 1
|
||||||
|
|
|
@ -7,6 +7,7 @@ from damask import Orientation
|
||||||
from damask import Table
|
from damask import Table
|
||||||
from damask import lattice
|
from damask import lattice
|
||||||
from damask import util
|
from damask import util
|
||||||
|
from damask import grid_filters
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
|
@ -25,13 +26,16 @@ class TestOrientation:
|
||||||
@pytest.mark.parametrize('shape',[None,5,(4,6)])
|
@pytest.mark.parametrize('shape',[None,5,(4,6)])
|
||||||
def test_equal(self,lattice,shape):
|
def test_equal(self,lattice,shape):
|
||||||
R = Rotation.from_random(shape)
|
R = Rotation.from_random(shape)
|
||||||
assert Orientation(R,lattice) == Orientation(R,lattice)
|
assert Orientation(R,lattice) == Orientation(R,lattice) if shape is None else \
|
||||||
|
(Orientation(R,lattice) == Orientation(R,lattice)).all()
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('lattice',Orientation.crystal_families)
|
@pytest.mark.parametrize('lattice',Orientation.crystal_families)
|
||||||
@pytest.mark.parametrize('shape',[None,5,(4,6)])
|
@pytest.mark.parametrize('shape',[None,5,(4,6)])
|
||||||
def test_unequal(self,lattice,shape):
|
def test_unequal(self,lattice,shape):
|
||||||
R = Rotation.from_random(shape)
|
R = Rotation.from_random(shape)
|
||||||
assert not(Orientation(R,lattice) != Orientation(R,lattice))
|
assert not ( Orientation(R,lattice) != Orientation(R,lattice) if shape is None else \
|
||||||
|
(Orientation(R,lattice) != Orientation(R,lattice)).any())
|
||||||
|
|
||||||
@pytest.mark.parametrize('a,b',[
|
@pytest.mark.parametrize('a,b',[
|
||||||
(dict(rotation=[1,0,0,0]),
|
(dict(rotation=[1,0,0,0]),
|
||||||
|
@ -115,7 +119,7 @@ class TestOrientation:
|
||||||
== np.eye(3))
|
== np.eye(3))
|
||||||
|
|
||||||
def test_from_cubochoric(self):
|
def test_from_cubochoric(self):
|
||||||
assert np.all(Orientation.from_cubochoric(c=np.zeros(3),lattice='triclinic').as_matrix()
|
assert np.all(Orientation.from_cubochoric(x=np.zeros(3),lattice='triclinic').as_matrix()
|
||||||
== np.eye(3))
|
== np.eye(3))
|
||||||
|
|
||||||
def test_from_spherical_component(self):
|
def test_from_spherical_component(self):
|
||||||
|
@ -138,7 +142,7 @@ class TestOrientation:
|
||||||
dict(lattice='hP',a=1.0 ),
|
dict(lattice='hP',a=1.0 ),
|
||||||
dict(lattice='cI',a=1.0, ),
|
dict(lattice='cI',a=1.0, ),
|
||||||
])
|
])
|
||||||
def test_from_direction(self,kwargs):
|
def test_from_directions(self,kwargs):
|
||||||
for a,b in np.random.random((10,2,3)):
|
for a,b in np.random.random((10,2,3)):
|
||||||
c = np.cross(b,a)
|
c = np.cross(b,a)
|
||||||
if np.all(np.isclose(c,0)): continue
|
if np.all(np.isclose(c,0)): continue
|
||||||
|
@ -148,6 +152,21 @@ class TestOrientation:
|
||||||
assert np.isclose(np.dot(x/np.linalg.norm(x),np.array([1,0,0])),1) \
|
assert np.isclose(np.dot(x/np.linalg.norm(x),np.array([1,0,0])),1) \
|
||||||
and np.isclose(np.dot(z/np.linalg.norm(z),np.array([0,0,1])),1)
|
and np.isclose(np.dot(z/np.linalg.norm(z),np.array([0,0,1])),1)
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('function',[Orientation.from_random,
|
||||||
|
Orientation.from_quaternion,
|
||||||
|
Orientation.from_Euler_angles,
|
||||||
|
Orientation.from_axis_angle,
|
||||||
|
Orientation.from_basis,
|
||||||
|
Orientation.from_matrix,
|
||||||
|
Orientation.from_Rodrigues_vector,
|
||||||
|
Orientation.from_homochoric,
|
||||||
|
Orientation.from_cubochoric,
|
||||||
|
Orientation.from_spherical_component,
|
||||||
|
Orientation.from_fiber_component,
|
||||||
|
Orientation.from_directions])
|
||||||
|
def test_invalid_from(self,function):
|
||||||
|
with pytest.raises(TypeError):
|
||||||
|
function(c=.1,degrees=True,invalid=66)
|
||||||
|
|
||||||
def test_negative_angle(self):
|
def test_negative_angle(self):
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
|
@ -218,6 +237,16 @@ class TestOrientation:
|
||||||
for r, theO in zip(o.reduced.flatten(),o.flatten()):
|
for r, theO in zip(o.reduced.flatten(),o.flatten()):
|
||||||
assert r == theO.reduced
|
assert r == theO.reduced
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('lattice',Orientation.crystal_families)
|
||||||
|
def test_reduced_corner_cases(self,lattice):
|
||||||
|
# test whether there is always a sym-eq rotation that falls into the FZ
|
||||||
|
N = np.random.randint(10,40)
|
||||||
|
size = np.ones(3)*np.pi**(2./3.)
|
||||||
|
grid = grid_filters.coordinates0_node([N+1,N+1,N+1],size,-size*.5)
|
||||||
|
evenly_distributed = Orientation.from_cubochoric(x=grid[:-2,:-2,:-2],lattice=lattice)
|
||||||
|
assert evenly_distributed.shape == evenly_distributed.reduced.shape
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('lattice',Orientation.crystal_families)
|
@pytest.mark.parametrize('lattice',Orientation.crystal_families)
|
||||||
@pytest.mark.parametrize('shape',[(1),(2,3),(4,3,2)])
|
@pytest.mark.parametrize('shape',[(1),(2,3),(4,3,2)])
|
||||||
@pytest.mark.parametrize('vector',np.array([[1,0,0],[1,2,3],[-1,1,-1]]))
|
@pytest.mark.parametrize('vector',np.array([[1,0,0],[1,2,3],[-1,1,-1]]))
|
||||||
|
@ -403,7 +432,7 @@ class TestOrientation:
|
||||||
def test_relationship_vectorize(self,set_of_quaternions,lattice,model):
|
def test_relationship_vectorize(self,set_of_quaternions,lattice,model):
|
||||||
r = Orientation(rotation=set_of_quaternions[:200].reshape((50,4,4)),lattice=lattice).related(model)
|
r = Orientation(rotation=set_of_quaternions[:200].reshape((50,4,4)),lattice=lattice).related(model)
|
||||||
for i in range(200):
|
for i in range(200):
|
||||||
assert r.reshape((-1,200))[:,i] == Orientation(set_of_quaternions[i],lattice).related(model)
|
assert (r.reshape((-1,200))[:,i] == Orientation(set_of_quaternions[i],lattice).related(model)).all()
|
||||||
|
|
||||||
@pytest.mark.parametrize('model',['Bain','KS','GT','GT_prime','NW','Pitsch'])
|
@pytest.mark.parametrize('model',['Bain','KS','GT','GT_prime','NW','Pitsch'])
|
||||||
@pytest.mark.parametrize('lattice',['cF','cI'])
|
@pytest.mark.parametrize('lattice',['cF','cI'])
|
||||||
|
|
|
@ -21,7 +21,7 @@ def default(tmp_path,ref_path):
|
||||||
fname = '12grains6x7x8_tensionY.hdf5'
|
fname = '12grains6x7x8_tensionY.hdf5'
|
||||||
shutil.copy(ref_path/fname,tmp_path)
|
shutil.copy(ref_path/fname,tmp_path)
|
||||||
f = Result(tmp_path/fname)
|
f = Result(tmp_path/fname)
|
||||||
f.pick('times',20.0)
|
f.view('times',20.0)
|
||||||
return f
|
return f
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
|
@ -43,56 +43,56 @@ class TestResult:
|
||||||
print(default)
|
print(default)
|
||||||
|
|
||||||
|
|
||||||
def test_pick_all(self,default):
|
def test_view_all(self,default):
|
||||||
default.pick('increments',True)
|
default.view('increments',True)
|
||||||
a = default.get_dataset_location('F')
|
a = default.get_dataset_location('F')
|
||||||
default.pick('increments','*')
|
default.view('increments','*')
|
||||||
b = default.get_dataset_location('F')
|
b = default.get_dataset_location('F')
|
||||||
default.pick('increments',default.incs_in_range(0,np.iinfo(int).max))
|
default.view('increments',default.incs_in_range(0,np.iinfo(int).max))
|
||||||
c = default.get_dataset_location('F')
|
c = default.get_dataset_location('F')
|
||||||
|
|
||||||
default.pick('times',True)
|
default.view('times',True)
|
||||||
d = default.get_dataset_location('F')
|
d = default.get_dataset_location('F')
|
||||||
default.pick('times','*')
|
default.view('times','*')
|
||||||
e = default.get_dataset_location('F')
|
e = default.get_dataset_location('F')
|
||||||
default.pick('times',default.times_in_range(0.0,np.inf))
|
default.view('times',default.times_in_range(0.0,np.inf))
|
||||||
f = default.get_dataset_location('F')
|
f = default.get_dataset_location('F')
|
||||||
assert a == b == c == d == e ==f
|
assert a == b == c == d == e ==f
|
||||||
|
|
||||||
@pytest.mark.parametrize('what',['increments','times','phases']) # ToDo: discuss homogenizations
|
@pytest.mark.parametrize('what',['increments','times','phases']) # ToDo: discuss homogenizations
|
||||||
def test_pick_none(self,default,what):
|
def test_view_none(self,default,what):
|
||||||
default.pick(what,False)
|
default.view(what,False)
|
||||||
a = default.get_dataset_location('F')
|
a = default.get_dataset_location('F')
|
||||||
default.pick(what,[])
|
default.view(what,[])
|
||||||
b = default.get_dataset_location('F')
|
b = default.get_dataset_location('F')
|
||||||
|
|
||||||
assert a == b == []
|
assert a == b == []
|
||||||
|
|
||||||
@pytest.mark.parametrize('what',['increments','times','phases']) # ToDo: discuss homogenizations
|
@pytest.mark.parametrize('what',['increments','times','phases']) # ToDo: discuss homogenizations
|
||||||
def test_pick_more(self,default,what):
|
def test_view_more(self,default,what):
|
||||||
default.pick(what,False)
|
default.view(what,False)
|
||||||
default.pick_more(what,'*')
|
default.view_more(what,'*')
|
||||||
a = default.get_dataset_location('F')
|
a = default.get_dataset_location('F')
|
||||||
|
|
||||||
default.pick(what,True)
|
default.view(what,True)
|
||||||
b = default.get_dataset_location('F')
|
b = default.get_dataset_location('F')
|
||||||
|
|
||||||
assert a == b
|
assert a == b
|
||||||
|
|
||||||
@pytest.mark.parametrize('what',['increments','times','phases']) # ToDo: discuss homogenizations
|
@pytest.mark.parametrize('what',['increments','times','phases']) # ToDo: discuss homogenizations
|
||||||
def test_pick_less(self,default,what):
|
def test_view_less(self,default,what):
|
||||||
default.pick(what,True)
|
default.view(what,True)
|
||||||
default.pick_less(what,'*')
|
default.view_less(what,'*')
|
||||||
a = default.get_dataset_location('F')
|
a = default.get_dataset_location('F')
|
||||||
|
|
||||||
default.pick(what,False)
|
default.view(what,False)
|
||||||
b = default.get_dataset_location('F')
|
b = default.get_dataset_location('F')
|
||||||
|
|
||||||
assert a == b == []
|
assert a == b == []
|
||||||
|
|
||||||
def test_pick_invalid(self,default):
|
def test_view_invalid(self,default):
|
||||||
with pytest.raises(AttributeError):
|
with pytest.raises(AttributeError):
|
||||||
default.pick('invalid',True)
|
default.view('invalid',True)
|
||||||
|
|
||||||
def test_add_absolute(self,default):
|
def test_add_absolute(self,default):
|
||||||
default.add_absolute('F_e')
|
default.add_absolute('F_e')
|
||||||
|
@ -307,7 +307,7 @@ class TestResult:
|
||||||
|
|
||||||
@pytest.mark.parametrize('overwrite',['off','on'])
|
@pytest.mark.parametrize('overwrite',['off','on'])
|
||||||
def test_add_overwrite(self,default,overwrite):
|
def test_add_overwrite(self,default,overwrite):
|
||||||
default.pick('times',default.times_in_range(0,np.inf)[-1])
|
default.view('times',default.times_in_range(0,np.inf)[-1])
|
||||||
|
|
||||||
default.add_stress_Cauchy()
|
default.add_stress_Cauchy()
|
||||||
loc = default.get_dataset_location('sigma')
|
loc = default.get_dataset_location('sigma')
|
||||||
|
|
|
@ -526,7 +526,7 @@ class TestRotation:
|
||||||
o = backward(forward(m))
|
o = backward(forward(m))
|
||||||
u = np.array([np.pi*2,np.pi,np.pi*2])
|
u = np.array([np.pi*2,np.pi,np.pi*2])
|
||||||
ok = np.allclose(m,o,atol=atol)
|
ok = np.allclose(m,o,atol=atol)
|
||||||
ok = ok or np.allclose(np.where(np.isclose(m,u),m-u,m),np.where(np.isclose(o,u),o-u,o),atol=atol)
|
ok |= np.allclose(np.where(np.isclose(m,u),m-u,m),np.where(np.isclose(o,u),o-u,o),atol=atol)
|
||||||
if np.isclose(m[1],0.0,atol=atol) or np.isclose(m[1],np.pi,atol=atol):
|
if np.isclose(m[1],0.0,atol=atol) or np.isclose(m[1],np.pi,atol=atol):
|
||||||
sum_phi = np.unwrap([m[0]+m[2],o[0]+o[2]])
|
sum_phi = np.unwrap([m[0]+m[2],o[0]+o[2]])
|
||||||
ok |= np.isclose(sum_phi[0],sum_phi[1],atol=atol)
|
ok |= np.isclose(sum_phi[0],sum_phi[1],atol=atol)
|
||||||
|
@ -550,19 +550,22 @@ class TestRotation:
|
||||||
assert ok and np.isclose(np.linalg.norm(o[:3]),1.0) and o[3]<=np.pi+1.e-9, f'{m},{o},{rot.as_quaternion()}'
|
assert ok and np.isclose(np.linalg.norm(o[:3]),1.0) and o[3]<=np.pi+1.e-9, f'{m},{o},{rot.as_quaternion()}'
|
||||||
|
|
||||||
@pytest.mark.parametrize('forward,backward',[(Rotation._ro2qu,Rotation._qu2ro),
|
@pytest.mark.parametrize('forward,backward',[(Rotation._ro2qu,Rotation._qu2ro),
|
||||||
#(Rotation._ro2om,Rotation._om2ro),
|
(Rotation._ro2om,Rotation._om2ro),
|
||||||
#(Rotation._ro2eu,Rotation._eu2ro),
|
(Rotation._ro2eu,Rotation._eu2ro),
|
||||||
(Rotation._ro2ax,Rotation._ax2ro),
|
(Rotation._ro2ax,Rotation._ax2ro),
|
||||||
(Rotation._ro2ho,Rotation._ho2ro),
|
(Rotation._ro2ho,Rotation._ho2ro),
|
||||||
(Rotation._ro2cu,Rotation._cu2ro)])
|
(Rotation._ro2cu,Rotation._cu2ro)])
|
||||||
def test_Rodrigues_internal(self,set_of_rotations,forward,backward):
|
def test_Rodrigues_internal(self,set_of_rotations,forward,backward):
|
||||||
"""Ensure invariance of conversion from Rodrigues-Frank vector and back."""
|
"""Ensure invariance of conversion from Rodrigues-Frank vector and back."""
|
||||||
cutoff = np.tan(np.pi*.5*(1.-1e-4))
|
cutoff = np.tan(np.pi*.5*(1.-1e-5))
|
||||||
for rot in set_of_rotations:
|
for rot in set_of_rotations:
|
||||||
m = rot.as_Rodrigues_vector()
|
m = rot.as_Rodrigues_vector()
|
||||||
o = backward(forward(m))
|
o = backward(forward(m))
|
||||||
ok = np.allclose(np.clip(m,None,cutoff),np.clip(o,None,cutoff),atol=atol)
|
ok = np.allclose(np.clip(m,None,cutoff),np.clip(o,None,cutoff),atol=atol)
|
||||||
ok = ok or np.isclose(m[3],0.0,atol=atol)
|
ok |= np.isclose(m[3],0.0,atol=atol)
|
||||||
|
if m[3] > cutoff:
|
||||||
|
ok |= np.allclose(m[:3],-1*o[:3])
|
||||||
|
|
||||||
assert ok and np.isclose(np.linalg.norm(o[:3]),1.0), f'{m},{o},{rot.as_quaternion()}'
|
assert ok and np.isclose(np.linalg.norm(o[:3]),1.0), f'{m},{o},{rot.as_quaternion()}'
|
||||||
|
|
||||||
@pytest.mark.parametrize('forward,backward',[(Rotation._ho2qu,Rotation._qu2ho),
|
@pytest.mark.parametrize('forward,backward',[(Rotation._ho2qu,Rotation._qu2ho),
|
||||||
|
@ -592,7 +595,7 @@ class TestRotation:
|
||||||
o = backward(forward(m))
|
o = backward(forward(m))
|
||||||
ok = np.allclose(m,o,atol=atol)
|
ok = np.allclose(m,o,atol=atol)
|
||||||
if np.count_nonzero(np.isclose(np.abs(o),np.pi**(2./3.)*.5)):
|
if np.count_nonzero(np.isclose(np.abs(o),np.pi**(2./3.)*.5)):
|
||||||
ok = ok or np.allclose(m*-1.,o,atol=atol)
|
ok |= np.allclose(m*-1.,o,atol=atol)
|
||||||
assert ok and np.max(np.abs(o)) < np.pi**(2./3.) * 0.5 + 1.e-9, f'{m},{o},{rot.as_quaternion()}'
|
assert ok and np.max(np.abs(o)) < np.pi**(2./3.) * 0.5 + 1.e-9, f'{m},{o},{rot.as_quaternion()}'
|
||||||
|
|
||||||
@pytest.mark.parametrize('vectorized, single',[(Rotation._qu2om,qu2om),
|
@pytest.mark.parametrize('vectorized, single',[(Rotation._qu2om,qu2om),
|
||||||
|
@ -686,6 +689,10 @@ class TestRotation:
|
||||||
with pytest.raises(TypeError):
|
with pytest.raises(TypeError):
|
||||||
Rotation(np.ones(3))
|
Rotation(np.ones(3))
|
||||||
|
|
||||||
|
def test_to_numpy(self):
|
||||||
|
r = Rotation.from_random(np.random.randint(0,10,4))
|
||||||
|
assert np.all(r.as_quaternion() == np.array(r))
|
||||||
|
|
||||||
@pytest.mark.parametrize('degrees',[True,False])
|
@pytest.mark.parametrize('degrees',[True,False])
|
||||||
def test_Eulers(self,set_of_rotations,degrees):
|
def test_Eulers(self,set_of_rotations,degrees):
|
||||||
for rot in set_of_rotations:
|
for rot in set_of_rotations:
|
||||||
|
@ -719,7 +726,7 @@ class TestRotation:
|
||||||
o = Rotation.from_axis_angle(rot.as_axis_angle()).as_axis_angle()
|
o = Rotation.from_axis_angle(rot.as_axis_angle()).as_axis_angle()
|
||||||
ok = np.allclose(m,o,atol=atol)
|
ok = np.allclose(m,o,atol=atol)
|
||||||
if np.isclose(m[3],np.pi,atol=atol):
|
if np.isclose(m[3],np.pi,atol=atol):
|
||||||
ok = ok or np.allclose(m*np.array([-1.,-1.,-1.,1.]),o,atol=atol)
|
ok |= np.allclose(m*np.array([-1.,-1.,-1.,1.]),o,atol=atol)
|
||||||
assert ok and np.isclose(np.linalg.norm(o[:3]),1.0) \
|
assert ok and np.isclose(np.linalg.norm(o[:3]),1.0) \
|
||||||
and o[3]<=np.pi+1.e-9, f'{m},{o},{rot.as_quaternion()}'
|
and o[3]<=np.pi+1.e-9, f'{m},{o},{rot.as_quaternion()}'
|
||||||
|
|
||||||
|
@ -740,7 +747,7 @@ class TestRotation:
|
||||||
m = rot.as_Rodrigues_vector()
|
m = rot.as_Rodrigues_vector()
|
||||||
o = Rotation.from_homochoric(rot.as_homochoric()*P*-1,P).as_Rodrigues_vector()
|
o = Rotation.from_homochoric(rot.as_homochoric()*P*-1,P).as_Rodrigues_vector()
|
||||||
ok = np.allclose(np.clip(m,None,cutoff),np.clip(o,None,cutoff),atol=atol)
|
ok = np.allclose(np.clip(m,None,cutoff),np.clip(o,None,cutoff),atol=atol)
|
||||||
ok = ok or np.isclose(m[3],0.0,atol=atol)
|
ok |= np.isclose(m[3],0.0,atol=atol)
|
||||||
assert ok and np.isclose(np.linalg.norm(o[:3]),1.0), f'{m},{o},{rot.as_quaternion()}'
|
assert ok and np.isclose(np.linalg.norm(o[:3]),1.0), f'{m},{o},{rot.as_quaternion()}'
|
||||||
|
|
||||||
@pytest.mark.parametrize('P',[1,-1])
|
@pytest.mark.parametrize('P',[1,-1])
|
||||||
|
@ -780,14 +787,32 @@ class TestRotation:
|
||||||
else:
|
else:
|
||||||
assert r.shape == shape
|
assert r.shape == shape
|
||||||
|
|
||||||
def test_equal(self):
|
@pytest.mark.parametrize('shape',[None,5,(4,6)])
|
||||||
assert Rotation.from_random(rng_seed=1) == Rotation.from_random(rng_seed=1)
|
def test_equal(self,shape):
|
||||||
|
R = Rotation.from_random(shape,rng_seed=1)
|
||||||
|
assert R == R if shape is None else (R == R).all()
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('shape',[None,5,(4,6)])
|
||||||
|
def test_unequal(self,shape):
|
||||||
|
R = Rotation.from_random(shape,rng_seed=1)
|
||||||
|
assert not (R != R if shape is None else (R != R).any())
|
||||||
|
|
||||||
|
|
||||||
|
def test_equal_ambiguous(self):
|
||||||
|
qu = np.random.rand(10,4)
|
||||||
|
qu[:,0] = 0.
|
||||||
|
qu/=np.linalg.norm(qu,axis=1,keepdims=True)
|
||||||
|
assert (Rotation(qu) == Rotation(-qu)).all()
|
||||||
|
|
||||||
def test_inversion(self):
|
def test_inversion(self):
|
||||||
r = Rotation.from_random()
|
r = Rotation.from_random()
|
||||||
assert r == ~~r
|
assert r == ~~r
|
||||||
|
|
||||||
@pytest.mark.parametrize('shape',[None,1,(1,),(4,2),(1,1,1)])
|
@pytest.mark.parametrize('shape',[1,(1,),(4,2),(1,1,1),tuple(np.random.randint(0,10,4))])
|
||||||
|
def test_size(self,shape):
|
||||||
|
assert Rotation.from_random(shape).size == np.prod(shape)
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('shape',[None,1,(1,),(4,2),(1,1,1),tuple(np.random.randint(0,10,4))])
|
||||||
def test_shape(self,shape):
|
def test_shape(self,shape):
|
||||||
r = Rotation.from_random(shape=shape)
|
r = Rotation.from_random(shape=shape)
|
||||||
assert r.shape == (shape if isinstance(shape,tuple) else (shape,) if shape else ())
|
assert r.shape == (shape if isinstance(shape,tuple) else (shape,) if shape else ())
|
||||||
|
@ -798,7 +823,7 @@ class TestRotation:
|
||||||
p = Rotation.from_random(shape=shape)
|
p = Rotation.from_random(shape=shape)
|
||||||
s = r.append(p)
|
s = r.append(p)
|
||||||
print(f'append 2x {shape} --> {s.shape}')
|
print(f'append 2x {shape} --> {s.shape}')
|
||||||
assert s[0,...] == r[0,...] and s[-1,...] == p[-1,...]
|
assert np.logical_and(s[0,...] == r[0,...], s[-1,...] == p[-1,...]).all()
|
||||||
|
|
||||||
@pytest.mark.parametrize('shape',[None,1,(1,),(4,2),(3,3,2)])
|
@pytest.mark.parametrize('shape',[None,1,(1,),(4,2),(3,3,2)])
|
||||||
def test_append_list(self,shape):
|
def test_append_list(self,shape):
|
||||||
|
@ -806,7 +831,7 @@ class TestRotation:
|
||||||
p = Rotation.from_random(shape=shape)
|
p = Rotation.from_random(shape=shape)
|
||||||
s = r.append([r,p])
|
s = r.append([r,p])
|
||||||
print(f'append 3x {shape} --> {s.shape}')
|
print(f'append 3x {shape} --> {s.shape}')
|
||||||
assert s[0,...] == r[0,...] and s[-1,...] == p[-1,...]
|
assert np.logical_and(s[0,...] == r[0,...], s[-1,...] == p[-1,...]).all()
|
||||||
|
|
||||||
@pytest.mark.parametrize('quat,standardized',[
|
@pytest.mark.parametrize('quat,standardized',[
|
||||||
([-1,0,0,0],[1,0,0,0]),
|
([-1,0,0,0],[1,0,0,0]),
|
||||||
|
@ -828,7 +853,7 @@ class TestRotation:
|
||||||
@pytest.mark.parametrize('order',['C','F'])
|
@pytest.mark.parametrize('order',['C','F'])
|
||||||
def test_flatten_reshape(self,shape,order):
|
def test_flatten_reshape(self,shape,order):
|
||||||
r = Rotation.from_random(shape=shape)
|
r = Rotation.from_random(shape=shape)
|
||||||
assert r == r.flatten(order).reshape(shape,order)
|
assert (r == r.flatten(order).reshape(shape,order)).all()
|
||||||
|
|
||||||
@pytest.mark.parametrize('function',[Rotation.from_quaternion,
|
@pytest.mark.parametrize('function',[Rotation.from_quaternion,
|
||||||
Rotation.from_Euler_angles,
|
Rotation.from_Euler_angles,
|
||||||
|
@ -939,7 +964,7 @@ class TestRotation:
|
||||||
|
|
||||||
def test_rotate_inverse(self):
|
def test_rotate_inverse(self):
|
||||||
R = Rotation.from_random()
|
R = Rotation.from_random()
|
||||||
assert np.allclose(np.eye(3),(~R@R).as_matrix())
|
assert np.allclose(np.eye(3),(~R*R).as_matrix())
|
||||||
|
|
||||||
@pytest.mark.parametrize('data',[np.random.rand(3),
|
@pytest.mark.parametrize('data',[np.random.rand(3),
|
||||||
np.random.rand(3,3),
|
np.random.rand(3,3),
|
||||||
|
@ -973,6 +998,42 @@ class TestRotation:
|
||||||
R_2 = Rotation.from_Euler_angles([360,0,0],degrees=True)
|
R_2 = Rotation.from_Euler_angles([360,0,0],degrees=True)
|
||||||
assert np.allclose(R_1.misorientation(R_2).as_matrix(),np.eye(3))
|
assert np.allclose(R_1.misorientation(R_2).as_matrix(),np.eye(3))
|
||||||
|
|
||||||
|
def test_composition(self):
|
||||||
|
a,b = (Rotation.from_random(),Rotation.from_random())
|
||||||
|
c = a * b
|
||||||
|
a *= b
|
||||||
|
assert c == a
|
||||||
|
|
||||||
|
def test_composition_invalid(self):
|
||||||
|
with pytest.raises(TypeError):
|
||||||
|
Rotation()*np.ones(3)
|
||||||
|
|
||||||
|
def test_composition_inverse(self):
|
||||||
|
a,b = (Rotation.from_random(),Rotation.from_random())
|
||||||
|
c = a / b
|
||||||
|
a /= b
|
||||||
|
assert c == a
|
||||||
|
|
||||||
|
def test_composition_inverse_invalid(self):
|
||||||
|
with pytest.raises(TypeError):
|
||||||
|
Rotation()/np.ones(3)
|
||||||
|
|
||||||
|
def test_power(self):
|
||||||
|
a = Rotation.from_random()
|
||||||
|
r = (np.random.rand()-.5)*4
|
||||||
|
b = a**r
|
||||||
|
a **= r
|
||||||
|
assert a == b
|
||||||
|
|
||||||
|
def test_invariant(self):
|
||||||
|
R = Rotation.from_random()
|
||||||
|
assert R/R == R*R**(-1) == Rotation()
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('item',[np.ones(3),np.ones((3,3)), np.ones((3,3,3,3))])
|
||||||
|
def test_apply(self,item):
|
||||||
|
r = Rotation.from_random()
|
||||||
|
assert (r.apply(item) == r@item).all()
|
||||||
|
|
||||||
@pytest.mark.parametrize('angle',[10,20,30,40,50,60,70,80,90,100,120])
|
@pytest.mark.parametrize('angle',[10,20,30,40,50,60,70,80,90,100,120])
|
||||||
def test_average(self,angle):
|
def test_average(self,angle):
|
||||||
R = Rotation.from_axis_angle([[0,0,1,10],[0,0,1,angle]],degrees=True)
|
R = Rotation.from_axis_angle([[0,0,1,10],[0,0,1,angle]],degrees=True)
|
||||||
|
|
|
@ -49,17 +49,18 @@ class TestUtil:
|
||||||
dist_sampled = np.histogram(centers[selected],bins)[0]/N_samples*np.sum(dist)
|
dist_sampled = np.histogram(centers[selected],bins)[0]/N_samples*np.sum(dist)
|
||||||
assert np.sqrt(((dist - dist_sampled) ** 2).mean()) < .025 and selected.shape[0]==N_samples
|
assert np.sqrt(((dist - dist_sampled) ** 2).mean()) < .025 and selected.shape[0]==N_samples
|
||||||
|
|
||||||
@pytest.mark.parametrize('point,normalize,answer',
|
@pytest.mark.parametrize('point,direction,normalize,keepdims,answer',
|
||||||
[
|
[
|
||||||
([1,0,0],False,[1,0,0]),
|
([1,0,0],'z',False,True, [1,0,0]),
|
||||||
([1,0,0],True, [1,0,0]),
|
([1,0,0],'z',True, False,[1,0]),
|
||||||
([0,1,1],False,[0,0.5,0]),
|
([0,1,1],'z',False,True, [0,0.5,0]),
|
||||||
([0,1,1],True, [0,0.41421356,0]),
|
([0,1,1],'y',True, False,[0.41421356,0]),
|
||||||
([1,1,1],False,[0.5,0.5,0]),
|
([1,1,0],'x',False,False,[0.5,0]),
|
||||||
([1,1,1],True, [0.3660254, 0.3660254, 0]),
|
([1,1,1],'y',True, True, [0.3660254, 0,0.3660254]),
|
||||||
])
|
])
|
||||||
def test_project_stereographic(self,point,normalize,answer):
|
def test_project_stereographic(self,point,direction,normalize,keepdims,answer):
|
||||||
assert np.allclose(util.project_stereographic(np.array(point),normalize=normalize),answer)
|
assert np.allclose(util.project_stereographic(np.array(point),direction=direction,
|
||||||
|
normalize=normalize,keepdims=keepdims),answer)
|
||||||
|
|
||||||
@pytest.mark.parametrize('fro,to,mode,answer',
|
@pytest.mark.parametrize('fro,to,mode,answer',
|
||||||
[
|
[
|
||||||
|
|
|
@ -19,7 +19,7 @@ module CPFEM
|
||||||
use HDF5_utilities
|
use HDF5_utilities
|
||||||
use results
|
use results
|
||||||
use lattice
|
use lattice
|
||||||
use constitutive
|
use phase
|
||||||
|
|
||||||
implicit none
|
implicit none
|
||||||
private
|
private
|
||||||
|
@ -72,7 +72,6 @@ contains
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
subroutine CPFEM_initAll
|
subroutine CPFEM_initAll
|
||||||
|
|
||||||
call parallelization_init
|
|
||||||
call DAMASK_interface_init
|
call DAMASK_interface_init
|
||||||
call prec_init
|
call prec_init
|
||||||
call IO_init
|
call IO_init
|
||||||
|
@ -86,7 +85,7 @@ subroutine CPFEM_initAll
|
||||||
call discretization_marc_init
|
call discretization_marc_init
|
||||||
call lattice_init
|
call lattice_init
|
||||||
call material_init(.false.)
|
call material_init(.false.)
|
||||||
call constitutive_init
|
call phase_init
|
||||||
call homogenization_init
|
call homogenization_init
|
||||||
call crystallite_init
|
call crystallite_init
|
||||||
call CPFEM_init
|
call CPFEM_init
|
||||||
|
@ -179,11 +178,11 @@ subroutine CPFEM_general(mode, ffn, ffn1, temperature_inp, dt, elFE, ip, cauchyS
|
||||||
|
|
||||||
if (iand(mode, CPFEM_AGERESULTS) /= 0_pInt) call CPFEM_forward
|
if (iand(mode, CPFEM_AGERESULTS) /= 0_pInt) call CPFEM_forward
|
||||||
|
|
||||||
chosenThermal1: select case (thermal_type(material_homogenizationAt(elCP)))
|
!chosenThermal1: select case (thermal_type(material_homogenizationAt(elCP)))
|
||||||
case (THERMAL_conduction_ID) chosenThermal1
|
! case (THERMAL_conduction_ID) chosenThermal1
|
||||||
temperature(material_homogenizationAt(elCP))%p(material_homogenizationMemberAt(ip,elCP)) = &
|
! temperature(material_homogenizationAt(elCP))%p(material_homogenizationMemberAt(ip,elCP)) = &
|
||||||
temperature_inp
|
! temperature_inp
|
||||||
end select chosenThermal1
|
!end select chosenThermal1
|
||||||
homogenization_F0(1:3,1:3,ma) = ffn
|
homogenization_F0(1:3,1:3,ma) = ffn
|
||||||
homogenization_F(1:3,1:3,ma) = ffn1
|
homogenization_F(1:3,1:3,ma) = ffn1
|
||||||
|
|
||||||
|
@ -258,7 +257,7 @@ end subroutine CPFEM_general
|
||||||
subroutine CPFEM_forward
|
subroutine CPFEM_forward
|
||||||
|
|
||||||
call homogenization_forward
|
call homogenization_forward
|
||||||
call constitutive_forward
|
call phase_forward
|
||||||
|
|
||||||
end subroutine CPFEM_forward
|
end subroutine CPFEM_forward
|
||||||
|
|
||||||
|
@ -273,7 +272,7 @@ subroutine CPFEM_results(inc,time)
|
||||||
|
|
||||||
call results_openJobFile
|
call results_openJobFile
|
||||||
call results_addIncrement(inc,time)
|
call results_addIncrement(inc,time)
|
||||||
call constitutive_results
|
call phase_results
|
||||||
call homogenization_results
|
call homogenization_results
|
||||||
call discretization_results
|
call discretization_results
|
||||||
call results_finalizeIncrement
|
call results_finalizeIncrement
|
||||||
|
|
|
@ -19,7 +19,7 @@ module CPFEM2
|
||||||
use discretization
|
use discretization
|
||||||
use HDF5_utilities
|
use HDF5_utilities
|
||||||
use homogenization
|
use homogenization
|
||||||
use constitutive
|
use phase
|
||||||
#if defined(Mesh)
|
#if defined(Mesh)
|
||||||
use FEM_quadrature
|
use FEM_quadrature
|
||||||
use discretization_mesh
|
use discretization_mesh
|
||||||
|
@ -60,7 +60,7 @@ subroutine CPFEM_initAll
|
||||||
call discretization_grid_init(restart=interface_restartInc>0)
|
call discretization_grid_init(restart=interface_restartInc>0)
|
||||||
#endif
|
#endif
|
||||||
call material_init(restart=interface_restartInc>0)
|
call material_init(restart=interface_restartInc>0)
|
||||||
call constitutive_init
|
call phase_init
|
||||||
call homogenization_init
|
call homogenization_init
|
||||||
call crystallite_init
|
call crystallite_init
|
||||||
call CPFEM_init
|
call CPFEM_init
|
||||||
|
@ -74,9 +74,22 @@ end subroutine CPFEM_initAll
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
subroutine CPFEM_init
|
subroutine CPFEM_init
|
||||||
|
|
||||||
|
integer(HID_T) :: fileHandle
|
||||||
|
|
||||||
|
|
||||||
print'(/,a)', ' <<<+- CPFEM init -+>>>'; flush(IO_STDOUT)
|
print'(/,a)', ' <<<+- CPFEM init -+>>>'; flush(IO_STDOUT)
|
||||||
|
|
||||||
if (interface_restartInc > 0) call crystallite_restartRead
|
|
||||||
|
if (interface_restartInc > 0) then
|
||||||
|
print'(/,a,i0,a)', ' reading restart information of increment from file'; flush(IO_STDOUT)
|
||||||
|
|
||||||
|
fileHandle = HDF5_openFile(getSolverJobName()//'_restart.hdf5','r')
|
||||||
|
|
||||||
|
call homogenization_restartRead(fileHandle)
|
||||||
|
call phase_restartRead(fileHandle)
|
||||||
|
|
||||||
|
call HDF5_closeFile(fileHandle)
|
||||||
|
endif
|
||||||
|
|
||||||
end subroutine CPFEM_init
|
end subroutine CPFEM_init
|
||||||
|
|
||||||
|
@ -86,7 +99,17 @@ end subroutine CPFEM_init
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
subroutine CPFEM_restartWrite
|
subroutine CPFEM_restartWrite
|
||||||
|
|
||||||
call crystallite_restartWrite
|
integer(HID_T) :: fileHandle
|
||||||
|
|
||||||
|
|
||||||
|
print*, ' writing field and constitutive data required for restart to file';flush(IO_STDOUT)
|
||||||
|
|
||||||
|
fileHandle = HDF5_openFile(getSolverJobName()//'_restart.hdf5','a')
|
||||||
|
|
||||||
|
call homogenization_restartWrite(fileHandle)
|
||||||
|
call phase_restartWrite(fileHandle)
|
||||||
|
|
||||||
|
call HDF5_closeFile(fileHandle)
|
||||||
|
|
||||||
end subroutine CPFEM_restartWrite
|
end subroutine CPFEM_restartWrite
|
||||||
|
|
||||||
|
@ -97,7 +120,7 @@ end subroutine CPFEM_restartWrite
|
||||||
subroutine CPFEM_forward
|
subroutine CPFEM_forward
|
||||||
|
|
||||||
call homogenization_forward
|
call homogenization_forward
|
||||||
call constitutive_forward
|
call phase_forward
|
||||||
|
|
||||||
end subroutine CPFEM_forward
|
end subroutine CPFEM_forward
|
||||||
|
|
||||||
|
@ -112,7 +135,7 @@ subroutine CPFEM_results(inc,time)
|
||||||
|
|
||||||
call results_openJobFile
|
call results_openJobFile
|
||||||
call results_addIncrement(inc,time)
|
call results_addIncrement(inc,time)
|
||||||
call constitutive_results
|
call phase_results
|
||||||
call homogenization_results
|
call homogenization_results
|
||||||
call discretization_results
|
call discretization_results
|
||||||
call results_finalizeIncrement
|
call results_finalizeIncrement
|
||||||
|
|
|
@ -43,7 +43,7 @@ void gethostname_c(char hostname[], int *stat){
|
||||||
|
|
||||||
|
|
||||||
void getusername_c(char username[], int *stat){
|
void getusername_c(char username[], int *stat){
|
||||||
struct passwd *pw = getpwuid(geteuid());
|
struct passwd *pw = getpwuid(getuid());
|
||||||
if(pw && strlen(pw->pw_name) <= STRLEN){
|
if(pw && strlen(pw->pw_name) <= STRLEN){
|
||||||
strncpy(username,pw->pw_name,STRLEN+1);
|
strncpy(username,pw->pw_name,STRLEN+1);
|
||||||
*stat = 0;
|
*stat = 0;
|
||||||
|
|
|
@ -199,7 +199,7 @@ subroutine DAMASK_interface_init
|
||||||
if (interface_restartInc > 0) &
|
if (interface_restartInc > 0) &
|
||||||
print'(a,i6.6)', ' Restart from increment: ', interface_restartInc
|
print'(a,i6.6)', ' Restart from increment: ', interface_restartInc
|
||||||
|
|
||||||
!call signalterm_c(c_funloc(catchSIGTERM))
|
call signalterm_c(c_funloc(catchSIGTERM))
|
||||||
call signalusr1_c(c_funloc(catchSIGUSR1))
|
call signalusr1_c(c_funloc(catchSIGUSR1))
|
||||||
call signalusr2_c(c_funloc(catchSIGUSR2))
|
call signalusr2_c(c_funloc(catchSIGUSR2))
|
||||||
call interface_setSIGTERM(.false.)
|
call interface_setSIGTERM(.false.)
|
||||||
|
@ -386,24 +386,14 @@ end function makeRelativePath
|
||||||
subroutine catchSIGTERM(signal) bind(C)
|
subroutine catchSIGTERM(signal) bind(C)
|
||||||
|
|
||||||
integer(C_INT), value :: signal
|
integer(C_INT), value :: signal
|
||||||
|
|
||||||
|
|
||||||
|
print'(a,i0)', ' received signal ',signal
|
||||||
call interface_setSIGTERM(.true.)
|
call interface_setSIGTERM(.true.)
|
||||||
|
|
||||||
print'(a,i0,a)', ' received signal ',signal, ', set SIGTERM=TRUE'
|
|
||||||
|
|
||||||
end subroutine catchSIGTERM
|
end subroutine catchSIGTERM
|
||||||
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief Set global variable interface_SIGTERM.
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
subroutine interface_setSIGTERM(state)
|
|
||||||
|
|
||||||
logical, intent(in) :: state
|
|
||||||
interface_SIGTERM = state
|
|
||||||
|
|
||||||
end subroutine interface_setSIGTERM
|
|
||||||
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @brief Set global variable interface_SIGUSR1 to .true.
|
!> @brief Set global variable interface_SIGUSR1 to .true.
|
||||||
!> @details This function can be registered to catch signals send to the executable.
|
!> @details This function can be registered to catch signals send to the executable.
|
||||||
|
@ -411,24 +401,14 @@ end subroutine interface_setSIGTERM
|
||||||
subroutine catchSIGUSR1(signal) bind(C)
|
subroutine catchSIGUSR1(signal) bind(C)
|
||||||
|
|
||||||
integer(C_INT), value :: signal
|
integer(C_INT), value :: signal
|
||||||
|
|
||||||
|
|
||||||
|
print'(a,i0)', ' received signal ',signal
|
||||||
call interface_setSIGUSR1(.true.)
|
call interface_setSIGUSR1(.true.)
|
||||||
|
|
||||||
print'(a,i0,a)', ' received signal ',signal, ', set SIGUSR1=TRUE'
|
|
||||||
|
|
||||||
end subroutine catchSIGUSR1
|
end subroutine catchSIGUSR1
|
||||||
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief Set global variable interface_SIGUSR.
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
subroutine interface_setSIGUSR1(state)
|
|
||||||
|
|
||||||
logical, intent(in) :: state
|
|
||||||
interface_SIGUSR1 = state
|
|
||||||
|
|
||||||
end subroutine interface_setSIGUSR1
|
|
||||||
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @brief Set global variable interface_SIGUSR2 to .true.
|
!> @brief Set global variable interface_SIGUSR2 to .true.
|
||||||
!> @details This function can be registered to catch signals send to the executable.
|
!> @details This function can be registered to catch signals send to the executable.
|
||||||
|
@ -436,20 +416,52 @@ end subroutine interface_setSIGUSR1
|
||||||
subroutine catchSIGUSR2(signal) bind(C)
|
subroutine catchSIGUSR2(signal) bind(C)
|
||||||
|
|
||||||
integer(C_INT), value :: signal
|
integer(C_INT), value :: signal
|
||||||
|
|
||||||
|
|
||||||
|
print'(a,i0,a)', ' received signal ',signal
|
||||||
call interface_setSIGUSR2(.true.)
|
call interface_setSIGUSR2(.true.)
|
||||||
|
|
||||||
print'(a,i0,a)', ' received signal ',signal, ', set SIGUSR2=TRUE'
|
|
||||||
|
|
||||||
end subroutine catchSIGUSR2
|
end subroutine catchSIGUSR2
|
||||||
|
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief Set global variable interface_SIGTERM.
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
subroutine interface_setSIGTERM(state)
|
||||||
|
|
||||||
|
logical, intent(in) :: state
|
||||||
|
|
||||||
|
|
||||||
|
interface_SIGTERM = state
|
||||||
|
print*, 'set SIGTERM to',state
|
||||||
|
|
||||||
|
end subroutine interface_setSIGTERM
|
||||||
|
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief Set global variable interface_SIGUSR.
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
subroutine interface_setSIGUSR1(state)
|
||||||
|
|
||||||
|
logical, intent(in) :: state
|
||||||
|
|
||||||
|
|
||||||
|
interface_SIGUSR1 = state
|
||||||
|
print*, 'set SIGUSR1 to',state
|
||||||
|
|
||||||
|
end subroutine interface_setSIGUSR1
|
||||||
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @brief Set global variable interface_SIGUSR2.
|
!> @brief Set global variable interface_SIGUSR2.
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
subroutine interface_setSIGUSR2(state)
|
subroutine interface_setSIGUSR2(state)
|
||||||
|
|
||||||
logical, intent(in) :: state
|
logical, intent(in) :: state
|
||||||
|
|
||||||
|
|
||||||
interface_SIGUSR2 = state
|
interface_SIGUSR2 = state
|
||||||
|
print*, 'set SIGUSR2 to',state
|
||||||
|
|
||||||
end subroutine interface_setSIGUSR2
|
end subroutine interface_setSIGUSR2
|
||||||
|
|
||||||
|
|
|
@ -7,20 +7,6 @@
|
||||||
!> @author Christoph Kords, Max-Planck-Institut für Eisenforschung GmbH
|
!> @author Christoph Kords, Max-Planck-Institut für Eisenforschung GmbH
|
||||||
!> @author Martin Diehl, Max-Planck-Institut für Eisenforschung GmbH
|
!> @author Martin Diehl, Max-Planck-Institut für Eisenforschung GmbH
|
||||||
!> @brief Interfaces DAMASK with MSC.Marc
|
!> @brief Interfaces DAMASK with MSC.Marc
|
||||||
!> @details Usage:
|
|
||||||
!> @details - choose material as hypela2
|
|
||||||
!> @details - set statevariable 2 to index of homogenization
|
|
||||||
!> @details - set statevariable 3 to index of microstructure
|
|
||||||
!> @details - use nonsymmetric option for solver (e.g. direct profile or multifrontal sparse, the latter seems to be faster!)
|
|
||||||
!> @details - in case of ddm (domain decomposition) a SYMMETRIC solver has to be used, i.e uncheck "non-symmetric"
|
|
||||||
!> @details Marc subroutines used:
|
|
||||||
!> @details - hypela2
|
|
||||||
!> @details - uedinc
|
|
||||||
!> @details - flux
|
|
||||||
!> @details - quit
|
|
||||||
!> @details Marc common blocks included:
|
|
||||||
!> @details - concom: lovl, inc
|
|
||||||
!> @details - creeps: timinc
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
#define QUOTE(x) #x
|
#define QUOTE(x) #x
|
||||||
#define PASTE(x,y) x ## y
|
#define PASTE(x,y) x ## y
|
||||||
|
@ -65,14 +51,8 @@ subroutine DAMASK_interface_init
|
||||||
|
|
||||||
print'(/,a)', ' Version: '//DAMASKVERSION
|
print'(/,a)', ' Version: '//DAMASKVERSION
|
||||||
|
|
||||||
! https://github.com/jeffhammond/HPCInfo/blob/master/docs/Preprocessor-Macros.md
|
|
||||||
#if __INTEL_COMPILER >= 1800
|
|
||||||
print'(/,a)', ' Compiled with: '//compiler_version()
|
print'(/,a)', ' Compiled with: '//compiler_version()
|
||||||
print'(a)', ' Compiler options: '//compiler_options()
|
print'(a)', ' Compiler options: '//compiler_options()
|
||||||
#else
|
|
||||||
print'(/,a,i4.4,a,i8.8)', ' Compiled with Intel fortran version :', __INTEL_COMPILER,&
|
|
||||||
', build date :', __INTEL_COMPILER_BUILD_DATE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
print'(/,a)', ' Compiled on: '//__DATE__//' at '//__TIME__
|
print'(/,a)', ' Compiled on: '//__DATE__//' at '//__TIME__
|
||||||
|
|
||||||
|
@ -239,7 +219,7 @@ subroutine hypela2(d,g,e,de,s,t,dt,ngens,m,nn,kcus,matus,ndi,nshear,disp, &
|
||||||
real(pReal), dimension(6) :: stress
|
real(pReal), dimension(6) :: stress
|
||||||
real(pReal), dimension(6,6) :: ddsdde
|
real(pReal), dimension(6,6) :: ddsdde
|
||||||
integer :: computationMode, i, cp_en, node, CPnodeID
|
integer :: computationMode, i, cp_en, node, CPnodeID
|
||||||
integer(4) :: defaultNumThreadsInt !< default value set by Marc
|
integer(pI32) :: defaultNumThreadsInt !< default value set by Marc
|
||||||
|
|
||||||
integer(pInt), save :: &
|
integer(pInt), save :: &
|
||||||
theInc = -1_pInt, & !< needs description
|
theInc = -1_pInt, & !< needs description
|
||||||
|
@ -256,7 +236,7 @@ subroutine hypela2(d,g,e,de,s,t,dt,ngens,m,nn,kcus,matus,ndi,nshear,disp, &
|
||||||
debug_Marc ! pointer to Marc debug options
|
debug_Marc ! pointer to Marc debug options
|
||||||
|
|
||||||
if(debug_basic) then
|
if(debug_basic) then
|
||||||
print'(a,/,i8,i8,i2)', ' MSC.MARC information on shape of element(2), IP:', m, nn
|
print'(a,/,i8,i8,i2)', ' MSC.Marc information on shape of element(2), IP:', m, nn
|
||||||
print'(a,2(i1))', ' Jacobian: ', ngens,ngens
|
print'(a,2(i1))', ' Jacobian: ', ngens,ngens
|
||||||
print'(a,i1)', ' Direct stress: ', ndi
|
print'(a,i1)', ' Direct stress: ', ndi
|
||||||
print'(a,i1)', ' Shear stress: ', nshear
|
print'(a,i1)', ' Shear stress: ', nshear
|
||||||
|
@ -271,7 +251,7 @@ subroutine hypela2(d,g,e,de,s,t,dt,ngens,m,nn,kcus,matus,ndi,nshear,disp, &
|
||||||
endif
|
endif
|
||||||
|
|
||||||
defaultNumThreadsInt = omp_get_num_threads() ! remember number of threads set by Marc
|
defaultNumThreadsInt = omp_get_num_threads() ! remember number of threads set by Marc
|
||||||
call omp_set_num_threads(1) ! no openMP
|
call omp_set_num_threads(1_pI32) ! no openMP
|
||||||
|
|
||||||
if (.not. CPFEM_init_done) then
|
if (.not. CPFEM_init_done) then
|
||||||
CPFEM_init_done = .true.
|
CPFEM_init_done = .true.
|
||||||
|
@ -351,7 +331,7 @@ end subroutine hypela2
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
subroutine flux(f,ts,n,time)
|
subroutine flux(f,ts,n,time)
|
||||||
use prec
|
use prec
|
||||||
use thermal_conduction
|
use homogenization
|
||||||
use discretization_marc
|
use discretization_marc
|
||||||
|
|
||||||
implicit none
|
implicit none
|
||||||
|
@ -364,7 +344,8 @@ subroutine flux(f,ts,n,time)
|
||||||
real(pReal), dimension(2), intent(out) :: &
|
real(pReal), dimension(2), intent(out) :: &
|
||||||
f
|
f
|
||||||
|
|
||||||
call thermal_conduction_getSourceAndItsTangent(f(1), f(2), ts(3), n(3),mesh_FEM2DAMASK_elem(n(1)))
|
f(2) = 0.0_pReal
|
||||||
|
call thermal_conduction_getSource(f(1), n(3),mesh_FEM2DAMASK_elem(n(1)))
|
||||||
|
|
||||||
end subroutine flux
|
end subroutine flux
|
||||||
|
|
||||||
|
@ -378,14 +359,28 @@ subroutine flux(f,ts,n,time)
|
||||||
subroutine uedinc(inc,incsub)
|
subroutine uedinc(inc,incsub)
|
||||||
use prec
|
use prec
|
||||||
use CPFEM
|
use CPFEM
|
||||||
|
use discretization_marc
|
||||||
|
|
||||||
implicit none
|
implicit none
|
||||||
integer, intent(in) :: inc, incsub
|
integer, intent(in) :: inc, incsub
|
||||||
|
integer :: n, nqncomp, nqdatatype
|
||||||
integer, save :: inc_written
|
integer, save :: inc_written
|
||||||
|
real(pReal), allocatable, dimension(:,:) :: d_n
|
||||||
#include QUOTE(PASTE(./marc/include/creeps,Marc4DAMASK)) ! creeps is needed for timinc (time increment)
|
#include QUOTE(PASTE(./marc/include/creeps,Marc4DAMASK)) ! creeps is needed for timinc (time increment)
|
||||||
|
|
||||||
|
|
||||||
if (inc > inc_written) then
|
if (inc > inc_written) then
|
||||||
|
allocate(d_n(3,count(mesh_FEM2DAMASK_node /= -1)))
|
||||||
|
do n = lbound(mesh_FEM2DAMASK_node,1), ubound(mesh_FEM2DAMASK_node,1)
|
||||||
|
if (mesh_FEM2DAMASK_node(n) /= -1) then
|
||||||
|
call nodvar(1,n,d_n(1:3,mesh_FEM2DAMASK_node(n)),nqncomp,nqdatatype)
|
||||||
|
if(nqncomp == 2) d_n(3,mesh_FEM2DAMASK_node(n)) = 0.0_pReal
|
||||||
|
endif
|
||||||
|
enddo
|
||||||
|
|
||||||
|
call discretization_marc_UpdateNodeAndIpCoords(d_n)
|
||||||
call CPFEM_results(inc,cptim)
|
call CPFEM_results(inc,cptim)
|
||||||
|
|
||||||
inc_written = inc
|
inc_written = inc
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
|
@ -71,6 +71,12 @@ module HDF5_utilities
|
||||||
module procedure HDF5_addAttribute_real_array
|
module procedure HDF5_addAttribute_real_array
|
||||||
end interface HDF5_addAttribute
|
end interface HDF5_addAttribute
|
||||||
|
|
||||||
|
#ifdef PETSc
|
||||||
|
logical, parameter, private :: parallel_default = .true.
|
||||||
|
#else
|
||||||
|
logical, parameter, private :: parallel_default = .false.
|
||||||
|
#endif
|
||||||
|
|
||||||
contains
|
contains
|
||||||
|
|
||||||
|
|
||||||
|
@ -105,16 +111,16 @@ end subroutine HDF5_utilities_init
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @brief open and initializes HDF5 output file
|
!> @brief open and initializes HDF5 output file
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
integer(HID_T) function HDF5_openFile(fileName,mode,parallel)
|
integer(HID_T) function HDF5_openFile(fileName,mode)
|
||||||
|
|
||||||
character(len=*), intent(in) :: fileName
|
character(len=*), intent(in) :: fileName
|
||||||
character, intent(in), optional :: mode
|
character, intent(in), optional :: mode
|
||||||
logical, intent(in), optional :: parallel
|
|
||||||
|
|
||||||
character :: m
|
character :: m
|
||||||
integer(HID_T) :: plist_id
|
integer(HID_T) :: plist_id
|
||||||
integer :: hdferr
|
integer :: hdferr
|
||||||
|
|
||||||
|
|
||||||
if (present(mode)) then
|
if (present(mode)) then
|
||||||
m = mode
|
m = mode
|
||||||
else
|
else
|
||||||
|
@ -125,10 +131,8 @@ integer(HID_T) function HDF5_openFile(fileName,mode,parallel)
|
||||||
if(hdferr < 0) error stop 'HDF5 error'
|
if(hdferr < 0) error stop 'HDF5 error'
|
||||||
|
|
||||||
#ifdef PETSc
|
#ifdef PETSc
|
||||||
if (present(parallel)) then; if (parallel) then
|
|
||||||
call h5pset_fapl_mpio_f(plist_id, PETSC_COMM_WORLD, MPI_INFO_NULL, hdferr)
|
call h5pset_fapl_mpio_f(plist_id, PETSC_COMM_WORLD, MPI_INFO_NULL, hdferr)
|
||||||
if(hdferr < 0) error stop 'HDF5 error'
|
if(hdferr < 0) error stop 'HDF5 error'
|
||||||
endif; endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (m == 'w') then
|
if (m == 'w') then
|
||||||
|
@ -547,7 +551,7 @@ subroutine HDF5_read_real1(loc_id,dataset,datasetName,parallel)
|
||||||
myStart, totalShape, loc_id,myShape,datasetName,parallel)
|
myStart, totalShape, loc_id,myShape,datasetName,parallel)
|
||||||
else
|
else
|
||||||
call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, &
|
call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, &
|
||||||
myStart, totalShape, loc_id,myShape,datasetName,.false.)
|
myStart, totalShape, loc_id,myShape,datasetName,parallel_default)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
call h5dread_f(dset_id, H5T_NATIVE_DOUBLE,dataset,totalShape, hdferr,&
|
call h5dread_f(dset_id, H5T_NATIVE_DOUBLE,dataset,totalShape, hdferr,&
|
||||||
|
@ -587,7 +591,7 @@ subroutine HDF5_read_real2(loc_id,dataset,datasetName,parallel)
|
||||||
myStart, totalShape, loc_id,myShape,datasetName,parallel)
|
myStart, totalShape, loc_id,myShape,datasetName,parallel)
|
||||||
else
|
else
|
||||||
call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, &
|
call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, &
|
||||||
myStart, totalShape, loc_id,myShape,datasetName,.false.)
|
myStart, totalShape, loc_id,myShape,datasetName,parallel_default)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
call h5dread_f(dset_id, H5T_NATIVE_DOUBLE,dataset,totalShape, hdferr,&
|
call h5dread_f(dset_id, H5T_NATIVE_DOUBLE,dataset,totalShape, hdferr,&
|
||||||
|
@ -627,7 +631,7 @@ subroutine HDF5_read_real3(loc_id,dataset,datasetName,parallel)
|
||||||
myStart, totalShape, loc_id,myShape,datasetName,parallel)
|
myStart, totalShape, loc_id,myShape,datasetName,parallel)
|
||||||
else
|
else
|
||||||
call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, &
|
call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, &
|
||||||
myStart, totalShape, loc_id,myShape,datasetName,.false.)
|
myStart, totalShape, loc_id,myShape,datasetName,parallel_default)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
call h5dread_f(dset_id, H5T_NATIVE_DOUBLE,dataset,totalShape, hdferr,&
|
call h5dread_f(dset_id, H5T_NATIVE_DOUBLE,dataset,totalShape, hdferr,&
|
||||||
|
@ -667,7 +671,7 @@ subroutine HDF5_read_real4(loc_id,dataset,datasetName,parallel)
|
||||||
myStart, totalShape, loc_id,myShape,datasetName,parallel)
|
myStart, totalShape, loc_id,myShape,datasetName,parallel)
|
||||||
else
|
else
|
||||||
call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, &
|
call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, &
|
||||||
myStart, totalShape, loc_id,myShape,datasetName,.false.)
|
myStart, totalShape, loc_id,myShape,datasetName,parallel_default)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
call h5dread_f(dset_id, H5T_NATIVE_DOUBLE,dataset,totalShape, hdferr,&
|
call h5dread_f(dset_id, H5T_NATIVE_DOUBLE,dataset,totalShape, hdferr,&
|
||||||
|
@ -707,7 +711,7 @@ subroutine HDF5_read_real5(loc_id,dataset,datasetName,parallel)
|
||||||
myStart, totalShape, loc_id,myShape,datasetName,parallel)
|
myStart, totalShape, loc_id,myShape,datasetName,parallel)
|
||||||
else
|
else
|
||||||
call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, &
|
call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, &
|
||||||
myStart, totalShape, loc_id,myShape,datasetName,.false.)
|
myStart, totalShape, loc_id,myShape,datasetName,parallel_default)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
call h5dread_f(dset_id, H5T_NATIVE_DOUBLE,dataset,totalShape, hdferr,&
|
call h5dread_f(dset_id, H5T_NATIVE_DOUBLE,dataset,totalShape, hdferr,&
|
||||||
|
@ -747,7 +751,7 @@ subroutine HDF5_read_real6(loc_id,dataset,datasetName,parallel)
|
||||||
myStart, totalShape, loc_id,myShape,datasetName,parallel)
|
myStart, totalShape, loc_id,myShape,datasetName,parallel)
|
||||||
else
|
else
|
||||||
call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, &
|
call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, &
|
||||||
myStart, totalShape, loc_id,myShape,datasetName,.false.)
|
myStart, totalShape, loc_id,myShape,datasetName,parallel_default)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
call h5dread_f(dset_id, H5T_NATIVE_DOUBLE,dataset,totalShape, hdferr,&
|
call h5dread_f(dset_id, H5T_NATIVE_DOUBLE,dataset,totalShape, hdferr,&
|
||||||
|
@ -787,7 +791,7 @@ subroutine HDF5_read_real7(loc_id,dataset,datasetName,parallel)
|
||||||
myStart, totalShape, loc_id,myShape,datasetName,parallel)
|
myStart, totalShape, loc_id,myShape,datasetName,parallel)
|
||||||
else
|
else
|
||||||
call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, &
|
call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, &
|
||||||
myStart, totalShape, loc_id,myShape,datasetName,.false.)
|
myStart, totalShape, loc_id,myShape,datasetName,parallel_default)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
call h5dread_f(dset_id, H5T_NATIVE_DOUBLE,dataset,totalShape, hdferr,&
|
call h5dread_f(dset_id, H5T_NATIVE_DOUBLE,dataset,totalShape, hdferr,&
|
||||||
|
@ -829,7 +833,7 @@ subroutine HDF5_read_int1(loc_id,dataset,datasetName,parallel)
|
||||||
myStart, totalShape, loc_id,myShape,datasetName,parallel)
|
myStart, totalShape, loc_id,myShape,datasetName,parallel)
|
||||||
else
|
else
|
||||||
call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, &
|
call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, &
|
||||||
myStart, totalShape, loc_id,myShape,datasetName,.false.)
|
myStart, totalShape, loc_id,myShape,datasetName,parallel_default)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
call h5dread_f(dset_id, H5T_NATIVE_INTEGER,dataset,totalShape, hdferr,&
|
call h5dread_f(dset_id, H5T_NATIVE_INTEGER,dataset,totalShape, hdferr,&
|
||||||
|
@ -869,7 +873,7 @@ subroutine HDF5_read_int2(loc_id,dataset,datasetName,parallel)
|
||||||
myStart, totalShape, loc_id,myShape,datasetName,parallel)
|
myStart, totalShape, loc_id,myShape,datasetName,parallel)
|
||||||
else
|
else
|
||||||
call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, &
|
call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, &
|
||||||
myStart, totalShape, loc_id,myShape,datasetName,.false.)
|
myStart, totalShape, loc_id,myShape,datasetName,parallel_default)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
call h5dread_f(dset_id, H5T_NATIVE_INTEGER,dataset,totalShape, hdferr,&
|
call h5dread_f(dset_id, H5T_NATIVE_INTEGER,dataset,totalShape, hdferr,&
|
||||||
|
@ -909,7 +913,7 @@ subroutine HDF5_read_int3(loc_id,dataset,datasetName,parallel)
|
||||||
myStart, totalShape, loc_id,myShape,datasetName,parallel)
|
myStart, totalShape, loc_id,myShape,datasetName,parallel)
|
||||||
else
|
else
|
||||||
call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, &
|
call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, &
|
||||||
myStart, totalShape, loc_id,myShape,datasetName,.false.)
|
myStart, totalShape, loc_id,myShape,datasetName,parallel_default)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
call h5dread_f(dset_id, H5T_NATIVE_INTEGER,dataset,totalShape, hdferr,&
|
call h5dread_f(dset_id, H5T_NATIVE_INTEGER,dataset,totalShape, hdferr,&
|
||||||
|
@ -949,7 +953,7 @@ subroutine HDF5_read_int4(loc_id,dataset,datasetName,parallel)
|
||||||
myStart, totalShape, loc_id,myShape,datasetName,parallel)
|
myStart, totalShape, loc_id,myShape,datasetName,parallel)
|
||||||
else
|
else
|
||||||
call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, &
|
call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, &
|
||||||
myStart, totalShape, loc_id,myShape,datasetName,.false.)
|
myStart, totalShape, loc_id,myShape,datasetName,parallel_default)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
call h5dread_f(dset_id, H5T_NATIVE_INTEGER,dataset,totalShape, hdferr,&
|
call h5dread_f(dset_id, H5T_NATIVE_INTEGER,dataset,totalShape, hdferr,&
|
||||||
|
@ -989,7 +993,7 @@ subroutine HDF5_read_int5(loc_id,dataset,datasetName,parallel)
|
||||||
myStart, totalShape, loc_id,myShape,datasetName,parallel)
|
myStart, totalShape, loc_id,myShape,datasetName,parallel)
|
||||||
else
|
else
|
||||||
call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, &
|
call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, &
|
||||||
myStart, totalShape, loc_id,myShape,datasetName,.false.)
|
myStart, totalShape, loc_id,myShape,datasetName,parallel_default)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
call h5dread_f(dset_id, H5T_NATIVE_INTEGER,dataset,totalShape, hdferr,&
|
call h5dread_f(dset_id, H5T_NATIVE_INTEGER,dataset,totalShape, hdferr,&
|
||||||
|
@ -1029,7 +1033,7 @@ subroutine HDF5_read_int6(loc_id,dataset,datasetName,parallel)
|
||||||
myStart, totalShape, loc_id,myShape,datasetName,parallel)
|
myStart, totalShape, loc_id,myShape,datasetName,parallel)
|
||||||
else
|
else
|
||||||
call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, &
|
call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, &
|
||||||
myStart, totalShape, loc_id,myShape,datasetName,.false.)
|
myStart, totalShape, loc_id,myShape,datasetName,parallel_default)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
call h5dread_f(dset_id, H5T_NATIVE_INTEGER,dataset,totalShape, hdferr,&
|
call h5dread_f(dset_id, H5T_NATIVE_INTEGER,dataset,totalShape, hdferr,&
|
||||||
|
@ -1069,7 +1073,7 @@ subroutine HDF5_read_int7(loc_id,dataset,datasetName,parallel)
|
||||||
myStart, totalShape, loc_id,myShape,datasetName,parallel)
|
myStart, totalShape, loc_id,myShape,datasetName,parallel)
|
||||||
else
|
else
|
||||||
call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, &
|
call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, &
|
||||||
myStart, totalShape, loc_id,myShape,datasetName,.false.)
|
myStart, totalShape, loc_id,myShape,datasetName,parallel_default)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
call h5dread_f(dset_id, H5T_NATIVE_INTEGER,dataset,totalShape, hdferr,&
|
call h5dread_f(dset_id, H5T_NATIVE_INTEGER,dataset,totalShape, hdferr,&
|
||||||
|
@ -1086,7 +1090,7 @@ end subroutine HDF5_read_int7
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
subroutine HDF5_write_real1(loc_id,dataset,datasetName,parallel)
|
subroutine HDF5_write_real1(loc_id,dataset,datasetName,parallel)
|
||||||
|
|
||||||
real(pReal), intent(inout), dimension(:) :: dataset !< data written to file
|
real(pReal), intent(in), dimension(:) :: dataset !< data written to file
|
||||||
integer(HID_T), intent(in) :: loc_id !< file or group handle
|
integer(HID_T), intent(in) :: loc_id !< file or group handle
|
||||||
character(len=*), intent(in) :: datasetName !< name of the dataset in the file
|
character(len=*), intent(in) :: datasetName !< name of the dataset in the file
|
||||||
logical, intent(in), optional :: parallel !< dataset is distributed over multiple processes
|
logical, intent(in), optional :: parallel !< dataset is distributed over multiple processes
|
||||||
|
@ -1109,7 +1113,7 @@ subroutine HDF5_write_real1(loc_id,dataset,datasetName,parallel)
|
||||||
myStart, totalShape,loc_id,myShape,datasetName,H5T_NATIVE_DOUBLE,parallel)
|
myStart, totalShape,loc_id,myShape,datasetName,H5T_NATIVE_DOUBLE,parallel)
|
||||||
else
|
else
|
||||||
call initialize_write(dset_id, filespace_id, memspace_id, plist_id, &
|
call initialize_write(dset_id, filespace_id, memspace_id, plist_id, &
|
||||||
myStart, totalShape,loc_id,myShape,datasetName,H5T_NATIVE_DOUBLE,.false.)
|
myStart, totalShape,loc_id,myShape,datasetName,H5T_NATIVE_DOUBLE,parallel_default)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if (product(totalShape) /= 0) then
|
if (product(totalShape) /= 0) then
|
||||||
|
@ -1127,7 +1131,7 @@ end subroutine HDF5_write_real1
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
subroutine HDF5_write_real2(loc_id,dataset,datasetName,parallel)
|
subroutine HDF5_write_real2(loc_id,dataset,datasetName,parallel)
|
||||||
|
|
||||||
real(pReal), intent(inout), dimension(:,:) :: dataset !< data written to file
|
real(pReal), intent(in), dimension(:,:) :: dataset !< data written to file
|
||||||
integer(HID_T), intent(in) :: loc_id !< file or group handle
|
integer(HID_T), intent(in) :: loc_id !< file or group handle
|
||||||
character(len=*), intent(in) :: datasetName !< name of the dataset in the file
|
character(len=*), intent(in) :: datasetName !< name of the dataset in the file
|
||||||
logical, intent(in), optional :: parallel !< dataset is distributed over multiple processes
|
logical, intent(in), optional :: parallel !< dataset is distributed over multiple processes
|
||||||
|
@ -1150,7 +1154,7 @@ subroutine HDF5_write_real2(loc_id,dataset,datasetName,parallel)
|
||||||
myStart, totalShape, loc_id,myShape,datasetName,H5T_NATIVE_DOUBLE,parallel)
|
myStart, totalShape, loc_id,myShape,datasetName,H5T_NATIVE_DOUBLE,parallel)
|
||||||
else
|
else
|
||||||
call initialize_write(dset_id, filespace_id, memspace_id, plist_id, &
|
call initialize_write(dset_id, filespace_id, memspace_id, plist_id, &
|
||||||
myStart, totalShape, loc_id,myShape,datasetName,H5T_NATIVE_DOUBLE,.false.)
|
myStart, totalShape, loc_id,myShape,datasetName,H5T_NATIVE_DOUBLE,parallel_default)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if (product(totalShape) /= 0) then
|
if (product(totalShape) /= 0) then
|
||||||
|
@ -1168,7 +1172,7 @@ end subroutine HDF5_write_real2
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
subroutine HDF5_write_real3(loc_id,dataset,datasetName,parallel)
|
subroutine HDF5_write_real3(loc_id,dataset,datasetName,parallel)
|
||||||
|
|
||||||
real(pReal), intent(inout), dimension(:,:,:) :: dataset !< data written to file
|
real(pReal), intent(in), dimension(:,:,:) :: dataset !< data written to file
|
||||||
integer(HID_T), intent(in) :: loc_id !< file or group handle
|
integer(HID_T), intent(in) :: loc_id !< file or group handle
|
||||||
character(len=*), intent(in) :: datasetName !< name of the dataset in the file
|
character(len=*), intent(in) :: datasetName !< name of the dataset in the file
|
||||||
logical, intent(in), optional :: parallel !< dataset is distributed over multiple processes
|
logical, intent(in), optional :: parallel !< dataset is distributed over multiple processes
|
||||||
|
@ -1191,7 +1195,7 @@ subroutine HDF5_write_real3(loc_id,dataset,datasetName,parallel)
|
||||||
myStart, totalShape, loc_id,myShape,datasetName,H5T_NATIVE_DOUBLE,parallel)
|
myStart, totalShape, loc_id,myShape,datasetName,H5T_NATIVE_DOUBLE,parallel)
|
||||||
else
|
else
|
||||||
call initialize_write(dset_id, filespace_id, memspace_id, plist_id, &
|
call initialize_write(dset_id, filespace_id, memspace_id, plist_id, &
|
||||||
myStart, totalShape, loc_id,myShape,datasetName,H5T_NATIVE_DOUBLE,.false.)
|
myStart, totalShape, loc_id,myShape,datasetName,H5T_NATIVE_DOUBLE,parallel_default)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if (product(totalShape) /= 0) then
|
if (product(totalShape) /= 0) then
|
||||||
|
@ -1209,7 +1213,7 @@ end subroutine HDF5_write_real3
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
subroutine HDF5_write_real4(loc_id,dataset,datasetName,parallel)
|
subroutine HDF5_write_real4(loc_id,dataset,datasetName,parallel)
|
||||||
|
|
||||||
real(pReal), intent(inout), dimension(:,:,:,:) :: dataset !< data written to file
|
real(pReal), intent(in), dimension(:,:,:,:) :: dataset !< data written to file
|
||||||
integer(HID_T), intent(in) :: loc_id !< file or group handle
|
integer(HID_T), intent(in) :: loc_id !< file or group handle
|
||||||
character(len=*), intent(in) :: datasetName !< name of the dataset in the file
|
character(len=*), intent(in) :: datasetName !< name of the dataset in the file
|
||||||
logical, intent(in), optional :: parallel !< dataset is distributed over multiple processes
|
logical, intent(in), optional :: parallel !< dataset is distributed over multiple processes
|
||||||
|
@ -1232,7 +1236,7 @@ subroutine HDF5_write_real4(loc_id,dataset,datasetName,parallel)
|
||||||
myStart, totalShape, loc_id,myShape,datasetName,H5T_NATIVE_DOUBLE,parallel)
|
myStart, totalShape, loc_id,myShape,datasetName,H5T_NATIVE_DOUBLE,parallel)
|
||||||
else
|
else
|
||||||
call initialize_write(dset_id, filespace_id, memspace_id, plist_id, &
|
call initialize_write(dset_id, filespace_id, memspace_id, plist_id, &
|
||||||
myStart, totalShape, loc_id,myShape,datasetName,H5T_NATIVE_DOUBLE,.false.)
|
myStart, totalShape, loc_id,myShape,datasetName,H5T_NATIVE_DOUBLE,parallel_default)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if (product(totalShape) /= 0) then
|
if (product(totalShape) /= 0) then
|
||||||
|
@ -1251,7 +1255,7 @@ end subroutine HDF5_write_real4
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
subroutine HDF5_write_real5(loc_id,dataset,datasetName,parallel)
|
subroutine HDF5_write_real5(loc_id,dataset,datasetName,parallel)
|
||||||
|
|
||||||
real(pReal), intent(inout), dimension(:,:,:,:,:) :: dataset !< data written to file
|
real(pReal), intent(in), dimension(:,:,:,:,:) :: dataset !< data written to file
|
||||||
integer(HID_T), intent(in) :: loc_id !< file or group handle
|
integer(HID_T), intent(in) :: loc_id !< file or group handle
|
||||||
character(len=*), intent(in) :: datasetName !< name of the dataset in the file
|
character(len=*), intent(in) :: datasetName !< name of the dataset in the file
|
||||||
logical, intent(in), optional :: parallel !< dataset is distributed over multiple processes
|
logical, intent(in), optional :: parallel !< dataset is distributed over multiple processes
|
||||||
|
@ -1274,7 +1278,7 @@ subroutine HDF5_write_real5(loc_id,dataset,datasetName,parallel)
|
||||||
myStart, totalShape, loc_id,myShape,datasetName,H5T_NATIVE_DOUBLE,parallel)
|
myStart, totalShape, loc_id,myShape,datasetName,H5T_NATIVE_DOUBLE,parallel)
|
||||||
else
|
else
|
||||||
call initialize_write(dset_id, filespace_id, memspace_id, plist_id, &
|
call initialize_write(dset_id, filespace_id, memspace_id, plist_id, &
|
||||||
myStart, totalShape, loc_id,myShape,datasetName,H5T_NATIVE_DOUBLE,.false.)
|
myStart, totalShape, loc_id,myShape,datasetName,H5T_NATIVE_DOUBLE,parallel_default)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if (product(totalShape) /= 0) then
|
if (product(totalShape) /= 0) then
|
||||||
|
@ -1292,7 +1296,7 @@ end subroutine HDF5_write_real5
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
subroutine HDF5_write_real6(loc_id,dataset,datasetName,parallel)
|
subroutine HDF5_write_real6(loc_id,dataset,datasetName,parallel)
|
||||||
|
|
||||||
real(pReal), intent(inout), dimension(:,:,:,:,:,:) :: dataset !< data written to file
|
real(pReal), intent(in), dimension(:,:,:,:,:,:) :: dataset !< data written to file
|
||||||
integer(HID_T), intent(in) :: loc_id !< file or group handle
|
integer(HID_T), intent(in) :: loc_id !< file or group handle
|
||||||
character(len=*), intent(in) :: datasetName !< name of the dataset in the file
|
character(len=*), intent(in) :: datasetName !< name of the dataset in the file
|
||||||
logical, intent(in), optional :: parallel !< dataset is distributed over multiple processes
|
logical, intent(in), optional :: parallel !< dataset is distributed over multiple processes
|
||||||
|
@ -1315,7 +1319,7 @@ subroutine HDF5_write_real6(loc_id,dataset,datasetName,parallel)
|
||||||
myStart, totalShape, loc_id,myShape,datasetName,H5T_NATIVE_DOUBLE,parallel)
|
myStart, totalShape, loc_id,myShape,datasetName,H5T_NATIVE_DOUBLE,parallel)
|
||||||
else
|
else
|
||||||
call initialize_write(dset_id, filespace_id, memspace_id, plist_id, &
|
call initialize_write(dset_id, filespace_id, memspace_id, plist_id, &
|
||||||
myStart, totalShape, loc_id,myShape,datasetName,H5T_NATIVE_DOUBLE,.false.)
|
myStart, totalShape, loc_id,myShape,datasetName,H5T_NATIVE_DOUBLE,parallel_default)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if (product(totalShape) /= 0) then
|
if (product(totalShape) /= 0) then
|
||||||
|
@ -1333,7 +1337,7 @@ end subroutine HDF5_write_real6
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
subroutine HDF5_write_real7(loc_id,dataset,datasetName,parallel)
|
subroutine HDF5_write_real7(loc_id,dataset,datasetName,parallel)
|
||||||
|
|
||||||
real(pReal), intent(inout), dimension(:,:,:,:,:,:,:) :: dataset !< data written to file
|
real(pReal), intent(in), dimension(:,:,:,:,:,:,:) :: dataset !< data written to file
|
||||||
integer(HID_T), intent(in) :: loc_id !< file or group handle
|
integer(HID_T), intent(in) :: loc_id !< file or group handle
|
||||||
character(len=*), intent(in) :: datasetName !< name of the dataset in the file
|
character(len=*), intent(in) :: datasetName !< name of the dataset in the file
|
||||||
logical, intent(in), optional :: parallel !< dataset is distributed over multiple processes
|
logical, intent(in), optional :: parallel !< dataset is distributed over multiple processes
|
||||||
|
@ -1356,7 +1360,7 @@ subroutine HDF5_write_real7(loc_id,dataset,datasetName,parallel)
|
||||||
myStart, totalShape, loc_id,myShape,datasetName,H5T_NATIVE_DOUBLE,parallel)
|
myStart, totalShape, loc_id,myShape,datasetName,H5T_NATIVE_DOUBLE,parallel)
|
||||||
else
|
else
|
||||||
call initialize_write(dset_id, filespace_id, memspace_id, plist_id, &
|
call initialize_write(dset_id, filespace_id, memspace_id, plist_id, &
|
||||||
myStart, totalShape, loc_id,myShape,datasetName,H5T_NATIVE_DOUBLE,.false.)
|
myStart, totalShape, loc_id,myShape,datasetName,H5T_NATIVE_DOUBLE,parallel_default)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if (product(totalShape) /= 0) then
|
if (product(totalShape) /= 0) then
|
||||||
|
@ -1375,7 +1379,7 @@ end subroutine HDF5_write_real7
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
subroutine HDF5_write_int1(loc_id,dataset,datasetName,parallel)
|
subroutine HDF5_write_int1(loc_id,dataset,datasetName,parallel)
|
||||||
|
|
||||||
integer, intent(inout), dimension(:) :: dataset !< data written to file
|
integer, intent(in), dimension(:) :: dataset !< data written to file
|
||||||
integer(HID_T), intent(in) :: loc_id !< file or group handle
|
integer(HID_T), intent(in) :: loc_id !< file or group handle
|
||||||
character(len=*), intent(in) :: datasetName !< name of the dataset in the file
|
character(len=*), intent(in) :: datasetName !< name of the dataset in the file
|
||||||
logical, intent(in), optional :: parallel !< dataset is distributed over multiple processes
|
logical, intent(in), optional :: parallel !< dataset is distributed over multiple processes
|
||||||
|
@ -1398,7 +1402,7 @@ subroutine HDF5_write_int1(loc_id,dataset,datasetName,parallel)
|
||||||
myStart, totalShape, loc_id,myShape,datasetName,H5T_NATIVE_INTEGER,parallel)
|
myStart, totalShape, loc_id,myShape,datasetName,H5T_NATIVE_INTEGER,parallel)
|
||||||
else
|
else
|
||||||
call initialize_write(dset_id, filespace_id, memspace_id, plist_id, &
|
call initialize_write(dset_id, filespace_id, memspace_id, plist_id, &
|
||||||
myStart, totalShape, loc_id,myShape,datasetName,H5T_NATIVE_INTEGER,.false.)
|
myStart, totalShape, loc_id,myShape,datasetName,H5T_NATIVE_INTEGER,parallel_default)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if (product(totalShape) /= 0) then
|
if (product(totalShape) /= 0) then
|
||||||
|
@ -1416,7 +1420,7 @@ end subroutine HDF5_write_int1
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
subroutine HDF5_write_int2(loc_id,dataset,datasetName,parallel)
|
subroutine HDF5_write_int2(loc_id,dataset,datasetName,parallel)
|
||||||
|
|
||||||
integer, intent(inout), dimension(:,:) :: dataset !< data written to file
|
integer, intent(in), dimension(:,:) :: dataset !< data written to file
|
||||||
integer(HID_T), intent(in) :: loc_id !< file or group handle
|
integer(HID_T), intent(in) :: loc_id !< file or group handle
|
||||||
character(len=*), intent(in) :: datasetName !< name of the dataset in the file
|
character(len=*), intent(in) :: datasetName !< name of the dataset in the file
|
||||||
logical, intent(in), optional :: parallel !< dataset is distributed over multiple processes
|
logical, intent(in), optional :: parallel !< dataset is distributed over multiple processes
|
||||||
|
@ -1439,7 +1443,7 @@ subroutine HDF5_write_int2(loc_id,dataset,datasetName,parallel)
|
||||||
myStart, totalShape, loc_id,myShape,datasetName,H5T_NATIVE_INTEGER,parallel)
|
myStart, totalShape, loc_id,myShape,datasetName,H5T_NATIVE_INTEGER,parallel)
|
||||||
else
|
else
|
||||||
call initialize_write(dset_id, filespace_id, memspace_id, plist_id, &
|
call initialize_write(dset_id, filespace_id, memspace_id, plist_id, &
|
||||||
myStart, totalShape, loc_id,myShape,datasetName,H5T_NATIVE_INTEGER,.false.)
|
myStart, totalShape, loc_id,myShape,datasetName,H5T_NATIVE_INTEGER,parallel_default)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if (product(totalShape) /= 0) then
|
if (product(totalShape) /= 0) then
|
||||||
|
@ -1457,7 +1461,7 @@ end subroutine HDF5_write_int2
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
subroutine HDF5_write_int3(loc_id,dataset,datasetName,parallel)
|
subroutine HDF5_write_int3(loc_id,dataset,datasetName,parallel)
|
||||||
|
|
||||||
integer, intent(inout), dimension(:,:,:) :: dataset !< data written to file
|
integer, intent(in), dimension(:,:,:) :: dataset !< data written to file
|
||||||
integer(HID_T), intent(in) :: loc_id !< file or group handle
|
integer(HID_T), intent(in) :: loc_id !< file or group handle
|
||||||
character(len=*), intent(in) :: datasetName !< name of the dataset in the file
|
character(len=*), intent(in) :: datasetName !< name of the dataset in the file
|
||||||
logical, intent(in), optional :: parallel !< dataset is distributed over multiple processes
|
logical, intent(in), optional :: parallel !< dataset is distributed over multiple processes
|
||||||
|
@ -1480,7 +1484,7 @@ subroutine HDF5_write_int3(loc_id,dataset,datasetName,parallel)
|
||||||
myStart, totalShape, loc_id,myShape,datasetName,H5T_NATIVE_INTEGER,parallel)
|
myStart, totalShape, loc_id,myShape,datasetName,H5T_NATIVE_INTEGER,parallel)
|
||||||
else
|
else
|
||||||
call initialize_write(dset_id, filespace_id, memspace_id, plist_id, &
|
call initialize_write(dset_id, filespace_id, memspace_id, plist_id, &
|
||||||
myStart, totalShape, loc_id,myShape,datasetName,H5T_NATIVE_INTEGER,.false.)
|
myStart, totalShape, loc_id,myShape,datasetName,H5T_NATIVE_INTEGER,parallel_default)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if (product(totalShape) /= 0) then
|
if (product(totalShape) /= 0) then
|
||||||
|
@ -1498,7 +1502,7 @@ end subroutine HDF5_write_int3
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
subroutine HDF5_write_int4(loc_id,dataset,datasetName,parallel)
|
subroutine HDF5_write_int4(loc_id,dataset,datasetName,parallel)
|
||||||
|
|
||||||
integer, intent(inout), dimension(:,:,:,:) :: dataset !< data written to file
|
integer, intent(in), dimension(:,:,:,:) :: dataset !< data written to file
|
||||||
integer(HID_T), intent(in) :: loc_id !< file or group handle
|
integer(HID_T), intent(in) :: loc_id !< file or group handle
|
||||||
character(len=*), intent(in) :: datasetName !< name of the dataset in the file
|
character(len=*), intent(in) :: datasetName !< name of the dataset in the file
|
||||||
logical, intent(in), optional :: parallel !< dataset is distributed over multiple processes
|
logical, intent(in), optional :: parallel !< dataset is distributed over multiple processes
|
||||||
|
@ -1521,7 +1525,7 @@ subroutine HDF5_write_int4(loc_id,dataset,datasetName,parallel)
|
||||||
myStart, totalShape, loc_id,myShape,datasetName,H5T_NATIVE_INTEGER,parallel)
|
myStart, totalShape, loc_id,myShape,datasetName,H5T_NATIVE_INTEGER,parallel)
|
||||||
else
|
else
|
||||||
call initialize_write(dset_id, filespace_id, memspace_id, plist_id, &
|
call initialize_write(dset_id, filespace_id, memspace_id, plist_id, &
|
||||||
myStart, totalShape, loc_id,myShape,datasetName,H5T_NATIVE_INTEGER,.false.)
|
myStart, totalShape, loc_id,myShape,datasetName,H5T_NATIVE_INTEGER,parallel_default)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if (product(totalShape) /= 0) then
|
if (product(totalShape) /= 0) then
|
||||||
|
@ -1539,7 +1543,7 @@ end subroutine HDF5_write_int4
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
subroutine HDF5_write_int5(loc_id,dataset,datasetName,parallel)
|
subroutine HDF5_write_int5(loc_id,dataset,datasetName,parallel)
|
||||||
|
|
||||||
integer, intent(inout), dimension(:,:,:,:,:) :: dataset !< data written to file
|
integer, intent(in), dimension(:,:,:,:,:) :: dataset !< data written to file
|
||||||
integer(HID_T), intent(in) :: loc_id !< file or group handle
|
integer(HID_T), intent(in) :: loc_id !< file or group handle
|
||||||
character(len=*), intent(in) :: datasetName !< name of the dataset in the file
|
character(len=*), intent(in) :: datasetName !< name of the dataset in the file
|
||||||
logical, intent(in), optional :: parallel !< dataset is distributed over multiple processes
|
logical, intent(in), optional :: parallel !< dataset is distributed over multiple processes
|
||||||
|
@ -1562,7 +1566,7 @@ subroutine HDF5_write_int5(loc_id,dataset,datasetName,parallel)
|
||||||
myStart, totalShape, loc_id,myShape,datasetName,H5T_NATIVE_INTEGER,parallel)
|
myStart, totalShape, loc_id,myShape,datasetName,H5T_NATIVE_INTEGER,parallel)
|
||||||
else
|
else
|
||||||
call initialize_write(dset_id, filespace_id, memspace_id, plist_id, &
|
call initialize_write(dset_id, filespace_id, memspace_id, plist_id, &
|
||||||
myStart, totalShape, loc_id,myShape,datasetName,H5T_NATIVE_INTEGER,.false.)
|
myStart, totalShape, loc_id,myShape,datasetName,H5T_NATIVE_INTEGER,parallel_default)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if (product(totalShape) /= 0) then
|
if (product(totalShape) /= 0) then
|
||||||
|
@ -1580,7 +1584,7 @@ end subroutine HDF5_write_int5
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
subroutine HDF5_write_int6(loc_id,dataset,datasetName,parallel)
|
subroutine HDF5_write_int6(loc_id,dataset,datasetName,parallel)
|
||||||
|
|
||||||
integer, intent(inout), dimension(:,:,:,:,:,:) :: dataset !< data written to file
|
integer, intent(in), dimension(:,:,:,:,:,:) :: dataset !< data written to file
|
||||||
integer(HID_T), intent(in) :: loc_id !< file or group handle
|
integer(HID_T), intent(in) :: loc_id !< file or group handle
|
||||||
character(len=*), intent(in) :: datasetName !< name of the dataset in the file
|
character(len=*), intent(in) :: datasetName !< name of the dataset in the file
|
||||||
logical, intent(in), optional :: parallel !< dataset is distributed over multiple processes
|
logical, intent(in), optional :: parallel !< dataset is distributed over multiple processes
|
||||||
|
@ -1603,7 +1607,7 @@ subroutine HDF5_write_int6(loc_id,dataset,datasetName,parallel)
|
||||||
myStart, totalShape, loc_id,myShape,datasetName,H5T_NATIVE_INTEGER,parallel)
|
myStart, totalShape, loc_id,myShape,datasetName,H5T_NATIVE_INTEGER,parallel)
|
||||||
else
|
else
|
||||||
call initialize_write(dset_id, filespace_id, memspace_id, plist_id, &
|
call initialize_write(dset_id, filespace_id, memspace_id, plist_id, &
|
||||||
myStart, totalShape, loc_id,myShape,datasetName,H5T_NATIVE_INTEGER,.false.)
|
myStart, totalShape, loc_id,myShape,datasetName,H5T_NATIVE_INTEGER,parallel_default)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if (product(totalShape) /= 0) then
|
if (product(totalShape) /= 0) then
|
||||||
|
@ -1621,7 +1625,7 @@ end subroutine HDF5_write_int6
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
subroutine HDF5_write_int7(loc_id,dataset,datasetName,parallel)
|
subroutine HDF5_write_int7(loc_id,dataset,datasetName,parallel)
|
||||||
|
|
||||||
integer, intent(inout), dimension(:,:,:,:,:,:,:) :: dataset !< data written to file
|
integer, intent(in), dimension(:,:,:,:,:,:,:) :: dataset !< data written to file
|
||||||
integer(HID_T), intent(in) :: loc_id !< file or group handle
|
integer(HID_T), intent(in) :: loc_id !< file or group handle
|
||||||
character(len=*), intent(in) :: datasetName !< name of the dataset in the file
|
character(len=*), intent(in) :: datasetName !< name of the dataset in the file
|
||||||
logical, intent(in), optional :: parallel !< dataset is distributed over multiple processes
|
logical, intent(in), optional :: parallel !< dataset is distributed over multiple processes
|
||||||
|
@ -1644,7 +1648,7 @@ subroutine HDF5_write_int7(loc_id,dataset,datasetName,parallel)
|
||||||
myStart, totalShape, loc_id,myShape,datasetName,H5T_NATIVE_INTEGER,parallel)
|
myStart, totalShape, loc_id,myShape,datasetName,H5T_NATIVE_INTEGER,parallel)
|
||||||
else
|
else
|
||||||
call initialize_write(dset_id, filespace_id, memspace_id, plist_id, &
|
call initialize_write(dset_id, filespace_id, memspace_id, plist_id, &
|
||||||
myStart, totalShape, loc_id,myShape,datasetName,H5T_NATIVE_INTEGER,.false.)
|
myStart, totalShape, loc_id,myShape,datasetName,H5T_NATIVE_INTEGER,parallel_default)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if (product(totalShape) /= 0) then
|
if (product(totalShape) /= 0) then
|
||||||
|
|
27
src/IO.f90
27
src/IO.f90
|
@ -65,8 +65,8 @@ end subroutine IO_init
|
||||||
function IO_readlines(fileName) result(fileContent)
|
function IO_readlines(fileName) result(fileContent)
|
||||||
|
|
||||||
character(len=*), intent(in) :: fileName
|
character(len=*), intent(in) :: fileName
|
||||||
|
|
||||||
character(len=pStringLen), dimension(:), allocatable :: fileContent !< file content, separated per lines
|
character(len=pStringLen), dimension(:), allocatable :: fileContent !< file content, separated per lines
|
||||||
|
|
||||||
character(len=pStringLen) :: line
|
character(len=pStringLen) :: line
|
||||||
character(len=:), allocatable :: rawData
|
character(len=:), allocatable :: rawData
|
||||||
integer :: &
|
integer :: &
|
||||||
|
@ -75,6 +75,7 @@ function IO_readlines(fileName) result(fileContent)
|
||||||
l
|
l
|
||||||
logical :: warned
|
logical :: warned
|
||||||
|
|
||||||
|
|
||||||
rawData = IO_read(fileName)
|
rawData = IO_read(fileName)
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
@ -112,16 +113,21 @@ end function IO_readlines
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @brief Read whole file.
|
!> @brief Read whole file.
|
||||||
!> @details ensures that the string ends with a new line (expected UNIX behavior)
|
!> @details ensures that the string ends with a new line (expected UNIX behavior) and rejects
|
||||||
|
! windows (CRLF) line endings
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
function IO_read(fileName) result(fileContent)
|
function IO_read(fileName) result(fileContent)
|
||||||
|
|
||||||
character(len=*), intent(in) :: fileName
|
character(len=*), intent(in) :: fileName
|
||||||
character(len=:), allocatable :: fileContent
|
character(len=:), allocatable :: fileContent
|
||||||
|
|
||||||
integer :: &
|
integer :: &
|
||||||
fileLength, &
|
fileLength, &
|
||||||
fileUnit, &
|
fileUnit, &
|
||||||
myStat
|
myStat, &
|
||||||
|
firstEOL
|
||||||
|
character, parameter :: CR = achar(13)
|
||||||
|
|
||||||
|
|
||||||
inquire(file = fileName, size=fileLength)
|
inquire(file = fileName, size=fileLength)
|
||||||
open(newunit=fileUnit, file=fileName, access='stream',&
|
open(newunit=fileUnit, file=fileName, access='stream',&
|
||||||
|
@ -137,8 +143,12 @@ function IO_read(fileName) result(fileContent)
|
||||||
if(myStat /= 0) call IO_error(102,ext_msg=trim(fileName))
|
if(myStat /= 0) call IO_error(102,ext_msg=trim(fileName))
|
||||||
close(fileUnit)
|
close(fileUnit)
|
||||||
|
|
||||||
|
|
||||||
if(fileContent(fileLength:fileLength) /= IO_EOL) fileContent = fileContent//IO_EOL ! ensure EOL@EOF
|
if(fileContent(fileLength:fileLength) /= IO_EOL) fileContent = fileContent//IO_EOL ! ensure EOL@EOF
|
||||||
|
|
||||||
|
firstEOL = index(fileContent,IO_EOL)
|
||||||
|
if(scan(fileContent(firstEOL:firstEOL),CR) /= 0) call IO_error(115)
|
||||||
|
|
||||||
end function IO_read
|
end function IO_read
|
||||||
|
|
||||||
|
|
||||||
|
@ -151,6 +161,7 @@ logical pure function IO_isBlank(string)
|
||||||
|
|
||||||
integer :: posNonBlank
|
integer :: posNonBlank
|
||||||
|
|
||||||
|
|
||||||
posNonBlank = verify(string,IO_WHITESPACE)
|
posNonBlank = verify(string,IO_WHITESPACE)
|
||||||
IO_isBlank = posNonBlank == 0 .or. posNonBlank == scan(string,IO_COMMENT)
|
IO_isBlank = posNonBlank == 0 .or. posNonBlank == scan(string,IO_COMMENT)
|
||||||
|
|
||||||
|
@ -170,6 +181,7 @@ pure function IO_stringPos(string)
|
||||||
|
|
||||||
integer :: left, right
|
integer :: left, right
|
||||||
|
|
||||||
|
|
||||||
allocate(IO_stringPos(1), source=0)
|
allocate(IO_stringPos(1), source=0)
|
||||||
right = 0
|
right = 0
|
||||||
|
|
||||||
|
@ -249,6 +261,7 @@ pure function IO_lc(string)
|
||||||
|
|
||||||
integer :: i,n
|
integer :: i,n
|
||||||
|
|
||||||
|
|
||||||
do i=1,len(string)
|
do i=1,len(string)
|
||||||
n = index(UPPER,string(i:i))
|
n = index(UPPER,string(i:i))
|
||||||
if(n/=0) then
|
if(n/=0) then
|
||||||
|
@ -271,6 +284,7 @@ function IO_rmComment(line)
|
||||||
character(len=:), allocatable :: IO_rmComment
|
character(len=:), allocatable :: IO_rmComment
|
||||||
integer :: split
|
integer :: split
|
||||||
|
|
||||||
|
|
||||||
split = index(line,IO_COMMENT)
|
split = index(line,IO_COMMENT)
|
||||||
|
|
||||||
if (split == 0) then
|
if (split == 0) then
|
||||||
|
@ -292,6 +306,7 @@ integer function IO_stringAsInt(string)
|
||||||
integer :: readStatus
|
integer :: readStatus
|
||||||
character(len=*), parameter :: VALIDCHARS = '0123456789+- '
|
character(len=*), parameter :: VALIDCHARS = '0123456789+- '
|
||||||
|
|
||||||
|
|
||||||
valid: if (verify(string,VALIDCHARS) == 0) then
|
valid: if (verify(string,VALIDCHARS) == 0) then
|
||||||
read(string,*,iostat=readStatus) IO_stringAsInt
|
read(string,*,iostat=readStatus) IO_stringAsInt
|
||||||
if (readStatus /= 0) call IO_error(111,ext_msg=string)
|
if (readStatus /= 0) call IO_error(111,ext_msg=string)
|
||||||
|
@ -313,6 +328,7 @@ real(pReal) function IO_stringAsFloat(string)
|
||||||
integer :: readStatus
|
integer :: readStatus
|
||||||
character(len=*), parameter :: VALIDCHARS = '0123456789eE.+- '
|
character(len=*), parameter :: VALIDCHARS = '0123456789eE.+- '
|
||||||
|
|
||||||
|
|
||||||
valid: if (verify(string,VALIDCHARS) == 0) then
|
valid: if (verify(string,VALIDCHARS) == 0) then
|
||||||
read(string,*,iostat=readStatus) IO_stringAsFloat
|
read(string,*,iostat=readStatus) IO_stringAsFloat
|
||||||
if (readStatus /= 0) call IO_error(112,ext_msg=string)
|
if (readStatus /= 0) call IO_error(112,ext_msg=string)
|
||||||
|
@ -331,6 +347,7 @@ logical function IO_stringAsBool(string)
|
||||||
|
|
||||||
character(len=*), intent(in) :: string !< string for conversion to int value
|
character(len=*), intent(in) :: string !< string for conversion to int value
|
||||||
|
|
||||||
|
|
||||||
if (trim(adjustl(string)) == 'True' .or. trim(adjustl(string)) == 'true') then
|
if (trim(adjustl(string)) == 'True' .or. trim(adjustl(string)) == 'true') then
|
||||||
IO_stringAsBool = .true.
|
IO_stringAsBool = .true.
|
||||||
elseif (trim(adjustl(string)) == 'False' .or. trim(adjustl(string)) == 'false') then
|
elseif (trim(adjustl(string)) == 'False' .or. trim(adjustl(string)) == 'false') then
|
||||||
|
@ -356,6 +373,7 @@ subroutine IO_error(error_ID,el,ip,g,instance,ext_msg)
|
||||||
character(len=:), allocatable :: msg
|
character(len=:), allocatable :: msg
|
||||||
character(len=pStringLen) :: formatString
|
character(len=pStringLen) :: formatString
|
||||||
|
|
||||||
|
|
||||||
select case (error_ID)
|
select case (error_ID)
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
@ -382,6 +400,9 @@ subroutine IO_error(error_ID,el,ip,g,instance,ext_msg)
|
||||||
msg = 'invalid character for logical:'
|
msg = 'invalid character for logical:'
|
||||||
case (114)
|
case (114)
|
||||||
msg = 'cannot decode base64 string:'
|
msg = 'cannot decode base64 string:'
|
||||||
|
case (115)
|
||||||
|
msg = 'found CR. Windows file endings (CRLF) are not supported.'
|
||||||
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! lattice error messages
|
! lattice error messages
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
#include "IO.f90"
|
#include "IO.f90"
|
||||||
#include "YAML_types.f90"
|
#include "YAML_types.f90"
|
||||||
#include "YAML_parse.f90"
|
#include "YAML_parse.f90"
|
||||||
#include "future.f90"
|
|
||||||
#include "config.f90"
|
#include "config.f90"
|
||||||
#include "LAPACK_interface.f90"
|
#include "LAPACK_interface.f90"
|
||||||
#include "math.f90"
|
#include "math.f90"
|
||||||
|
@ -17,38 +16,36 @@
|
||||||
#include "results.f90"
|
#include "results.f90"
|
||||||
#include "geometry_plastic_nonlocal.f90"
|
#include "geometry_plastic_nonlocal.f90"
|
||||||
#include "discretization.f90"
|
#include "discretization.f90"
|
||||||
#ifdef Marc4DAMASK
|
|
||||||
#include "marc/discretization_marc.f90"
|
#include "marc/discretization_marc.f90"
|
||||||
#endif
|
|
||||||
#include "material.f90"
|
#include "material.f90"
|
||||||
#include "lattice.f90"
|
#include "lattice.f90"
|
||||||
#include "constitutive.f90"
|
#include "phase.f90"
|
||||||
#include "constitutive_mech.f90"
|
#include "phase_mechanical.f90"
|
||||||
#include "constitutive_plastic_none.f90"
|
#include "phase_mechanical_plastic.f90"
|
||||||
#include "constitutive_plastic_isotropic.f90"
|
#include "phase_mechanical_plastic_none.f90"
|
||||||
#include "constitutive_plastic_phenopowerlaw.f90"
|
#include "phase_mechanical_plastic_isotropic.f90"
|
||||||
#include "constitutive_plastic_kinehardening.f90"
|
#include "phase_mechanical_plastic_phenopowerlaw.f90"
|
||||||
#include "constitutive_plastic_dislotwin.f90"
|
#include "phase_mechanical_plastic_kinehardening.f90"
|
||||||
#include "constitutive_plastic_disloTungsten.f90"
|
#include "phase_mechanical_plastic_dislotwin.f90"
|
||||||
#include "constitutive_plastic_nonlocal.f90"
|
#include "phase_mechanical_plastic_dislotungsten.f90"
|
||||||
#include "constitutive_thermal.f90"
|
#include "phase_mechanical_plastic_nonlocal.f90"
|
||||||
#include "source_thermal_dissipation.f90"
|
#include "phase_mechanical_eigen.f90"
|
||||||
#include "source_thermal_externalheat.f90"
|
#include "phase_mechanical_eigen_cleavageopening.f90"
|
||||||
#include "kinematics_thermal_expansion.f90"
|
#include "phase_mechanical_eigen_slipplaneopening.f90"
|
||||||
#include "constitutive_damage.f90"
|
#include "phase_mechanical_eigen_thermalexpansion.f90"
|
||||||
#include "source_damage_isoBrittle.f90"
|
#include "phase_thermal.f90"
|
||||||
#include "source_damage_isoDuctile.f90"
|
#include "phase_thermal_dissipation.f90"
|
||||||
#include "source_damage_anisoBrittle.f90"
|
#include "phase_thermal_externalheat.f90"
|
||||||
#include "source_damage_anisoDuctile.f90"
|
#include "phase_damage.f90"
|
||||||
#include "kinematics_cleavage_opening.f90"
|
#include "phase_damage_isobrittle.f90"
|
||||||
#include "kinematics_slipplane_opening.f90"
|
#include "phase_damage_isoductile.f90"
|
||||||
#include "thermal_isothermal.f90"
|
#include "phase_damage_anisobrittle.f90"
|
||||||
#include "thermal_conduction.f90"
|
#include "phase_damage_anisoductile.f90"
|
||||||
#include "damage_none.f90"
|
|
||||||
#include "damage_nonlocal.f90"
|
|
||||||
#include "homogenization.f90"
|
#include "homogenization.f90"
|
||||||
#include "homogenization_mech.f90"
|
#include "homogenization_mechanical.f90"
|
||||||
#include "homogenization_mech_none.f90"
|
#include "homogenization_mechanical_pass.f90"
|
||||||
#include "homogenization_mech_isostrain.f90"
|
#include "homogenization_mechanical_isostrain.f90"
|
||||||
#include "homogenization_mech_RGC.f90"
|
#include "homogenization_mechanical_RGC.f90"
|
||||||
|
#include "homogenization_thermal.f90"
|
||||||
|
#include "homogenization_damage.f90"
|
||||||
#include "CPFEM.f90"
|
#include "CPFEM.f90"
|
||||||
|
|
|
@ -5,16 +5,10 @@
|
||||||
!! precedence over material.yaml.
|
!! precedence over material.yaml.
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
module config
|
module config
|
||||||
use prec
|
|
||||||
use DAMASK_interface
|
|
||||||
use IO
|
use IO
|
||||||
use YAML_parse
|
use YAML_parse
|
||||||
use YAML_types
|
use YAML_types
|
||||||
|
|
||||||
#ifdef PETSc
|
|
||||||
#include <petsc/finclude/petscsys.h>
|
|
||||||
use petscsys
|
|
||||||
#endif
|
|
||||||
|
|
||||||
implicit none
|
implicit none
|
||||||
private
|
private
|
||||||
|
@ -50,17 +44,12 @@ end subroutine config_init
|
||||||
subroutine parse_material
|
subroutine parse_material
|
||||||
|
|
||||||
logical :: fileExists
|
logical :: fileExists
|
||||||
character(len=:), allocatable :: fname
|
|
||||||
|
|
||||||
fname = getSolverJobName()//'.yaml'
|
|
||||||
inquire(file=fname,exist=fileExists)
|
inquire(file='material.yaml',exist=fileExists)
|
||||||
if(.not. fileExists) then
|
if(.not. fileExists) call IO_error(100,ext_msg='material.yaml')
|
||||||
fname = 'material.yaml'
|
print*, 'reading material.yaml'; flush(IO_STDOUT)
|
||||||
inquire(file=fname,exist=fileExists)
|
config_material => YAML_parse_file('material.yaml')
|
||||||
if(.not. fileExists) call IO_error(100,ext_msg=fname)
|
|
||||||
endif
|
|
||||||
print*, 'reading '//fname; flush(IO_STDOUT)
|
|
||||||
config_material => YAML_parse_file(fname)
|
|
||||||
|
|
||||||
end subroutine parse_material
|
end subroutine parse_material
|
||||||
|
|
||||||
|
@ -72,6 +61,7 @@ subroutine parse_numerics
|
||||||
|
|
||||||
logical :: fexist
|
logical :: fexist
|
||||||
|
|
||||||
|
|
||||||
config_numerics => emptyDict
|
config_numerics => emptyDict
|
||||||
inquire(file='numerics.yaml', exist=fexist)
|
inquire(file='numerics.yaml', exist=fexist)
|
||||||
if (fexist) then
|
if (fexist) then
|
||||||
|
@ -89,6 +79,7 @@ subroutine parse_debug
|
||||||
|
|
||||||
logical :: fexist
|
logical :: fexist
|
||||||
|
|
||||||
|
|
||||||
config_debug => emptyDict
|
config_debug => emptyDict
|
||||||
inquire(file='debug.yaml', exist=fexist)
|
inquire(file='debug.yaml', exist=fexist)
|
||||||
fileExists: if (fexist) then
|
fileExists: if (fexist) then
|
||||||
|
|
1434
src/constitutive.f90
1434
src/constitutive.f90
File diff suppressed because it is too large
Load Diff
|
@ -1,253 +0,0 @@
|
||||||
!----------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief internal microstructure state for all damage sources and kinematics constitutive models
|
|
||||||
!----------------------------------------------------------------------------------------------------
|
|
||||||
submodule(constitutive) constitutive_damage
|
|
||||||
|
|
||||||
interface
|
|
||||||
|
|
||||||
module function source_damage_anisoBrittle_init(source_length) result(mySources)
|
|
||||||
integer, intent(in) :: source_length
|
|
||||||
logical, dimension(:,:), allocatable :: mySources
|
|
||||||
end function source_damage_anisoBrittle_init
|
|
||||||
|
|
||||||
module function source_damage_anisoDuctile_init(source_length) result(mySources)
|
|
||||||
integer, intent(in) :: source_length
|
|
||||||
logical, dimension(:,:), allocatable :: mySources
|
|
||||||
end function source_damage_anisoDuctile_init
|
|
||||||
|
|
||||||
module function source_damage_isoBrittle_init(source_length) result(mySources)
|
|
||||||
integer, intent(in) :: source_length
|
|
||||||
logical, dimension(:,:), allocatable :: mySources
|
|
||||||
end function source_damage_isoBrittle_init
|
|
||||||
|
|
||||||
module function source_damage_isoDuctile_init(source_length) result(mySources)
|
|
||||||
integer, intent(in) :: source_length
|
|
||||||
logical, dimension(:,:), allocatable :: mySources
|
|
||||||
end function source_damage_isoDuctile_init
|
|
||||||
|
|
||||||
module function kinematics_cleavage_opening_init(kinematics_length) result(myKinematics)
|
|
||||||
integer, intent(in) :: kinematics_length
|
|
||||||
logical, dimension(:,:), allocatable :: myKinematics
|
|
||||||
end function kinematics_cleavage_opening_init
|
|
||||||
|
|
||||||
module function kinematics_slipplane_opening_init(kinematics_length) result(myKinematics)
|
|
||||||
integer, intent(in) :: kinematics_length
|
|
||||||
logical, dimension(:,:), allocatable :: myKinematics
|
|
||||||
end function kinematics_slipplane_opening_init
|
|
||||||
|
|
||||||
|
|
||||||
module subroutine source_damage_anisobrittle_getRateAndItsTangent(localphiDot, dLocalphiDot_dPhi, phi, phase, constituent)
|
|
||||||
integer, intent(in) :: &
|
|
||||||
phase, & !< phase ID of element
|
|
||||||
constituent !< position of element within its phase instance
|
|
||||||
real(pReal), intent(in) :: &
|
|
||||||
phi !< damage parameter
|
|
||||||
real(pReal), intent(out) :: &
|
|
||||||
localphiDot, &
|
|
||||||
dLocalphiDot_dPhi
|
|
||||||
end subroutine source_damage_anisoBrittle_getRateAndItsTangent
|
|
||||||
|
|
||||||
module subroutine source_damage_anisoDuctile_getRateAndItsTangent(localphiDot, dLocalphiDot_dPhi, phi, phase, constituent)
|
|
||||||
integer, intent(in) :: &
|
|
||||||
phase, & !< phase ID of element
|
|
||||||
constituent !< position of element within its phase instance
|
|
||||||
real(pReal), intent(in) :: &
|
|
||||||
phi !< damage parameter
|
|
||||||
real(pReal), intent(out) :: &
|
|
||||||
localphiDot, &
|
|
||||||
dLocalphiDot_dPhi
|
|
||||||
end subroutine source_damage_anisoDuctile_getRateAndItsTangent
|
|
||||||
|
|
||||||
module subroutine source_damage_isoBrittle_getRateAndItsTangent(localphiDot, dLocalphiDot_dPhi, phi, phase, constituent)
|
|
||||||
integer, intent(in) :: &
|
|
||||||
phase, & !< phase ID of element
|
|
||||||
constituent !< position of element within its phase instance
|
|
||||||
real(pReal), intent(in) :: &
|
|
||||||
phi !< damage parameter
|
|
||||||
real(pReal), intent(out) :: &
|
|
||||||
localphiDot, &
|
|
||||||
dLocalphiDot_dPhi
|
|
||||||
end subroutine source_damage_isoBrittle_getRateAndItsTangent
|
|
||||||
|
|
||||||
module subroutine source_damage_isoDuctile_getRateAndItsTangent(localphiDot, dLocalphiDot_dPhi, phi, phase, constituent)
|
|
||||||
integer, intent(in) :: &
|
|
||||||
phase, & !< phase ID of element
|
|
||||||
constituent !< position of element within its phase instance
|
|
||||||
real(pReal), intent(in) :: &
|
|
||||||
phi !< damage parameter
|
|
||||||
real(pReal), intent(out) :: &
|
|
||||||
localphiDot, &
|
|
||||||
dLocalphiDot_dPhi
|
|
||||||
end subroutine source_damage_isoDuctile_getRateAndItsTangent
|
|
||||||
|
|
||||||
module subroutine source_damage_anisoBrittle_results(phase,group)
|
|
||||||
integer, intent(in) :: phase
|
|
||||||
character(len=*), intent(in) :: group
|
|
||||||
end subroutine source_damage_anisoBrittle_results
|
|
||||||
|
|
||||||
module subroutine source_damage_anisoDuctile_results(phase,group)
|
|
||||||
integer, intent(in) :: phase
|
|
||||||
character(len=*), intent(in) :: group
|
|
||||||
end subroutine source_damage_anisoDuctile_results
|
|
||||||
|
|
||||||
module subroutine source_damage_isoBrittle_results(phase,group)
|
|
||||||
integer, intent(in) :: phase
|
|
||||||
character(len=*), intent(in) :: group
|
|
||||||
end subroutine source_damage_isoBrittle_results
|
|
||||||
|
|
||||||
module subroutine source_damage_isoDuctile_results(phase,group)
|
|
||||||
integer, intent(in) :: phase
|
|
||||||
character(len=*), intent(in) :: group
|
|
||||||
end subroutine source_damage_isoDuctile_results
|
|
||||||
|
|
||||||
end interface
|
|
||||||
|
|
||||||
contains
|
|
||||||
|
|
||||||
!----------------------------------------------------------------------------------------------
|
|
||||||
!< @brief initialize damage sources and kinematics mechanism
|
|
||||||
!----------------------------------------------------------------------------------------------
|
|
||||||
module subroutine damage_init
|
|
||||||
|
|
||||||
integer :: &
|
|
||||||
ph !< counter in phase loop
|
|
||||||
class(tNode), pointer :: &
|
|
||||||
phases, &
|
|
||||||
phase, &
|
|
||||||
sources, &
|
|
||||||
kinematics
|
|
||||||
|
|
||||||
phases => config_material%get('phase')
|
|
||||||
|
|
||||||
allocate(sourceState (phases%length))
|
|
||||||
allocate(phase_Nsources(phases%length),source = 0) ! same for kinematics
|
|
||||||
|
|
||||||
do ph = 1,phases%length
|
|
||||||
phase => phases%get(ph)
|
|
||||||
sources => phase%get('source',defaultVal=emptyList)
|
|
||||||
phase_Nsources(ph) = sources%length
|
|
||||||
allocate(sourceState(ph)%p(phase_Nsources(ph)))
|
|
||||||
enddo
|
|
||||||
|
|
||||||
allocate(phase_source(maxval(phase_Nsources),phases%length), source = SOURCE_undefined_ID)
|
|
||||||
|
|
||||||
! initialize source mechanisms
|
|
||||||
if(maxval(phase_Nsources) /= 0) then
|
|
||||||
where(source_damage_isoBrittle_init (maxval(phase_Nsources))) phase_source = SOURCE_damage_isoBrittle_ID
|
|
||||||
where(source_damage_isoDuctile_init (maxval(phase_Nsources))) phase_source = SOURCE_damage_isoDuctile_ID
|
|
||||||
where(source_damage_anisoBrittle_init (maxval(phase_Nsources))) phase_source = SOURCE_damage_anisoBrittle_ID
|
|
||||||
where(source_damage_anisoDuctile_init (maxval(phase_Nsources))) phase_source = SOURCE_damage_anisoDuctile_ID
|
|
||||||
endif
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
! initialize kinematic mechanisms
|
|
||||||
allocate(phase_Nkinematics(phases%length),source = 0)
|
|
||||||
do ph = 1,phases%length
|
|
||||||
phase => phases%get(ph)
|
|
||||||
kinematics => phase%get('kinematics',defaultVal=emptyList)
|
|
||||||
phase_Nkinematics(ph) = kinematics%length
|
|
||||||
enddo
|
|
||||||
|
|
||||||
allocate(phase_kinematics(maxval(phase_Nkinematics),phases%length), source = KINEMATICS_undefined_ID)
|
|
||||||
|
|
||||||
if(maxval(phase_Nkinematics) /= 0) then
|
|
||||||
where(kinematics_cleavage_opening_init(maxval(phase_Nkinematics))) phase_kinematics = KINEMATICS_cleavage_opening_ID
|
|
||||||
where(kinematics_slipplane_opening_init(maxval(phase_Nkinematics))) phase_kinematics = KINEMATICS_slipplane_opening_ID
|
|
||||||
endif
|
|
||||||
|
|
||||||
end subroutine damage_init
|
|
||||||
|
|
||||||
|
|
||||||
!----------------------------------------------------------------------------------------------
|
|
||||||
!< @brief returns local part of nonlocal damage driving force
|
|
||||||
!----------------------------------------------------------------------------------------------
|
|
||||||
module subroutine constitutive_damage_getRateAndItsTangents(phiDot, dPhiDot_dPhi, phi, ip, el)
|
|
||||||
|
|
||||||
integer, intent(in) :: &
|
|
||||||
ip, & !< integration point number
|
|
||||||
el !< element number
|
|
||||||
real(pReal), intent(in) :: &
|
|
||||||
phi !< damage parameter
|
|
||||||
real(pReal), intent(inout) :: &
|
|
||||||
phiDot, &
|
|
||||||
dPhiDot_dPhi
|
|
||||||
|
|
||||||
real(pReal) :: &
|
|
||||||
localphiDot, &
|
|
||||||
dLocalphiDot_dPhi
|
|
||||||
integer :: &
|
|
||||||
phase, &
|
|
||||||
grain, &
|
|
||||||
source, &
|
|
||||||
constituent
|
|
||||||
|
|
||||||
phiDot = 0.0_pReal
|
|
||||||
dPhiDot_dPhi = 0.0_pReal
|
|
||||||
|
|
||||||
do grain = 1, homogenization_Nconstituents(material_homogenizationAt(el))
|
|
||||||
phase = material_phaseAt(grain,el)
|
|
||||||
constituent = material_phasememberAt(grain,ip,el)
|
|
||||||
do source = 1, phase_Nsources(phase)
|
|
||||||
select case(phase_source(source,phase))
|
|
||||||
case (SOURCE_damage_isoBrittle_ID)
|
|
||||||
call source_damage_isobrittle_getRateAndItsTangent (localphiDot, dLocalphiDot_dPhi, phi, phase, constituent)
|
|
||||||
|
|
||||||
case (SOURCE_damage_isoDuctile_ID)
|
|
||||||
call source_damage_isoductile_getRateAndItsTangent (localphiDot, dLocalphiDot_dPhi, phi, phase, constituent)
|
|
||||||
|
|
||||||
case (SOURCE_damage_anisoBrittle_ID)
|
|
||||||
call source_damage_anisobrittle_getRateAndItsTangent(localphiDot, dLocalphiDot_dPhi, phi, phase, constituent)
|
|
||||||
|
|
||||||
case (SOURCE_damage_anisoDuctile_ID)
|
|
||||||
call source_damage_anisoductile_getRateAndItsTangent(localphiDot, dLocalphiDot_dPhi, phi, phase, constituent)
|
|
||||||
|
|
||||||
case default
|
|
||||||
localphiDot = 0.0_pReal
|
|
||||||
dLocalphiDot_dPhi = 0.0_pReal
|
|
||||||
|
|
||||||
end select
|
|
||||||
phiDot = phiDot + localphiDot
|
|
||||||
dPhiDot_dPhi = dPhiDot_dPhi + dLocalphiDot_dPhi
|
|
||||||
enddo
|
|
||||||
enddo
|
|
||||||
|
|
||||||
end subroutine constitutive_damage_getRateAndItsTangents
|
|
||||||
|
|
||||||
|
|
||||||
!----------------------------------------------------------------------------------------------
|
|
||||||
!< @brief writes damage sources results to HDF5 output file
|
|
||||||
!----------------------------------------------------------------------------------------------
|
|
||||||
module subroutine damage_results(group,ph)
|
|
||||||
|
|
||||||
character(len=*), intent(in) :: group
|
|
||||||
integer, intent(in) :: ph
|
|
||||||
|
|
||||||
integer :: so
|
|
||||||
|
|
||||||
sourceLoop: do so = 1, phase_Nsources(ph)
|
|
||||||
|
|
||||||
if (phase_source(so,ph) /= SOURCE_UNDEFINED_ID) &
|
|
||||||
call results_closeGroup(results_addGroup(group//'sources/')) ! should be 'damage'
|
|
||||||
|
|
||||||
sourceType: select case (phase_source(so,ph))
|
|
||||||
|
|
||||||
case (SOURCE_damage_anisoBrittle_ID) sourceType
|
|
||||||
call source_damage_anisoBrittle_results(ph,group//'sources/')
|
|
||||||
|
|
||||||
case (SOURCE_damage_anisoDuctile_ID) sourceType
|
|
||||||
call source_damage_anisoDuctile_results(ph,group//'sources/')
|
|
||||||
|
|
||||||
case (SOURCE_damage_isoBrittle_ID) sourceType
|
|
||||||
call source_damage_isoBrittle_results(ph,group//'sources/')
|
|
||||||
|
|
||||||
case (SOURCE_damage_isoDuctile_ID) sourceType
|
|
||||||
call source_damage_isoDuctile_results(ph,group//'sources/')
|
|
||||||
|
|
||||||
end select sourceType
|
|
||||||
|
|
||||||
enddo SourceLoop
|
|
||||||
|
|
||||||
end subroutine damage_results
|
|
||||||
|
|
||||||
|
|
||||||
end submodule constitutive_damage
|
|
|
@ -1,125 +0,0 @@
|
||||||
!----------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief internal microstructure state for all thermal sources and kinematics constitutive models
|
|
||||||
!----------------------------------------------------------------------------------------------------
|
|
||||||
submodule(constitutive) constitutive_thermal
|
|
||||||
|
|
||||||
interface
|
|
||||||
|
|
||||||
module function source_thermal_dissipation_init(source_length) result(mySources)
|
|
||||||
integer, intent(in) :: source_length
|
|
||||||
logical, dimension(:,:), allocatable :: mySources
|
|
||||||
end function source_thermal_dissipation_init
|
|
||||||
|
|
||||||
module function source_thermal_externalheat_init(source_length) result(mySources)
|
|
||||||
integer, intent(in) :: source_length
|
|
||||||
logical, dimension(:,:), allocatable :: mySources
|
|
||||||
end function source_thermal_externalheat_init
|
|
||||||
|
|
||||||
module function kinematics_thermal_expansion_init(kinematics_length) result(myKinematics)
|
|
||||||
integer, intent(in) :: kinematics_length
|
|
||||||
logical, dimension(:,:), allocatable :: myKinematics
|
|
||||||
end function kinematics_thermal_expansion_init
|
|
||||||
|
|
||||||
|
|
||||||
module subroutine source_thermal_dissipation_getRateAndItsTangent(TDot, dTDot_dT, Tstar, Lp, phase)
|
|
||||||
integer, intent(in) :: &
|
|
||||||
phase !< phase ID of element
|
|
||||||
real(pReal), intent(in), dimension(3,3) :: &
|
|
||||||
Tstar !< 2nd Piola Kirchhoff stress tensor for a given element
|
|
||||||
real(pReal), intent(in), dimension(3,3) :: &
|
|
||||||
Lp !< plastic velocuty gradient for a given element
|
|
||||||
real(pReal), intent(out) :: &
|
|
||||||
TDot, &
|
|
||||||
dTDot_dT
|
|
||||||
end subroutine source_thermal_dissipation_getRateAndItsTangent
|
|
||||||
|
|
||||||
module subroutine source_thermal_externalheat_getRateAndItsTangent(TDot, dTDot_dT, phase, of)
|
|
||||||
integer, intent(in) :: &
|
|
||||||
phase, &
|
|
||||||
of
|
|
||||||
real(pReal), intent(out) :: &
|
|
||||||
TDot, &
|
|
||||||
dTDot_dT
|
|
||||||
end subroutine source_thermal_externalheat_getRateAndItsTangent
|
|
||||||
|
|
||||||
end interface
|
|
||||||
|
|
||||||
contains
|
|
||||||
|
|
||||||
!----------------------------------------------------------------------------------------------
|
|
||||||
!< @brief initializes thermal sources and kinematics mechanism
|
|
||||||
!----------------------------------------------------------------------------------------------
|
|
||||||
module subroutine thermal_init
|
|
||||||
|
|
||||||
! initialize source mechanisms
|
|
||||||
if(maxval(phase_Nsources) /= 0) then
|
|
||||||
where(source_thermal_dissipation_init (maxval(phase_Nsources))) phase_source = SOURCE_thermal_dissipation_ID
|
|
||||||
where(source_thermal_externalheat_init(maxval(phase_Nsources))) phase_source = SOURCE_thermal_externalheat_ID
|
|
||||||
endif
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!initialize kinematic mechanisms
|
|
||||||
if(maxval(phase_Nkinematics) /= 0) where(kinematics_thermal_expansion_init(maxval(phase_Nkinematics))) &
|
|
||||||
phase_kinematics = KINEMATICS_thermal_expansion_ID
|
|
||||||
|
|
||||||
end subroutine thermal_init
|
|
||||||
|
|
||||||
|
|
||||||
!----------------------------------------------------------------------------------------------
|
|
||||||
!< @brief calculates thermal dissipation rate
|
|
||||||
!----------------------------------------------------------------------------------------------
|
|
||||||
module subroutine constitutive_thermal_getRateAndItsTangents(TDot, dTDot_dT, T, S, Lp, ip, el)
|
|
||||||
integer, intent(in) :: &
|
|
||||||
ip, & !< integration point number
|
|
||||||
el !< element number
|
|
||||||
real(pReal), intent(in) :: &
|
|
||||||
T
|
|
||||||
real(pReal), intent(in), dimension(:,:,:,:,:) :: &
|
|
||||||
S, & !< current 2nd Piola Kirchhoff stress
|
|
||||||
Lp !< plastic velocity gradient
|
|
||||||
real(pReal), intent(inout) :: &
|
|
||||||
TDot, &
|
|
||||||
dTDot_dT
|
|
||||||
|
|
||||||
real(pReal) :: &
|
|
||||||
my_Tdot, &
|
|
||||||
my_dTdot_dT
|
|
||||||
integer :: &
|
|
||||||
phase, &
|
|
||||||
homog, &
|
|
||||||
instance, &
|
|
||||||
grain, &
|
|
||||||
source, &
|
|
||||||
constituent
|
|
||||||
|
|
||||||
homog = material_homogenizationAt(el)
|
|
||||||
instance = thermal_typeInstance(homog)
|
|
||||||
|
|
||||||
do grain = 1, homogenization_Nconstituents(homog)
|
|
||||||
phase = material_phaseAt(grain,el)
|
|
||||||
constituent = material_phasememberAt(grain,ip,el)
|
|
||||||
do source = 1, phase_Nsources(phase)
|
|
||||||
select case(phase_source(source,phase))
|
|
||||||
case (SOURCE_thermal_dissipation_ID)
|
|
||||||
call source_thermal_dissipation_getRateAndItsTangent(my_Tdot, my_dTdot_dT, &
|
|
||||||
S(1:3,1:3,grain,ip,el), &
|
|
||||||
Lp(1:3,1:3,grain,ip,el), &
|
|
||||||
phase)
|
|
||||||
|
|
||||||
case (SOURCE_thermal_externalheat_ID)
|
|
||||||
call source_thermal_externalheat_getRateAndItsTangent(my_Tdot, my_dTdot_dT, &
|
|
||||||
phase, constituent)
|
|
||||||
|
|
||||||
case default
|
|
||||||
my_Tdot = 0.0_pReal
|
|
||||||
my_dTdot_dT = 0.0_pReal
|
|
||||||
end select
|
|
||||||
Tdot = Tdot + my_Tdot
|
|
||||||
dTdot_dT = dTdot_dT + my_dTdot_dT
|
|
||||||
enddo
|
|
||||||
enddo
|
|
||||||
|
|
||||||
end subroutine constitutive_thermal_getRateAndItsTangents
|
|
||||||
|
|
||||||
|
|
||||||
end submodule constitutive_thermal
|
|
|
@ -1,39 +0,0 @@
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @author Pratheek Shanthraj, Max-Planck-Institut für Eisenforschung GmbH
|
|
||||||
!> @brief material subroutine for constant damage field
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
module damage_none
|
|
||||||
use prec
|
|
||||||
use config
|
|
||||||
use material
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
public
|
|
||||||
|
|
||||||
contains
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief allocates all neccessary fields, reads information from material configuration file
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
subroutine damage_none_init
|
|
||||||
|
|
||||||
integer :: h,Nmaterialpoints
|
|
||||||
|
|
||||||
print'(/,a)', ' <<<+- damage_none init -+>>>'; flush(6)
|
|
||||||
|
|
||||||
do h = 1, size(material_name_homogenization)
|
|
||||||
if (damage_type(h) /= DAMAGE_NONE_ID) cycle
|
|
||||||
|
|
||||||
Nmaterialpoints = count(material_homogenizationAt == h)
|
|
||||||
damageState(h)%sizeState = 0
|
|
||||||
allocate(damageState(h)%state0 (0,Nmaterialpoints))
|
|
||||||
allocate(damageState(h)%subState0(0,Nmaterialpoints))
|
|
||||||
allocate(damageState(h)%state (0,Nmaterialpoints))
|
|
||||||
|
|
||||||
allocate (damage(h)%p(Nmaterialpoints), source=1.0_pReal)
|
|
||||||
|
|
||||||
enddo
|
|
||||||
|
|
||||||
end subroutine damage_none_init
|
|
||||||
|
|
||||||
end module damage_none
|
|
|
@ -1,208 +0,0 @@
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @author Pratheek Shanthraj, Max-Planck-Institut für Eisenforschung GmbH
|
|
||||||
!> @brief material subroutine for non-locally evolving damage field
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
module damage_nonlocal
|
|
||||||
use prec
|
|
||||||
use material
|
|
||||||
use config
|
|
||||||
use YAML_types
|
|
||||||
use lattice
|
|
||||||
use constitutive
|
|
||||||
use results
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
private
|
|
||||||
|
|
||||||
type :: tParameters
|
|
||||||
character(len=pStringLen), allocatable, dimension(:) :: &
|
|
||||||
output
|
|
||||||
end type tParameters
|
|
||||||
|
|
||||||
type, private :: tNumerics
|
|
||||||
real(pReal) :: &
|
|
||||||
charLength !< characteristic length scale for gradient problems
|
|
||||||
end type tNumerics
|
|
||||||
|
|
||||||
type(tparameters), dimension(:), allocatable :: &
|
|
||||||
param
|
|
||||||
type(tNumerics), private :: &
|
|
||||||
num
|
|
||||||
|
|
||||||
public :: &
|
|
||||||
damage_nonlocal_init, &
|
|
||||||
damage_nonlocal_getSourceAndItsTangent, &
|
|
||||||
damage_nonlocal_getDiffusion, &
|
|
||||||
damage_nonlocal_getMobility, &
|
|
||||||
damage_nonlocal_putNonLocalDamage, &
|
|
||||||
damage_nonlocal_results
|
|
||||||
|
|
||||||
contains
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief module initialization
|
|
||||||
!> @details reads in material parameters, allocates arrays, and does sanity checks
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
subroutine damage_nonlocal_init
|
|
||||||
|
|
||||||
integer :: Ninstances,Nmaterialpoints,h
|
|
||||||
class(tNode), pointer :: &
|
|
||||||
num_generic, &
|
|
||||||
material_homogenization, &
|
|
||||||
homog, &
|
|
||||||
homogDamage
|
|
||||||
|
|
||||||
print'(/,a)', ' <<<+- damage_nonlocal init -+>>>'; flush(6)
|
|
||||||
|
|
||||||
!------------------------------------------------------------------------------------
|
|
||||||
! read numerics parameter
|
|
||||||
num_generic => config_numerics%get('generic',defaultVal= emptyDict)
|
|
||||||
num%charLength = num_generic%get_asFloat('charLength',defaultVal=1.0_pReal)
|
|
||||||
|
|
||||||
Ninstances = count(damage_type == DAMAGE_nonlocal_ID)
|
|
||||||
allocate(param(Ninstances))
|
|
||||||
|
|
||||||
material_homogenization => config_material%get('homogenization')
|
|
||||||
do h = 1, material_homogenization%length
|
|
||||||
if (damage_type(h) /= DAMAGE_NONLOCAL_ID) cycle
|
|
||||||
homog => material_homogenization%get(h)
|
|
||||||
homogDamage => homog%get('damage')
|
|
||||||
associate(prm => param(damage_typeInstance(h)))
|
|
||||||
|
|
||||||
#if defined (__GFORTRAN__)
|
|
||||||
prm%output = output_asStrings(homogDamage)
|
|
||||||
#else
|
|
||||||
prm%output = homogDamage%get_asStrings('output',defaultVal=emptyStringArray)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Nmaterialpoints = count(material_homogenizationAt == h)
|
|
||||||
damageState(h)%sizeState = 1
|
|
||||||
allocate(damageState(h)%state0 (1,Nmaterialpoints), source=1.0_pReal)
|
|
||||||
allocate(damageState(h)%subState0(1,Nmaterialpoints), source=1.0_pReal)
|
|
||||||
allocate(damageState(h)%state (1,Nmaterialpoints), source=1.0_pReal)
|
|
||||||
|
|
||||||
damage(h)%p => damageState(h)%state(1,:)
|
|
||||||
|
|
||||||
end associate
|
|
||||||
enddo
|
|
||||||
|
|
||||||
end subroutine damage_nonlocal_init
|
|
||||||
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief calculates homogenized damage driving forces
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
subroutine damage_nonlocal_getSourceAndItsTangent(phiDot, dPhiDot_dPhi, phi, ip, el)
|
|
||||||
|
|
||||||
integer, intent(in) :: &
|
|
||||||
ip, & !< integration point number
|
|
||||||
el !< element number
|
|
||||||
real(pReal), intent(in) :: &
|
|
||||||
phi
|
|
||||||
real(pReal) :: &
|
|
||||||
phiDot, dPhiDot_dPhi
|
|
||||||
|
|
||||||
phiDot = 0.0_pReal
|
|
||||||
dPhiDot_dPhi = 0.0_pReal
|
|
||||||
|
|
||||||
call constitutive_damage_getRateAndItsTangents(phiDot, dPhiDot_dPhi, phi, ip, el)
|
|
||||||
phiDot = phiDot/real(homogenization_Nconstituents(material_homogenizationAt(el)),pReal)
|
|
||||||
dPhiDot_dPhi = dPhiDot_dPhi/real(homogenization_Nconstituents(material_homogenizationAt(el)),pReal)
|
|
||||||
|
|
||||||
end subroutine damage_nonlocal_getSourceAndItsTangent
|
|
||||||
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief returns homogenized non local damage diffusion tensor in reference configuration
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
function damage_nonlocal_getDiffusion(ip,el)
|
|
||||||
|
|
||||||
integer, intent(in) :: &
|
|
||||||
ip, & !< integration point number
|
|
||||||
el !< element number
|
|
||||||
real(pReal), dimension(3,3) :: &
|
|
||||||
damage_nonlocal_getDiffusion
|
|
||||||
integer :: &
|
|
||||||
homog, &
|
|
||||||
grain
|
|
||||||
|
|
||||||
homog = material_homogenizationAt(el)
|
|
||||||
damage_nonlocal_getDiffusion = 0.0_pReal
|
|
||||||
do grain = 1, homogenization_Nconstituents(homog)
|
|
||||||
damage_nonlocal_getDiffusion = damage_nonlocal_getDiffusion + &
|
|
||||||
crystallite_push33ToRef(grain,ip,el,lattice_D(1:3,1:3,material_phaseAt(grain,el)))
|
|
||||||
enddo
|
|
||||||
|
|
||||||
damage_nonlocal_getDiffusion = &
|
|
||||||
num%charLength**2*damage_nonlocal_getDiffusion/real(homogenization_Nconstituents(homog),pReal)
|
|
||||||
|
|
||||||
end function damage_nonlocal_getDiffusion
|
|
||||||
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief Returns homogenized nonlocal damage mobility
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
real(pReal) function damage_nonlocal_getMobility(ip,el)
|
|
||||||
|
|
||||||
integer, intent(in) :: &
|
|
||||||
ip, & !< integration point number
|
|
||||||
el !< element number
|
|
||||||
integer :: &
|
|
||||||
co
|
|
||||||
|
|
||||||
damage_nonlocal_getMobility = 0.0_pReal
|
|
||||||
|
|
||||||
do co = 1, homogenization_Nconstituents(material_homogenizationAt(el))
|
|
||||||
damage_nonlocal_getMobility = damage_nonlocal_getMobility + lattice_M(material_phaseAt(co,el))
|
|
||||||
enddo
|
|
||||||
|
|
||||||
damage_nonlocal_getMobility = damage_nonlocal_getMobility/&
|
|
||||||
real(homogenization_Nconstituents(material_homogenizationAt(el)),pReal)
|
|
||||||
|
|
||||||
end function damage_nonlocal_getMobility
|
|
||||||
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief updated nonlocal damage field with solution from damage phase field PDE
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
subroutine damage_nonlocal_putNonLocalDamage(phi,ip,el)
|
|
||||||
|
|
||||||
integer, intent(in) :: &
|
|
||||||
ip, & !< integration point number
|
|
||||||
el !< element number
|
|
||||||
real(pReal), intent(in) :: &
|
|
||||||
phi
|
|
||||||
integer :: &
|
|
||||||
homog, &
|
|
||||||
offset
|
|
||||||
|
|
||||||
homog = material_homogenizationAt(el)
|
|
||||||
offset = material_homogenizationMemberAt(ip,el)
|
|
||||||
damage(homog)%p(offset) = phi
|
|
||||||
|
|
||||||
end subroutine damage_nonlocal_putNonLocalDamage
|
|
||||||
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief writes results to HDF5 output file
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
subroutine damage_nonlocal_results(homog,group)
|
|
||||||
|
|
||||||
integer, intent(in) :: homog
|
|
||||||
character(len=*), intent(in) :: group
|
|
||||||
|
|
||||||
integer :: o
|
|
||||||
|
|
||||||
associate(prm => param(damage_typeInstance(homog)))
|
|
||||||
outputsLoop: do o = 1,size(prm%output)
|
|
||||||
select case(prm%output(o))
|
|
||||||
case ('phi')
|
|
||||||
call results_writeDataset(group,damage(homog)%p,prm%output(o),&
|
|
||||||
'damage indicator','-')
|
|
||||||
end select
|
|
||||||
enddo outputsLoop
|
|
||||||
end associate
|
|
||||||
|
|
||||||
end subroutine damage_nonlocal_results
|
|
||||||
|
|
||||||
end module damage_nonlocal
|
|
|
@ -686,7 +686,7 @@ module element
|
||||||
1, 5,11, 7, 8,12,15,14, &
|
1, 5,11, 7, 8,12,15,14, &
|
||||||
5, 2, 6,11,12, 9,13,15, &
|
5, 2, 6,11,12, 9,13,15, &
|
||||||
7,11, 6, 3,14,15,13,10, &
|
7,11, 6, 3,14,15,13,10, &
|
||||||
8,12,15, 4, 4, 9,13,10 &
|
8,12,15,14, 4, 9,13,10 &
|
||||||
#if !defined(__GFORTRAN__)
|
#if !defined(__GFORTRAN__)
|
||||||
],shape(CELL6))
|
],shape(CELL6))
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -1,35 +0,0 @@
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @author Martin Diehl, Max-Planck-Institut für Eisenforschung GmbH
|
|
||||||
!> @brief New fortran functions for compiler versions that do not support them
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
module future
|
|
||||||
use prec
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
public
|
|
||||||
|
|
||||||
contains
|
|
||||||
|
|
||||||
#if defined(__GFORTRAN__) && __GNUC__<9 || defined(__INTEL_COMPILER) && INTEL_COMPILER<1800
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief substitute for the findloc intrinsic (only for integer, dimension(:) at the moment)
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
function findloc(a,v)
|
|
||||||
|
|
||||||
integer, intent(in), dimension(:) :: a
|
|
||||||
integer, intent(in) :: v
|
|
||||||
integer :: i,j
|
|
||||||
integer, allocatable, dimension(:) :: findloc
|
|
||||||
|
|
||||||
allocate(findloc(count(a==v)))
|
|
||||||
j = 1
|
|
||||||
do i = 1, size(a)
|
|
||||||
if (a(i)==v) then
|
|
||||||
findloc(j) = i
|
|
||||||
j = j + 1
|
|
||||||
endif
|
|
||||||
enddo
|
|
||||||
end function findloc
|
|
||||||
#endif
|
|
||||||
|
|
||||||
end module future
|
|
|
@ -18,9 +18,9 @@ program DAMASK_grid
|
||||||
use CPFEM2
|
use CPFEM2
|
||||||
use material
|
use material
|
||||||
use spectral_utilities
|
use spectral_utilities
|
||||||
use grid_mech_spectral_basic
|
use grid_mechanical_spectral_basic
|
||||||
use grid_mech_spectral_polarisation
|
use grid_mechanical_spectral_polarisation
|
||||||
use grid_mech_FEM
|
use grid_mechanical_FEM
|
||||||
use grid_damage_spectral
|
use grid_damage_spectral
|
||||||
use grid_thermal_spectral
|
use grid_thermal_spectral
|
||||||
use results
|
use results
|
||||||
|
@ -36,10 +36,11 @@ program DAMASK_grid
|
||||||
integer :: N, & !< number of increments
|
integer :: N, & !< number of increments
|
||||||
f_out, & !< frequency of result writes
|
f_out, & !< frequency of result writes
|
||||||
f_restart !< frequency of restart writes
|
f_restart !< frequency of restart writes
|
||||||
logical :: drop_guessing !< do not follow trajectory of former loadcase
|
logical :: estimate_rate !< follow trajectory of former loadcase
|
||||||
integer(kind(FIELD_UNDEFINED_ID)), allocatable :: ID(:)
|
|
||||||
end type tLoadCase
|
end type tLoadCase
|
||||||
|
|
||||||
|
integer(kind(FIELD_UNDEFINED_ID)), allocatable :: ID(:)
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! variables related to information from load case and geom file
|
! variables related to information from load case and geom file
|
||||||
real(pReal), dimension(9) :: temp_valueVector !< temporarily from loadcase file when reading in tensors (initialize to 0.0)
|
real(pReal), dimension(9) :: temp_valueVector !< temporarily from loadcase file when reading in tensors (initialize to 0.0)
|
||||||
|
@ -53,6 +54,7 @@ program DAMASK_grid
|
||||||
integer, parameter :: &
|
integer, parameter :: &
|
||||||
subStepFactor = 2 !< for each substep, divide the last time increment by 2.0
|
subStepFactor = 2 !< for each substep, divide the last time increment by 2.0
|
||||||
real(pReal) :: &
|
real(pReal) :: &
|
||||||
|
T_0 = 300.0_pReal, &
|
||||||
time = 0.0_pReal, & !< elapsed time
|
time = 0.0_pReal, & !< elapsed time
|
||||||
time0 = 0.0_pReal, & !< begin of interval
|
time0 = 0.0_pReal, & !< begin of interval
|
||||||
timeinc = 1.0_pReal, & !< current time interval
|
timeinc = 1.0_pReal, & !< current time interval
|
||||||
|
@ -61,10 +63,12 @@ program DAMASK_grid
|
||||||
logical :: &
|
logical :: &
|
||||||
guess, & !< guess along former trajectory
|
guess, & !< guess along former trajectory
|
||||||
stagIterate, &
|
stagIterate, &
|
||||||
cutBack = .false.
|
cutBack = .false.,&
|
||||||
|
signal
|
||||||
integer :: &
|
integer :: &
|
||||||
i, j, m, field, &
|
i, j, m, field, &
|
||||||
errorID = 0, &
|
errorID = 0, &
|
||||||
|
ierr,&
|
||||||
cutBackLevel = 0, & !< cut back level \f$ t = \frac{t_{inc}}{2^l} \f$
|
cutBackLevel = 0, & !< cut back level \f$ t = \frac{t_{inc}}{2^l} \f$
|
||||||
stepFraction = 0, & !< fraction of current time interval
|
stepFraction = 0, & !< fraction of current time interval
|
||||||
l = 0, & !< current load case
|
l = 0, & !< current load case
|
||||||
|
@ -76,30 +80,33 @@ program DAMASK_grid
|
||||||
maxCutBack, & !< max number of cut backs
|
maxCutBack, & !< max number of cut backs
|
||||||
stagItMax !< max number of field level staggered iterations
|
stagItMax !< max number of field level staggered iterations
|
||||||
character(len=pStringLen) :: &
|
character(len=pStringLen) :: &
|
||||||
incInfo, &
|
incInfo
|
||||||
loadcase_string
|
|
||||||
|
|
||||||
type(tLoadCase), allocatable, dimension(:) :: loadCases !< array of all load cases
|
type(tLoadCase), allocatable, dimension(:) :: loadCases !< array of all load cases
|
||||||
type(tSolutionState), allocatable, dimension(:) :: solres
|
type(tSolutionState), allocatable, dimension(:) :: solres
|
||||||
procedure(grid_mech_spectral_basic_init), pointer :: &
|
procedure(grid_mechanical_spectral_basic_init), pointer :: &
|
||||||
mech_init
|
mechanical_init
|
||||||
procedure(grid_mech_spectral_basic_forward), pointer :: &
|
procedure(grid_mechanical_spectral_basic_forward), pointer :: &
|
||||||
mech_forward
|
mechanical_forward
|
||||||
procedure(grid_mech_spectral_basic_solution), pointer :: &
|
procedure(grid_mechanical_spectral_basic_solution), pointer :: &
|
||||||
mech_solution
|
mechanical_solution
|
||||||
procedure(grid_mech_spectral_basic_updateCoords), pointer :: &
|
procedure(grid_mechanical_spectral_basic_updateCoords), pointer :: &
|
||||||
mech_updateCoords
|
mechanical_updateCoords
|
||||||
procedure(grid_mech_spectral_basic_restartWrite), pointer :: &
|
procedure(grid_mechanical_spectral_basic_restartWrite), pointer :: &
|
||||||
mech_restartWrite
|
mechanical_restartWrite
|
||||||
|
|
||||||
external :: &
|
external :: &
|
||||||
quit
|
quit
|
||||||
class (tNode), pointer :: &
|
class (tNode), pointer :: &
|
||||||
num_grid, &
|
num_grid, &
|
||||||
debug_grid, & ! pointer to grid debug options
|
|
||||||
config_load, &
|
config_load, &
|
||||||
load_steps, &
|
load_steps, &
|
||||||
load_step, &
|
load_step, &
|
||||||
|
solver, &
|
||||||
|
initial_conditions, &
|
||||||
|
ic_thermal, &
|
||||||
|
thermal, &
|
||||||
|
step_bc, &
|
||||||
step_mech, &
|
step_mech, &
|
||||||
step_discretization, &
|
step_discretization, &
|
||||||
step_deformation, &
|
step_deformation, &
|
||||||
|
@ -109,17 +116,11 @@ program DAMASK_grid
|
||||||
! init DAMASK (all modules)
|
! init DAMASK (all modules)
|
||||||
|
|
||||||
call CPFEM_initAll
|
call CPFEM_initAll
|
||||||
print'(/,a)', ' <<<+- DAMASK_spectral init -+>>>'; flush(IO_STDOUT)
|
print'(/,a)', ' <<<+- DAMASK_grid init -+>>>'; flush(IO_STDOUT)
|
||||||
|
|
||||||
print*, 'Shanthraj et al., Handbook of Mechanics of Materials, 2019'
|
print*, 'Shanthraj et al., Handbook of Mechanics of Materials, 2019'
|
||||||
print*, 'https://doi.org/10.1007/978-981-10-6855-3_80'
|
print*, 'https://doi.org/10.1007/978-981-10-6855-3_80'
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
! initialize field solver information
|
|
||||||
nActiveFields = 1
|
|
||||||
if (any(thermal_type == THERMAL_conduction_ID )) nActiveFields = nActiveFields + 1
|
|
||||||
if (any(damage_type == DAMAGE_nonlocal_ID )) nActiveFields = nActiveFields + 1
|
|
||||||
allocate(solres(nActiveFields))
|
|
||||||
|
|
||||||
!-------------------------------------------------------------------------------------------------
|
!-------------------------------------------------------------------------------------------------
|
||||||
! reading field paramters from numerics file and do sanity checks
|
! reading field paramters from numerics file and do sanity checks
|
||||||
|
@ -130,62 +131,69 @@ program DAMASK_grid
|
||||||
if (stagItMax < 0) call IO_error(301,ext_msg='maxStaggeredIter')
|
if (stagItMax < 0) call IO_error(301,ext_msg='maxStaggeredIter')
|
||||||
if (maxCutBack < 0) call IO_error(301,ext_msg='maxCutBack')
|
if (maxCutBack < 0) call IO_error(301,ext_msg='maxCutBack')
|
||||||
|
|
||||||
|
config_load => YAML_parse_file(trim(interface_loadFile))
|
||||||
|
solver => config_load%get('solver')
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! assign mechanics solver depending on selected type
|
! assign mechanics solver depending on selected type
|
||||||
|
|
||||||
debug_grid => config_debug%get('grid',defaultVal=emptyList)
|
nActiveFields = 1
|
||||||
select case (trim(num_grid%get_asString('solver', defaultVal = 'Basic')))
|
select case (solver%get_asString('mechanical'))
|
||||||
case ('Basic')
|
case ('spectral_basic')
|
||||||
mech_init => grid_mech_spectral_basic_init
|
mechanical_init => grid_mechanical_spectral_basic_init
|
||||||
mech_forward => grid_mech_spectral_basic_forward
|
mechanical_forward => grid_mechanical_spectral_basic_forward
|
||||||
mech_solution => grid_mech_spectral_basic_solution
|
mechanical_solution => grid_mechanical_spectral_basic_solution
|
||||||
mech_updateCoords => grid_mech_spectral_basic_updateCoords
|
mechanical_updateCoords => grid_mechanical_spectral_basic_updateCoords
|
||||||
mech_restartWrite => grid_mech_spectral_basic_restartWrite
|
mechanical_restartWrite => grid_mechanical_spectral_basic_restartWrite
|
||||||
|
|
||||||
case ('Polarisation')
|
case ('spectral_polarization')
|
||||||
mech_init => grid_mech_spectral_polarisation_init
|
mechanical_init => grid_mechanical_spectral_polarisation_init
|
||||||
mech_forward => grid_mech_spectral_polarisation_forward
|
mechanical_forward => grid_mechanical_spectral_polarisation_forward
|
||||||
mech_solution => grid_mech_spectral_polarisation_solution
|
mechanical_solution => grid_mechanical_spectral_polarisation_solution
|
||||||
mech_updateCoords => grid_mech_spectral_polarisation_updateCoords
|
mechanical_updateCoords => grid_mechanical_spectral_polarisation_updateCoords
|
||||||
mech_restartWrite => grid_mech_spectral_polarisation_restartWrite
|
mechanical_restartWrite => grid_mechanical_spectral_polarisation_restartWrite
|
||||||
|
|
||||||
case ('FEM')
|
case ('FEM')
|
||||||
mech_init => grid_mech_FEM_init
|
mechanical_init => grid_mechanical_FEM_init
|
||||||
mech_forward => grid_mech_FEM_forward
|
mechanical_forward => grid_mechanical_FEM_forward
|
||||||
mech_solution => grid_mech_FEM_solution
|
mechanical_solution => grid_mechanical_FEM_solution
|
||||||
mech_updateCoords => grid_mech_FEM_updateCoords
|
mechanical_updateCoords => grid_mechanical_FEM_updateCoords
|
||||||
mech_restartWrite => grid_mech_FEM_restartWrite
|
mechanical_restartWrite => grid_mechanical_FEM_restartWrite
|
||||||
|
|
||||||
case default
|
case default
|
||||||
call IO_error(error_ID = 891, ext_msg = trim(num_grid%get_asString('solver')))
|
call IO_error(error_ID = 891, ext_msg = trim(solver%get_asString('mechanical')))
|
||||||
|
|
||||||
end select
|
end select
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
! initialize field solver information
|
||||||
|
if (solver%get_asString('thermal',defaultVal = 'n/a') == 'spectral') nActiveFields = nActiveFields + 1
|
||||||
|
if (solver%get_asString('damage', defaultVal = 'n/a') == 'spectral') nActiveFields = nActiveFields + 1
|
||||||
|
|
||||||
|
allocate(solres(nActiveFields))
|
||||||
|
allocate( ID(nActiveFields))
|
||||||
|
|
||||||
|
field = 1
|
||||||
|
ID(field) = FIELD_MECH_ID ! mechanical active by default
|
||||||
|
thermalActive: if (solver%get_asString('thermal',defaultVal = 'n/a') == 'spectral') then
|
||||||
|
field = field + 1
|
||||||
|
ID(field) = FIELD_THERMAL_ID
|
||||||
|
endif thermalActive
|
||||||
|
damageActive: if (solver%get_asString('damage',defaultVal = 'n/a') == 'spectral') then
|
||||||
|
field = field + 1
|
||||||
|
ID(field) = FIELD_DAMAGE_ID
|
||||||
|
endif damageActive
|
||||||
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! reading information from load case file and to sanity checks
|
load_steps => config_load%get('loadstep')
|
||||||
config_load => YAML_parse_file(trim(interface_loadFile))
|
|
||||||
|
|
||||||
load_steps => config_load%get('step')
|
|
||||||
allocate(loadCases(load_steps%length)) ! array of load cases
|
allocate(loadCases(load_steps%length)) ! array of load cases
|
||||||
|
|
||||||
do l = 1, load_steps%length
|
do l = 1, load_steps%length
|
||||||
|
|
||||||
allocate(loadCases(l)%ID(nActiveFields))
|
|
||||||
field = 1
|
|
||||||
loadCases(l)%ID(field) = FIELD_MECH_ID ! mechanical active by default
|
|
||||||
thermalActive: if (any(thermal_type == THERMAL_conduction_ID)) then
|
|
||||||
field = field + 1
|
|
||||||
loadCases(l)%ID(field) = FIELD_THERMAL_ID
|
|
||||||
endif thermalActive
|
|
||||||
damageActive: if (any(damage_type == DAMAGE_nonlocal_ID)) then
|
|
||||||
field = field + 1
|
|
||||||
loadCases(l)%ID(field) = FIELD_DAMAGE_ID
|
|
||||||
endif damageActive
|
|
||||||
|
|
||||||
load_step => load_steps%get(l)
|
load_step => load_steps%get(l)
|
||||||
|
step_bc => load_step%get('boundary_conditions')
|
||||||
step_mech => load_step%get('mechanics')
|
step_mech => step_bc%get('mechanical')
|
||||||
loadCases(l)%stress%myType=''
|
loadCases(l)%stress%myType=''
|
||||||
readMech: do m = 1, step_mech%length
|
readMech: do m = 1, step_mech%length
|
||||||
select case (step_mech%getKey(m))
|
select case (step_mech%getKey(m))
|
||||||
|
@ -222,16 +230,14 @@ program DAMASK_grid
|
||||||
loadCases(l)%t = step_discretization%get_asFloat('t')
|
loadCases(l)%t = step_discretization%get_asFloat('t')
|
||||||
loadCases(l)%N = step_discretization%get_asInt ('N')
|
loadCases(l)%N = step_discretization%get_asInt ('N')
|
||||||
loadCases(l)%r = step_discretization%get_asFloat('r', defaultVal= 1.0_pReal)
|
loadCases(l)%r = step_discretization%get_asFloat('r', defaultVal= 1.0_pReal)
|
||||||
loadCases(l)%f_out = step_discretization%get_asInt ('f_out', defaultVal=1)
|
|
||||||
loadCases(l)%f_restart = step_discretization%get_asInt ('f_restart', defaultVal=huge(0))
|
|
||||||
|
|
||||||
loadCases(l)%drop_guessing = (load_step%get_asBool('drop_guessing',defaultVal=.false.) .or. &
|
loadCases(l)%f_restart = load_step%get_asInt('f_restart', defaultVal=huge(0))
|
||||||
merge(.false.,.true.,l > 1))
|
loadCases(l)%f_out = load_step%get_asInt('f_out', defaultVal=1)
|
||||||
|
loadCases(l)%estimate_rate = (load_step%get_asBool('estimate_rate',defaultVal=.true.) .and. l>1)
|
||||||
|
|
||||||
reportAndCheck: if (worldrank == 0) then
|
reportAndCheck: if (worldrank == 0) then
|
||||||
write (loadcase_string, '(i0)' ) l
|
|
||||||
print'(/,a,i0)', ' load case: ', l
|
print'(/,a,i0)', ' load case: ', l
|
||||||
print*, ' drop_guessing:', loadCases(l)%drop_guessing
|
print*, ' estimate_rate:', loadCases(l)%estimate_rate
|
||||||
if (loadCases(l)%deformation%myType == 'L') then
|
if (loadCases(l)%deformation%myType == 'L') then
|
||||||
do j = 1, 3
|
do j = 1, 3
|
||||||
if (any(loadCases(l)%deformation%mask(j,1:3) .eqv. .true.) .and. &
|
if (any(loadCases(l)%deformation%mask(j,1:3) .eqv. .true.) .and. &
|
||||||
|
@ -289,7 +295,7 @@ program DAMASK_grid
|
||||||
if (loadCases(l)%f_restart < huge(0)) &
|
if (loadCases(l)%f_restart < huge(0)) &
|
||||||
print'(a,i0)', ' f_restart: ', loadCases(l)%f_restart
|
print'(a,i0)', ' f_restart: ', loadCases(l)%f_restart
|
||||||
|
|
||||||
if (errorID > 0) call IO_error(error_ID = errorID, ext_msg = loadcase_string) ! exit with error message
|
if (errorID > 0) call IO_error(error_ID = errorID, el = l)
|
||||||
|
|
||||||
endif reportAndCheck
|
endif reportAndCheck
|
||||||
enddo
|
enddo
|
||||||
|
@ -298,12 +304,14 @@ program DAMASK_grid
|
||||||
! doing initialization depending on active solvers
|
! doing initialization depending on active solvers
|
||||||
call spectral_Utilities_init
|
call spectral_Utilities_init
|
||||||
do field = 1, nActiveFields
|
do field = 1, nActiveFields
|
||||||
select case (loadCases(1)%ID(field))
|
select case (ID(field))
|
||||||
case(FIELD_MECH_ID)
|
case(FIELD_MECH_ID)
|
||||||
call mech_init
|
call mechanical_init
|
||||||
|
|
||||||
case(FIELD_THERMAL_ID)
|
case(FIELD_THERMAL_ID)
|
||||||
call grid_thermal_spectral_init
|
initial_conditions => config_load%get('initial_conditions',defaultVal=emptyDict)
|
||||||
|
thermal => initial_conditions%get('thermal',defaultVal=emptyDict)
|
||||||
|
call grid_thermal_spectral_init(thermal%get_asFloat('T',defaultVal = T_0))
|
||||||
|
|
||||||
case(FIELD_DAMAGE_ID)
|
case(FIELD_DAMAGE_ID)
|
||||||
call grid_damage_spectral_init
|
call grid_damage_spectral_init
|
||||||
|
@ -331,7 +339,7 @@ program DAMASK_grid
|
||||||
|
|
||||||
loadCaseLooping: do l = 1, size(loadCases)
|
loadCaseLooping: do l = 1, size(loadCases)
|
||||||
time0 = time ! load case start time
|
time0 = time ! load case start time
|
||||||
guess = .not. loadCases(l)%drop_guessing ! change of load case? homogeneous guess for the first inc
|
guess = loadCases(l)%estimate_rate ! change of load case? homogeneous guess for the first inc
|
||||||
|
|
||||||
incLooping: do inc = 1, loadCases(l)%N
|
incLooping: do inc = 1, loadCases(l)%N
|
||||||
totalIncsCounter = totalIncsCounter + 1
|
totalIncsCounter = totalIncsCounter + 1
|
||||||
|
@ -374,9 +382,9 @@ program DAMASK_grid
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! forward fields
|
! forward fields
|
||||||
do field = 1, nActiveFields
|
do field = 1, nActiveFields
|
||||||
select case(loadCases(l)%ID(field))
|
select case(ID(field))
|
||||||
case(FIELD_MECH_ID)
|
case(FIELD_MECH_ID)
|
||||||
call mech_forward (&
|
call mechanical_forward (&
|
||||||
cutBack,guess,timeinc,timeIncOld,remainingLoadCaseTime, &
|
cutBack,guess,timeinc,timeIncOld,remainingLoadCaseTime, &
|
||||||
deformation_BC = loadCases(l)%deformation, &
|
deformation_BC = loadCases(l)%deformation, &
|
||||||
stress_BC = loadCases(l)%stress, &
|
stress_BC = loadCases(l)%stress, &
|
||||||
|
@ -394,9 +402,9 @@ program DAMASK_grid
|
||||||
stagIterate = .true.
|
stagIterate = .true.
|
||||||
do while (stagIterate)
|
do while (stagIterate)
|
||||||
do field = 1, nActiveFields
|
do field = 1, nActiveFields
|
||||||
select case(loadCases(l)%ID(field))
|
select case(ID(field))
|
||||||
case(FIELD_MECH_ID)
|
case(FIELD_MECH_ID)
|
||||||
solres(field) = mech_solution(incInfo)
|
solres(field) = mechanical_solution(incInfo)
|
||||||
case(FIELD_THERMAL_ID)
|
case(FIELD_THERMAL_ID)
|
||||||
solres(field) = grid_thermal_spectral_solution(timeinc)
|
solres(field) = grid_thermal_spectral_solution(timeinc)
|
||||||
case(FIELD_DAMAGE_ID)
|
case(FIELD_DAMAGE_ID)
|
||||||
|
@ -417,13 +425,13 @@ program DAMASK_grid
|
||||||
|
|
||||||
if ( (all(solres(:)%converged .and. solres(:)%stagConverged)) & ! converged
|
if ( (all(solres(:)%converged .and. solres(:)%stagConverged)) & ! converged
|
||||||
.and. .not. solres(1)%termIll) then ! and acceptable solution found
|
.and. .not. solres(1)%termIll) then ! and acceptable solution found
|
||||||
call mech_updateCoords
|
call mechanical_updateCoords
|
||||||
timeIncOld = timeinc
|
timeIncOld = timeinc
|
||||||
cutBack = .false.
|
cutBack = .false.
|
||||||
guess = .true. ! start guessing after first converged (sub)inc
|
guess = .true. ! start guessing after first converged (sub)inc
|
||||||
if (worldrank == 0) then
|
if (worldrank == 0) then
|
||||||
write(statUnit,*) totalIncsCounter, time, cutBackLevel, &
|
write(statUnit,*) totalIncsCounter, time, cutBackLevel, &
|
||||||
solres%converged, solres%iterationsNeeded
|
solres(1)%converged, solres(1)%iterationsNeeded
|
||||||
flush(statUnit)
|
flush(statUnit)
|
||||||
endif
|
endif
|
||||||
elseif (cutBackLevel < maxCutBack) then ! further cutbacking tolerated?
|
elseif (cutBackLevel < maxCutBack) then ! further cutbacking tolerated?
|
||||||
|
@ -449,15 +457,24 @@ program DAMASK_grid
|
||||||
print'(/,a,i0,a)', ' increment ', totalIncsCounter, ' NOT converged'
|
print'(/,a,i0,a)', ' increment ', totalIncsCounter, ' NOT converged'
|
||||||
endif; flush(IO_STDOUT)
|
endif; flush(IO_STDOUT)
|
||||||
|
|
||||||
if (mod(inc,loadCases(l)%f_out) == 0) then
|
call MPI_Allreduce(interface_SIGUSR1,signal,1,MPI_LOGICAL,MPI_LOR,PETSC_COMM_WORLD,ierr)
|
||||||
|
if (ierr /= 0) error stop 'MPI error'
|
||||||
|
if (mod(inc,loadCases(l)%f_out) == 0 .or. signal) then
|
||||||
print'(1/,a)', ' ... writing results to file ......................................'
|
print'(1/,a)', ' ... writing results to file ......................................'
|
||||||
flush(IO_STDOUT)
|
flush(IO_STDOUT)
|
||||||
call CPFEM_results(totalIncsCounter,time)
|
call CPFEM_results(totalIncsCounter,time)
|
||||||
endif
|
endif
|
||||||
if (mod(inc,loadCases(l)%f_restart) == 0) then
|
if(signal) call interface_setSIGUSR1(.false.)
|
||||||
call mech_restartWrite
|
call MPI_Allreduce(interface_SIGUSR2,signal,1,MPI_LOGICAL,MPI_LOR,PETSC_COMM_WORLD,ierr)
|
||||||
|
if (ierr /= 0) error stop 'MPI error'
|
||||||
|
if (mod(inc,loadCases(l)%f_restart) == 0 .or. signal) then
|
||||||
|
call mechanical_restartWrite
|
||||||
call CPFEM_restartWrite
|
call CPFEM_restartWrite
|
||||||
endif
|
endif
|
||||||
|
if(signal) call interface_setSIGUSR2(.false.)
|
||||||
|
call MPI_Allreduce(interface_SIGTERM,signal,1,MPI_LOGICAL,MPI_LOR,PETSC_COMM_WORLD,ierr)
|
||||||
|
if (ierr /= 0) error stop 'MPI error'
|
||||||
|
if (signal) exit loadCaseLooping
|
||||||
endif skipping
|
endif skipping
|
||||||
|
|
||||||
enddo incLooping
|
enddo incLooping
|
||||||
|
|
|
@ -68,8 +68,11 @@ subroutine discretization_grid_init(restart)
|
||||||
|
|
||||||
print'(/,a)', ' <<<+- discretization_grid init -+>>>'; flush(IO_STDOUT)
|
print'(/,a)', ' <<<+- discretization_grid init -+>>>'; flush(IO_STDOUT)
|
||||||
|
|
||||||
if(worldrank == 0) call readVTR(grid,geomSize,origin,materialAt_global)
|
if(worldrank == 0) then
|
||||||
|
call readVTR(grid,geomSize,origin,materialAt_global)
|
||||||
|
else
|
||||||
|
allocate(materialAt_global(0)) ! needed for IntelMPI
|
||||||
|
endif
|
||||||
|
|
||||||
call MPI_Bcast(grid,3,MPI_INTEGER,0,PETSC_COMM_WORLD, ierr)
|
call MPI_Bcast(grid,3,MPI_INTEGER,0,PETSC_COMM_WORLD, ierr)
|
||||||
if (ierr /= 0) error stop 'MPI error'
|
if (ierr /= 0) error stop 'MPI error'
|
||||||
|
|
|
@ -15,8 +15,8 @@ module grid_damage_spectral
|
||||||
use IO
|
use IO
|
||||||
use spectral_utilities
|
use spectral_utilities
|
||||||
use discretization_grid
|
use discretization_grid
|
||||||
use damage_nonlocal
|
|
||||||
use YAML_types
|
use YAML_types
|
||||||
|
use homogenization
|
||||||
use config
|
use config
|
||||||
|
|
||||||
implicit none
|
implicit none
|
||||||
|
@ -160,7 +160,7 @@ function grid_damage_spectral_solution(timeinc) result(solution)
|
||||||
|
|
||||||
real(pReal), intent(in) :: &
|
real(pReal), intent(in) :: &
|
||||||
timeinc !< increment in time for current solution
|
timeinc !< increment in time for current solution
|
||||||
integer :: i, j, k, cell
|
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, solnNorm
|
||||||
|
@ -193,10 +193,10 @@ function grid_damage_spectral_solution(timeinc) result(solution)
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! updating damage state
|
! updating damage state
|
||||||
cell = 0
|
ce = 0
|
||||||
do k = 1, grid3; do j = 1, grid(2); do i = 1,grid(1)
|
do k = 1, grid3; do j = 1, grid(2); do i = 1,grid(1)
|
||||||
cell = cell + 1
|
ce = ce + 1
|
||||||
call damage_nonlocal_putNonLocalDamage(phi_current(i,j,k),1,cell)
|
call damage_nonlocal_putNonLocalDamage(phi_current(i,j,k),ce)
|
||||||
enddo; enddo; enddo
|
enddo; enddo; enddo
|
||||||
|
|
||||||
call VecMin(solution_vec,devNull,phi_min,ierr); CHKERRQ(ierr)
|
call VecMin(solution_vec,devNull,phi_min,ierr); CHKERRQ(ierr)
|
||||||
|
@ -216,7 +216,7 @@ end function grid_damage_spectral_solution
|
||||||
subroutine grid_damage_spectral_forward(cutBack)
|
subroutine grid_damage_spectral_forward(cutBack)
|
||||||
|
|
||||||
logical, intent(in) :: cutBack
|
logical, intent(in) :: cutBack
|
||||||
integer :: i, j, k, cell
|
integer :: i, j, k, ce
|
||||||
DM :: dm_local
|
DM :: dm_local
|
||||||
PetscScalar, dimension(:,:,:), pointer :: x_scal
|
PetscScalar, dimension(:,:,:), pointer :: x_scal
|
||||||
PetscErrorCode :: ierr
|
PetscErrorCode :: ierr
|
||||||
|
@ -226,14 +226,14 @@ subroutine grid_damage_spectral_forward(cutBack)
|
||||||
phi_stagInc = phi_lastInc
|
phi_stagInc = phi_lastInc
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! reverting damage field state
|
! reverting damage field state
|
||||||
cell = 0
|
ce = 0
|
||||||
call SNESGetDM(damage_snes,dm_local,ierr); CHKERRQ(ierr)
|
call SNESGetDM(damage_snes,dm_local,ierr); CHKERRQ(ierr)
|
||||||
call DMDAVecGetArrayF90(dm_local,solution_vec,x_scal,ierr); CHKERRQ(ierr) !< get the data out of PETSc to work with
|
call DMDAVecGetArrayF90(dm_local,solution_vec,x_scal,ierr); CHKERRQ(ierr) !< get the data out of PETSc to work with
|
||||||
x_scal(xstart:xend,ystart:yend,zstart:zend) = phi_current
|
x_scal(xstart:xend,ystart:yend,zstart:zend) = phi_current
|
||||||
call DMDAVecRestoreArrayF90(dm_local,solution_vec,x_scal,ierr); CHKERRQ(ierr)
|
call DMDAVecRestoreArrayF90(dm_local,solution_vec,x_scal,ierr); CHKERRQ(ierr)
|
||||||
do k = 1, grid3; do j = 1, grid(2); do i = 1,grid(1)
|
do k = 1, grid3; do j = 1, grid(2); do i = 1,grid(1)
|
||||||
cell = cell + 1
|
ce = ce + 1
|
||||||
call damage_nonlocal_putNonLocalDamage(phi_current(i,j,k),1,cell)
|
call damage_nonlocal_putNonLocalDamage(phi_current(i,j,k),ce)
|
||||||
enddo; enddo; enddo
|
enddo; enddo; enddo
|
||||||
else
|
else
|
||||||
phi_lastInc = phi_current
|
phi_lastInc = phi_current
|
||||||
|
@ -258,7 +258,7 @@ subroutine formResidual(in,x_scal,f_scal,dummy,ierr)
|
||||||
f_scal
|
f_scal
|
||||||
PetscObject :: dummy
|
PetscObject :: dummy
|
||||||
PetscErrorCode :: ierr
|
PetscErrorCode :: ierr
|
||||||
integer :: i, j, k, cell
|
integer :: i, j, k, ce
|
||||||
real(pReal) :: phiDot, dPhiDot_dPhi, mobility
|
real(pReal) :: phiDot, dPhiDot_dPhi, mobility
|
||||||
|
|
||||||
phi_current = x_scal
|
phi_current = x_scal
|
||||||
|
@ -269,20 +269,20 @@ subroutine formResidual(in,x_scal,f_scal,dummy,ierr)
|
||||||
call utilities_FFTscalarForward
|
call utilities_FFTscalarForward
|
||||||
call utilities_fourierScalarGradient !< calculate gradient of damage field
|
call utilities_fourierScalarGradient !< calculate gradient of damage field
|
||||||
call utilities_FFTvectorBackward
|
call utilities_FFTvectorBackward
|
||||||
cell = 0
|
ce = 0
|
||||||
do k = 1, grid3; do j = 1, grid(2); do i = 1,grid(1)
|
do k = 1, grid3; do j = 1, grid(2); do i = 1,grid(1)
|
||||||
cell = cell + 1
|
ce = ce + 1
|
||||||
vectorField_real(1:3,i,j,k) = matmul(damage_nonlocal_getDiffusion(1,cell) - K_ref, &
|
vectorField_real(1:3,i,j,k) = matmul(damage_nonlocal_getDiffusion(ce) - K_ref, &
|
||||||
vectorField_real(1:3,i,j,k))
|
vectorField_real(1:3,i,j,k))
|
||||||
enddo; enddo; enddo
|
enddo; enddo; enddo
|
||||||
call utilities_FFTvectorForward
|
call utilities_FFTvectorForward
|
||||||
call utilities_fourierVectorDivergence !< calculate damage divergence in fourier field
|
call utilities_fourierVectorDivergence !< calculate damage divergence in fourier field
|
||||||
call utilities_FFTscalarBackward
|
call utilities_FFTscalarBackward
|
||||||
cell = 0
|
ce = 0
|
||||||
do k = 1, grid3; do j = 1, grid(2); do i = 1,grid(1)
|
do k = 1, grid3; do j = 1, grid(2); do i = 1,grid(1)
|
||||||
cell = cell + 1
|
ce = ce + 1
|
||||||
call damage_nonlocal_getSourceAndItsTangent(phiDot, dPhiDot_dPhi, phi_current(i,j,k), 1, cell)
|
call damage_nonlocal_getSourceAndItsTangent(phiDot, dPhiDot_dPhi, phi_current(i,j,k),ce)
|
||||||
mobility = damage_nonlocal_getMobility(1,cell)
|
mobility = damage_nonlocal_getMobility(ce)
|
||||||
scalarField_real(i,j,k) = params%timeinc*(scalarField_real(i,j,k) + phiDot) &
|
scalarField_real(i,j,k) = params%timeinc*(scalarField_real(i,j,k) + phiDot) &
|
||||||
+ mobility*(phi_lastInc(i,j,k) - phi_current(i,j,k)) &
|
+ mobility*(phi_lastInc(i,j,k) - phi_current(i,j,k)) &
|
||||||
+ mu_ref*phi_current(i,j,k)
|
+ mu_ref*phi_current(i,j,k)
|
||||||
|
@ -310,15 +310,15 @@ end subroutine formResidual
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
subroutine updateReference
|
subroutine updateReference
|
||||||
|
|
||||||
integer :: i,j,k,cell,ierr
|
integer :: i,j,k,ce,ierr
|
||||||
|
|
||||||
cell = 0
|
ce = 0
|
||||||
K_ref = 0.0_pReal
|
K_ref = 0.0_pReal
|
||||||
mu_ref = 0.0_pReal
|
mu_ref = 0.0_pReal
|
||||||
do k = 1, grid3; do j = 1, grid(2); do i = 1,grid(1)
|
do k = 1, grid3; do j = 1, grid(2); do i = 1,grid(1)
|
||||||
cell = cell + 1
|
ce = ce + 1
|
||||||
K_ref = K_ref + damage_nonlocal_getDiffusion(1,cell)
|
K_ref = K_ref + damage_nonlocal_getDiffusion(ce)
|
||||||
mu_ref = mu_ref + damage_nonlocal_getMobility(1,cell)
|
mu_ref = mu_ref + damage_nonlocal_getMobility(ce)
|
||||||
enddo; enddo; enddo
|
enddo; enddo; enddo
|
||||||
K_ref = K_ref*wgt
|
K_ref = K_ref*wgt
|
||||||
call MPI_Allreduce(MPI_IN_PLACE,K_ref,9,MPI_DOUBLE,MPI_SUM,PETSC_COMM_WORLD,ierr)
|
call MPI_Allreduce(MPI_IN_PLACE,K_ref,9,MPI_DOUBLE,MPI_SUM,PETSC_COMM_WORLD,ierr)
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
!> @author Pratheek Shanthraj, Max-Planck-Institut für Eisenforschung GmbH
|
!> @author Pratheek Shanthraj, Max-Planck-Institut für Eisenforschung GmbH
|
||||||
!> @brief Grid solver for mechanics: FEM
|
!> @brief Grid solver for mechanics: FEM
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
module grid_mech_FEM
|
module grid_mechanical_FEM
|
||||||
#include <petsc/finclude/petscsnes.h>
|
#include <petsc/finclude/petscsnes.h>
|
||||||
#include <petsc/finclude/petscdmda.h>
|
#include <petsc/finclude/petscdmda.h>
|
||||||
use PETScdmda
|
use PETScdmda
|
||||||
|
@ -45,8 +45,8 @@ module grid_mech_FEM
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! PETSc data
|
! PETSc data
|
||||||
DM :: mech_grid
|
DM :: mechanical_grid
|
||||||
SNES :: mech_snes
|
SNES :: mechanical_snes
|
||||||
Vec :: solution_current, solution_lastInc, solution_rate
|
Vec :: solution_current, solution_lastInc, solution_rate
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
@ -79,18 +79,18 @@ module grid_mech_FEM
|
||||||
totalIter = 0 !< total iteration in current increment
|
totalIter = 0 !< total iteration in current increment
|
||||||
|
|
||||||
public :: &
|
public :: &
|
||||||
grid_mech_FEM_init, &
|
grid_mechanical_FEM_init, &
|
||||||
grid_mech_FEM_solution, &
|
grid_mechanical_FEM_solution, &
|
||||||
grid_mech_FEM_forward, &
|
grid_mechanical_FEM_forward, &
|
||||||
grid_mech_FEM_updateCoords, &
|
grid_mechanical_FEM_updateCoords, &
|
||||||
grid_mech_FEM_restartWrite
|
grid_mechanical_FEM_restartWrite
|
||||||
|
|
||||||
contains
|
contains
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @brief allocates all necessary fields and fills them with data, potentially from restart info
|
!> @brief allocates all necessary fields and fills them with data, potentially from restart info
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
subroutine grid_mech_FEM_init
|
subroutine grid_mechanical_FEM_init
|
||||||
|
|
||||||
real(pReal), parameter :: HGCoeff = 0.0e-2_pReal
|
real(pReal), parameter :: HGCoeff = 0.0e-2_pReal
|
||||||
real(pReal), parameter, dimension(4,8) :: &
|
real(pReal), parameter, dimension(4,8) :: &
|
||||||
|
@ -108,13 +108,11 @@ subroutine grid_mech_FEM_init
|
||||||
u_current,u_lastInc
|
u_current,u_lastInc
|
||||||
PetscInt, dimension(0:worldsize-1) :: localK
|
PetscInt, dimension(0:worldsize-1) :: localK
|
||||||
integer(HID_T) :: fileHandle, groupHandle
|
integer(HID_T) :: fileHandle, groupHandle
|
||||||
character(len=pStringLen) :: &
|
|
||||||
fileName
|
|
||||||
class(tNode), pointer :: &
|
class(tNode), pointer :: &
|
||||||
num_grid, &
|
num_grid, &
|
||||||
debug_grid
|
debug_grid
|
||||||
|
|
||||||
print'(/,a)', ' <<<+- grid_mech_FEM init -+>>>'; flush(IO_STDOUT)
|
print'(/,a)', ' <<<+- grid_mechanical_FEM init -+>>>'; flush(IO_STDOUT)
|
||||||
|
|
||||||
!-------------------------------------------------------------------------------------------------
|
!-------------------------------------------------------------------------------------------------
|
||||||
! debugging options
|
! debugging options
|
||||||
|
@ -141,8 +139,11 @@ subroutine grid_mech_FEM_init
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! set default and user defined options for PETSc
|
! set default and user defined options for PETSc
|
||||||
call PetscOptionsInsertString(PETSC_NULL_OPTIONS,'-mech_snes_type newtonls -mech_ksp_type fgmres &
|
call PetscOptionsInsertString(PETSC_NULL_OPTIONS, &
|
||||||
&-mech_ksp_max_it 25 -mech_pc_type ml -mech_mg_levels_ksp_type chebyshev',ierr)
|
'-mechanical_snes_type newtonls -mechanical_ksp_type fgmres &
|
||||||
|
&-mechanical_ksp_max_it 25 -mechanical_pc_type ml &
|
||||||
|
&-mechanical_mg_levels_ksp_type chebyshev', &
|
||||||
|
ierr)
|
||||||
CHKERRQ(ierr)
|
CHKERRQ(ierr)
|
||||||
call PetscOptionsInsertString(PETSC_NULL_OPTIONS,num_grid%get_asString('petsc_options',defaultVal=''),ierr)
|
call PetscOptionsInsertString(PETSC_NULL_OPTIONS,num_grid%get_asString('petsc_options',defaultVal=''),ierr)
|
||||||
CHKERRQ(ierr)
|
CHKERRQ(ierr)
|
||||||
|
@ -155,8 +156,10 @@ subroutine grid_mech_FEM_init
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! initialize solver specific parts of PETSc
|
! initialize solver specific parts of PETSc
|
||||||
call SNESCreate(PETSC_COMM_WORLD,mech_snes,ierr); CHKERRQ(ierr)
|
call SNESCreate(PETSC_COMM_WORLD,mechanical_snes,ierr)
|
||||||
call SNESSetOptionsPrefix(mech_snes,'mech_',ierr);CHKERRQ(ierr)
|
CHKERRQ(ierr)
|
||||||
|
call SNESSetOptionsPrefix(mechanical_snes,'mechanical_',ierr)
|
||||||
|
CHKERRQ(ierr)
|
||||||
localK = 0
|
localK = 0
|
||||||
localK(worldrank) = grid3
|
localK(worldrank) = grid3
|
||||||
call MPI_Allreduce(MPI_IN_PLACE,localK,worldsize,MPI_INTEGER,MPI_SUM,PETSC_COMM_WORLD,ierr)
|
call MPI_Allreduce(MPI_IN_PLACE,localK,worldsize,MPI_INTEGER,MPI_SUM,PETSC_COMM_WORLD,ierr)
|
||||||
|
@ -167,34 +170,44 @@ subroutine grid_mech_FEM_init
|
||||||
1, 1, worldsize, &
|
1, 1, worldsize, &
|
||||||
3, 1, &
|
3, 1, &
|
||||||
[grid(1)],[grid(2)],localK, &
|
[grid(1)],[grid(2)],localK, &
|
||||||
mech_grid,ierr)
|
mechanical_grid,ierr)
|
||||||
CHKERRQ(ierr)
|
CHKERRQ(ierr)
|
||||||
call SNESSetDM(mech_snes,mech_grid,ierr); CHKERRQ(ierr)
|
call SNESSetDM(mechanical_snes,mechanical_grid,ierr)
|
||||||
call DMsetFromOptions(mech_grid,ierr); CHKERRQ(ierr)
|
|
||||||
call DMsetUp(mech_grid,ierr); CHKERRQ(ierr)
|
|
||||||
call DMDASetUniformCoordinates(mech_grid,0.0_pReal,geomSize(1),0.0_pReal,geomSize(2),0.0_pReal,geomSize(3),ierr)
|
|
||||||
CHKERRQ(ierr)
|
CHKERRQ(ierr)
|
||||||
call DMCreateGlobalVector(mech_grid,solution_current,ierr); CHKERRQ(ierr)
|
call DMsetFromOptions(mechanical_grid,ierr)
|
||||||
call DMCreateGlobalVector(mech_grid,solution_lastInc,ierr); CHKERRQ(ierr)
|
|
||||||
call DMCreateGlobalVector(mech_grid,solution_rate ,ierr); CHKERRQ(ierr)
|
|
||||||
call DMSNESSetFunctionLocal(mech_grid,formResidual,PETSC_NULL_SNES,ierr)
|
|
||||||
CHKERRQ(ierr)
|
CHKERRQ(ierr)
|
||||||
call DMSNESSetJacobianLocal(mech_grid,formJacobian,PETSC_NULL_SNES,ierr)
|
call DMsetUp(mechanical_grid,ierr)
|
||||||
CHKERRQ(ierr)
|
CHKERRQ(ierr)
|
||||||
call SNESSetConvergenceTest(mech_snes,converged,PETSC_NULL_SNES,PETSC_NULL_FUNCTION,ierr) ! specify custom convergence check function "_converged"
|
call DMDASetUniformCoordinates(mechanical_grid,0.0_pReal,geomSize(1),0.0_pReal,geomSize(2),0.0_pReal,geomSize(3),ierr)
|
||||||
|
CHKERRQ(ierr)
|
||||||
|
call DMCreateGlobalVector(mechanical_grid,solution_current,ierr)
|
||||||
|
CHKERRQ(ierr)
|
||||||
|
call DMCreateGlobalVector(mechanical_grid,solution_lastInc,ierr)
|
||||||
|
CHKERRQ(ierr)
|
||||||
|
call DMCreateGlobalVector(mechanical_grid,solution_rate ,ierr)
|
||||||
|
CHKERRQ(ierr)
|
||||||
|
call DMSNESSetFunctionLocal(mechanical_grid,formResidual,PETSC_NULL_SNES,ierr)
|
||||||
|
CHKERRQ(ierr)
|
||||||
|
call DMSNESSetJacobianLocal(mechanical_grid,formJacobian,PETSC_NULL_SNES,ierr)
|
||||||
|
CHKERRQ(ierr)
|
||||||
|
call SNESSetConvergenceTest(mechanical_snes,converged,PETSC_NULL_SNES,PETSC_NULL_FUNCTION,ierr) ! specify custom convergence check function "_converged"
|
||||||
|
CHKERRQ(ierr)
|
||||||
|
call SNESSetMaxLinearSolveFailures(mechanical_snes, huge(1), ierr) ! ignore linear solve failures
|
||||||
|
CHKERRQ(ierr)
|
||||||
|
call SNESSetFromOptions(mechanical_snes,ierr) ! pull it all together with additional cli arguments
|
||||||
CHKERRQ(ierr)
|
CHKERRQ(ierr)
|
||||||
call SNESSetMaxLinearSolveFailures(mech_snes, huge(1), ierr); CHKERRQ(ierr) ! ignore linear solve failures
|
|
||||||
call SNESSetFromOptions(mech_snes,ierr); CHKERRQ(ierr) ! pull it all together with additional cli arguments
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! init fields
|
! init fields
|
||||||
call VecSet(solution_current,0.0_pReal,ierr);CHKERRQ(ierr)
|
call VecSet(solution_current,0.0_pReal,ierr);CHKERRQ(ierr)
|
||||||
call VecSet(solution_lastInc,0.0_pReal,ierr);CHKERRQ(ierr)
|
call VecSet(solution_lastInc,0.0_pReal,ierr);CHKERRQ(ierr)
|
||||||
call VecSet(solution_rate ,0.0_pReal,ierr);CHKERRQ(ierr)
|
call VecSet(solution_rate ,0.0_pReal,ierr);CHKERRQ(ierr)
|
||||||
call DMDAVecGetArrayF90(mech_grid,solution_current,u_current,ierr); CHKERRQ(ierr)
|
call DMDAVecGetArrayF90(mechanical_grid,solution_current,u_current,ierr)
|
||||||
call DMDAVecGetArrayF90(mech_grid,solution_lastInc,u_lastInc,ierr); CHKERRQ(ierr)
|
CHKERRQ(ierr)
|
||||||
|
call DMDAVecGetArrayF90(mechanical_grid,solution_lastInc,u_lastInc,ierr)
|
||||||
|
CHKERRQ(ierr)
|
||||||
|
|
||||||
call DMDAGetCorners(mech_grid,xstart,ystart,zstart,xend,yend,zend,ierr) ! local grid extent
|
call DMDAGetCorners(mechanical_grid,xstart,ystart,zstart,xend,yend,zend,ierr) ! local grid extent
|
||||||
CHKERRQ(ierr)
|
CHKERRQ(ierr)
|
||||||
xend = xstart+xend-1
|
xend = xstart+xend-1
|
||||||
yend = ystart+yend-1
|
yend = ystart+yend-1
|
||||||
|
@ -219,8 +232,7 @@ subroutine grid_mech_FEM_init
|
||||||
restartRead: if (interface_restartInc > 0) then
|
restartRead: if (interface_restartInc > 0) then
|
||||||
print'(/,a,i0,a)', ' reading restart data of increment ', interface_restartInc, ' from file'
|
print'(/,a,i0,a)', ' reading restart data of increment ', interface_restartInc, ' from file'
|
||||||
|
|
||||||
write(fileName,'(a,a,i0,a)') trim(getSolverJobName()),'_',worldrank,'.hdf5'
|
fileHandle = HDF5_openFile(getSolverJobName()//'_restart.hdf5','r')
|
||||||
fileHandle = HDF5_openFile(fileName)
|
|
||||||
groupHandle = HDF5_openGroup(fileHandle,'solver')
|
groupHandle = HDF5_openGroup(fileHandle,'solver')
|
||||||
|
|
||||||
call HDF5_read(groupHandle,P_aim, 'P_aim')
|
call HDF5_read(groupHandle,P_aim, 'P_aim')
|
||||||
|
@ -242,9 +254,9 @@ subroutine grid_mech_FEM_init
|
||||||
call utilities_constitutiveResponse(P_current,P_av,C_volAvg,devNull, & ! stress field, stress avg, global average of stiffness and (min+max)/2
|
call utilities_constitutiveResponse(P_current,P_av,C_volAvg,devNull, & ! stress field, stress avg, global average of stiffness and (min+max)/2
|
||||||
F, & ! target F
|
F, & ! target F
|
||||||
0.0_pReal) ! time increment
|
0.0_pReal) ! time increment
|
||||||
call DMDAVecRestoreArrayF90(mech_grid,solution_current,u_current,ierr)
|
call DMDAVecRestoreArrayF90(mechanical_grid,solution_current,u_current,ierr)
|
||||||
CHKERRQ(ierr)
|
CHKERRQ(ierr)
|
||||||
call DMDAVecRestoreArrayF90(mech_grid,solution_lastInc,u_lastInc,ierr)
|
call DMDAVecRestoreArrayF90(mechanical_grid,solution_lastInc,u_lastInc,ierr)
|
||||||
CHKERRQ(ierr)
|
CHKERRQ(ierr)
|
||||||
|
|
||||||
restartRead2: if (interface_restartInc > 0) then
|
restartRead2: if (interface_restartInc > 0) then
|
||||||
|
@ -257,13 +269,13 @@ subroutine grid_mech_FEM_init
|
||||||
|
|
||||||
endif restartRead2
|
endif restartRead2
|
||||||
|
|
||||||
end subroutine grid_mech_FEM_init
|
end subroutine grid_mechanical_FEM_init
|
||||||
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @brief solution for the FEM scheme with internal iterations
|
!> @brief solution for the FEM scheme with internal iterations
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
function grid_mech_FEM_solution(incInfoIn) result(solution)
|
function grid_mechanical_FEM_solution(incInfoIn) result(solution)
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! input data for solution
|
! input data for solution
|
||||||
|
@ -284,11 +296,13 @@ function grid_mech_FEM_solution(incInfoIn) result(solution)
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! solve BVP
|
! solve BVP
|
||||||
call SNESsolve(mech_snes,PETSC_NULL_VEC,solution_current,ierr); CHKERRQ(ierr)
|
call SNESsolve(mechanical_snes,PETSC_NULL_VEC,solution_current,ierr)
|
||||||
|
CHKERRQ(ierr)
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! check convergence
|
! check convergence
|
||||||
call SNESGetConvergedReason(mech_snes,reason,ierr); CHKERRQ(ierr)
|
call SNESGetConvergedReason(mechanical_snes,reason,ierr)
|
||||||
|
CHKERRQ(ierr)
|
||||||
|
|
||||||
solution%converged = reason > 0
|
solution%converged = reason > 0
|
||||||
solution%iterationsNeeded = totalIter
|
solution%iterationsNeeded = totalIter
|
||||||
|
@ -296,14 +310,14 @@ function grid_mech_FEM_solution(incInfoIn) result(solution)
|
||||||
terminallyIll = .false.
|
terminallyIll = .false.
|
||||||
P_aim = merge(P_aim,P_av,params%stress_mask)
|
P_aim = merge(P_aim,P_av,params%stress_mask)
|
||||||
|
|
||||||
end function grid_mech_FEM_solution
|
end function grid_mechanical_FEM_solution
|
||||||
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @brief forwarding routine
|
!> @brief forwarding routine
|
||||||
!> @details find new boundary conditions and best F estimate for end of current timestep
|
!> @details find new boundary conditions and best F estimate for end of current timestep
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
subroutine grid_mech_FEM_forward(cutBack,guess,Delta_t,Delta_t_old,t_remaining,&
|
subroutine grid_mechanical_FEM_forward(cutBack,guess,Delta_t,Delta_t_old,t_remaining,&
|
||||||
deformation_BC,stress_BC,rotation_BC)
|
deformation_BC,stress_BC,rotation_BC)
|
||||||
|
|
||||||
logical, intent(in) :: &
|
logical, intent(in) :: &
|
||||||
|
@ -323,8 +337,10 @@ subroutine grid_mech_FEM_forward(cutBack,guess,Delta_t,Delta_t_old,t_remaining,&
|
||||||
u_current,u_lastInc
|
u_current,u_lastInc
|
||||||
|
|
||||||
|
|
||||||
call DMDAVecGetArrayF90(mech_grid,solution_current,u_current,ierr); CHKERRQ(ierr)
|
call DMDAVecGetArrayF90(mechanical_grid,solution_current,u_current,ierr)
|
||||||
call DMDAVecGetArrayF90(mech_grid,solution_lastInc,u_lastInc,ierr); CHKERRQ(ierr)
|
CHKERRQ(ierr)
|
||||||
|
call DMDAVecGetArrayF90(mechanical_grid,solution_lastInc,u_lastInc,ierr)
|
||||||
|
CHKERRQ(ierr)
|
||||||
|
|
||||||
if (cutBack) then
|
if (cutBack) then
|
||||||
C_volAvg = C_volAvgLastInc
|
C_volAvg = C_volAvgLastInc
|
||||||
|
@ -371,8 +387,10 @@ subroutine grid_mech_FEM_forward(cutBack,guess,Delta_t,Delta_t_old,t_remaining,&
|
||||||
|
|
||||||
call VecAXPY(solution_current,Delta_t,solution_rate,ierr); CHKERRQ(ierr)
|
call VecAXPY(solution_current,Delta_t,solution_rate,ierr); CHKERRQ(ierr)
|
||||||
|
|
||||||
call DMDAVecRestoreArrayF90(mech_grid,solution_current,u_current,ierr); CHKERRQ(ierr)
|
call DMDAVecRestoreArrayF90(mechanical_grid,solution_current,u_current,ierr)
|
||||||
call DMDAVecRestoreArrayF90(mech_grid,solution_lastInc,u_lastInc,ierr); CHKERRQ(ierr)
|
CHKERRQ(ierr)
|
||||||
|
call DMDAVecRestoreArrayF90(mechanical_grid,solution_lastInc,u_lastInc,ierr)
|
||||||
|
CHKERRQ(ierr)
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! set module wide available data
|
! set module wide available data
|
||||||
|
@ -380,36 +398,37 @@ subroutine grid_mech_FEM_forward(cutBack,guess,Delta_t,Delta_t_old,t_remaining,&
|
||||||
params%rotation_BC = rotation_BC
|
params%rotation_BC = rotation_BC
|
||||||
params%timeinc = Delta_t
|
params%timeinc = Delta_t
|
||||||
|
|
||||||
end subroutine grid_mech_FEM_forward
|
end subroutine grid_mechanical_FEM_forward
|
||||||
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @brief Update coordinates
|
!> @brief Update coordinates
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
subroutine grid_mech_FEM_updateCoords
|
subroutine grid_mechanical_FEM_updateCoords
|
||||||
|
|
||||||
call utilities_updateCoords(F)
|
call utilities_updateCoords(F)
|
||||||
|
|
||||||
end subroutine grid_mech_FEM_updateCoords
|
end subroutine grid_mechanical_FEM_updateCoords
|
||||||
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @brief Write current solver and constitutive data for restart to file
|
!> @brief Write current solver and constitutive data for restart to file
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
subroutine grid_mech_FEM_restartWrite
|
subroutine grid_mechanical_FEM_restartWrite
|
||||||
|
|
||||||
PetscErrorCode :: ierr
|
PetscErrorCode :: ierr
|
||||||
integer(HID_T) :: fileHandle, groupHandle
|
integer(HID_T) :: fileHandle, groupHandle
|
||||||
PetscScalar, dimension(:,:,:,:), pointer :: u_current,u_lastInc
|
PetscScalar, dimension(:,:,:,:), pointer :: u_current,u_lastInc
|
||||||
character(len=pStringLen) :: fileName
|
|
||||||
|
|
||||||
call DMDAVecGetArrayF90(mech_grid,solution_current,u_current,ierr); CHKERRQ(ierr)
|
|
||||||
call DMDAVecGetArrayF90(mech_grid,solution_lastInc,u_lastInc,ierr); CHKERRQ(ierr)
|
call DMDAVecGetArrayF90(mechanical_grid,solution_current,u_current,ierr)
|
||||||
|
CHKERRQ(ierr)
|
||||||
|
call DMDAVecGetArrayF90(mechanical_grid,solution_lastInc,u_lastInc,ierr)
|
||||||
|
CHKERRQ(ierr)
|
||||||
|
|
||||||
print*, 'writing solver data required for restart to file'; flush(IO_STDOUT)
|
print*, 'writing solver data required for restart to file'; flush(IO_STDOUT)
|
||||||
|
|
||||||
write(fileName,'(a,a,i0,a)') trim(getSolverJobName()),'_',worldrank,'.hdf5'
|
fileHandle = HDF5_openFile(getSolverJobName()//'_restart.hdf5','w')
|
||||||
fileHandle = HDF5_openFile(fileName,'w')
|
|
||||||
groupHandle = HDF5_addGroup(fileHandle,'solver')
|
groupHandle = HDF5_addGroup(fileHandle,'solver')
|
||||||
|
|
||||||
call HDF5_write(groupHandle,P_aim, 'P_aim')
|
call HDF5_write(groupHandle,P_aim, 'P_aim')
|
||||||
|
@ -427,10 +446,12 @@ subroutine grid_mech_FEM_restartWrite
|
||||||
call HDF5_closeGroup(groupHandle)
|
call HDF5_closeGroup(groupHandle)
|
||||||
call HDF5_closeFile(fileHandle)
|
call HDF5_closeFile(fileHandle)
|
||||||
|
|
||||||
call DMDAVecRestoreArrayF90(mech_grid,solution_current,u_current,ierr);CHKERRQ(ierr)
|
call DMDAVecRestoreArrayF90(mechanical_grid,solution_current,u_current,ierr)
|
||||||
call DMDAVecRestoreArrayF90(mech_grid,solution_lastInc,u_lastInc,ierr);CHKERRQ(ierr)
|
CHKERRQ(ierr)
|
||||||
|
call DMDAVecRestoreArrayF90(mechanical_grid,solution_lastInc,u_lastInc,ierr)
|
||||||
|
CHKERRQ(ierr)
|
||||||
|
|
||||||
end subroutine grid_mech_FEM_restartWrite
|
end subroutine grid_mechanical_FEM_restartWrite
|
||||||
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
@ -498,8 +519,10 @@ subroutine formResidual(da_local,x_local, &
|
||||||
PetscErrorCode :: ierr
|
PetscErrorCode :: ierr
|
||||||
real(pReal), dimension(3,3,3,3) :: devNull
|
real(pReal), dimension(3,3,3,3) :: devNull
|
||||||
|
|
||||||
call SNESGetNumberFunctionEvals(mech_snes,nfuncs,ierr); CHKERRQ(ierr)
|
call SNESGetNumberFunctionEvals(mechanical_snes,nfuncs,ierr)
|
||||||
call SNESGetIterationNumber(mech_snes,PETScIter,ierr); CHKERRQ(ierr)
|
CHKERRQ(ierr)
|
||||||
|
call SNESGetIterationNumber(mechanical_snes,PETScIter,ierr)
|
||||||
|
CHKERRQ(ierr)
|
||||||
|
|
||||||
if (nfuncs == 0 .and. PETScIter == 0) totalIter = -1 ! new increment
|
if (nfuncs == 0 .and. PETScIter == 0) totalIter = -1 ! new increment
|
||||||
|
|
||||||
|
@ -679,4 +702,4 @@ subroutine formJacobian(da_local,x_local,Jac_pre,Jac,dummy,ierr)
|
||||||
|
|
||||||
end subroutine formJacobian
|
end subroutine formJacobian
|
||||||
|
|
||||||
end module grid_mech_FEM
|
end module grid_mechanical_FEM
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
!> @author Philip Eisenlohr, Max-Planck-Institut für Eisenforschung GmbH
|
!> @author Philip Eisenlohr, Max-Planck-Institut für Eisenforschung GmbH
|
||||||
!> @brief Grid solver for mechanics: Spectral basic
|
!> @brief Grid solver for mechanics: Spectral basic
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
module grid_mech_spectral_basic
|
module grid_mechanical_spectral_basic
|
||||||
#include <petsc/finclude/petscsnes.h>
|
#include <petsc/finclude/petscsnes.h>
|
||||||
#include <petsc/finclude/petscdmda.h>
|
#include <petsc/finclude/petscdmda.h>
|
||||||
use PETScdmda
|
use PETScdmda
|
||||||
|
@ -79,18 +79,18 @@ module grid_mech_spectral_basic
|
||||||
totalIter = 0 !< total iteration in current increment
|
totalIter = 0 !< total iteration in current increment
|
||||||
|
|
||||||
public :: &
|
public :: &
|
||||||
grid_mech_spectral_basic_init, &
|
grid_mechanical_spectral_basic_init, &
|
||||||
grid_mech_spectral_basic_solution, &
|
grid_mechanical_spectral_basic_solution, &
|
||||||
grid_mech_spectral_basic_forward, &
|
grid_mechanical_spectral_basic_forward, &
|
||||||
grid_mech_spectral_basic_updateCoords, &
|
grid_mechanical_spectral_basic_updateCoords, &
|
||||||
grid_mech_spectral_basic_restartWrite
|
grid_mechanical_spectral_basic_restartWrite
|
||||||
|
|
||||||
contains
|
contains
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @brief allocates all necessary fields and fills them with data, potentially from restart info
|
!> @brief allocates all necessary fields and fills them with data, potentially from restart info
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
subroutine grid_mech_spectral_basic_init
|
subroutine grid_mechanical_spectral_basic_init
|
||||||
|
|
||||||
real(pReal), dimension(3,3,grid(1),grid(2),grid3) :: P
|
real(pReal), dimension(3,3,grid(1),grid(2),grid3) :: P
|
||||||
PetscErrorCode :: ierr
|
PetscErrorCode :: ierr
|
||||||
|
@ -99,13 +99,11 @@ subroutine grid_mech_spectral_basic_init
|
||||||
PetscInt, dimension(0:worldsize-1) :: localK
|
PetscInt, dimension(0:worldsize-1) :: localK
|
||||||
integer(HID_T) :: fileHandle, groupHandle
|
integer(HID_T) :: fileHandle, groupHandle
|
||||||
integer :: fileUnit
|
integer :: fileUnit
|
||||||
character(len=pStringLen) :: &
|
|
||||||
fileName
|
|
||||||
class (tNode), pointer :: &
|
class (tNode), pointer :: &
|
||||||
num_grid, &
|
num_grid, &
|
||||||
debug_grid
|
debug_grid
|
||||||
|
|
||||||
print'(/,a)', ' <<<+- grid_mech_spectral_basic init -+>>>'; flush(IO_STDOUT)
|
print'(/,a)', ' <<<+- grid_mechanical_spectral_basic init -+>>>'; flush(IO_STDOUT)
|
||||||
|
|
||||||
print*, 'Eisenlohr et al., International Journal of Plasticity 46:37–53, 2013'
|
print*, 'Eisenlohr et al., International Journal of Plasticity 46:37–53, 2013'
|
||||||
print*, 'https://doi.org/10.1016/j.ijplas.2012.09.012'//IO_EOL
|
print*, 'https://doi.org/10.1016/j.ijplas.2012.09.012'//IO_EOL
|
||||||
|
@ -139,7 +137,7 @@ subroutine grid_mech_spectral_basic_init
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! set default and user defined options for PETSc
|
! set default and user defined options for PETSc
|
||||||
call PetscOptionsInsertString(PETSC_NULL_OPTIONS,'-mech_snes_type ngmres',ierr)
|
call PetscOptionsInsertString(PETSC_NULL_OPTIONS,'-mechanical_snes_type ngmres',ierr)
|
||||||
CHKERRQ(ierr)
|
CHKERRQ(ierr)
|
||||||
call PetscOptionsInsertString(PETSC_NULL_OPTIONS,num_grid%get_asString('petsc_options',defaultVal=''),ierr)
|
call PetscOptionsInsertString(PETSC_NULL_OPTIONS,num_grid%get_asString('petsc_options',defaultVal=''),ierr)
|
||||||
CHKERRQ(ierr)
|
CHKERRQ(ierr)
|
||||||
|
@ -152,7 +150,7 @@ subroutine grid_mech_spectral_basic_init
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! initialize solver specific parts of PETSc
|
! initialize solver specific parts of PETSc
|
||||||
call SNESCreate(PETSC_COMM_WORLD,snes,ierr); CHKERRQ(ierr)
|
call SNESCreate(PETSC_COMM_WORLD,snes,ierr); CHKERRQ(ierr)
|
||||||
call SNESSetOptionsPrefix(snes,'mech_',ierr);CHKERRQ(ierr)
|
call SNESSetOptionsPrefix(snes,'mechanical_',ierr);CHKERRQ(ierr)
|
||||||
localK = 0
|
localK = 0
|
||||||
localK(worldrank) = grid3
|
localK(worldrank) = grid3
|
||||||
call MPI_Allreduce(MPI_IN_PLACE,localK,worldsize,MPI_INTEGER,MPI_SUM,PETSC_COMM_WORLD,ierr)
|
call MPI_Allreduce(MPI_IN_PLACE,localK,worldsize,MPI_INTEGER,MPI_SUM,PETSC_COMM_WORLD,ierr)
|
||||||
|
@ -182,8 +180,7 @@ subroutine grid_mech_spectral_basic_init
|
||||||
restartRead: if (interface_restartInc > 0) then
|
restartRead: if (interface_restartInc > 0) then
|
||||||
print'(/,a,i0,a)', ' reading restart data of increment ', interface_restartInc, ' from file'
|
print'(/,a,i0,a)', ' reading restart data of increment ', interface_restartInc, ' from file'
|
||||||
|
|
||||||
write(fileName,'(a,a,i0,a)') trim(getSolverJobName()),'_',worldrank,'.hdf5'
|
fileHandle = HDF5_openFile(getSolverJobName()//'_restart.hdf5','r')
|
||||||
fileHandle = HDF5_openFile(fileName)
|
|
||||||
groupHandle = HDF5_openGroup(fileHandle,'solver')
|
groupHandle = HDF5_openGroup(fileHandle,'solver')
|
||||||
|
|
||||||
call HDF5_read(groupHandle,P_aim, 'P_aim')
|
call HDF5_read(groupHandle,P_aim, 'P_aim')
|
||||||
|
@ -222,13 +219,13 @@ subroutine grid_mech_spectral_basic_init
|
||||||
call utilities_updateGamma(C_minMaxAvg)
|
call utilities_updateGamma(C_minMaxAvg)
|
||||||
call utilities_saveReferenceStiffness
|
call utilities_saveReferenceStiffness
|
||||||
|
|
||||||
end subroutine grid_mech_spectral_basic_init
|
end subroutine grid_mechanical_spectral_basic_init
|
||||||
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @brief solution for the basic scheme with internal iterations
|
!> @brief solution for the basic scheme with internal iterations
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
function grid_mech_spectral_basic_solution(incInfoIn) result(solution)
|
function grid_mechanical_spectral_basic_solution(incInfoIn) result(solution)
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! input data for solution
|
! input data for solution
|
||||||
|
@ -262,14 +259,14 @@ function grid_mech_spectral_basic_solution(incInfoIn) result(solution)
|
||||||
terminallyIll = .false.
|
terminallyIll = .false.
|
||||||
P_aim = merge(P_aim,P_av,params%stress_mask)
|
P_aim = merge(P_aim,P_av,params%stress_mask)
|
||||||
|
|
||||||
end function grid_mech_spectral_basic_solution
|
end function grid_mechanical_spectral_basic_solution
|
||||||
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @brief forwarding routine
|
!> @brief forwarding routine
|
||||||
!> @details find new boundary conditions and best F estimate for end of current timestep
|
!> @details find new boundary conditions and best F estimate for end of current timestep
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
subroutine grid_mech_spectral_basic_forward(cutBack,guess,Delta_t,Delta_t_old,t_remaining,&
|
subroutine grid_mechanical_spectral_basic_forward(cutBack,guess,Delta_t,Delta_t_old,t_remaining,&
|
||||||
deformation_BC,stress_BC,rotation_BC)
|
deformation_BC,stress_BC,rotation_BC)
|
||||||
|
|
||||||
logical, intent(in) :: &
|
logical, intent(in) :: &
|
||||||
|
@ -339,13 +336,13 @@ subroutine grid_mech_spectral_basic_forward(cutBack,guess,Delta_t,Delta_t_old,t_
|
||||||
params%rotation_BC = rotation_BC
|
params%rotation_BC = rotation_BC
|
||||||
params%timeinc = Delta_t
|
params%timeinc = Delta_t
|
||||||
|
|
||||||
end subroutine grid_mech_spectral_basic_forward
|
end subroutine grid_mechanical_spectral_basic_forward
|
||||||
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @brief Update coordinates
|
!> @brief Update coordinates
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
subroutine grid_mech_spectral_basic_updateCoords
|
subroutine grid_mechanical_spectral_basic_updateCoords
|
||||||
|
|
||||||
PetscErrorCode :: ierr
|
PetscErrorCode :: ierr
|
||||||
PetscScalar, dimension(:,:,:,:), pointer :: F
|
PetscScalar, dimension(:,:,:,:), pointer :: F
|
||||||
|
@ -354,25 +351,23 @@ subroutine grid_mech_spectral_basic_updateCoords
|
||||||
call utilities_updateCoords(F)
|
call utilities_updateCoords(F)
|
||||||
call DMDAVecRestoreArrayF90(da,solution_vec,F,ierr); CHKERRQ(ierr)
|
call DMDAVecRestoreArrayF90(da,solution_vec,F,ierr); CHKERRQ(ierr)
|
||||||
|
|
||||||
end subroutine grid_mech_spectral_basic_updateCoords
|
end subroutine grid_mechanical_spectral_basic_updateCoords
|
||||||
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @brief Write current solver and constitutive data for restart to file
|
!> @brief Write current solver and constitutive data for restart to file
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
subroutine grid_mech_spectral_basic_restartWrite
|
subroutine grid_mechanical_spectral_basic_restartWrite
|
||||||
|
|
||||||
PetscErrorCode :: ierr
|
PetscErrorCode :: ierr
|
||||||
integer(HID_T) :: fileHandle, groupHandle
|
integer(HID_T) :: fileHandle, groupHandle
|
||||||
PetscScalar, dimension(:,:,:,:), pointer :: F
|
PetscScalar, dimension(:,:,:,:), pointer :: F
|
||||||
character(len=pStringLen) :: fileName
|
|
||||||
|
|
||||||
call DMDAVecGetArrayF90(da,solution_vec,F,ierr); CHKERRQ(ierr)
|
call DMDAVecGetArrayF90(da,solution_vec,F,ierr); CHKERRQ(ierr)
|
||||||
|
|
||||||
print*, 'writing solver data required for restart to file'; flush(IO_STDOUT)
|
print*, 'writing solver data required for restart to file'; flush(IO_STDOUT)
|
||||||
|
|
||||||
write(fileName,'(a,a,i0,a)') trim(getSolverJobName()),'_',worldrank,'.hdf5'
|
fileHandle = HDF5_openFile(getSolverJobName()//'_restart.hdf5','w')
|
||||||
fileHandle = HDF5_openFile(fileName,'w')
|
|
||||||
groupHandle = HDF5_addGroup(fileHandle,'solver')
|
groupHandle = HDF5_addGroup(fileHandle,'solver')
|
||||||
|
|
||||||
call HDF5_write(groupHandle,P_aim, 'P_aim')
|
call HDF5_write(groupHandle,P_aim, 'P_aim')
|
||||||
|
@ -393,7 +388,7 @@ subroutine grid_mech_spectral_basic_restartWrite
|
||||||
|
|
||||||
call DMDAVecRestoreArrayF90(da,solution_vec,F,ierr); CHKERRQ(ierr)
|
call DMDAVecRestoreArrayF90(da,solution_vec,F,ierr); CHKERRQ(ierr)
|
||||||
|
|
||||||
end subroutine grid_mech_spectral_basic_restartWrite
|
end subroutine grid_mechanical_spectral_basic_restartWrite
|
||||||
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
@ -506,4 +501,4 @@ subroutine formResidual(in, F, &
|
||||||
end subroutine formResidual
|
end subroutine formResidual
|
||||||
|
|
||||||
|
|
||||||
end module grid_mech_spectral_basic
|
end module grid_mechanical_spectral_basic
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
!> @author Philip Eisenlohr, Max-Planck-Institut für Eisenforschung GmbH
|
!> @author Philip Eisenlohr, Max-Planck-Institut für Eisenforschung GmbH
|
||||||
!> @brief Grid solver for mechanics: Spectral Polarisation
|
!> @brief Grid solver for mechanics: Spectral Polarisation
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
module grid_mech_spectral_polarisation
|
module grid_mechanical_spectral_polarisation
|
||||||
#include <petsc/finclude/petscsnes.h>
|
#include <petsc/finclude/petscsnes.h>
|
||||||
#include <petsc/finclude/petscdmda.h>
|
#include <petsc/finclude/petscdmda.h>
|
||||||
use PETScdmda
|
use PETScdmda
|
||||||
|
@ -90,18 +90,18 @@ module grid_mech_spectral_polarisation
|
||||||
totalIter = 0 !< total iteration in current increment
|
totalIter = 0 !< total iteration in current increment
|
||||||
|
|
||||||
public :: &
|
public :: &
|
||||||
grid_mech_spectral_polarisation_init, &
|
grid_mechanical_spectral_polarisation_init, &
|
||||||
grid_mech_spectral_polarisation_solution, &
|
grid_mechanical_spectral_polarisation_solution, &
|
||||||
grid_mech_spectral_polarisation_forward, &
|
grid_mechanical_spectral_polarisation_forward, &
|
||||||
grid_mech_spectral_polarisation_updateCoords, &
|
grid_mechanical_spectral_polarisation_updateCoords, &
|
||||||
grid_mech_spectral_polarisation_restartWrite
|
grid_mechanical_spectral_polarisation_restartWrite
|
||||||
|
|
||||||
contains
|
contains
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @brief allocates all necessary fields and fills them with data, potentially from restart info
|
!> @brief allocates all necessary fields and fills them with data, potentially from restart info
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
subroutine grid_mech_spectral_polarisation_init
|
subroutine grid_mechanical_spectral_polarisation_init
|
||||||
|
|
||||||
real(pReal), dimension(3,3,grid(1),grid(2),grid3) :: P
|
real(pReal), dimension(3,3,grid(1),grid(2),grid3) :: P
|
||||||
PetscErrorCode :: ierr
|
PetscErrorCode :: ierr
|
||||||
|
@ -112,13 +112,11 @@ subroutine grid_mech_spectral_polarisation_init
|
||||||
PetscInt, dimension(0:worldsize-1) :: localK
|
PetscInt, dimension(0:worldsize-1) :: localK
|
||||||
integer(HID_T) :: fileHandle, groupHandle
|
integer(HID_T) :: fileHandle, groupHandle
|
||||||
integer :: fileUnit
|
integer :: fileUnit
|
||||||
character(len=pStringLen) :: &
|
|
||||||
fileName
|
|
||||||
class (tNode), pointer :: &
|
class (tNode), pointer :: &
|
||||||
num_grid, &
|
num_grid, &
|
||||||
debug_grid
|
debug_grid
|
||||||
|
|
||||||
print'(/,a)', ' <<<+- grid_mech_spectral_polarisation init -+>>>'; flush(IO_STDOUT)
|
print'(/,a)', ' <<<+- grid_mechanical_spectral_polarization init -+>>>'; flush(IO_STDOUT)
|
||||||
|
|
||||||
print*, 'Shanthraj et al., International Journal of Plasticity 66:31–45, 2015'
|
print*, 'Shanthraj et al., International Journal of Plasticity 66:31–45, 2015'
|
||||||
print*, 'https://doi.org/10.1016/j.ijplas.2014.02.006'
|
print*, 'https://doi.org/10.1016/j.ijplas.2014.02.006'
|
||||||
|
@ -157,7 +155,7 @@ subroutine grid_mech_spectral_polarisation_init
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! set default and user defined options for PETSc
|
! set default and user defined options for PETSc
|
||||||
call PetscOptionsInsertString(PETSC_NULL_OPTIONS,'-mech_snes_type ngmres',ierr)
|
call PetscOptionsInsertString(PETSC_NULL_OPTIONS,'-mechanical_snes_type ngmres',ierr)
|
||||||
CHKERRQ(ierr)
|
CHKERRQ(ierr)
|
||||||
call PetscOptionsInsertString(PETSC_NULL_OPTIONS,num_grid%get_asString('petsc_options',defaultVal=''),ierr)
|
call PetscOptionsInsertString(PETSC_NULL_OPTIONS,num_grid%get_asString('petsc_options',defaultVal=''),ierr)
|
||||||
CHKERRQ(ierr)
|
CHKERRQ(ierr)
|
||||||
|
@ -172,7 +170,7 @@ subroutine grid_mech_spectral_polarisation_init
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! initialize solver specific parts of PETSc
|
! initialize solver specific parts of PETSc
|
||||||
call SNESCreate(PETSC_COMM_WORLD,snes,ierr); CHKERRQ(ierr)
|
call SNESCreate(PETSC_COMM_WORLD,snes,ierr); CHKERRQ(ierr)
|
||||||
call SNESSetOptionsPrefix(snes,'mech_',ierr);CHKERRQ(ierr)
|
call SNESSetOptionsPrefix(snes,'mechanical_',ierr);CHKERRQ(ierr)
|
||||||
localK = 0
|
localK = 0
|
||||||
localK(worldrank) = grid3
|
localK(worldrank) = grid3
|
||||||
call MPI_Allreduce(MPI_IN_PLACE,localK,worldsize,MPI_INTEGER,MPI_SUM,PETSC_COMM_WORLD,ierr)
|
call MPI_Allreduce(MPI_IN_PLACE,localK,worldsize,MPI_INTEGER,MPI_SUM,PETSC_COMM_WORLD,ierr)
|
||||||
|
@ -204,8 +202,7 @@ subroutine grid_mech_spectral_polarisation_init
|
||||||
restartRead: if (interface_restartInc > 0) then
|
restartRead: if (interface_restartInc > 0) then
|
||||||
print'(/,a,i0,a)', ' reading restart data of increment ', interface_restartInc, ' from file'
|
print'(/,a,i0,a)', ' reading restart data of increment ', interface_restartInc, ' from file'
|
||||||
|
|
||||||
write(fileName,'(a,a,i0,a)') trim(getSolverJobName()),'_',worldrank,'.hdf5'
|
fileHandle = HDF5_openFile(getSolverJobName()//'_restart.hdf5','r')
|
||||||
fileHandle = HDF5_openFile(fileName)
|
|
||||||
groupHandle = HDF5_openGroup(fileHandle,'solver')
|
groupHandle = HDF5_openGroup(fileHandle,'solver')
|
||||||
|
|
||||||
call HDF5_read(groupHandle,P_aim, 'P_aim')
|
call HDF5_read(groupHandle,P_aim, 'P_aim')
|
||||||
|
@ -250,13 +247,13 @@ subroutine grid_mech_spectral_polarisation_init
|
||||||
C_scale = C_minMaxAvg
|
C_scale = C_minMaxAvg
|
||||||
S_scale = math_invSym3333(C_minMaxAvg)
|
S_scale = math_invSym3333(C_minMaxAvg)
|
||||||
|
|
||||||
end subroutine grid_mech_spectral_polarisation_init
|
end subroutine grid_mechanical_spectral_polarisation_init
|
||||||
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @brief solution for the Polarisation scheme with internal iterations
|
!> @brief solution for the Polarisation scheme with internal iterations
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
function grid_mech_spectral_polarisation_solution(incInfoIn) result(solution)
|
function grid_mechanical_spectral_polarisation_solution(incInfoIn) result(solution)
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! input data for solution
|
! input data for solution
|
||||||
|
@ -294,14 +291,14 @@ function grid_mech_spectral_polarisation_solution(incInfoIn) result(solution)
|
||||||
terminallyIll = .false.
|
terminallyIll = .false.
|
||||||
P_aim = merge(P_aim,P_av,params%stress_mask)
|
P_aim = merge(P_aim,P_av,params%stress_mask)
|
||||||
|
|
||||||
end function grid_mech_spectral_polarisation_solution
|
end function grid_mechanical_spectral_polarisation_solution
|
||||||
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @brief forwarding routine
|
!> @brief forwarding routine
|
||||||
!> @details find new boundary conditions and best F estimate for end of current timestep
|
!> @details find new boundary conditions and best F estimate for end of current timestep
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
subroutine grid_mech_spectral_polarisation_forward(cutBack,guess,Delta_t,Delta_t_old,t_remaining,&
|
subroutine grid_mechanical_spectral_polarisation_forward(cutBack,guess,Delta_t,Delta_t_old,t_remaining,&
|
||||||
deformation_BC,stress_BC,rotation_BC)
|
deformation_BC,stress_BC,rotation_BC)
|
||||||
|
|
||||||
logical, intent(in) :: &
|
logical, intent(in) :: &
|
||||||
|
@ -393,13 +390,13 @@ subroutine grid_mech_spectral_polarisation_forward(cutBack,guess,Delta_t,Delta_t
|
||||||
params%rotation_BC = rotation_BC
|
params%rotation_BC = rotation_BC
|
||||||
params%timeinc = Delta_t
|
params%timeinc = Delta_t
|
||||||
|
|
||||||
end subroutine grid_mech_spectral_polarisation_forward
|
end subroutine grid_mechanical_spectral_polarisation_forward
|
||||||
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @brief Update coordinates
|
!> @brief Update coordinates
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
subroutine grid_mech_spectral_polarisation_updateCoords
|
subroutine grid_mechanical_spectral_polarisation_updateCoords
|
||||||
|
|
||||||
PetscErrorCode :: ierr
|
PetscErrorCode :: ierr
|
||||||
PetscScalar, dimension(:,:,:,:), pointer :: FandF_tau
|
PetscScalar, dimension(:,:,:,:), pointer :: FandF_tau
|
||||||
|
@ -408,18 +405,17 @@ subroutine grid_mech_spectral_polarisation_updateCoords
|
||||||
call utilities_updateCoords(FandF_tau(0:8,:,:,:))
|
call utilities_updateCoords(FandF_tau(0:8,:,:,:))
|
||||||
call DMDAVecRestoreArrayF90(da,solution_vec,FandF_tau,ierr); CHKERRQ(ierr)
|
call DMDAVecRestoreArrayF90(da,solution_vec,FandF_tau,ierr); CHKERRQ(ierr)
|
||||||
|
|
||||||
end subroutine grid_mech_spectral_polarisation_updateCoords
|
end subroutine grid_mechanical_spectral_polarisation_updateCoords
|
||||||
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @brief Write current solver and constitutive data for restart to file
|
!> @brief Write current solver and constitutive data for restart to file
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
subroutine grid_mech_spectral_polarisation_restartWrite
|
subroutine grid_mechanical_spectral_polarisation_restartWrite
|
||||||
|
|
||||||
PetscErrorCode :: ierr
|
PetscErrorCode :: ierr
|
||||||
integer(HID_T) :: fileHandle, groupHandle
|
integer(HID_T) :: fileHandle, groupHandle
|
||||||
PetscScalar, dimension(:,:,:,:), pointer :: FandF_tau, F, F_tau
|
PetscScalar, dimension(:,:,:,:), pointer :: FandF_tau, F, F_tau
|
||||||
character(len=pStringLen) :: fileName
|
|
||||||
|
|
||||||
call DMDAVecGetArrayF90(da,solution_vec,FandF_tau,ierr); CHKERRQ(ierr)
|
call DMDAVecGetArrayF90(da,solution_vec,FandF_tau,ierr); CHKERRQ(ierr)
|
||||||
F => FandF_tau(0: 8,:,:,:)
|
F => FandF_tau(0: 8,:,:,:)
|
||||||
|
@ -427,8 +423,7 @@ subroutine grid_mech_spectral_polarisation_restartWrite
|
||||||
|
|
||||||
print*, 'writing solver data required for restart to file'; flush(IO_STDOUT)
|
print*, 'writing solver data required for restart to file'; flush(IO_STDOUT)
|
||||||
|
|
||||||
write(fileName,'(a,a,i0,a)') trim(getSolverJobName()),'_',worldrank,'.hdf5'
|
fileHandle = HDF5_openFile(getSolverJobName()//'_restart.hdf5','w')
|
||||||
fileHandle = HDF5_openFile(fileName,'w')
|
|
||||||
groupHandle = HDF5_addGroup(fileHandle,'solver')
|
groupHandle = HDF5_addGroup(fileHandle,'solver')
|
||||||
|
|
||||||
call HDF5_write(groupHandle,F_aim, 'P_aim')
|
call HDF5_write(groupHandle,F_aim, 'P_aim')
|
||||||
|
@ -450,7 +445,7 @@ subroutine grid_mech_spectral_polarisation_restartWrite
|
||||||
|
|
||||||
call DMDAVecRestoreArrayF90(da,solution_vec,FandF_tau,ierr); CHKERRQ(ierr)
|
call DMDAVecRestoreArrayF90(da,solution_vec,FandF_tau,ierr); CHKERRQ(ierr)
|
||||||
|
|
||||||
end subroutine grid_mech_spectral_polarisation_restartWrite
|
end subroutine grid_mechanical_spectral_polarisation_restartWrite
|
||||||
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
@ -618,4 +613,4 @@ subroutine formResidual(in, FandF_tau, &
|
||||||
|
|
||||||
end subroutine formResidual
|
end subroutine formResidual
|
||||||
|
|
||||||
end module grid_mech_spectral_polarisation
|
end module grid_mechanical_spectral_polarisation
|
||||||
|
|
|
@ -15,7 +15,7 @@ module grid_thermal_spectral
|
||||||
use IO
|
use IO
|
||||||
use spectral_utilities
|
use spectral_utilities
|
||||||
use discretization_grid
|
use discretization_grid
|
||||||
use thermal_conduction
|
use homogenization
|
||||||
use YAML_types
|
use YAML_types
|
||||||
use config
|
use config
|
||||||
use material
|
use material
|
||||||
|
@ -61,10 +61,12 @@ contains
|
||||||
!> @brief allocates all neccessary fields and fills them with data
|
!> @brief allocates all neccessary fields and fills them with data
|
||||||
! ToDo: Restart not implemented
|
! ToDo: Restart not implemented
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
subroutine grid_thermal_spectral_init
|
subroutine grid_thermal_spectral_init(T_0)
|
||||||
|
|
||||||
|
real(pReal), intent(in) :: T_0
|
||||||
|
|
||||||
PetscInt, dimension(0:worldsize-1) :: localK
|
PetscInt, dimension(0:worldsize-1) :: localK
|
||||||
integer :: i, j, k, cell
|
integer :: i, j, k, ce
|
||||||
DM :: thermal_grid
|
DM :: thermal_grid
|
||||||
PetscScalar, dimension(:,:,:), pointer :: x_scal
|
PetscScalar, dimension(:,:,:), pointer :: x_scal
|
||||||
PetscErrorCode :: ierr
|
PetscErrorCode :: ierr
|
||||||
|
@ -128,12 +130,13 @@ subroutine grid_thermal_spectral_init
|
||||||
allocate(T_current(grid(1),grid(2),grid3), source=0.0_pReal)
|
allocate(T_current(grid(1),grid(2),grid3), source=0.0_pReal)
|
||||||
allocate(T_lastInc(grid(1),grid(2),grid3), source=0.0_pReal)
|
allocate(T_lastInc(grid(1),grid(2),grid3), source=0.0_pReal)
|
||||||
allocate(T_stagInc(grid(1),grid(2),grid3), source=0.0_pReal)
|
allocate(T_stagInc(grid(1),grid(2),grid3), source=0.0_pReal)
|
||||||
cell = 0
|
ce = 0
|
||||||
do k = 1, grid3; do j = 1, grid(2); do i = 1,grid(1)
|
do k = 1, grid3; do j = 1, grid(2); do i = 1,grid(1)
|
||||||
cell = cell + 1
|
ce = ce + 1
|
||||||
T_current(i,j,k) = temperature(material_homogenizationAt(cell))%p(material_homogenizationMemberAt(1,cell))
|
T_current(i,j,k) = T_0
|
||||||
T_lastInc(i,j,k) = T_current(i,j,k)
|
T_lastInc(i,j,k) = T_current(i,j,k)
|
||||||
T_stagInc(i,j,k) = T_current(i,j,k)
|
T_stagInc(i,j,k) = T_current(i,j,k)
|
||||||
|
call homogenization_thermal_setField(T_0,0.0_pReal,ce)
|
||||||
enddo; enddo; enddo
|
enddo; enddo; enddo
|
||||||
call DMDAVecGetArrayF90(thermal_grid,solution_vec,x_scal,ierr); CHKERRQ(ierr) !< get the data out of PETSc to work with
|
call DMDAVecGetArrayF90(thermal_grid,solution_vec,x_scal,ierr); CHKERRQ(ierr) !< get the data out of PETSc to work with
|
||||||
x_scal(xstart:xend,ystart:yend,zstart:zend) = T_current
|
x_scal(xstart:xend,ystart:yend,zstart:zend) = T_current
|
||||||
|
@ -151,7 +154,7 @@ function grid_thermal_spectral_solution(timeinc) result(solution)
|
||||||
|
|
||||||
real(pReal), intent(in) :: &
|
real(pReal), intent(in) :: &
|
||||||
timeinc !< increment in time for current solution
|
timeinc !< increment in time for current solution
|
||||||
integer :: i, j, k, cell
|
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, solnNorm
|
||||||
|
@ -184,12 +187,12 @@ function grid_thermal_spectral_solution(timeinc) result(solution)
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! updating thermal state
|
! updating thermal state
|
||||||
cell = 0
|
ce = 0
|
||||||
do k = 1, grid3; do j = 1, grid(2); do i = 1,grid(1)
|
do k = 1, grid3; do j = 1, grid(2); do i = 1,grid(1)
|
||||||
cell = cell + 1
|
ce = ce + 1
|
||||||
call thermal_conduction_putTemperatureAndItsRate(T_current(i,j,k), &
|
call homogenization_thermal_setField(T_current(i,j,k), &
|
||||||
(T_current(i,j,k)-T_lastInc(i,j,k))/params%timeinc, &
|
(T_current(i,j,k)-T_lastInc(i,j,k))/params%timeinc, &
|
||||||
1,cell)
|
ce)
|
||||||
enddo; enddo; enddo
|
enddo; enddo; enddo
|
||||||
|
|
||||||
call VecMin(solution_vec,devNull,T_min,ierr); CHKERRQ(ierr)
|
call VecMin(solution_vec,devNull,T_min,ierr); CHKERRQ(ierr)
|
||||||
|
@ -209,7 +212,7 @@ end function grid_thermal_spectral_solution
|
||||||
subroutine grid_thermal_spectral_forward(cutBack)
|
subroutine grid_thermal_spectral_forward(cutBack)
|
||||||
|
|
||||||
logical, intent(in) :: cutBack
|
logical, intent(in) :: cutBack
|
||||||
integer :: i, j, k, cell
|
integer :: i, j, k, ce
|
||||||
DM :: dm_local
|
DM :: dm_local
|
||||||
PetscScalar, dimension(:,:,:), pointer :: x_scal
|
PetscScalar, dimension(:,:,:), pointer :: x_scal
|
||||||
PetscErrorCode :: ierr
|
PetscErrorCode :: ierr
|
||||||
|
@ -220,17 +223,16 @@ subroutine grid_thermal_spectral_forward(cutBack)
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! reverting thermal field state
|
! reverting thermal field state
|
||||||
cell = 0
|
ce = 0
|
||||||
call SNESGetDM(thermal_snes,dm_local,ierr); CHKERRQ(ierr)
|
call SNESGetDM(thermal_snes,dm_local,ierr); CHKERRQ(ierr)
|
||||||
call DMDAVecGetArrayF90(dm_local,solution_vec,x_scal,ierr); CHKERRQ(ierr) !< get the data out of PETSc to work with
|
call DMDAVecGetArrayF90(dm_local,solution_vec,x_scal,ierr); CHKERRQ(ierr) !< get the data out of PETSc to work with
|
||||||
x_scal(xstart:xend,ystart:yend,zstart:zend) = T_current
|
x_scal(xstart:xend,ystart:yend,zstart:zend) = T_current
|
||||||
call DMDAVecRestoreArrayF90(dm_local,solution_vec,x_scal,ierr); CHKERRQ(ierr)
|
call DMDAVecRestoreArrayF90(dm_local,solution_vec,x_scal,ierr); CHKERRQ(ierr)
|
||||||
do k = 1, grid3; do j = 1, grid(2); do i = 1,grid(1)
|
do k = 1, grid3; do j = 1, grid(2); do i = 1,grid(1)
|
||||||
cell = cell + 1
|
ce = ce + 1
|
||||||
call thermal_conduction_putTemperatureAndItsRate(T_current(i,j,k), &
|
call homogenization_thermal_setField(T_current(i,j,k), &
|
||||||
(T_current(i,j,k) - &
|
(T_current(i,j,k)-T_lastInc(i,j,k))/params%timeinc, &
|
||||||
T_lastInc(i,j,k))/params%timeinc, &
|
ce)
|
||||||
1,cell)
|
|
||||||
enddo; enddo; enddo
|
enddo; enddo; enddo
|
||||||
else
|
else
|
||||||
T_lastInc = T_current
|
T_lastInc = T_current
|
||||||
|
@ -255,8 +257,8 @@ subroutine formResidual(in,x_scal,f_scal,dummy,ierr)
|
||||||
f_scal
|
f_scal
|
||||||
PetscObject :: dummy
|
PetscObject :: dummy
|
||||||
PetscErrorCode :: ierr
|
PetscErrorCode :: ierr
|
||||||
integer :: i, j, k, cell
|
integer :: i, j, k, ce
|
||||||
real(pReal) :: Tdot, dTdot_dT
|
real(pReal) :: Tdot
|
||||||
|
|
||||||
T_current = x_scal
|
T_current = x_scal
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
@ -266,22 +268,22 @@ subroutine formResidual(in,x_scal,f_scal,dummy,ierr)
|
||||||
call utilities_FFTscalarForward
|
call utilities_FFTscalarForward
|
||||||
call utilities_fourierScalarGradient !< calculate gradient of temperature field
|
call utilities_fourierScalarGradient !< calculate gradient of temperature field
|
||||||
call utilities_FFTvectorBackward
|
call utilities_FFTvectorBackward
|
||||||
cell = 0
|
ce = 0
|
||||||
do k = 1, grid3; do j = 1, grid(2); do i = 1,grid(1)
|
do k = 1, grid3; do j = 1, grid(2); do i = 1,grid(1)
|
||||||
cell = cell + 1
|
ce = ce + 1
|
||||||
vectorField_real(1:3,i,j,k) = matmul(thermal_conduction_getConductivity(1,cell) - K_ref, &
|
vectorField_real(1:3,i,j,k) = matmul(thermal_conduction_getConductivity(ce) - K_ref, &
|
||||||
vectorField_real(1:3,i,j,k))
|
vectorField_real(1:3,i,j,k))
|
||||||
enddo; enddo; enddo
|
enddo; enddo; enddo
|
||||||
call utilities_FFTvectorForward
|
call utilities_FFTvectorForward
|
||||||
call utilities_fourierVectorDivergence !< calculate temperature divergence in fourier field
|
call utilities_fourierVectorDivergence !< calculate temperature divergence in fourier field
|
||||||
call utilities_FFTscalarBackward
|
call utilities_FFTscalarBackward
|
||||||
cell = 0
|
ce = 0
|
||||||
do k = 1, grid3; do j = 1, grid(2); do i = 1,grid(1)
|
do k = 1, grid3; do j = 1, grid(2); do i = 1,grid(1)
|
||||||
cell = cell + 1
|
ce = ce + 1
|
||||||
call thermal_conduction_getSourceAndItsTangent(Tdot, dTdot_dT, T_current(i,j,k), 1, cell)
|
call thermal_conduction_getSource(Tdot,1,ce)
|
||||||
scalarField_real(i,j,k) = params%timeinc*(scalarField_real(i,j,k) + Tdot) &
|
scalarField_real(i,j,k) = params%timeinc*(scalarField_real(i,j,k) + Tdot) &
|
||||||
+ thermal_conduction_getMassDensity (1,cell)* &
|
+ thermal_conduction_getMassDensity (ce)* &
|
||||||
thermal_conduction_getSpecificHeat(1,cell)*(T_lastInc(i,j,k) - &
|
thermal_conduction_getSpecificHeat(ce)*(T_lastInc(i,j,k) - &
|
||||||
T_current(i,j,k))&
|
T_current(i,j,k))&
|
||||||
+ mu_ref*T_current(i,j,k)
|
+ mu_ref*T_current(i,j,k)
|
||||||
enddo; enddo; enddo
|
enddo; enddo; enddo
|
||||||
|
@ -304,15 +306,15 @@ end subroutine formResidual
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
subroutine updateReference
|
subroutine updateReference
|
||||||
|
|
||||||
integer :: i,j,k,cell,ierr
|
integer :: i,j,k,ce,ierr
|
||||||
|
|
||||||
cell = 0
|
ce = 0
|
||||||
K_ref = 0.0_pReal
|
K_ref = 0.0_pReal
|
||||||
mu_ref = 0.0_pReal
|
mu_ref = 0.0_pReal
|
||||||
do k = 1, grid3; do j = 1, grid(2); do i = 1,grid(1)
|
do k = 1, grid3; do j = 1, grid(2); do i = 1,grid(1)
|
||||||
cell = cell + 1
|
ce = ce + 1
|
||||||
K_ref = K_ref + thermal_conduction_getConductivity(1,cell)
|
K_ref = K_ref + thermal_conduction_getConductivity(ce)
|
||||||
mu_ref = mu_ref + thermal_conduction_getMassDensity(1,cell)* thermal_conduction_getSpecificHeat(1,cell)
|
mu_ref = mu_ref + thermal_conduction_getMassDensity(ce)* thermal_conduction_getSpecificHeat(ce)
|
||||||
enddo; enddo; enddo
|
enddo; enddo; enddo
|
||||||
K_ref = K_ref*wgt
|
K_ref = K_ref*wgt
|
||||||
call MPI_Allreduce(MPI_IN_PLACE,K_ref,9,MPI_DOUBLE,MPI_SUM,PETSC_COMM_WORLD,ierr)
|
call MPI_Allreduce(MPI_IN_PLACE,K_ref,9,MPI_DOUBLE,MPI_SUM,PETSC_COMM_WORLD,ierr)
|
||||||
|
|
|
@ -10,17 +10,47 @@ module homogenization
|
||||||
use config
|
use config
|
||||||
use math
|
use math
|
||||||
use material
|
use material
|
||||||
use constitutive
|
use phase
|
||||||
use discretization
|
use discretization
|
||||||
use thermal_isothermal
|
use HDF5_utilities
|
||||||
use thermal_conduction
|
|
||||||
use damage_none
|
|
||||||
use damage_nonlocal
|
|
||||||
use results
|
use results
|
||||||
|
use lattice
|
||||||
|
|
||||||
implicit none
|
implicit none
|
||||||
private
|
private
|
||||||
|
|
||||||
|
|
||||||
|
enum, bind(c); enumerator :: &
|
||||||
|
THERMAL_ISOTHERMAL_ID, &
|
||||||
|
THERMAL_CONDUCTION_ID, &
|
||||||
|
DAMAGE_NONE_ID, &
|
||||||
|
DAMAGE_NONLOCAL_ID, &
|
||||||
|
HOMOGENIZATION_UNDEFINED_ID, &
|
||||||
|
HOMOGENIZATION_NONE_ID, &
|
||||||
|
HOMOGENIZATION_ISOSTRAIN_ID, &
|
||||||
|
HOMOGENIZATION_RGC_ID
|
||||||
|
end enum
|
||||||
|
|
||||||
|
type(tState), allocatable, dimension(:), public :: &
|
||||||
|
homogState, &
|
||||||
|
damageState_h
|
||||||
|
|
||||||
|
integer(kind(THERMAL_isothermal_ID)), dimension(:), allocatable :: &
|
||||||
|
thermal_type !< thermal transport model
|
||||||
|
integer(kind(DAMAGE_none_ID)), dimension(:), allocatable :: &
|
||||||
|
damage_type !< nonlocal damage model
|
||||||
|
integer(kind(HOMOGENIZATION_undefined_ID)), dimension(:), allocatable :: &
|
||||||
|
homogenization_type !< type of each homogenization
|
||||||
|
|
||||||
|
type, private :: tNumerics_damage
|
||||||
|
real(pReal) :: &
|
||||||
|
charLength !< characteristic length scale for gradient problems
|
||||||
|
end type tNumerics_damage
|
||||||
|
|
||||||
|
type(tNumerics_damage), private :: &
|
||||||
|
num_damage
|
||||||
|
|
||||||
|
|
||||||
logical, public :: &
|
logical, public :: &
|
||||||
terminallyIll = .false. !< at least one material point is terminally ill
|
terminallyIll = .false. !< at least one material point is terminally ill
|
||||||
|
|
||||||
|
@ -39,10 +69,6 @@ module homogenization
|
||||||
type :: tNumerics
|
type :: tNumerics
|
||||||
integer :: &
|
integer :: &
|
||||||
nMPstate !< materialpoint state loop limit
|
nMPstate !< materialpoint state loop limit
|
||||||
real(pReal) :: &
|
|
||||||
subStepMinHomog, & !< minimum (relative) size of sub-step allowed during cutback in homogenization
|
|
||||||
subStepSizeHomog, & !< size of first substep when cutback in homogenization
|
|
||||||
stepIncreaseHomog !< increase of next substep size when previous substep converged in homogenization
|
|
||||||
end type tNumerics
|
end type tNumerics
|
||||||
|
|
||||||
type(tNumerics) :: num
|
type(tNumerics) :: num
|
||||||
|
@ -50,48 +76,143 @@ module homogenization
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
interface
|
interface
|
||||||
|
|
||||||
module subroutine mech_init(num_homog)
|
module subroutine mechanical_init(num_homog)
|
||||||
class(tNode), pointer, intent(in) :: &
|
class(tNode), pointer, intent(in) :: &
|
||||||
num_homog !< pointer to mechanical homogenization numerics data
|
num_homog !< pointer to mechanical homogenization numerics data
|
||||||
end subroutine mech_init
|
end subroutine mechanical_init
|
||||||
|
|
||||||
module subroutine mech_partition(subF,ip,el)
|
module subroutine thermal_init
|
||||||
|
end subroutine thermal_init
|
||||||
|
|
||||||
|
module subroutine damage_init
|
||||||
|
end subroutine damage_init
|
||||||
|
|
||||||
|
module subroutine mechanical_partition(subF,ce)
|
||||||
real(pReal), intent(in), dimension(3,3) :: &
|
real(pReal), intent(in), dimension(3,3) :: &
|
||||||
subF
|
subF
|
||||||
integer, intent(in) :: &
|
integer, intent(in) :: &
|
||||||
ip, & !< integration point
|
ce
|
||||||
el !< element number
|
end subroutine mechanical_partition
|
||||||
end subroutine mech_partition
|
|
||||||
|
|
||||||
module subroutine mech_homogenize(ip,el)
|
module subroutine thermal_partition(ce)
|
||||||
|
integer, intent(in) :: ce
|
||||||
|
end subroutine thermal_partition
|
||||||
|
|
||||||
|
module subroutine damage_partition(ce)
|
||||||
|
integer, intent(in) :: ce
|
||||||
|
end subroutine damage_partition
|
||||||
|
|
||||||
|
module subroutine thermal_homogenize(ip,el)
|
||||||
|
integer, intent(in) :: ip,el
|
||||||
|
end subroutine thermal_homogenize
|
||||||
|
|
||||||
|
module subroutine mechanical_homogenize(dt,ce)
|
||||||
|
real(pReal), intent(in) :: dt
|
||||||
integer, intent(in) :: &
|
integer, intent(in) :: &
|
||||||
ip, & !< integration point
|
ce !< cell
|
||||||
el !< element number
|
end subroutine mechanical_homogenize
|
||||||
end subroutine mech_homogenize
|
|
||||||
|
|
||||||
module subroutine mech_results(group_base,h)
|
module subroutine mechanical_results(group_base,ho)
|
||||||
character(len=*), intent(in) :: group_base
|
character(len=*), intent(in) :: group_base
|
||||||
integer, intent(in) :: h
|
integer, intent(in) :: ho
|
||||||
end subroutine mech_results
|
end subroutine mechanical_results
|
||||||
|
|
||||||
module function mech_updateState(subdt,subF,ip,el) result(doneAndHappy)
|
module function mechanical_updateState(subdt,subF,ce) result(doneAndHappy)
|
||||||
real(pReal), intent(in) :: &
|
real(pReal), intent(in) :: &
|
||||||
subdt !< current time step
|
subdt !< current time step
|
||||||
real(pReal), intent(in), dimension(3,3) :: &
|
real(pReal), intent(in), dimension(3,3) :: &
|
||||||
subF
|
subF
|
||||||
integer, intent(in) :: &
|
integer, intent(in) :: &
|
||||||
ip, & !< integration point
|
ce !< cell
|
||||||
el !< element number
|
|
||||||
logical, dimension(2) :: doneAndHappy
|
logical, dimension(2) :: doneAndHappy
|
||||||
end function mech_updateState
|
end function mechanical_updateState
|
||||||
|
|
||||||
|
|
||||||
|
module function thermal_conduction_getConductivity(ce) result(K)
|
||||||
|
integer, intent(in) :: ce
|
||||||
|
real(pReal), dimension(3,3) :: K
|
||||||
|
end function thermal_conduction_getConductivity
|
||||||
|
|
||||||
|
module function thermal_conduction_getSpecificHeat(ce) result(c_P)
|
||||||
|
integer, intent(in) :: ce
|
||||||
|
real(pReal) :: c_P
|
||||||
|
end function thermal_conduction_getSpecificHeat
|
||||||
|
|
||||||
|
module function thermal_conduction_getMassDensity(ce) result(rho)
|
||||||
|
integer, intent(in) :: ce
|
||||||
|
real(pReal) :: rho
|
||||||
|
end function thermal_conduction_getMassDensity
|
||||||
|
|
||||||
|
module subroutine homogenization_thermal_setField(T,dot_T, ce)
|
||||||
|
integer, intent(in) :: ce
|
||||||
|
real(pReal), intent(in) :: T, dot_T
|
||||||
|
end subroutine homogenization_thermal_setField
|
||||||
|
|
||||||
|
module subroutine thermal_conduction_results(ho,group)
|
||||||
|
integer, intent(in) :: ho
|
||||||
|
character(len=*), intent(in) :: group
|
||||||
|
end subroutine thermal_conduction_results
|
||||||
|
|
||||||
|
module function homogenization_thermal_T(ce) result(T)
|
||||||
|
integer, intent(in) :: ce
|
||||||
|
real(pReal) :: T
|
||||||
|
end function homogenization_thermal_T
|
||||||
|
|
||||||
|
module subroutine thermal_conduction_getSource(Tdot, ip, el)
|
||||||
|
integer, intent(in) :: &
|
||||||
|
ip, &
|
||||||
|
el
|
||||||
|
real(pReal), intent(out) :: Tdot
|
||||||
|
end subroutine thermal_conduction_getSource
|
||||||
|
|
||||||
|
module function damage_nonlocal_getMobility(ce) result(M)
|
||||||
|
integer, intent(in) :: ce
|
||||||
|
real(pReal) :: M
|
||||||
|
end function damage_nonlocal_getMobility
|
||||||
|
|
||||||
|
module subroutine damage_nonlocal_getSourceAndItsTangent(phiDot, dPhiDot_dPhi, phi, ce)
|
||||||
|
integer, intent(in) :: ce
|
||||||
|
real(pReal), intent(in) :: &
|
||||||
|
phi
|
||||||
|
real(pReal) :: &
|
||||||
|
phiDot, dPhiDot_dPhi
|
||||||
|
end subroutine damage_nonlocal_getSourceAndItsTangent
|
||||||
|
|
||||||
|
module subroutine damage_nonlocal_putNonLocalDamage(phi,ce)
|
||||||
|
integer, intent(in) :: ce
|
||||||
|
real(pReal), intent(in) :: &
|
||||||
|
phi
|
||||||
|
end subroutine damage_nonlocal_putNonLocalDamage
|
||||||
|
|
||||||
|
module subroutine damage_nonlocal_results(ho,group)
|
||||||
|
integer, intent(in) :: ho
|
||||||
|
character(len=*), intent(in) :: group
|
||||||
|
end subroutine damage_nonlocal_results
|
||||||
|
|
||||||
end interface
|
end interface
|
||||||
|
|
||||||
public :: &
|
public :: &
|
||||||
homogenization_init, &
|
homogenization_init, &
|
||||||
materialpoint_stressAndItsTangent, &
|
materialpoint_stressAndItsTangent, &
|
||||||
|
thermal_conduction_getSpecificHeat, &
|
||||||
|
thermal_conduction_getConductivity, &
|
||||||
|
thermal_conduction_getMassDensity, &
|
||||||
|
thermal_conduction_getSource, &
|
||||||
|
damage_nonlocal_getMobility, &
|
||||||
|
damage_nonlocal_getSourceAndItsTangent, &
|
||||||
|
damage_nonlocal_putNonLocalDamage, &
|
||||||
|
homogenization_thermal_setfield, &
|
||||||
|
homogenization_thermal_T, &
|
||||||
homogenization_forward, &
|
homogenization_forward, &
|
||||||
homogenization_results
|
homogenization_results, &
|
||||||
|
homogenization_restartRead, &
|
||||||
|
homogenization_restartWrite, &
|
||||||
|
THERMAL_CONDUCTION_ID, &
|
||||||
|
DAMAGE_NONLOCAL_ID
|
||||||
|
|
||||||
|
public :: &
|
||||||
|
damage_nonlocal_init, &
|
||||||
|
damage_nonlocal_getDiffusion
|
||||||
|
|
||||||
contains
|
contains
|
||||||
|
|
||||||
|
@ -99,7 +220,7 @@ contains
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @brief module initialization
|
!> @brief module initialization
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
subroutine homogenization_init
|
subroutine homogenization_init()
|
||||||
|
|
||||||
class (tNode) , pointer :: &
|
class (tNode) , pointer :: &
|
||||||
num_homog, &
|
num_homog, &
|
||||||
|
@ -107,27 +228,21 @@ subroutine homogenization_init
|
||||||
|
|
||||||
print'(/,a)', ' <<<+- homogenization init -+>>>'; flush(IO_STDOUT)
|
print'(/,a)', ' <<<+- homogenization init -+>>>'; flush(IO_STDOUT)
|
||||||
|
|
||||||
|
|
||||||
|
allocate(homogState (size(material_name_homogenization)))
|
||||||
|
allocate(damageState_h (size(material_name_homogenization)))
|
||||||
|
call material_parseHomogenization()
|
||||||
|
|
||||||
num_homog => config_numerics%get('homogenization',defaultVal=emptyDict)
|
num_homog => config_numerics%get('homogenization',defaultVal=emptyDict)
|
||||||
num_homogGeneric => num_homog%get('generic',defaultVal=emptyDict)
|
num_homogGeneric => num_homog%get('generic',defaultVal=emptyDict)
|
||||||
|
|
||||||
num%nMPstate = num_homogGeneric%get_asInt('nMPstate',defaultVal=10)
|
num%nMPstate = num_homogGeneric%get_asInt('nMPstate',defaultVal=10)
|
||||||
num%subStepMinHomog = num_homogGeneric%get_asFloat('subStepMin', defaultVal=1.0e-3_pReal)
|
|
||||||
num%subStepSizeHomog = num_homogGeneric%get_asFloat('subStepSize', defaultVal=0.25_pReal)
|
|
||||||
num%stepIncreaseHomog = num_homogGeneric%get_asFloat('stepIncrease', defaultVal=1.5_pReal)
|
|
||||||
|
|
||||||
if (num%nMPstate < 1) call IO_error(301,ext_msg='nMPstate')
|
if (num%nMPstate < 1) call IO_error(301,ext_msg='nMPstate')
|
||||||
if (num%subStepMinHomog <= 0.0_pReal) call IO_error(301,ext_msg='subStepMinHomog')
|
|
||||||
if (num%subStepSizeHomog <= 0.0_pReal) call IO_error(301,ext_msg='subStepSizeHomog')
|
|
||||||
if (num%stepIncreaseHomog <= 0.0_pReal) call IO_error(301,ext_msg='stepIncreaseHomog')
|
|
||||||
|
|
||||||
|
call mechanical_init(num_homog)
|
||||||
call mech_init(num_homog)
|
call thermal_init()
|
||||||
|
call damage_init()
|
||||||
if (any(thermal_type == THERMAL_isothermal_ID)) call thermal_isothermal_init
|
call damage_nonlocal_init()
|
||||||
if (any(thermal_type == THERMAL_conduction_ID)) call thermal_conduction_init
|
|
||||||
|
|
||||||
if (any(damage_type == DAMAGE_none_ID)) call damage_none_init
|
|
||||||
if (any(damage_type == DAMAGE_nonlocal_ID)) call damage_nonlocal_init
|
|
||||||
|
|
||||||
|
|
||||||
end subroutine homogenization_init
|
end subroutine homogenization_init
|
||||||
|
@ -144,126 +259,96 @@ subroutine materialpoint_stressAndItsTangent(dt,FEsolving_execIP,FEsolving_execE
|
||||||
NiterationMPstate, &
|
NiterationMPstate, &
|
||||||
ip, & !< integration point number
|
ip, & !< integration point number
|
||||||
el, & !< element number
|
el, & !< element number
|
||||||
myNgrains, co, ce, ho, me
|
myNgrains, co, ce, ho, me, ph
|
||||||
real(pReal) :: &
|
|
||||||
subFrac, &
|
|
||||||
subStep
|
|
||||||
logical :: &
|
logical :: &
|
||||||
converged
|
converged
|
||||||
logical, dimension(2) :: &
|
logical, dimension(2) :: &
|
||||||
doneAndHappy
|
doneAndHappy
|
||||||
|
|
||||||
|
!$OMP PARALLEL
|
||||||
!$OMP PARALLEL DO PRIVATE(ce,me,ho,myNgrains,NiterationMPstate,subFrac,converged,subStep,doneAndHappy)
|
!$OMP DO PRIVATE(ce,me,ho,myNgrains,NiterationMPstate,converged,doneAndHappy)
|
||||||
do el = FEsolving_execElem(1),FEsolving_execElem(2)
|
do el = FEsolving_execElem(1),FEsolving_execElem(2)
|
||||||
ho = material_homogenizationAt(el)
|
ho = material_homogenizationAt(el)
|
||||||
myNgrains = homogenization_Nconstituents(ho)
|
myNgrains = homogenization_Nconstituents(ho)
|
||||||
do ip = FEsolving_execIP(1),FEsolving_execIP(2)
|
do ip = FEsolving_execIP(1),FEsolving_execIP(2)
|
||||||
me = material_homogenizationMemberAt(ip,el)
|
ce = (el-1)*discretization_nIPs + ip
|
||||||
!--------------------------------------------------------------------------------------------------
|
me = material_homogenizationMemberAt2(ce)
|
||||||
! initialize restoration points
|
|
||||||
call constitutive_initializeRestorationPoints(ip,el)
|
|
||||||
|
|
||||||
subFrac = 0.0_pReal
|
call phase_restore(ce,.false.) ! wrong name (is more a forward function)
|
||||||
converged = .false. ! pretend failed step ...
|
|
||||||
subStep = 1.0_pReal/num%subStepSizeHomog ! ... larger then the requested calculation
|
|
||||||
|
|
||||||
if (homogState(ho)%sizeState > 0) &
|
if(homogState(ho)%sizeState > 0) homogState(ho)%State(:,me) = homogState(ho)%State0(:,me)
|
||||||
homogState(ho)%subState0(:,me) = homogState(ho)%State0(:,me)
|
if(damageState_h(ho)%sizeState > 0) damageState_h(ho)%State(:,me) = damageState_h(ho)%State0(:,me)
|
||||||
if (damageState(ho)%sizeState > 0) &
|
call damage_partition(ce)
|
||||||
damageState(ho)%subState0(:,me) = damageState(ho)%State0(:,me)
|
|
||||||
|
|
||||||
cutBackLooping: do while (.not. terminallyIll .and. subStep > num%subStepMinHomog)
|
doneAndHappy = [.false.,.true.]
|
||||||
|
|
||||||
if (converged) then
|
|
||||||
subFrac = subFrac + subStep
|
|
||||||
subStep = min(1.0_pReal-subFrac,num%stepIncreaseHomog*subStep) ! introduce flexibility for step increase/acceleration
|
|
||||||
|
|
||||||
steppingNeeded: if (subStep > num%subStepMinHomog) then
|
|
||||||
|
|
||||||
! wind forward grain starting point
|
|
||||||
call constitutive_windForward(ip,el)
|
|
||||||
|
|
||||||
if(homogState(ho)%sizeState > 0) &
|
|
||||||
homogState(ho)%subState0(:,me) = homogState(ho)%State(:,me)
|
|
||||||
if(damageState(ho)%sizeState > 0) &
|
|
||||||
damageState(ho)%subState0(:,me) = damageState(ho)%State(:,me)
|
|
||||||
|
|
||||||
endif steppingNeeded
|
|
||||||
elseif ( (myNgrains == 1 .and. subStep <= 1.0 ) .or. & ! single grain already tried internal subStepping in crystallite
|
|
||||||
num%subStepSizeHomog * subStep <= num%subStepMinHomog ) then ! would require too small subStep
|
|
||||||
! cutback makes no sense
|
|
||||||
if (.not. terminallyIll) & ! so first signals terminally ill...
|
|
||||||
print*, ' Integration point ', ip,' at element ', el, ' terminally ill'
|
|
||||||
terminallyIll = .true. ! ...and kills all others
|
|
||||||
else ! cutback makes sense
|
|
||||||
subStep = num%subStepSizeHomog * subStep ! crystallite had severe trouble, so do a significant cutback
|
|
||||||
|
|
||||||
call constitutive_restore(ip,el,subStep < 1.0_pReal)
|
|
||||||
|
|
||||||
if(homogState(ho)%sizeState > 0) &
|
|
||||||
homogState(ho)%State(:,me) = homogState(ho)%subState0(:,me)
|
|
||||||
if(damageState(ho)%sizeState > 0) &
|
|
||||||
damageState(ho)%State(:,me) = damageState(ho)%subState0(:,me)
|
|
||||||
endif
|
|
||||||
|
|
||||||
if (subStep > num%subStepMinHomog) doneAndHappy = [.false.,.true.]
|
|
||||||
|
|
||||||
NiterationMPstate = 0
|
NiterationMPstate = 0
|
||||||
convergenceLooping: do while (.not. terminallyIll &
|
convergenceLooping: do while (.not. (terminallyIll .or. doneAndHappy(1)) &
|
||||||
.and. .not. doneAndHappy(1) &
|
|
||||||
.and. NiterationMPstate < num%nMPstate)
|
.and. NiterationMPstate < num%nMPstate)
|
||||||
NiterationMPstate = NiterationMPstate + 1
|
NiterationMPstate = NiterationMPstate + 1
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
! deformation partitioning
|
|
||||||
|
|
||||||
if (.not. doneAndHappy(1)) then
|
if (.not. doneAndHappy(1)) then
|
||||||
ce = (el-1)*discretization_nIPs + ip
|
call mechanical_partition(homogenization_F(1:3,1:3,ce),ce)
|
||||||
call mech_partition(homogenization_F0(1:3,1:3,ce) &
|
|
||||||
+ (homogenization_F(1:3,1:3,ce)-homogenization_F0(1:3,1:3,ce))&
|
|
||||||
*(subStep+subFrac), &
|
|
||||||
ip,el)
|
|
||||||
converged = .true.
|
converged = .true.
|
||||||
do co = 1, myNgrains
|
do co = 1, myNgrains
|
||||||
converged = converged .and. crystallite_stress(dt*subStep,co,ip,el)
|
converged = converged .and. crystallite_stress(dt,co,ip,el)
|
||||||
enddo
|
enddo
|
||||||
|
|
||||||
if (.not. converged) then
|
if (.not. converged) then
|
||||||
doneAndHappy = [.true.,.false.]
|
doneAndHappy = [.true.,.false.]
|
||||||
else
|
else
|
||||||
ce = (el-1)*discretization_nIPs + ip
|
doneAndHappy = mechanical_updateState(dt,homogenization_F(1:3,1:3,ce),ce)
|
||||||
doneAndHappy = mech_updateState(dt*subStep, &
|
|
||||||
homogenization_F0(1:3,1:3,ce) &
|
|
||||||
+ (homogenization_F(1:3,1:3,ce)-homogenization_F0(1:3,1:3,ce)) &
|
|
||||||
*(subStep+subFrac), &
|
|
||||||
ip,el)
|
|
||||||
converged = all(doneAndHappy)
|
converged = all(doneAndHappy)
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
enddo convergenceLooping
|
enddo convergenceLooping
|
||||||
enddo cutBackLooping
|
if (.not. converged) then
|
||||||
|
if (.not. terminallyIll) print*, ' Integration point ', ip,' at element ', el, ' terminally ill'
|
||||||
|
terminallyIll = .true.
|
||||||
|
endif
|
||||||
enddo
|
enddo
|
||||||
enddo
|
enddo
|
||||||
!$OMP END PARALLEL DO
|
!$OMP END DO
|
||||||
|
|
||||||
if (.not. terminallyIll) then
|
if (.not. terminallyIll) then
|
||||||
!$OMP PARALLEL DO PRIVATE(ho,myNgrains)
|
!$OMP DO PRIVATE(ho,ph,ce)
|
||||||
|
do el = FEsolving_execElem(1),FEsolving_execElem(2)
|
||||||
|
if (terminallyIll) continue
|
||||||
|
ho = material_homogenizationAt(el)
|
||||||
|
do ip = FEsolving_execIP(1),FEsolving_execIP(2)
|
||||||
|
ce = (el-1)*discretization_nIPs + ip
|
||||||
|
call thermal_partition(ce)
|
||||||
|
do co = 1, homogenization_Nconstituents(ho)
|
||||||
|
ph = material_phaseAt(co,el)
|
||||||
|
if (.not. thermal_stress(dt,ph,material_phaseMemberAt(co,ip,el))) then
|
||||||
|
if (.not. terminallyIll) & ! so first signals terminally ill...
|
||||||
|
print*, ' Integration point ', ip,' at element ', el, ' terminally ill'
|
||||||
|
terminallyIll = .true. ! ...and kills all others
|
||||||
|
endif
|
||||||
|
enddo
|
||||||
|
call thermal_homogenize(ip,el)
|
||||||
|
enddo
|
||||||
|
enddo
|
||||||
|
!$OMP END DO
|
||||||
|
|
||||||
|
!$OMP DO PRIVATE(ho,ce)
|
||||||
elementLooping3: do el = FEsolving_execElem(1),FEsolving_execElem(2)
|
elementLooping3: do el = FEsolving_execElem(1),FEsolving_execElem(2)
|
||||||
ho = material_homogenizationAt(el)
|
ho = material_homogenizationAt(el)
|
||||||
myNgrains = homogenization_Nconstituents(ho)
|
|
||||||
IpLooping3: do ip = FEsolving_execIP(1),FEsolving_execIP(2)
|
IpLooping3: do ip = FEsolving_execIP(1),FEsolving_execIP(2)
|
||||||
do co = 1, myNgrains
|
ce = (el-1)*discretization_nIPs + ip
|
||||||
|
do co = 1, homogenization_Nconstituents(ho)
|
||||||
call crystallite_orientations(co,ip,el)
|
call crystallite_orientations(co,ip,el)
|
||||||
enddo
|
enddo
|
||||||
call mech_homogenize(ip,el)
|
call mechanical_homogenize(dt,ce)
|
||||||
enddo IpLooping3
|
enddo IpLooping3
|
||||||
enddo elementLooping3
|
enddo elementLooping3
|
||||||
!$OMP END PARALLEL DO
|
!$OMP END DO
|
||||||
else
|
else
|
||||||
print'(/,a,/)', ' << HOMOG >> Material Point terminally ill'
|
print'(/,a,/)', ' << HOMOG >> Material Point terminally ill'
|
||||||
endif
|
endif
|
||||||
|
!$OMP END PARALLEL
|
||||||
|
|
||||||
end subroutine materialpoint_stressAndItsTangent
|
end subroutine materialpoint_stressAndItsTangent
|
||||||
|
|
||||||
|
@ -283,7 +368,7 @@ subroutine homogenization_results
|
||||||
group_base = 'current/homogenization/'//trim(material_name_homogenization(ho))
|
group_base = 'current/homogenization/'//trim(material_name_homogenization(ho))
|
||||||
call results_closeGroup(results_addGroup(group_base))
|
call results_closeGroup(results_addGroup(group_base))
|
||||||
|
|
||||||
call mech_results(group_base,ho)
|
call mechanical_results(group_base,ho)
|
||||||
|
|
||||||
group = trim(group_base)//'/damage'
|
group = trim(group_base)//'/damage'
|
||||||
call results_closeGroup(results_addGroup(group))
|
call results_closeGroup(results_addGroup(group))
|
||||||
|
@ -315,9 +400,185 @@ subroutine homogenization_forward
|
||||||
|
|
||||||
do ho = 1, size(material_name_homogenization)
|
do ho = 1, size(material_name_homogenization)
|
||||||
homogState (ho)%state0 = homogState (ho)%state
|
homogState (ho)%state0 = homogState (ho)%state
|
||||||
damageState(ho)%state0 = damageState(ho)%state
|
if(damageState_h(ho)%sizeState > 0) &
|
||||||
|
damageState_h(ho)%state0 = damageState_h(ho)%state
|
||||||
enddo
|
enddo
|
||||||
|
|
||||||
end subroutine homogenization_forward
|
end subroutine homogenization_forward
|
||||||
|
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
subroutine homogenization_restartWrite(fileHandle)
|
||||||
|
|
||||||
|
integer(HID_T), intent(in) :: fileHandle
|
||||||
|
|
||||||
|
integer(HID_T), dimension(2) :: groupHandle
|
||||||
|
integer :: ho
|
||||||
|
|
||||||
|
|
||||||
|
groupHandle(1) = HDF5_addGroup(fileHandle,'homogenization')
|
||||||
|
|
||||||
|
do ho = 1, size(material_name_homogenization)
|
||||||
|
|
||||||
|
groupHandle(2) = HDF5_addGroup(groupHandle(1),material_name_homogenization(ho))
|
||||||
|
|
||||||
|
call HDF5_write(groupHandle(2),homogState(ho)%state,'omega') ! ToDo: should be done by mech
|
||||||
|
|
||||||
|
call HDF5_closeGroup(groupHandle(2))
|
||||||
|
|
||||||
|
enddo
|
||||||
|
|
||||||
|
call HDF5_closeGroup(groupHandle(1))
|
||||||
|
|
||||||
|
end subroutine homogenization_restartWrite
|
||||||
|
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
subroutine homogenization_restartRead(fileHandle)
|
||||||
|
|
||||||
|
integer(HID_T), intent(in) :: fileHandle
|
||||||
|
|
||||||
|
integer(HID_T), dimension(2) :: groupHandle
|
||||||
|
integer :: ho
|
||||||
|
|
||||||
|
|
||||||
|
groupHandle(1) = HDF5_openGroup(fileHandle,'homogenization')
|
||||||
|
|
||||||
|
do ho = 1, size(material_name_homogenization)
|
||||||
|
|
||||||
|
groupHandle(2) = HDF5_openGroup(groupHandle(1),material_name_homogenization(ho))
|
||||||
|
|
||||||
|
call HDF5_read(groupHandle(2),homogState(ho)%state,'omega') ! ToDo: should be done by mech
|
||||||
|
|
||||||
|
call HDF5_closeGroup(groupHandle(2))
|
||||||
|
|
||||||
|
enddo
|
||||||
|
|
||||||
|
call HDF5_closeGroup(groupHandle(1))
|
||||||
|
|
||||||
|
end subroutine homogenization_restartRead
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief module initialization
|
||||||
|
!> @details reads in material parameters, allocates arrays, and does sanity checks
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
subroutine damage_nonlocal_init
|
||||||
|
|
||||||
|
integer :: Ninstances,Nmaterialpoints,h
|
||||||
|
class(tNode), pointer :: &
|
||||||
|
num_generic, &
|
||||||
|
material_homogenization
|
||||||
|
|
||||||
|
print'(/,a)', ' <<<+- damage_nonlocal init -+>>>'; flush(6)
|
||||||
|
|
||||||
|
!------------------------------------------------------------------------------------
|
||||||
|
! read numerics parameter
|
||||||
|
num_generic => config_numerics%get('generic',defaultVal= emptyDict)
|
||||||
|
num_damage%charLength = num_generic%get_asFloat('charLength',defaultVal=1.0_pReal)
|
||||||
|
|
||||||
|
Ninstances = count(damage_type == DAMAGE_nonlocal_ID)
|
||||||
|
|
||||||
|
material_homogenization => config_material%get('homogenization')
|
||||||
|
do h = 1, material_homogenization%length
|
||||||
|
if (damage_type(h) /= DAMAGE_NONLOCAL_ID) cycle
|
||||||
|
|
||||||
|
Nmaterialpoints = count(material_homogenizationAt == h)
|
||||||
|
damageState_h(h)%sizeState = 1
|
||||||
|
allocate(damageState_h(h)%state0 (1,Nmaterialpoints), source=1.0_pReal)
|
||||||
|
allocate(damageState_h(h)%state (1,Nmaterialpoints), source=1.0_pReal)
|
||||||
|
|
||||||
|
enddo
|
||||||
|
|
||||||
|
end subroutine damage_nonlocal_init
|
||||||
|
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief returns homogenized non local damage diffusion tensor in reference configuration
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
function damage_nonlocal_getDiffusion(ce)
|
||||||
|
|
||||||
|
integer, intent(in) :: ce
|
||||||
|
real(pReal), dimension(3,3) :: &
|
||||||
|
damage_nonlocal_getDiffusion
|
||||||
|
integer :: &
|
||||||
|
ho, &
|
||||||
|
co
|
||||||
|
|
||||||
|
ho = material_homogenizationAt2(ce)
|
||||||
|
damage_nonlocal_getDiffusion = 0.0_pReal
|
||||||
|
|
||||||
|
do co = 1, homogenization_Nconstituents(ho)
|
||||||
|
damage_nonlocal_getDiffusion = damage_nonlocal_getDiffusion + &
|
||||||
|
crystallite_push33ToRef(co,ce,lattice_D(1:3,1:3,material_phaseAt2(co,ce)))
|
||||||
|
enddo
|
||||||
|
|
||||||
|
damage_nonlocal_getDiffusion = &
|
||||||
|
num_damage%charLength**2*damage_nonlocal_getDiffusion/real(homogenization_Nconstituents(ho),pReal)
|
||||||
|
|
||||||
|
end function damage_nonlocal_getDiffusion
|
||||||
|
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief parses the homogenization part from the material configuration
|
||||||
|
! ToDo: This should be done in homogenization
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
subroutine material_parseHomogenization
|
||||||
|
|
||||||
|
class(tNode), pointer :: &
|
||||||
|
material_homogenization, &
|
||||||
|
homog, &
|
||||||
|
homogMech, &
|
||||||
|
homogThermal, &
|
||||||
|
homogDamage
|
||||||
|
|
||||||
|
integer :: h
|
||||||
|
|
||||||
|
material_homogenization => config_material%get('homogenization')
|
||||||
|
|
||||||
|
allocate(homogenization_type(size(material_name_homogenization)), source=HOMOGENIZATION_undefined_ID)
|
||||||
|
allocate(thermal_type(size(material_name_homogenization)), source=THERMAL_isothermal_ID)
|
||||||
|
allocate(damage_type (size(material_name_homogenization)), source=DAMAGE_none_ID)
|
||||||
|
|
||||||
|
do h=1, size(material_name_homogenization)
|
||||||
|
homog => material_homogenization%get(h)
|
||||||
|
homogMech => homog%get('mechanics')
|
||||||
|
select case (homogMech%get_asString('type'))
|
||||||
|
case('pass')
|
||||||
|
homogenization_type(h) = HOMOGENIZATION_NONE_ID
|
||||||
|
case('isostrain')
|
||||||
|
homogenization_type(h) = HOMOGENIZATION_ISOSTRAIN_ID
|
||||||
|
case('RGC')
|
||||||
|
homogenization_type(h) = HOMOGENIZATION_RGC_ID
|
||||||
|
case default
|
||||||
|
call IO_error(500,ext_msg=homogMech%get_asString('type'))
|
||||||
|
end select
|
||||||
|
|
||||||
|
if (homog%contains('thermal')) then
|
||||||
|
homogThermal => homog%get('thermal')
|
||||||
|
select case (homogThermal%get_asString('type'))
|
||||||
|
case('pass')
|
||||||
|
thermal_type(h) = THERMAL_conduction_ID
|
||||||
|
case default
|
||||||
|
call IO_error(500,ext_msg=homogThermal%get_asString('type'))
|
||||||
|
end select
|
||||||
|
endif
|
||||||
|
|
||||||
|
if (homog%contains('damage')) then
|
||||||
|
homogDamage => homog%get('damage')
|
||||||
|
select case (homogDamage%get_asString('type'))
|
||||||
|
case('pass')
|
||||||
|
damage_type(h) = DAMAGE_nonlocal_ID
|
||||||
|
case default
|
||||||
|
call IO_error(500,ext_msg=homogDamage%get_asString('type'))
|
||||||
|
end select
|
||||||
|
endif
|
||||||
|
enddo
|
||||||
|
|
||||||
|
end subroutine material_parseHomogenization
|
||||||
|
|
||||||
|
|
||||||
end module homogenization
|
end module homogenization
|
||||||
|
|
|
@ -0,0 +1,168 @@
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @author Martin Diehl, KU Leuven
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
submodule(homogenization) homogenization_damage
|
||||||
|
|
||||||
|
use lattice
|
||||||
|
|
||||||
|
type :: tDataContainer
|
||||||
|
real(pReal), dimension(:), allocatable :: phi
|
||||||
|
end type tDataContainer
|
||||||
|
|
||||||
|
type(tDataContainer), dimension(:), allocatable :: current
|
||||||
|
|
||||||
|
type :: tParameters
|
||||||
|
character(len=pStringLen), allocatable, dimension(:) :: &
|
||||||
|
output
|
||||||
|
end type tParameters
|
||||||
|
|
||||||
|
type(tparameters), dimension(:), allocatable :: &
|
||||||
|
param
|
||||||
|
|
||||||
|
contains
|
||||||
|
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief Allocate variables and set parameters.
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
module subroutine damage_init()
|
||||||
|
|
||||||
|
class(tNode), pointer :: &
|
||||||
|
configHomogenizations, &
|
||||||
|
configHomogenization, &
|
||||||
|
configHomogenizationDamage
|
||||||
|
integer :: ho
|
||||||
|
|
||||||
|
|
||||||
|
print'(/,a)', ' <<<+- homogenization:damage init -+>>>'
|
||||||
|
print'(/,a)', ' <<<+- homogenization:damage:isodamage init -+>>>'
|
||||||
|
|
||||||
|
configHomogenizations => config_material%get('homogenization')
|
||||||
|
allocate(param(configHomogenizations%length))
|
||||||
|
allocate(current(configHomogenizations%length))
|
||||||
|
|
||||||
|
do ho = 1, configHomogenizations%length
|
||||||
|
allocate(current(ho)%phi(count(material_homogenizationAt2==ho)), source=1.0_pReal)
|
||||||
|
configHomogenization => configHomogenizations%get(ho)
|
||||||
|
associate(prm => param(ho))
|
||||||
|
if (configHomogenization%contains('damage')) then
|
||||||
|
configHomogenizationDamage => configHomogenization%get('damage')
|
||||||
|
#if defined (__GFORTRAN__)
|
||||||
|
prm%output = output_asStrings(configHomogenizationDamage)
|
||||||
|
#else
|
||||||
|
prm%output = configHomogenizationDamage%get_asStrings('output',defaultVal=emptyStringArray)
|
||||||
|
#endif
|
||||||
|
else
|
||||||
|
prm%output = emptyStringArray
|
||||||
|
endif
|
||||||
|
end associate
|
||||||
|
enddo
|
||||||
|
|
||||||
|
end subroutine damage_init
|
||||||
|
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief Partition temperature onto the individual constituents.
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
module subroutine damage_partition(ce)
|
||||||
|
|
||||||
|
real(pReal) :: phi
|
||||||
|
integer, intent(in) :: ce
|
||||||
|
|
||||||
|
integer :: co
|
||||||
|
|
||||||
|
|
||||||
|
if(damageState_h(material_homogenizationAt2(ce))%sizeState < 1) return
|
||||||
|
phi = damagestate_h(material_homogenizationAt2(ce))%state(1,material_homogenizationMemberAt2(ce))
|
||||||
|
do co = 1, homogenization_Nconstituents(material_homogenizationAt2(ce))
|
||||||
|
call phase_damage_set_phi(phi,co,ce)
|
||||||
|
enddo
|
||||||
|
|
||||||
|
end subroutine damage_partition
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief Returns homogenized nonlocal damage mobility
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
module function damage_nonlocal_getMobility(ce) result(M)
|
||||||
|
|
||||||
|
integer, intent(in) :: ce
|
||||||
|
integer :: &
|
||||||
|
co
|
||||||
|
real(pReal) :: M
|
||||||
|
|
||||||
|
M = 0.0_pReal
|
||||||
|
|
||||||
|
do co = 1, homogenization_Nconstituents(material_homogenizationAt2(ce))
|
||||||
|
M = M + lattice_M(material_phaseAt2(co,ce))
|
||||||
|
enddo
|
||||||
|
|
||||||
|
M = M/real(homogenization_Nconstituents(material_homogenizationAt2(ce)),pReal)
|
||||||
|
|
||||||
|
end function damage_nonlocal_getMobility
|
||||||
|
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief calculates homogenized damage driving forces
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
module subroutine damage_nonlocal_getSourceAndItsTangent(phiDot, dPhiDot_dPhi, phi, ce)
|
||||||
|
|
||||||
|
integer, intent(in) :: ce
|
||||||
|
real(pReal), intent(in) :: &
|
||||||
|
phi
|
||||||
|
real(pReal) :: &
|
||||||
|
phiDot, dPhiDot_dPhi
|
||||||
|
|
||||||
|
phiDot = 0.0_pReal
|
||||||
|
dPhiDot_dPhi = 0.0_pReal
|
||||||
|
|
||||||
|
call phase_damage_getRateAndItsTangents(phiDot, dPhiDot_dPhi, phi, ce)
|
||||||
|
phiDot = phiDot/real(homogenization_Nconstituents(material_homogenizationAt2(ce)),pReal)
|
||||||
|
dPhiDot_dPhi = dPhiDot_dPhi/real(homogenization_Nconstituents(material_homogenizationAt2(ce)),pReal)
|
||||||
|
|
||||||
|
end subroutine damage_nonlocal_getSourceAndItsTangent
|
||||||
|
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief updated nonlocal damage field with solution from damage phase field PDE
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
module subroutine damage_nonlocal_putNonLocalDamage(phi,ce)
|
||||||
|
|
||||||
|
integer, intent(in) :: ce
|
||||||
|
real(pReal), intent(in) :: &
|
||||||
|
phi
|
||||||
|
integer :: &
|
||||||
|
ho, &
|
||||||
|
me
|
||||||
|
|
||||||
|
ho = material_homogenizationAt2(ce)
|
||||||
|
me = material_homogenizationMemberAt2(ce)
|
||||||
|
damagestate_h(ho)%state(1,me) = phi
|
||||||
|
|
||||||
|
end subroutine damage_nonlocal_putNonLocalDamage
|
||||||
|
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief writes results to HDF5 output file
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
module subroutine damage_nonlocal_results(ho,group)
|
||||||
|
|
||||||
|
integer, intent(in) :: ho
|
||||||
|
character(len=*), intent(in) :: group
|
||||||
|
|
||||||
|
integer :: o
|
||||||
|
|
||||||
|
associate(prm => param(ho))
|
||||||
|
outputsLoop: do o = 1,size(prm%output)
|
||||||
|
select case(prm%output(o))
|
||||||
|
case ('phi')
|
||||||
|
call results_writeDataset(group,damagestate_h(ho)%state(1,:),prm%output(o),&
|
||||||
|
'damage indicator','-')
|
||||||
|
end select
|
||||||
|
enddo outputsLoop
|
||||||
|
end associate
|
||||||
|
|
||||||
|
end subroutine damage_nonlocal_results
|
||||||
|
|
||||||
|
end submodule homogenization_damage
|
|
@ -2,75 +2,72 @@
|
||||||
!> @author Martin Diehl, KU Leuven
|
!> @author Martin Diehl, KU Leuven
|
||||||
!> @brief Partition F and homogenize P/dPdF
|
!> @brief Partition F and homogenize P/dPdF
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
submodule(homogenization) homogenization_mech
|
submodule(homogenization) mechanical
|
||||||
|
|
||||||
|
|
||||||
interface
|
interface
|
||||||
|
|
||||||
module subroutine mech_none_init
|
module subroutine mechanical_pass_init
|
||||||
end subroutine mech_none_init
|
end subroutine mechanical_pass_init
|
||||||
|
|
||||||
module subroutine mech_isostrain_init
|
module subroutine mechanical_isostrain_init
|
||||||
end subroutine mech_isostrain_init
|
end subroutine mechanical_isostrain_init
|
||||||
|
|
||||||
module subroutine mech_RGC_init(num_homogMech)
|
module subroutine mechanical_RGC_init(num_homogMech)
|
||||||
class(tNode), pointer, intent(in) :: &
|
class(tNode), pointer, intent(in) :: &
|
||||||
num_homogMech !< pointer to mechanical homogenization numerics data
|
num_homogMech !< pointer to mechanical homogenization numerics data
|
||||||
end subroutine mech_RGC_init
|
end subroutine mechanical_RGC_init
|
||||||
|
|
||||||
|
|
||||||
module subroutine mech_isostrain_partitionDeformation(F,avgF)
|
module subroutine mechanical_isostrain_partitionDeformation(F,avgF)
|
||||||
real(pReal), dimension (:,:,:), intent(out) :: F !< partitioned deformation gradient
|
real(pReal), dimension (:,:,:), intent(out) :: F !< partitioned deformation gradient
|
||||||
real(pReal), dimension (3,3), intent(in) :: avgF !< average deformation gradient at material point
|
real(pReal), dimension (3,3), intent(in) :: avgF !< average deformation gradient at material point
|
||||||
end subroutine mech_isostrain_partitionDeformation
|
end subroutine mechanical_isostrain_partitionDeformation
|
||||||
|
|
||||||
module subroutine mech_RGC_partitionDeformation(F,avgF,instance,of)
|
module subroutine mechanical_RGC_partitionDeformation(F,avgF,ce)
|
||||||
real(pReal), dimension (:,:,:), intent(out) :: F !< partitioned deformation gradient
|
real(pReal), dimension (:,:,:), intent(out) :: F !< partitioned deformation gradient
|
||||||
real(pReal), dimension (3,3), intent(in) :: avgF !< average deformation gradient at material point
|
real(pReal), dimension (3,3), intent(in) :: avgF !< average deformation gradient at material point
|
||||||
integer, intent(in) :: &
|
integer, intent(in) :: &
|
||||||
instance, &
|
ce
|
||||||
of
|
end subroutine mechanical_RGC_partitionDeformation
|
||||||
end subroutine mech_RGC_partitionDeformation
|
|
||||||
|
|
||||||
|
|
||||||
module subroutine mech_isostrain_averageStressAndItsTangent(avgP,dAvgPdAvgF,P,dPdF,instance)
|
module subroutine mechanical_isostrain_averageStressAndItsTangent(avgP,dAvgPdAvgF,P,dPdF,ho)
|
||||||
real(pReal), dimension (3,3), intent(out) :: avgP !< average stress at material point
|
real(pReal), dimension (3,3), intent(out) :: avgP !< average stress at material point
|
||||||
real(pReal), dimension (3,3,3,3), intent(out) :: dAvgPdAvgF !< average stiffness at material point
|
real(pReal), dimension (3,3,3,3), intent(out) :: dAvgPdAvgF !< average stiffness at material point
|
||||||
|
|
||||||
real(pReal), dimension (:,:,:), intent(in) :: P !< partitioned stresses
|
real(pReal), dimension (:,:,:), intent(in) :: P !< partitioned stresses
|
||||||
real(pReal), dimension (:,:,:,:,:), intent(in) :: dPdF !< partitioned stiffnesses
|
real(pReal), dimension (:,:,:,:,:), intent(in) :: dPdF !< partitioned stiffnesses
|
||||||
integer, intent(in) :: instance
|
integer, intent(in) :: ho
|
||||||
end subroutine mech_isostrain_averageStressAndItsTangent
|
end subroutine mechanical_isostrain_averageStressAndItsTangent
|
||||||
|
|
||||||
module subroutine mech_RGC_averageStressAndItsTangent(avgP,dAvgPdAvgF,P,dPdF,instance)
|
module subroutine mechanical_RGC_averageStressAndItsTangent(avgP,dAvgPdAvgF,P,dPdF,ho)
|
||||||
real(pReal), dimension (3,3), intent(out) :: avgP !< average stress at material point
|
real(pReal), dimension (3,3), intent(out) :: avgP !< average stress at material point
|
||||||
real(pReal), dimension (3,3,3,3), intent(out) :: dAvgPdAvgF !< average stiffness at material point
|
real(pReal), dimension (3,3,3,3), intent(out) :: dAvgPdAvgF !< average stiffness at material point
|
||||||
|
|
||||||
real(pReal), dimension (:,:,:), intent(in) :: P !< partitioned stresses
|
real(pReal), dimension (:,:,:), intent(in) :: P !< partitioned stresses
|
||||||
real(pReal), dimension (:,:,:,:,:), intent(in) :: dPdF !< partitioned stiffnesses
|
real(pReal), dimension (:,:,:,:,:), intent(in) :: dPdF !< partitioned stiffnesses
|
||||||
integer, intent(in) :: instance
|
integer, intent(in) :: ho
|
||||||
end subroutine mech_RGC_averageStressAndItsTangent
|
end subroutine mechanical_RGC_averageStressAndItsTangent
|
||||||
|
|
||||||
|
|
||||||
module function mech_RGC_updateState(P,F,F0,avgF,dt,dPdF,ip,el) result(doneAndHappy)
|
module function mechanical_RGC_updateState(P,F,avgF,dt,dPdF,ce) result(doneAndHappy)
|
||||||
logical, dimension(2) :: doneAndHappy
|
logical, dimension(2) :: doneAndHappy
|
||||||
real(pReal), dimension(:,:,:), intent(in) :: &
|
real(pReal), dimension(:,:,:), intent(in) :: &
|
||||||
P,& !< partitioned stresses
|
P,& !< partitioned stresses
|
||||||
F,& !< partitioned deformation gradients
|
F !< partitioned deformation gradients
|
||||||
F0 !< partitioned initial deformation gradients
|
|
||||||
real(pReal), dimension(:,:,:,:,:), intent(in) :: dPdF !< partitioned stiffnesses
|
real(pReal), dimension(:,:,:,:,:), intent(in) :: dPdF !< partitioned stiffnesses
|
||||||
real(pReal), dimension(3,3), intent(in) :: avgF !< average F
|
real(pReal), dimension(3,3), intent(in) :: avgF !< average F
|
||||||
real(pReal), intent(in) :: dt !< time increment
|
real(pReal), intent(in) :: dt !< time increment
|
||||||
integer, intent(in) :: &
|
integer, intent(in) :: &
|
||||||
ip, & !< integration point number
|
ce !< cell
|
||||||
el !< element number
|
end function mechanical_RGC_updateState
|
||||||
end function mech_RGC_updateState
|
|
||||||
|
|
||||||
|
|
||||||
module subroutine mech_RGC_results(instance,group)
|
module subroutine mechanical_RGC_results(ho,group)
|
||||||
integer, intent(in) :: instance !< homogenization instance
|
integer, intent(in) :: ho !< homogenization type
|
||||||
character(len=*), intent(in) :: group !< group name in HDF5 file
|
character(len=*), intent(in) :: group !< group name in HDF5 file
|
||||||
end subroutine mech_RGC_results
|
end subroutine mechanical_RGC_results
|
||||||
|
|
||||||
end interface
|
end interface
|
||||||
|
|
||||||
|
@ -79,7 +76,7 @@ contains
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @brief Allocate variables and set parameters.
|
!> @brief Allocate variables and set parameters.
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
module subroutine mech_init(num_homog)
|
module subroutine mechanical_init(num_homog)
|
||||||
|
|
||||||
class(tNode), pointer, intent(in) :: &
|
class(tNode), pointer, intent(in) :: &
|
||||||
num_homog
|
num_homog
|
||||||
|
@ -87,7 +84,7 @@ module subroutine mech_init(num_homog)
|
||||||
class(tNode), pointer :: &
|
class(tNode), pointer :: &
|
||||||
num_homogMech
|
num_homogMech
|
||||||
|
|
||||||
print'(/,a)', ' <<<+- homogenization_mech init -+>>>'
|
print'(/,a)', ' <<<+- homogenization:mechanical init -+>>>'
|
||||||
|
|
||||||
allocate(homogenization_dPdF(3,3,3,3,discretization_nIPs*discretization_Nelems), source=0.0_pReal)
|
allocate(homogenization_dPdF(3,3,3,3,discretization_nIPs*discretization_Nelems), source=0.0_pReal)
|
||||||
homogenization_F0 = spread(math_I3,3,discretization_nIPs*discretization_Nelems) ! initialize to identity
|
homogenization_F0 = spread(math_I3,3,discretization_nIPs*discretization_Nelems) ! initialize to identity
|
||||||
|
@ -95,150 +92,145 @@ module subroutine mech_init(num_homog)
|
||||||
allocate(homogenization_P(3,3,discretization_nIPs*discretization_Nelems), source=0.0_pReal)
|
allocate(homogenization_P(3,3,discretization_nIPs*discretization_Nelems), source=0.0_pReal)
|
||||||
|
|
||||||
num_homogMech => num_homog%get('mech',defaultVal=emptyDict)
|
num_homogMech => num_homog%get('mech',defaultVal=emptyDict)
|
||||||
if (any(homogenization_type == HOMOGENIZATION_NONE_ID)) call mech_none_init
|
if (any(homogenization_type == HOMOGENIZATION_NONE_ID)) call mechanical_pass_init
|
||||||
if (any(homogenization_type == HOMOGENIZATION_ISOSTRAIN_ID)) call mech_isostrain_init
|
if (any(homogenization_type == HOMOGENIZATION_ISOSTRAIN_ID)) call mechanical_isostrain_init
|
||||||
if (any(homogenization_type == HOMOGENIZATION_RGC_ID)) call mech_RGC_init(num_homogMech)
|
if (any(homogenization_type == HOMOGENIZATION_RGC_ID)) call mechanical_RGC_init(num_homogMech)
|
||||||
|
|
||||||
end subroutine mech_init
|
end subroutine mechanical_init
|
||||||
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @brief Partition F onto the individual constituents.
|
!> @brief Partition F onto the individual constituents.
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
module subroutine mech_partition(subF,ip,el)
|
module subroutine mechanical_partition(subF,ce)
|
||||||
|
|
||||||
real(pReal), intent(in), dimension(3,3) :: &
|
real(pReal), intent(in), dimension(3,3) :: &
|
||||||
subF
|
subF
|
||||||
integer, intent(in) :: &
|
integer, intent(in) :: &
|
||||||
ip, & !< integration point
|
ce
|
||||||
el !< element number
|
|
||||||
|
|
||||||
chosenHomogenization: select case(homogenization_type(material_homogenizationAt(el)))
|
integer :: co
|
||||||
|
real(pReal), dimension (3,3,homogenization_Nconstituents(material_homogenizationAt2(ce))) :: Fs
|
||||||
|
|
||||||
|
|
||||||
|
chosenHomogenization: select case(homogenization_type(material_homogenizationAt2(ce)))
|
||||||
|
|
||||||
case (HOMOGENIZATION_NONE_ID) chosenHomogenization
|
case (HOMOGENIZATION_NONE_ID) chosenHomogenization
|
||||||
crystallite_F(1:3,1:3,1,ip,el) = subF
|
Fs(1:3,1:3,1) = subF
|
||||||
|
|
||||||
case (HOMOGENIZATION_ISOSTRAIN_ID) chosenHomogenization
|
case (HOMOGENIZATION_ISOSTRAIN_ID) chosenHomogenization
|
||||||
call mech_isostrain_partitionDeformation(&
|
call mechanical_isostrain_partitionDeformation(Fs,subF)
|
||||||
crystallite_F(1:3,1:3,1:homogenization_Nconstituents(material_homogenizationAt(el)),ip,el), &
|
|
||||||
subF)
|
|
||||||
|
|
||||||
case (HOMOGENIZATION_RGC_ID) chosenHomogenization
|
case (HOMOGENIZATION_RGC_ID) chosenHomogenization
|
||||||
call mech_RGC_partitionDeformation(&
|
call mechanical_RGC_partitionDeformation(Fs,subF,ce)
|
||||||
crystallite_F(1:3,1:3,1:homogenization_Nconstituents(material_homogenizationAt(el)),ip,el), &
|
|
||||||
subF,&
|
|
||||||
ip, &
|
|
||||||
el)
|
|
||||||
|
|
||||||
end select chosenHomogenization
|
end select chosenHomogenization
|
||||||
|
|
||||||
end subroutine mech_partition
|
do co = 1,homogenization_Nconstituents(material_homogenizationAt2(ce))
|
||||||
|
call phase_mechanical_setF(Fs(1:3,1:3,co),co,ce)
|
||||||
|
enddo
|
||||||
|
|
||||||
|
|
||||||
|
end subroutine mechanical_partition
|
||||||
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @brief Average P and dPdF from the individual constituents.
|
!> @brief Average P and dPdF from the individual constituents.
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
module subroutine mech_homogenize(ip,el)
|
module subroutine mechanical_homogenize(dt,ce)
|
||||||
|
|
||||||
integer, intent(in) :: &
|
real(pReal), intent(in) :: dt
|
||||||
ip, & !< integration point
|
integer, intent(in) :: ce
|
||||||
el !< element number
|
|
||||||
integer :: co,ce
|
integer :: co
|
||||||
real(pReal) :: dPdFs(3,3,3,3,homogenization_Nconstituents(material_homogenizationAt(el)))
|
real(pReal) :: dPdFs(3,3,3,3,homogenization_Nconstituents(material_homogenizationAt2(ce)))
|
||||||
|
real(pReal) :: Ps(3,3,homogenization_Nconstituents(material_homogenizationAt2(ce)))
|
||||||
|
|
||||||
|
|
||||||
ce = (el-1)* discretization_nIPs + ip
|
chosenHomogenization: select case(homogenization_type(material_homogenizationAt2(ce)))
|
||||||
chosenHomogenization: select case(homogenization_type(material_homogenizationAt(el)))
|
|
||||||
|
|
||||||
case (HOMOGENIZATION_NONE_ID) chosenHomogenization
|
case (HOMOGENIZATION_NONE_ID) chosenHomogenization
|
||||||
homogenization_P(1:3,1:3,ce) = crystallite_P(1:3,1:3,1,ip,el)
|
homogenization_P(1:3,1:3,ce) = phase_mechanical_getP(1,ce)
|
||||||
homogenization_dPdF(1:3,1:3,1:3,1:3,ce) = crystallite_stressTangent(1,ip,el)
|
homogenization_dPdF(1:3,1:3,1:3,1:3,ce) = phase_mechanical_dPdF(dt,1,ce)
|
||||||
|
|
||||||
case (HOMOGENIZATION_ISOSTRAIN_ID) chosenHomogenization
|
case (HOMOGENIZATION_ISOSTRAIN_ID) chosenHomogenization
|
||||||
do co = 1, homogenization_Nconstituents(material_homogenizationAt(el))
|
do co = 1, homogenization_Nconstituents(material_homogenizationAt2(ce))
|
||||||
dPdFs(:,:,:,:,co) = crystallite_stressTangent(co,ip,el)
|
dPdFs(:,:,:,:,co) = phase_mechanical_dPdF(dt,co,ce)
|
||||||
|
Ps(:,:,co) = phase_mechanical_getP(co,ce)
|
||||||
enddo
|
enddo
|
||||||
call mech_isostrain_averageStressAndItsTangent(&
|
call mechanical_isostrain_averageStressAndItsTangent(&
|
||||||
homogenization_P(1:3,1:3,ce), &
|
homogenization_P(1:3,1:3,ce), &
|
||||||
homogenization_dPdF(1:3,1:3,1:3,1:3,ce),&
|
homogenization_dPdF(1:3,1:3,1:3,1:3,ce),&
|
||||||
crystallite_P(1:3,1:3,1:homogenization_Nconstituents(material_homogenizationAt(el)),ip,el), &
|
Ps,dPdFs, &
|
||||||
dPdFs, &
|
material_homogenizationAt2(ce))
|
||||||
homogenization_typeInstance(material_homogenizationAt(el)))
|
|
||||||
|
|
||||||
case (HOMOGENIZATION_RGC_ID) chosenHomogenization
|
case (HOMOGENIZATION_RGC_ID) chosenHomogenization
|
||||||
do co = 1, homogenization_Nconstituents(material_homogenizationAt(el))
|
do co = 1, homogenization_Nconstituents(material_homogenizationAt2(ce))
|
||||||
dPdFs(:,:,:,:,co) = crystallite_stressTangent(co,ip,el)
|
dPdFs(:,:,:,:,co) = phase_mechanical_dPdF(dt,co,ce)
|
||||||
|
Ps(:,:,co) = phase_mechanical_getP(co,ce)
|
||||||
enddo
|
enddo
|
||||||
call mech_RGC_averageStressAndItsTangent(&
|
call mechanical_RGC_averageStressAndItsTangent(&
|
||||||
homogenization_P(1:3,1:3,ce), &
|
homogenization_P(1:3,1:3,ce), &
|
||||||
homogenization_dPdF(1:3,1:3,1:3,1:3,ce),&
|
homogenization_dPdF(1:3,1:3,1:3,1:3,ce),&
|
||||||
crystallite_P(1:3,1:3,1:homogenization_Nconstituents(material_homogenizationAt(el)),ip,el), &
|
Ps,dPdFs, &
|
||||||
dPdFs, &
|
material_homogenizationAt2(ce))
|
||||||
homogenization_typeInstance(material_homogenizationAt(el)))
|
|
||||||
|
|
||||||
end select chosenHomogenization
|
end select chosenHomogenization
|
||||||
|
|
||||||
end subroutine mech_homogenize
|
end subroutine mechanical_homogenize
|
||||||
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @brief update the internal state of the homogenization scheme and tell whether "done" and
|
!> @brief update the internal state of the homogenization scheme and tell whether "done" and
|
||||||
!> "happy" with result
|
!> "happy" with result
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
module function mech_updateState(subdt,subF,ip,el) result(doneAndHappy)
|
module function mechanical_updateState(subdt,subF,ce) result(doneAndHappy)
|
||||||
|
|
||||||
real(pReal), intent(in) :: &
|
real(pReal), intent(in) :: &
|
||||||
subdt !< current time step
|
subdt !< current time step
|
||||||
real(pReal), intent(in), dimension(3,3) :: &
|
real(pReal), intent(in), dimension(3,3) :: &
|
||||||
subF
|
subF
|
||||||
integer, intent(in) :: &
|
integer, intent(in) :: &
|
||||||
ip, & !< integration point
|
ce
|
||||||
el !< element number
|
|
||||||
logical, dimension(2) :: doneAndHappy
|
logical, dimension(2) :: doneAndHappy
|
||||||
|
|
||||||
integer :: co
|
integer :: co
|
||||||
real(pReal) :: dPdFs(3,3,3,3,homogenization_Nconstituents(material_homogenizationAt(el)))
|
real(pReal) :: dPdFs(3,3,3,3,homogenization_Nconstituents(material_homogenizationAt2(ce)))
|
||||||
|
real(pReal) :: Fs(3,3,homogenization_Nconstituents(material_homogenizationAt2(ce)))
|
||||||
|
real(pReal) :: Ps(3,3,homogenization_Nconstituents(material_homogenizationAt2(ce)))
|
||||||
|
|
||||||
|
|
||||||
if (homogenization_type(material_homogenizationAt(el)) == HOMOGENIZATION_RGC_ID) then
|
if (homogenization_type(material_homogenizationAt2(ce)) == HOMOGENIZATION_RGC_ID) then
|
||||||
do co = 1, homogenization_Nconstituents(material_homogenizationAt(el))
|
do co = 1, homogenization_Nconstituents(material_homogenizationAt2(ce))
|
||||||
dPdFs(:,:,:,:,co) = crystallite_stressTangent(co,ip,el)
|
dPdFs(:,:,:,:,co) = phase_mechanical_dPdF(subdt,co,ce)
|
||||||
|
Fs(:,:,co) = phase_mechanical_getF(co,ce)
|
||||||
|
Ps(:,:,co) = phase_mechanical_getP(co,ce)
|
||||||
enddo
|
enddo
|
||||||
doneAndHappy = &
|
doneAndHappy = mechanical_RGC_updateState(Ps,Fs,subF,subdt,dPdFs,ce)
|
||||||
mech_RGC_updateState(crystallite_P(1:3,1:3,1:homogenization_Nconstituents(material_homogenizationAt(el)),ip,el), &
|
|
||||||
crystallite_F(1:3,1:3,1:homogenization_Nconstituents(material_homogenizationAt(el)),ip,el), &
|
|
||||||
crystallite_partitionedF0(1:3,1:3,1:homogenization_Nconstituents(material_homogenizationAt(el)),ip,el),&
|
|
||||||
subF,&
|
|
||||||
subdt, &
|
|
||||||
dPdFs, &
|
|
||||||
ip, &
|
|
||||||
el)
|
|
||||||
else
|
else
|
||||||
doneAndHappy = .true.
|
doneAndHappy = .true.
|
||||||
endif
|
endif
|
||||||
|
|
||||||
end function mech_updateState
|
end function mechanical_updateState
|
||||||
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @brief Write results to file.
|
!> @brief Write results to file.
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
module subroutine mech_results(group_base,h)
|
module subroutine mechanical_results(group_base,ho)
|
||||||
use material, only: &
|
|
||||||
material_homogenization_type => homogenization_type
|
|
||||||
|
|
||||||
character(len=*), intent(in) :: group_base
|
character(len=*), intent(in) :: group_base
|
||||||
integer, intent(in) :: h
|
integer, intent(in) :: ho
|
||||||
|
|
||||||
character(len=:), allocatable :: group
|
character(len=:), allocatable :: group
|
||||||
|
|
||||||
group = trim(group_base)//'/mech'
|
group = trim(group_base)//'/mech'
|
||||||
call results_closeGroup(results_addGroup(group))
|
call results_closeGroup(results_addGroup(group))
|
||||||
|
|
||||||
select case(material_homogenization_type(h))
|
select case(homogenization_type(ho))
|
||||||
|
|
||||||
case(HOMOGENIZATION_rgc_ID)
|
case(HOMOGENIZATION_rgc_ID)
|
||||||
call mech_RGC_results(homogenization_typeInstance(h),group)
|
call mechanical_RGC_results(ho,group)
|
||||||
|
|
||||||
end select
|
end select
|
||||||
|
|
||||||
|
@ -249,7 +241,7 @@ module subroutine mech_results(group_base,h)
|
||||||
!call results_writeDataset(group,temp,'P',&
|
!call results_writeDataset(group,temp,'P',&
|
||||||
! '1st Piola-Kirchhoff stress','Pa')
|
! '1st Piola-Kirchhoff stress','Pa')
|
||||||
|
|
||||||
end subroutine mech_results
|
end subroutine mechanical_results
|
||||||
|
|
||||||
|
|
||||||
end submodule homogenization_mech
|
end submodule mechanical
|
|
@ -6,7 +6,7 @@
|
||||||
!> @brief Relaxed grain cluster (RGC) homogenization scheme
|
!> @brief Relaxed grain cluster (RGC) homogenization scheme
|
||||||
!> N_constituents is defined as p x q x r (cluster)
|
!> N_constituents is defined as p x q x r (cluster)
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
submodule(homogenization:homogenization_mech) homogenization_mech_RGC
|
submodule(homogenization:mechanical) RGC
|
||||||
use rotations
|
use rotations
|
||||||
use lattice
|
use lattice
|
||||||
|
|
||||||
|
@ -24,9 +24,6 @@ submodule(homogenization:homogenization_mech) homogenization_mech_RGC
|
||||||
end type tParameters
|
end type tParameters
|
||||||
|
|
||||||
type :: tRGCstate
|
type :: tRGCstate
|
||||||
real(pReal), pointer, dimension(:) :: &
|
|
||||||
work, &
|
|
||||||
penaltyEnergy
|
|
||||||
real(pReal), pointer, dimension(:,:) :: &
|
real(pReal), pointer, dimension(:,:) :: &
|
||||||
relaxationVector
|
relaxationVector
|
||||||
end type tRGCstate
|
end type tRGCstate
|
||||||
|
@ -74,14 +71,13 @@ contains
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @brief allocates all necessary fields, reads information from material configuration file
|
!> @brief allocates all necessary fields, reads information from material configuration file
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
module subroutine mech_RGC_init(num_homogMech)
|
module subroutine mechanical_RGC_init(num_homogMech)
|
||||||
|
|
||||||
class(tNode), pointer, intent(in) :: &
|
class(tNode), pointer, intent(in) :: &
|
||||||
num_homogMech !< pointer to mechanical homogenization numerics data
|
num_homogMech !< pointer to mechanical homogenization numerics data
|
||||||
|
|
||||||
integer :: &
|
integer :: &
|
||||||
Ninstances, &
|
ho, &
|
||||||
h, &
|
|
||||||
Nmaterialpoints, &
|
Nmaterialpoints, &
|
||||||
sizeState, nIntFaceTot
|
sizeState, nIntFaceTot
|
||||||
|
|
||||||
|
@ -91,10 +87,9 @@ module subroutine mech_RGC_init(num_homogMech)
|
||||||
homog, &
|
homog, &
|
||||||
homogMech
|
homogMech
|
||||||
|
|
||||||
print'(/,a)', ' <<<+- homogenization_mech_rgc init -+>>>'
|
print'(/,a)', ' <<<+- homogenization:mechanical:RGC init -+>>>'
|
||||||
|
|
||||||
Ninstances = count(homogenization_type == HOMOGENIZATION_RGC_ID)
|
print'(a,i2)', ' # instances: ',count(homogenization_type == HOMOGENIZATION_RGC_ID); flush(IO_STDOUT)
|
||||||
print'(a,i2)', ' # instances: ',Ninstances; flush(IO_STDOUT)
|
|
||||||
|
|
||||||
print*, 'Tjahjanto et al., International Journal of Material Forming 2(1):939–942, 2009'
|
print*, 'Tjahjanto et al., International Journal of Material Forming 2(1):939–942, 2009'
|
||||||
print*, 'https://doi.org/10.1007/s12289-009-0619-1'//IO_EOL
|
print*, 'https://doi.org/10.1007/s12289-009-0619-1'//IO_EOL
|
||||||
|
@ -104,10 +99,11 @@ module subroutine mech_RGC_init(num_homogMech)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
allocate(param(Ninstances))
|
material_homogenization => config_material%get('homogenization')
|
||||||
allocate(state(Ninstances))
|
allocate(param(material_homogenization%length))
|
||||||
allocate(state0(Ninstances))
|
allocate(state(material_homogenization%length))
|
||||||
allocate(dependentState(Ninstances))
|
allocate(state0(material_homogenization%length))
|
||||||
|
allocate(dependentState(material_homogenization%length))
|
||||||
|
|
||||||
num_RGC => num_homogMech%get('RGC',defaultVal=emptyDict)
|
num_RGC => num_homogMech%get('RGC',defaultVal=emptyDict)
|
||||||
|
|
||||||
|
@ -140,15 +136,14 @@ module subroutine mech_RGC_init(num_homogMech)
|
||||||
if (num%volDiscrPow <= 0.0_pReal) call IO_error(301,ext_msg='volDiscrPw_RGC')
|
if (num%volDiscrPow <= 0.0_pReal) call IO_error(301,ext_msg='volDiscrPw_RGC')
|
||||||
|
|
||||||
|
|
||||||
material_homogenization => config_material%get('homogenization')
|
do ho = 1, size(homogenization_type)
|
||||||
do h = 1, size(homogenization_type)
|
if (homogenization_type(ho) /= HOMOGENIZATION_RGC_ID) cycle
|
||||||
if (homogenization_type(h) /= HOMOGENIZATION_RGC_ID) cycle
|
homog => material_homogenization%get(ho)
|
||||||
homog => material_homogenization%get(h)
|
|
||||||
homogMech => homog%get('mechanics')
|
homogMech => homog%get('mechanics')
|
||||||
associate(prm => param(homogenization_typeInstance(h)), &
|
associate(prm => param(ho), &
|
||||||
stt => state(homogenization_typeInstance(h)), &
|
stt => state(ho), &
|
||||||
st0 => state0(homogenization_typeInstance(h)), &
|
st0 => state0(ho), &
|
||||||
dst => dependentState(homogenization_typeInstance(h)))
|
dst => dependentState(ho))
|
||||||
|
|
||||||
#if defined (__GFORTRAN__)
|
#if defined (__GFORTRAN__)
|
||||||
prm%output = output_asStrings(homogMech)
|
prm%output = output_asStrings(homogMech)
|
||||||
|
@ -157,8 +152,8 @@ module subroutine mech_RGC_init(num_homogMech)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
prm%N_constituents = homogMech%get_asInts('cluster_size',requiredSize=3)
|
prm%N_constituents = homogMech%get_asInts('cluster_size',requiredSize=3)
|
||||||
if (homogenization_Nconstituents(h) /= product(prm%N_constituents)) &
|
if (homogenization_Nconstituents(ho) /= product(prm%N_constituents)) &
|
||||||
call IO_error(211,ext_msg='N_constituents (mech_RGC)')
|
call IO_error(211,ext_msg='N_constituents (mechanical_RGC)')
|
||||||
|
|
||||||
prm%xi_alpha = homogMech%get_asFloat('xi_alpha')
|
prm%xi_alpha = homogMech%get_asFloat('xi_alpha')
|
||||||
prm%c_alpha = homogMech%get_asFloat('c_alpha')
|
prm%c_alpha = homogMech%get_asFloat('c_alpha')
|
||||||
|
@ -166,22 +161,18 @@ module subroutine mech_RGC_init(num_homogMech)
|
||||||
prm%D_alpha = homogMech%get_asFloats('D_alpha', requiredSize=3)
|
prm%D_alpha = homogMech%get_asFloats('D_alpha', requiredSize=3)
|
||||||
prm%a_g = homogMech%get_asFloats('a_g', requiredSize=3)
|
prm%a_g = homogMech%get_asFloats('a_g', requiredSize=3)
|
||||||
|
|
||||||
Nmaterialpoints = count(material_homogenizationAt == h)
|
Nmaterialpoints = count(material_homogenizationAt == ho)
|
||||||
nIntFaceTot = 3*( (prm%N_constituents(1)-1)*prm%N_constituents(2)*prm%N_constituents(3) &
|
nIntFaceTot = 3*( (prm%N_constituents(1)-1)*prm%N_constituents(2)*prm%N_constituents(3) &
|
||||||
+ prm%N_constituents(1)*(prm%N_constituents(2)-1)*prm%N_constituents(3) &
|
+ prm%N_constituents(1)*(prm%N_constituents(2)-1)*prm%N_constituents(3) &
|
||||||
+ prm%N_constituents(1)*prm%N_constituents(2)*(prm%N_constituents(3)-1))
|
+ prm%N_constituents(1)*prm%N_constituents(2)*(prm%N_constituents(3)-1))
|
||||||
sizeState = nIntFaceTot &
|
sizeState = nIntFaceTot
|
||||||
+ size(['avg constitutive work ','average penalty energy'])
|
|
||||||
|
|
||||||
homogState(h)%sizeState = sizeState
|
homogState(ho)%sizeState = sizeState
|
||||||
allocate(homogState(h)%state0 (sizeState,Nmaterialpoints), source=0.0_pReal)
|
allocate(homogState(ho)%state0 (sizeState,Nmaterialpoints), source=0.0_pReal)
|
||||||
allocate(homogState(h)%subState0(sizeState,Nmaterialpoints), source=0.0_pReal)
|
allocate(homogState(ho)%state (sizeState,Nmaterialpoints), source=0.0_pReal)
|
||||||
allocate(homogState(h)%state (sizeState,Nmaterialpoints), source=0.0_pReal)
|
|
||||||
|
|
||||||
stt%relaxationVector => homogState(h)%state(1:nIntFaceTot,:)
|
stt%relaxationVector => homogState(ho)%state(1:nIntFaceTot,:)
|
||||||
st0%relaxationVector => homogState(h)%state0(1:nIntFaceTot,:)
|
st0%relaxationVector => homogState(ho)%state0(1:nIntFaceTot,:)
|
||||||
stt%work => homogState(h)%state(nIntFaceTot+1,:)
|
|
||||||
stt%penaltyEnergy => homogState(h)%state(nIntFaceTot+2,:)
|
|
||||||
|
|
||||||
allocate(dst%volumeDiscrepancy( Nmaterialpoints), source=0.0_pReal)
|
allocate(dst%volumeDiscrepancy( Nmaterialpoints), source=0.0_pReal)
|
||||||
allocate(dst%relaxationRate_avg( Nmaterialpoints), source=0.0_pReal)
|
allocate(dst%relaxationRate_avg( Nmaterialpoints), source=0.0_pReal)
|
||||||
|
@ -190,35 +181,36 @@ module subroutine mech_RGC_init(num_homogMech)
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! assigning cluster orientations
|
! assigning cluster orientations
|
||||||
dependentState(homogenization_typeInstance(h))%orientation = spread(eu2om(prm%a_g*inRad),3,Nmaterialpoints)
|
dependentState(ho)%orientation = spread(eu2om(prm%a_g*inRad),3,Nmaterialpoints)
|
||||||
!dst%orientation = spread(eu2om(prm%a_g*inRad),3,Nmaterialpoints) ifort version 18.0.1 crashes (for whatever reason)
|
!dst%orientation = spread(eu2om(prm%a_g*inRad),3,Nmaterialpoints) ifort version 18.0.1 crashes (for whatever reason)
|
||||||
|
|
||||||
end associate
|
end associate
|
||||||
|
|
||||||
enddo
|
enddo
|
||||||
|
|
||||||
end subroutine mech_RGC_init
|
end subroutine mechanical_RGC_init
|
||||||
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @brief partitions the deformation gradient onto the constituents
|
!> @brief partitions the deformation gradient onto the constituents
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
module subroutine mech_RGC_partitionDeformation(F,avgF,instance,of)
|
module subroutine mechanical_RGC_partitionDeformation(F,avgF,ce)
|
||||||
|
|
||||||
real(pReal), dimension (:,:,:), intent(out) :: F !< partitioned F per grain
|
real(pReal), dimension (:,:,:), intent(out) :: F !< partitioned F per grain
|
||||||
|
|
||||||
real(pReal), dimension (3,3), intent(in) :: avgF !< averaged F
|
real(pReal), dimension (3,3), intent(in) :: avgF !< averaged F
|
||||||
integer, intent(in) :: &
|
integer, intent(in) :: &
|
||||||
instance, &
|
ce
|
||||||
of
|
|
||||||
|
|
||||||
real(pReal), dimension(3) :: aVect,nVect
|
real(pReal), dimension(3) :: aVect,nVect
|
||||||
integer, dimension(4) :: intFace
|
integer, dimension(4) :: intFace
|
||||||
integer, dimension(3) :: iGrain3
|
integer, dimension(3) :: iGrain3
|
||||||
integer :: iGrain,iFace,i,j
|
integer :: iGrain,iFace,i,j,ho,me
|
||||||
|
|
||||||
associate(prm => param(instance))
|
associate(prm => param(material_homogenizationAt2(ce)))
|
||||||
|
|
||||||
|
ho = material_homogenizationAt2(ce)
|
||||||
|
me = material_homogenizationMemberAt2(ce)
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! compute the deformation gradient of individual grains due to relaxations
|
! compute the deformation gradient of individual grains due to relaxations
|
||||||
F = 0.0_pReal
|
F = 0.0_pReal
|
||||||
|
@ -226,8 +218,8 @@ module subroutine mech_RGC_partitionDeformation(F,avgF,instance,of)
|
||||||
iGrain3 = grain1to3(iGrain,prm%N_constituents)
|
iGrain3 = grain1to3(iGrain,prm%N_constituents)
|
||||||
do iFace = 1,6
|
do iFace = 1,6
|
||||||
intFace = getInterface(iFace,iGrain3) ! identifying 6 interfaces of each grain
|
intFace = getInterface(iFace,iGrain3) ! identifying 6 interfaces of each grain
|
||||||
aVect = relaxationVector(intFace,instance,of) ! get the relaxation vectors for each interface from global relaxation vector array
|
aVect = relaxationVector(intFace,ho,me) ! get the relaxation vectors for each interface from global relaxation vector array
|
||||||
nVect = interfaceNormal(intFace,instance,of)
|
nVect = interfaceNormal(intFace,ho,me)
|
||||||
forall (i=1:3,j=1:3) &
|
forall (i=1:3,j=1:3) &
|
||||||
F(i,j,iGrain) = F(i,j,iGrain) + aVect(i)*nVect(j) ! calculating deformation relaxations due to interface relaxation
|
F(i,j,iGrain) = F(i,j,iGrain) + aVect(i)*nVect(j) ! calculating deformation relaxations due to interface relaxation
|
||||||
enddo
|
enddo
|
||||||
|
@ -236,29 +228,27 @@ module subroutine mech_RGC_partitionDeformation(F,avgF,instance,of)
|
||||||
|
|
||||||
end associate
|
end associate
|
||||||
|
|
||||||
end subroutine mech_RGC_partitionDeformation
|
end subroutine mechanical_RGC_partitionDeformation
|
||||||
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @brief update the internal state of the homogenization scheme and tell whether "done" and
|
!> @brief update the internal state of the homogenization scheme and tell whether "done" and
|
||||||
! "happy" with result
|
! "happy" with result
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
module function mech_RGC_updateState(P,F,F0,avgF,dt,dPdF,ip,el) result(doneAndHappy)
|
module function mechanical_RGC_updateState(P,F,avgF,dt,dPdF,ce) result(doneAndHappy)
|
||||||
logical, dimension(2) :: doneAndHappy
|
logical, dimension(2) :: doneAndHappy
|
||||||
real(pReal), dimension(:,:,:), intent(in) :: &
|
real(pReal), dimension(:,:,:), intent(in) :: &
|
||||||
P,& !< partitioned stresses
|
P,& !< partitioned stresses
|
||||||
F,& !< partitioned deformation gradients
|
F !< partitioned deformation gradients
|
||||||
F0 !< partitioned initial deformation gradients
|
|
||||||
real(pReal), dimension(:,:,:,:,:), intent(in) :: dPdF !< partitioned stiffnesses
|
real(pReal), dimension(:,:,:,:,:), intent(in) :: dPdF !< partitioned stiffnesses
|
||||||
real(pReal), dimension(3,3), intent(in) :: avgF !< average F
|
real(pReal), dimension(3,3), intent(in) :: avgF !< average F
|
||||||
real(pReal), intent(in) :: dt !< time increment
|
real(pReal), intent(in) :: dt !< time increment
|
||||||
integer, intent(in) :: &
|
integer, intent(in) :: &
|
||||||
ip, & !< integration point number
|
ce !< cell
|
||||||
el !< element number
|
|
||||||
|
|
||||||
integer, dimension(4) :: intFaceN,intFaceP,faceID
|
integer, dimension(4) :: intFaceN,intFaceP,faceID
|
||||||
integer, dimension(3) :: nGDim,iGr3N,iGr3P
|
integer, dimension(3) :: nGDim,iGr3N,iGr3P
|
||||||
integer :: instance,iNum,i,j,nIntFaceTot,iGrN,iGrP,iMun,iFace,k,l,ipert,iGrain,nGrain, of
|
integer :: ho,iNum,i,j,nIntFaceTot,iGrN,iGrP,iMun,iFace,k,l,ipert,iGrain,nGrain, me
|
||||||
real(pReal), dimension(3,3,size(P,3)) :: R,pF,pR,D,pD
|
real(pReal), dimension(3,3,size(P,3)) :: R,pF,pR,D,pD
|
||||||
real(pReal), dimension(3,size(P,3)) :: NN,devNull
|
real(pReal), dimension(3,size(P,3)) :: NN,devNull
|
||||||
real(pReal), dimension(3) :: normP,normN,mornP,mornN
|
real(pReal), dimension(3) :: normP,normN,mornP,mornN
|
||||||
|
@ -272,10 +262,10 @@ module function mech_RGC_updateState(P,F,F0,avgF,dt,dPdF,ip,el) result(doneAndHa
|
||||||
return
|
return
|
||||||
endif zeroTimeStep
|
endif zeroTimeStep
|
||||||
|
|
||||||
instance = homogenization_typeInstance(material_homogenizationAt(el))
|
ho = material_homogenizationAt2(ce)
|
||||||
of = material_homogenizationMemberAt(ip,el)
|
|
||||||
|
|
||||||
associate(stt => state(instance), st0 => state0(instance), dst => dependentState(instance), prm => param(instance))
|
me = material_homogenizationMemberAt2(ce)
|
||||||
|
associate(stt => state(ho), st0 => state0(ho), dst => dependentState(ho), prm => param(ho))
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! get the dimension of the cluster (grains and interfaces)
|
! get the dimension of the cluster (grains and interfaces)
|
||||||
|
@ -289,36 +279,36 @@ module function mech_RGC_updateState(P,F,F0,avgF,dt,dPdF,ip,el) result(doneAndHa
|
||||||
! allocate the size of the global relaxation arrays/jacobian matrices depending on the size of the cluster
|
! allocate the size of the global relaxation arrays/jacobian matrices depending on the size of the cluster
|
||||||
allocate(resid(3*nIntFaceTot), source=0.0_pReal)
|
allocate(resid(3*nIntFaceTot), source=0.0_pReal)
|
||||||
allocate(tract(nIntFaceTot,3), source=0.0_pReal)
|
allocate(tract(nIntFaceTot,3), source=0.0_pReal)
|
||||||
relax = stt%relaxationVector(:,of)
|
relax = stt%relaxationVector(:,me)
|
||||||
drelax = stt%relaxationVector(:,of) - st0%relaxationVector(:,of)
|
drelax = stt%relaxationVector(:,me) - st0%relaxationVector(:,me)
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! computing interface mismatch and stress penalty tensor for all interfaces of all grains
|
! computing interface mismatch and stress penalty tensor for all interfaces of all grains
|
||||||
call stressPenalty(R,NN,avgF,F,ip,el,instance,of)
|
call stressPenalty(R,NN,avgF,F,ho,me)
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! calculating volume discrepancy and stress penalty related to overall volume discrepancy
|
! calculating volume discrepancy and stress penalty related to overall volume discrepancy
|
||||||
call volumePenalty(D,dst%volumeDiscrepancy(of),avgF,F,nGrain,instance,of)
|
call volumePenalty(D,dst%volumeDiscrepancy(me),avgF,F,nGrain)
|
||||||
|
|
||||||
!------------------------------------------------------------------------------------------------
|
!------------------------------------------------------------------------------------------------
|
||||||
! computing the residual stress from the balance of traction at all (interior) interfaces
|
! computing the residual stress from the balance of traction at all (interior) interfaces
|
||||||
do iNum = 1,nIntFaceTot
|
do iNum = 1,nIntFaceTot
|
||||||
faceID = interface1to4(iNum,param(instance)%N_constituents) ! identifying the interface ID in local coordinate system (4-dimensional index)
|
faceID = interface1to4(iNum,param(ho)%N_constituents) ! identifying the interface ID in local coordinate system (4-dimensional index)
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! identify the left/bottom/back grain (-|N)
|
! identify the left/bottom/back grain (-|N)
|
||||||
iGr3N = faceID(2:4) ! identifying the grain ID in local coordinate system (3-dimensional index)
|
iGr3N = faceID(2:4) ! identifying the grain ID in local coordinate system (3-dimensional index)
|
||||||
iGrN = grain3to1(iGr3N,param(instance)%N_constituents) ! translate the local grain ID into global coordinate system (1-dimensional index)
|
iGrN = grain3to1(iGr3N,param(ho)%N_constituents) ! translate the local grain ID into global coordinate system (1-dimensional index)
|
||||||
intFaceN = getInterface(2*faceID(1),iGr3N)
|
intFaceN = getInterface(2*faceID(1),iGr3N)
|
||||||
normN = interfaceNormal(intFaceN,instance,of)
|
normN = interfaceNormal(intFaceN,ho,me)
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! identify the right/up/front grain (+|P)
|
! identify the right/up/front grain (+|P)
|
||||||
iGr3P = iGr3N
|
iGr3P = iGr3N
|
||||||
iGr3P(faceID(1)) = iGr3N(faceID(1))+1 ! identifying the grain ID in local coordinate system (3-dimensional index)
|
iGr3P(faceID(1)) = iGr3N(faceID(1))+1 ! identifying the grain ID in local coordinate system (3-dimensional index)
|
||||||
iGrP = grain3to1(iGr3P,param(instance)%N_constituents) ! translate the local grain ID into global coordinate system (1-dimensional index)
|
iGrP = grain3to1(iGr3P,param(ho)%N_constituents) ! translate the local grain ID into global coordinate system (1-dimensional index)
|
||||||
intFaceP = getInterface(2*faceID(1)-1,iGr3P)
|
intFaceP = getInterface(2*faceID(1)-1,iGr3P)
|
||||||
normP = interfaceNormal(intFaceP,instance,of)
|
normP = interfaceNormal(intFaceP,ho,me)
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! compute the residual of traction at the interface (in local system, 4-dimensional index)
|
! compute the residual of traction at the interface (in local system, 4-dimensional index)
|
||||||
|
@ -346,20 +336,9 @@ module function mech_RGC_updateState(P,F,F0,avgF,dt,dPdF,ip,el) result(doneAndHa
|
||||||
if (residMax < num%rtol*stresMax .or. residMax < num%atol) then
|
if (residMax < num%rtol*stresMax .or. residMax < num%atol) then
|
||||||
doneAndHappy = .true.
|
doneAndHappy = .true.
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
dst%mismatch(1:3,me) = sum(NN,2)/real(nGrain,pReal)
|
||||||
! compute/update the state for postResult, i.e., all energy densities computed by time-integration
|
dst%relaxationRate_avg(me) = sum(abs(drelax))/dt/real(3*nIntFaceTot,pReal)
|
||||||
do iGrain = 1,product(prm%N_constituents)
|
dst%relaxationRate_max(me) = maxval(abs(drelax))/dt
|
||||||
do i = 1,3;do j = 1,3
|
|
||||||
stt%work(of) = stt%work(of) &
|
|
||||||
+ P(i,j,iGrain)*(F(i,j,iGrain) - F0(i,j,iGrain))/real(nGrain,pReal)
|
|
||||||
stt%penaltyEnergy(of) = stt%penaltyEnergy(of) &
|
|
||||||
+ R(i,j,iGrain)*(F(i,j,iGrain) - F0(i,j,iGrain))/real(nGrain,pReal)
|
|
||||||
enddo; enddo
|
|
||||||
enddo
|
|
||||||
|
|
||||||
dst%mismatch(1:3,of) = sum(NN,2)/real(nGrain,pReal)
|
|
||||||
dst%relaxationRate_avg(of) = sum(abs(drelax))/dt/real(3*nIntFaceTot,pReal)
|
|
||||||
dst%relaxationRate_max(of) = maxval(abs(drelax))/dt
|
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -378,18 +357,18 @@ module function mech_RGC_updateState(P,F,F0,avgF,dt,dPdF,ip,el) result(doneAndHa
|
||||||
! ... of the constitutive stress tangent, assembled from dPdF or material constitutive model "smatrix"
|
! ... of the constitutive stress tangent, assembled from dPdF or material constitutive model "smatrix"
|
||||||
allocate(smatrix(3*nIntFaceTot,3*nIntFaceTot), source=0.0_pReal)
|
allocate(smatrix(3*nIntFaceTot,3*nIntFaceTot), source=0.0_pReal)
|
||||||
do iNum = 1,nIntFaceTot
|
do iNum = 1,nIntFaceTot
|
||||||
faceID = interface1to4(iNum,param(instance)%N_constituents) ! assembling of local dPdF into global Jacobian matrix
|
faceID = interface1to4(iNum,param(ho)%N_constituents) ! assembling of local dPdF into global Jacobian matrix
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! identify the left/bottom/back grain (-|N)
|
! identify the left/bottom/back grain (-|N)
|
||||||
iGr3N = faceID(2:4) ! identifying the grain ID in local coordinate sytem
|
iGr3N = faceID(2:4) ! identifying the grain ID in local coordinate sytem
|
||||||
iGrN = grain3to1(iGr3N,param(instance)%N_constituents) ! translate into global grain ID
|
iGrN = grain3to1(iGr3N,param(ho)%N_constituents) ! translate into global grain ID
|
||||||
intFaceN = getInterface(2*faceID(1),iGr3N) ! identifying the connecting interface in local coordinate system
|
intFaceN = getInterface(2*faceID(1),iGr3N) ! identifying the connecting interface in local coordinate system
|
||||||
normN = interfaceNormal(intFaceN,instance,of)
|
normN = interfaceNormal(intFaceN,ho,me)
|
||||||
do iFace = 1,6
|
do iFace = 1,6
|
||||||
intFaceN = getInterface(iFace,iGr3N) ! identifying all interfaces that influence relaxation of the above interface
|
intFaceN = getInterface(iFace,iGr3N) ! identifying all interfaces that influence relaxation of the above interface
|
||||||
mornN = interfaceNormal(intFaceN,instance,of)
|
mornN = interfaceNormal(intFaceN,ho,me)
|
||||||
iMun = interface4to1(intFaceN,param(instance)%N_constituents) ! translate the interfaces ID into local 4-dimensional index
|
iMun = interface4to1(intFaceN,param(ho)%N_constituents) ! translate the interfaces ID into local 4-dimensional index
|
||||||
if (iMun > 0) then ! get the corresponding tangent
|
if (iMun > 0) then ! get the corresponding tangent
|
||||||
do i=1,3; do j=1,3; do k=1,3; do l=1,3
|
do i=1,3; do j=1,3; do k=1,3; do l=1,3
|
||||||
smatrix(3*(iNum-1)+i,3*(iMun-1)+j) = smatrix(3*(iNum-1)+i,3*(iMun-1)+j) &
|
smatrix(3*(iNum-1)+i,3*(iMun-1)+j) = smatrix(3*(iNum-1)+i,3*(iMun-1)+j) &
|
||||||
|
@ -404,13 +383,13 @@ module function mech_RGC_updateState(P,F,F0,avgF,dt,dPdF,ip,el) result(doneAndHa
|
||||||
! identify the right/up/front grain (+|P)
|
! identify the right/up/front grain (+|P)
|
||||||
iGr3P = iGr3N
|
iGr3P = iGr3N
|
||||||
iGr3P(faceID(1)) = iGr3N(faceID(1))+1 ! identifying the grain ID in local coordinate sytem
|
iGr3P(faceID(1)) = iGr3N(faceID(1))+1 ! identifying the grain ID in local coordinate sytem
|
||||||
iGrP = grain3to1(iGr3P,param(instance)%N_constituents) ! translate into global grain ID
|
iGrP = grain3to1(iGr3P,param(ho)%N_constituents) ! translate into global grain ID
|
||||||
intFaceP = getInterface(2*faceID(1)-1,iGr3P) ! identifying the connecting interface in local coordinate system
|
intFaceP = getInterface(2*faceID(1)-1,iGr3P) ! identifying the connecting interface in local coordinate system
|
||||||
normP = interfaceNormal(intFaceP,instance,of)
|
normP = interfaceNormal(intFaceP,ho,me)
|
||||||
do iFace = 1,6
|
do iFace = 1,6
|
||||||
intFaceP = getInterface(iFace,iGr3P) ! identifying all interfaces that influence relaxation of the above interface
|
intFaceP = getInterface(iFace,iGr3P) ! identifying all interfaces that influence relaxation of the above interface
|
||||||
mornP = interfaceNormal(intFaceP,instance,of)
|
mornP = interfaceNormal(intFaceP,ho,me)
|
||||||
iMun = interface4to1(intFaceP,param(instance)%N_constituents) ! translate the interfaces ID into local 4-dimensional index
|
iMun = interface4to1(intFaceP,param(ho)%N_constituents) ! translate the interfaces ID into local 4-dimensional index
|
||||||
if (iMun > 0) then ! get the corresponding tangent
|
if (iMun > 0) then ! get the corresponding tangent
|
||||||
do i=1,3; do j=1,3; do k=1,3; do l=1,3
|
do i=1,3; do j=1,3; do k=1,3; do l=1,3
|
||||||
smatrix(3*(iNum-1)+i,3*(iMun-1)+j) = smatrix(3*(iNum-1)+i,3*(iMun-1)+j) &
|
smatrix(3*(iNum-1)+i,3*(iMun-1)+j) = smatrix(3*(iNum-1)+i,3*(iMun-1)+j) &
|
||||||
|
@ -430,31 +409,31 @@ module function mech_RGC_updateState(P,F,F0,avgF,dt,dPdF,ip,el) result(doneAndHa
|
||||||
do ipert = 1,3*nIntFaceTot
|
do ipert = 1,3*nIntFaceTot
|
||||||
p_relax = relax
|
p_relax = relax
|
||||||
p_relax(ipert) = relax(ipert) + num%pPert ! perturb the relaxation vector
|
p_relax(ipert) = relax(ipert) + num%pPert ! perturb the relaxation vector
|
||||||
stt%relaxationVector(:,of) = p_relax
|
stt%relaxationVector(:,me) = p_relax
|
||||||
call grainDeformation(pF,avgF,instance,of) ! rain deformation from perturbed state
|
call grainDeformation(pF,avgF,ho,me) ! rain deformation from perturbed state
|
||||||
call stressPenalty(pR,DevNull, avgF,pF,ip,el,instance,of) ! stress penalty due to interface mismatch from perturbed state
|
call stressPenalty(pR,DevNull, avgF,pF,ho,me) ! stress penalty due to interface mismatch from perturbed state
|
||||||
call volumePenalty(pD,devNull(1,1), avgF,pF,nGrain,instance,of) ! stress penalty due to volume discrepancy from perturbed state
|
call volumePenalty(pD,devNull(1,1), avgF,pF,nGrain) ! stress penalty due to volume discrepancy from perturbed state
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! computing the global stress residual array from the perturbed state
|
! computing the global stress residual array from the perturbed state
|
||||||
p_resid = 0.0_pReal
|
p_resid = 0.0_pReal
|
||||||
do iNum = 1,nIntFaceTot
|
do iNum = 1,nIntFaceTot
|
||||||
faceID = interface1to4(iNum,param(instance)%N_constituents) ! identifying the interface ID in local coordinate system (4-dimensional index)
|
faceID = interface1to4(iNum,param(ho)%N_constituents) ! identifying the interface ID in local coordinate system (4-dimensional index)
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! identify the left/bottom/back grain (-|N)
|
! identify the left/bottom/back grain (-|N)
|
||||||
iGr3N = faceID(2:4) ! identify the grain ID in local coordinate system (3-dimensional index)
|
iGr3N = faceID(2:4) ! identify the grain ID in local coordinate system (3-dimensional index)
|
||||||
iGrN = grain3to1(iGr3N,param(instance)%N_constituents) ! translate the local grain ID into global coordinate system (1-dimensional index)
|
iGrN = grain3to1(iGr3N,param(ho)%N_constituents) ! translate the local grain ID into global coordinate system (1-dimensional index)
|
||||||
intFaceN = getInterface(2*faceID(1),iGr3N) ! identify the interface ID of the grain
|
intFaceN = getInterface(2*faceID(1),iGr3N) ! identify the interface ID of the grain
|
||||||
normN = interfaceNormal(intFaceN,instance,of)
|
normN = interfaceNormal(intFaceN,ho,me)
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! identify the right/up/front grain (+|P)
|
! identify the right/up/front grain (+|P)
|
||||||
iGr3P = iGr3N
|
iGr3P = iGr3N
|
||||||
iGr3P(faceID(1)) = iGr3N(faceID(1))+1 ! identify the grain ID in local coordinate system (3-dimensional index)
|
iGr3P(faceID(1)) = iGr3N(faceID(1))+1 ! identify the grain ID in local coordinate system (3-dimensional index)
|
||||||
iGrP = grain3to1(iGr3P,param(instance)%N_constituents) ! translate the local grain ID into global coordinate system (1-dimensional index)
|
iGrP = grain3to1(iGr3P,param(ho)%N_constituents) ! translate the local grain ID into global coordinate system (1-dimensional index)
|
||||||
intFaceP = getInterface(2*faceID(1)-1,iGr3P) ! identify the interface ID of the grain
|
intFaceP = getInterface(2*faceID(1)-1,iGr3P) ! identify the interface ID of the grain
|
||||||
normP = interfaceNormal(intFaceP,instance,of)
|
normP = interfaceNormal(intFaceP,ho,me)
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! compute the residual stress (contribution of mismatch and volume penalties) from perturbed state
|
! compute the residual stress (contribution of mismatch and volume penalties) from perturbed state
|
||||||
|
@ -494,11 +473,11 @@ module function mech_RGC_updateState(P,F,F0,avgF,dt,dPdF,ip,el) result(doneAndHa
|
||||||
do i = 1,3*nIntFaceTot;do j = 1,3*nIntFaceTot
|
do i = 1,3*nIntFaceTot;do j = 1,3*nIntFaceTot
|
||||||
drelax(i) = drelax(i) - jnverse(i,j)*resid(j) ! Calculate the correction for the state variable
|
drelax(i) = drelax(i) - jnverse(i,j)*resid(j) ! Calculate the correction for the state variable
|
||||||
enddo; enddo
|
enddo; enddo
|
||||||
stt%relaxationVector(:,of) = relax + drelax ! Updateing the state variable for the next iteration
|
stt%relaxationVector(:,me) = relax + drelax ! Updateing the state variable for the next iteration
|
||||||
if (any(abs(drelax) > num%maxdRelax)) then ! Forcing cutback when the incremental change of relaxation vector becomes too large
|
if (any(abs(drelax) > num%maxdRelax)) then ! Forcing cutback when the incremental change of relaxation vector becomes too large
|
||||||
doneAndHappy = [.true.,.false.]
|
doneAndHappy = [.true.,.false.]
|
||||||
!$OMP CRITICAL (write2out)
|
!$OMP CRITICAL (write2out)
|
||||||
print'(a,i3,a,i3,a)',' RGC_updateState: ip ',ip,' | el ',el,' enforces cutback'
|
print'(a,i3,a,i3,a)',' RGC_updateState: enforces cutback'
|
||||||
print'(a,e15.8)',' due to large relaxation change = ',maxval(abs(drelax))
|
print'(a,e15.8)',' due to large relaxation change = ',maxval(abs(drelax))
|
||||||
flush(IO_STDOUT)
|
flush(IO_STDOUT)
|
||||||
!$OMP END CRITICAL (write2out)
|
!$OMP END CRITICAL (write2out)
|
||||||
|
@ -510,27 +489,26 @@ module function mech_RGC_updateState(P,F,F0,avgF,dt,dPdF,ip,el) result(doneAndHa
|
||||||
!------------------------------------------------------------------------------------------------
|
!------------------------------------------------------------------------------------------------
|
||||||
!> @brief calculate stress-like penalty due to deformation mismatch
|
!> @brief calculate stress-like penalty due to deformation mismatch
|
||||||
!------------------------------------------------------------------------------------------------
|
!------------------------------------------------------------------------------------------------
|
||||||
subroutine stressPenalty(rPen,nMis,avgF,fDef,ip,el,instance,of)
|
subroutine stressPenalty(rPen,nMis,avgF,fDef,ho,me)
|
||||||
|
|
||||||
real(pReal), dimension (:,:,:), intent(out) :: rPen !< stress-like penalty
|
real(pReal), dimension (:,:,:), intent(out) :: rPen !< stress-like penalty
|
||||||
real(pReal), dimension (:,:), intent(out) :: nMis !< total amount of mismatch
|
real(pReal), dimension (:,:), intent(out) :: nMis !< total amount of mismatch
|
||||||
|
|
||||||
real(pReal), dimension (:,:,:), intent(in) :: fDef !< deformation gradients
|
real(pReal), dimension (:,:,:), intent(in) :: fDef !< deformation gradients
|
||||||
real(pReal), dimension (3,3), intent(in) :: avgF !< initial effective stretch tensor
|
real(pReal), dimension (3,3), intent(in) :: avgF !< initial effective stretch tensor
|
||||||
integer, intent(in) :: ip,el,instance,of
|
integer, intent(in) :: ho, me
|
||||||
|
|
||||||
integer, dimension (4) :: intFace
|
integer, dimension (4) :: intFace
|
||||||
integer, dimension (3) :: iGrain3,iGNghb3,nGDim
|
integer, dimension (3) :: iGrain3,iGNghb3,nGDim
|
||||||
real(pReal), dimension (3,3) :: gDef,nDef
|
real(pReal), dimension (3,3) :: gDef,nDef
|
||||||
real(pReal), dimension (3) :: nVect,surfCorr
|
real(pReal), dimension (3) :: nVect,surfCorr
|
||||||
real(pReal), dimension (2) :: Gmoduli
|
|
||||||
integer :: iGrain,iGNghb,iFace,i,j,k,l
|
integer :: iGrain,iGNghb,iFace,i,j,k,l
|
||||||
real(pReal) :: muGrain,muGNghb,nDefNorm
|
real(pReal) :: muGrain,muGNghb,nDefNorm
|
||||||
real(pReal), parameter :: &
|
real(pReal), parameter :: &
|
||||||
nDefToler = 1.0e-10_pReal, &
|
nDefToler = 1.0e-10_pReal, &
|
||||||
b = 2.5e-10_pReal ! Length of Burgers vector
|
b = 2.5e-10_pReal ! Length of Burgers vector
|
||||||
|
|
||||||
nGDim = param(instance)%N_constituents
|
nGDim = param(ho)%N_constituents
|
||||||
rPen = 0.0_pReal
|
rPen = 0.0_pReal
|
||||||
nMis = 0.0_pReal
|
nMis = 0.0_pReal
|
||||||
|
|
||||||
|
@ -538,27 +516,26 @@ module function mech_RGC_updateState(P,F,F0,avgF,dt,dPdF,ip,el) result(doneAndHa
|
||||||
! get the correction factor the modulus of penalty stress representing the evolution of area of
|
! get the correction factor the modulus of penalty stress representing the evolution of area of
|
||||||
! the interfaces due to deformations
|
! the interfaces due to deformations
|
||||||
|
|
||||||
surfCorr = surfaceCorrection(avgF,instance,of)
|
surfCorr = surfaceCorrection(avgF,ho,me)
|
||||||
|
|
||||||
associate(prm => param(instance))
|
|
||||||
|
|
||||||
|
associate(prm => param(ho))
|
||||||
|
|
||||||
!-----------------------------------------------------------------------------------------------
|
!-----------------------------------------------------------------------------------------------
|
||||||
! computing the mismatch and penalty stress tensor of all grains
|
! computing the mismatch and penalty stress tensor of all grains
|
||||||
grainLoop: do iGrain = 1,product(prm%N_constituents)
|
grainLoop: do iGrain = 1,product(prm%N_constituents)
|
||||||
muGrain = equivalentMu(iGrain,ip,el)
|
muGrain = equivalentMu(iGrain,ce)
|
||||||
iGrain3 = grain1to3(iGrain,prm%N_constituents) ! get the grain ID in local 3-dimensional index (x,y,z)-position
|
iGrain3 = grain1to3(iGrain,prm%N_constituents) ! get the grain ID in local 3-dimensional index (x,y,z)-position
|
||||||
|
|
||||||
interfaceLoop: do iFace = 1,6
|
interfaceLoop: do iFace = 1,6
|
||||||
intFace = getInterface(iFace,iGrain3) ! get the 4-dimensional index of the interface in local numbering system of the grain
|
intFace = getInterface(iFace,iGrain3) ! get the 4-dimensional index of the interface in local numbering system of the grain
|
||||||
nVect = interfaceNormal(intFace,instance,of)
|
nVect = interfaceNormal(intFace,ho,me)
|
||||||
iGNghb3 = iGrain3 ! identify the neighboring grain across the interface
|
iGNghb3 = iGrain3 ! identify the neighboring grain across the interface
|
||||||
iGNghb3(abs(intFace(1))) = iGNghb3(abs(intFace(1))) &
|
iGNghb3(abs(intFace(1))) = iGNghb3(abs(intFace(1))) &
|
||||||
+ int(real(intFace(1),pReal)/real(abs(intFace(1)),pReal))
|
+ int(real(intFace(1),pReal)/real(abs(intFace(1)),pReal))
|
||||||
where(iGNghb3 < 1) iGNghb3 = nGDim
|
where(iGNghb3 < 1) iGNghb3 = nGDim
|
||||||
where(iGNghb3 >nGDim) iGNghb3 = 1
|
where(iGNghb3 >nGDim) iGNghb3 = 1
|
||||||
iGNghb = grain3to1(iGNghb3,prm%N_constituents) ! get the ID of the neighboring grain
|
iGNghb = grain3to1(iGNghb3,prm%N_constituents) ! get the ID of the neighboring grain
|
||||||
muGNghb = equivalentMu(iGNghb,ip,el)
|
muGNghb = equivalentMu(iGNghb,ce)
|
||||||
gDef = 0.5_pReal*(fDef(1:3,1:3,iGNghb) - fDef(1:3,1:3,iGrain)) ! difference/jump in deformation gradeint across the neighbor
|
gDef = 0.5_pReal*(fDef(1:3,1:3,iGNghb) - fDef(1:3,1:3,iGrain)) ! difference/jump in deformation gradeint across the neighbor
|
||||||
|
|
||||||
!-------------------------------------------------------------------------------------------
|
!-------------------------------------------------------------------------------------------
|
||||||
|
@ -597,7 +574,7 @@ module function mech_RGC_updateState(P,F,F0,avgF,dt,dPdF,ip,el) result(doneAndHa
|
||||||
!------------------------------------------------------------------------------------------------
|
!------------------------------------------------------------------------------------------------
|
||||||
!> @brief calculate stress-like penalty due to volume discrepancy
|
!> @brief calculate stress-like penalty due to volume discrepancy
|
||||||
!------------------------------------------------------------------------------------------------
|
!------------------------------------------------------------------------------------------------
|
||||||
subroutine volumePenalty(vPen,vDiscrep,fAvg,fDef,nGrain,instance,of)
|
subroutine volumePenalty(vPen,vDiscrep,fAvg,fDef,nGrain)
|
||||||
|
|
||||||
real(pReal), dimension (:,:,:), intent(out) :: vPen ! stress-like penalty due to volume
|
real(pReal), dimension (:,:,:), intent(out) :: vPen ! stress-like penalty due to volume
|
||||||
real(pReal), intent(out) :: vDiscrep ! total volume discrepancy
|
real(pReal), intent(out) :: vDiscrep ! total volume discrepancy
|
||||||
|
@ -605,9 +582,7 @@ module function mech_RGC_updateState(P,F,F0,avgF,dt,dPdF,ip,el) result(doneAndHa
|
||||||
real(pReal), dimension (:,:,:), intent(in) :: fDef ! deformation gradients
|
real(pReal), dimension (:,:,:), intent(in) :: fDef ! deformation gradients
|
||||||
real(pReal), dimension (3,3), intent(in) :: fAvg ! overall deformation gradient
|
real(pReal), dimension (3,3), intent(in) :: fAvg ! overall deformation gradient
|
||||||
integer, intent(in) :: &
|
integer, intent(in) :: &
|
||||||
Ngrain, &
|
Ngrain
|
||||||
instance, &
|
|
||||||
of
|
|
||||||
|
|
||||||
real(pReal), dimension(size(vPen,3)) :: gVol
|
real(pReal), dimension(size(vPen,3)) :: gVol
|
||||||
integer :: i
|
integer :: i
|
||||||
|
@ -637,14 +612,14 @@ module function mech_RGC_updateState(P,F,F0,avgF,dt,dPdF,ip,el) result(doneAndHa
|
||||||
!> @brief compute the correction factor accouted for surface evolution (area change) due to
|
!> @brief compute the correction factor accouted for surface evolution (area change) due to
|
||||||
! deformation
|
! deformation
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
function surfaceCorrection(avgF,instance,of)
|
function surfaceCorrection(avgF,ho,me)
|
||||||
|
|
||||||
real(pReal), dimension(3) :: surfaceCorrection
|
real(pReal), dimension(3) :: surfaceCorrection
|
||||||
|
|
||||||
real(pReal), dimension(3,3), intent(in) :: avgF !< average F
|
real(pReal), dimension(3,3), intent(in) :: avgF !< average F
|
||||||
integer, intent(in) :: &
|
integer, intent(in) :: &
|
||||||
instance, &
|
ho, &
|
||||||
of
|
me
|
||||||
real(pReal), dimension(3,3) :: invC
|
real(pReal), dimension(3,3) :: invC
|
||||||
real(pReal), dimension(3) :: nVect
|
real(pReal), dimension(3) :: nVect
|
||||||
real(pReal) :: detF
|
real(pReal) :: detF
|
||||||
|
@ -655,7 +630,7 @@ module function mech_RGC_updateState(P,F,F0,avgF,dt,dPdF,ip,el) result(doneAndHa
|
||||||
|
|
||||||
surfaceCorrection = 0.0_pReal
|
surfaceCorrection = 0.0_pReal
|
||||||
do iBase = 1,3
|
do iBase = 1,3
|
||||||
nVect = interfaceNormal([iBase,1,1,1],instance,of)
|
nVect = interfaceNormal([iBase,1,1,1],ho,me)
|
||||||
do i = 1,3; do j = 1,3
|
do i = 1,3; do j = 1,3
|
||||||
surfaceCorrection(iBase) = surfaceCorrection(iBase) + invC(i,j)*nVect(i)*nVect(j) ! compute the component of (the inverse of) the stretch in the direction of the normal
|
surfaceCorrection(iBase) = surfaceCorrection(iBase) + invC(i,j)*nVect(i)*nVect(j) ! compute the component of (the inverse of) the stretch in the direction of the normal
|
||||||
enddo; enddo
|
enddo; enddo
|
||||||
|
@ -668,15 +643,17 @@ module function mech_RGC_updateState(P,F,F0,avgF,dt,dPdF,ip,el) result(doneAndHa
|
||||||
!-------------------------------------------------------------------------------------------------
|
!-------------------------------------------------------------------------------------------------
|
||||||
!> @brief compute the equivalent shear and bulk moduli from the elasticity tensor
|
!> @brief compute the equivalent shear and bulk moduli from the elasticity tensor
|
||||||
!-------------------------------------------------------------------------------------------------
|
!-------------------------------------------------------------------------------------------------
|
||||||
real(pReal) function equivalentMu(grainID,ip,el)
|
real(pReal) function equivalentMu(grainID,ce)
|
||||||
|
|
||||||
integer, intent(in) :: &
|
integer, intent(in) :: &
|
||||||
grainID,&
|
grainID,&
|
||||||
ip, & !< integration point number
|
ce
|
||||||
el !< element number
|
|
||||||
|
real(pReal), dimension(6,6) :: C
|
||||||
|
|
||||||
|
|
||||||
equivalentMu = lattice_equivalent_mu(constitutive_homogenizedC(grainID,ip,el),'voigt')
|
C = phase_homogenizedC(material_phaseAt2(grainID,ce),material_phaseMemberAt2(grainID,ce))
|
||||||
|
equivalentMu = lattice_equivalent_mu(C,'voigt')
|
||||||
|
|
||||||
end function equivalentMu
|
end function equivalentMu
|
||||||
|
|
||||||
|
@ -685,14 +662,14 @@ module function mech_RGC_updateState(P,F,F0,avgF,dt,dPdF,ip,el) result(doneAndHa
|
||||||
!> @brief calculating the grain deformation gradient (the same with
|
!> @brief calculating the grain deformation gradient (the same with
|
||||||
! homogenization_RGC_partitionDeformation, but used only for perturbation scheme)
|
! homogenization_RGC_partitionDeformation, but used only for perturbation scheme)
|
||||||
!-------------------------------------------------------------------------------------------------
|
!-------------------------------------------------------------------------------------------------
|
||||||
subroutine grainDeformation(F, avgF, instance, of)
|
subroutine grainDeformation(F, avgF, ho, me)
|
||||||
|
|
||||||
real(pReal), dimension(:,:,:), intent(out) :: F !< partitioned F per grain
|
real(pReal), dimension(:,:,:), intent(out) :: F !< partitioned F per grain
|
||||||
|
|
||||||
real(pReal), dimension(:,:), intent(in) :: avgF !< averaged F
|
real(pReal), dimension(:,:), intent(in) :: avgF !< averaged F
|
||||||
integer, intent(in) :: &
|
integer, intent(in) :: &
|
||||||
instance, &
|
ho, &
|
||||||
of
|
me
|
||||||
|
|
||||||
real(pReal), dimension(3) :: aVect,nVect
|
real(pReal), dimension(3) :: aVect,nVect
|
||||||
integer, dimension(4) :: intFace
|
integer, dimension(4) :: intFace
|
||||||
|
@ -702,15 +679,15 @@ module function mech_RGC_updateState(P,F,F0,avgF,dt,dPdF,ip,el) result(doneAndHa
|
||||||
!-----------------------------------------------------------------------------------------------
|
!-----------------------------------------------------------------------------------------------
|
||||||
! compute the deformation gradient of individual grains due to relaxations
|
! compute the deformation gradient of individual grains due to relaxations
|
||||||
|
|
||||||
associate(prm => param(instance))
|
associate (prm => param(ho))
|
||||||
|
|
||||||
F = 0.0_pReal
|
F = 0.0_pReal
|
||||||
do iGrain = 1,product(prm%N_constituents)
|
do iGrain = 1,product(prm%N_constituents)
|
||||||
iGrain3 = grain1to3(iGrain,prm%N_constituents)
|
iGrain3 = grain1to3(iGrain,prm%N_constituents)
|
||||||
do iFace = 1,6
|
do iFace = 1,6
|
||||||
intFace = getInterface(iFace,iGrain3)
|
intFace = getInterface(iFace,iGrain3)
|
||||||
aVect = relaxationVector(intFace,instance,of)
|
aVect = relaxationVector(intFace,ho,me)
|
||||||
nVect = interfaceNormal(intFace,instance,of)
|
nVect = interfaceNormal(intFace,ho,me)
|
||||||
forall (i=1:3,j=1:3) &
|
forall (i=1:3,j=1:3) &
|
||||||
F(i,j,iGrain) = F(i,j,iGrain) + aVect(i)*nVect(j) ! effective relaxations
|
F(i,j,iGrain) = F(i,j,iGrain) + aVect(i)*nVect(j) ! effective relaxations
|
||||||
enddo
|
enddo
|
||||||
|
@ -721,49 +698,43 @@ module function mech_RGC_updateState(P,F,F0,avgF,dt,dPdF,ip,el) result(doneAndHa
|
||||||
|
|
||||||
end subroutine grainDeformation
|
end subroutine grainDeformation
|
||||||
|
|
||||||
end function mech_RGC_updateState
|
end function mechanical_RGC_updateState
|
||||||
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @brief derive average stress and stiffness from constituent quantities
|
!> @brief derive average stress and stiffness from constituent quantities
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
module subroutine mech_RGC_averageStressAndItsTangent(avgP,dAvgPdAvgF,P,dPdF,instance)
|
module subroutine mechanical_RGC_averageStressAndItsTangent(avgP,dAvgPdAvgF,P,dPdF,ho)
|
||||||
|
|
||||||
real(pReal), dimension (3,3), intent(out) :: avgP !< average stress at material point
|
real(pReal), dimension (3,3), intent(out) :: avgP !< average stress at material point
|
||||||
real(pReal), dimension (3,3,3,3), intent(out) :: dAvgPdAvgF !< average stiffness at material point
|
real(pReal), dimension (3,3,3,3), intent(out) :: dAvgPdAvgF !< average stiffness at material point
|
||||||
|
|
||||||
real(pReal), dimension (:,:,:), intent(in) :: P !< partitioned stresses
|
real(pReal), dimension (:,:,:), intent(in) :: P !< partitioned stresses
|
||||||
real(pReal), dimension (:,:,:,:,:), intent(in) :: dPdF !< partitioned stiffnesses
|
real(pReal), dimension (:,:,:,:,:), intent(in) :: dPdF !< partitioned stiffnesses
|
||||||
integer, intent(in) :: instance
|
integer, intent(in) :: ho
|
||||||
|
|
||||||
avgP = sum(P,3) /real(product(param(instance)%N_constituents),pReal)
|
avgP = sum(P,3) /real(product(param(ho)%N_constituents),pReal)
|
||||||
dAvgPdAvgF = sum(dPdF,5)/real(product(param(instance)%N_constituents),pReal)
|
dAvgPdAvgF = sum(dPdF,5)/real(product(param(ho)%N_constituents),pReal)
|
||||||
|
|
||||||
end subroutine mech_RGC_averageStressAndItsTangent
|
end subroutine mechanical_RGC_averageStressAndItsTangent
|
||||||
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @brief writes results to HDF5 output file
|
!> @brief writes results to HDF5 output file
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
module subroutine mech_RGC_results(instance,group)
|
module subroutine mechanical_RGC_results(ho,group)
|
||||||
|
|
||||||
integer, intent(in) :: instance
|
integer, intent(in) :: ho
|
||||||
character(len=*), intent(in) :: group
|
character(len=*), intent(in) :: group
|
||||||
|
|
||||||
integer :: o
|
integer :: o
|
||||||
|
|
||||||
associate(stt => state(instance), dst => dependentState(instance), prm => param(instance))
|
associate(stt => state(ho), dst => dependentState(ho), prm => param(ho))
|
||||||
outputsLoop: do o = 1,size(prm%output)
|
outputsLoop: do o = 1,size(prm%output)
|
||||||
select case(trim(prm%output(o)))
|
select case(trim(prm%output(o)))
|
||||||
case('W')
|
|
||||||
call results_writeDataset(group,stt%work,trim(prm%output(o)), &
|
|
||||||
'work density','J/m³')
|
|
||||||
case('M')
|
case('M')
|
||||||
call results_writeDataset(group,dst%mismatch,trim(prm%output(o)), &
|
call results_writeDataset(group,dst%mismatch,trim(prm%output(o)), &
|
||||||
'average mismatch tensor','1')
|
'average mismatch tensor','1')
|
||||||
case('R')
|
|
||||||
call results_writeDataset(group,stt%penaltyEnergy,trim(prm%output(o)), &
|
|
||||||
'mismatch penalty density','J/m³')
|
|
||||||
case('Delta_V')
|
case('Delta_V')
|
||||||
call results_writeDataset(group,dst%volumeDiscrepancy,trim(prm%output(o)), &
|
call results_writeDataset(group,dst%volumeDiscrepancy,trim(prm%output(o)), &
|
||||||
'volume discrepancy','m³')
|
'volume discrepancy','m³')
|
||||||
|
@ -777,17 +748,17 @@ module subroutine mech_RGC_results(instance,group)
|
||||||
enddo outputsLoop
|
enddo outputsLoop
|
||||||
end associate
|
end associate
|
||||||
|
|
||||||
end subroutine mech_RGC_results
|
end subroutine mechanical_RGC_results
|
||||||
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @brief collect relaxation vectors of an interface
|
!> @brief collect relaxation vectors of an interface
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
pure function relaxationVector(intFace,instance,of)
|
pure function relaxationVector(intFace,ho,me)
|
||||||
|
|
||||||
real(pReal), dimension (3) :: relaxationVector
|
real(pReal), dimension (3) :: relaxationVector
|
||||||
|
|
||||||
integer, intent(in) :: instance,of
|
integer, intent(in) :: ho,me
|
||||||
integer, dimension(4), intent(in) :: intFace !< set of interface ID in 4D array (normal and position)
|
integer, dimension(4), intent(in) :: intFace !< set of interface ID in 4D array (normal and position)
|
||||||
|
|
||||||
integer :: iNum
|
integer :: iNum
|
||||||
|
@ -795,29 +766,35 @@ pure function relaxationVector(intFace,instance,of)
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! collect the interface relaxation vector from the global state array
|
! collect the interface relaxation vector from the global state array
|
||||||
|
|
||||||
iNum = interface4to1(intFace,param(instance)%N_constituents) ! identify the position of the interface in global state array
|
associate (prm => param(ho), &
|
||||||
|
stt => state(ho))
|
||||||
|
|
||||||
|
iNum = interface4to1(intFace,prm%N_constituents) ! identify the position of the interface in global state array
|
||||||
if (iNum > 0) then
|
if (iNum > 0) then
|
||||||
relaxationVector = state(instance)%relaxationVector((3*iNum-2):(3*iNum),of)
|
relaxationVector = stt%relaxationVector((3*iNum-2):(3*iNum),me)
|
||||||
else
|
else
|
||||||
relaxationVector = 0.0_pReal
|
relaxationVector = 0.0_pReal
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
end associate
|
||||||
|
|
||||||
end function relaxationVector
|
end function relaxationVector
|
||||||
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @brief identify the normal of an interface
|
!> @brief identify the normal of an interface
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
pure function interfaceNormal(intFace,instance,of)
|
pure function interfaceNormal(intFace,ho,me)
|
||||||
|
|
||||||
real(pReal), dimension(3) :: interfaceNormal
|
real(pReal), dimension(3) :: interfaceNormal
|
||||||
|
|
||||||
integer, dimension(4), intent(in) :: intFace !< interface ID in 4D array (normal and position)
|
integer, dimension(4), intent(in) :: intFace !< interface ID in 4D array (normal and position)
|
||||||
integer, intent(in) :: &
|
integer, intent(in) :: &
|
||||||
instance, &
|
ho, &
|
||||||
of
|
me
|
||||||
|
|
||||||
integer :: nPos
|
integer :: nPos
|
||||||
|
associate (dst => dependentState(ho))
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! get the normal of the interface, identified from the value of intFace(1)
|
! get the normal of the interface, identified from the value of intFace(1)
|
||||||
|
@ -825,7 +802,9 @@ pure function interfaceNormal(intFace,instance,of)
|
||||||
nPos = abs(intFace(1)) ! identify the position of the interface in global state array
|
nPos = abs(intFace(1)) ! identify the position of the interface in global state array
|
||||||
interfaceNormal(nPos) = real(intFace(1)/abs(intFace(1)),pReal) ! get the normal vector w.r.t. cluster axis
|
interfaceNormal(nPos) = real(intFace(1)/abs(intFace(1)),pReal) ! get the normal vector w.r.t. cluster axis
|
||||||
|
|
||||||
interfaceNormal = matmul(dependentState(instance)%orientation(1:3,1:3,of),interfaceNormal) ! map the normal vector into sample coordinate system (basis)
|
interfaceNormal = matmul(dst%orientation(1:3,1:3,me),interfaceNormal) ! map the normal vector into sample coordinate system (basis)
|
||||||
|
|
||||||
|
end associate
|
||||||
|
|
||||||
end function interfaceNormal
|
end function interfaceNormal
|
||||||
|
|
||||||
|
@ -970,4 +949,4 @@ pure function interface1to4(iFace1D, nGDim)
|
||||||
end function interface1to4
|
end function interface1to4
|
||||||
|
|
||||||
|
|
||||||
end submodule homogenization_mech_RGC
|
end submodule RGC
|
|
@ -4,7 +4,7 @@
|
||||||
!> @author Philip Eisenlohr, Max-Planck-Institut für Eisenforschung GmbH
|
!> @author Philip Eisenlohr, Max-Planck-Institut für Eisenforschung GmbH
|
||||||
!> @brief Isostrain (full constraint Taylor assuption) homogenization scheme
|
!> @brief Isostrain (full constraint Taylor assuption) homogenization scheme
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
submodule(homogenization:homogenization_mech) homogenization_mech_isostrain
|
submodule(homogenization:mechanical) isostrain
|
||||||
|
|
||||||
enum, bind(c); enumerator :: &
|
enum, bind(c); enumerator :: &
|
||||||
parallel_ID, &
|
parallel_ID, &
|
||||||
|
@ -26,10 +26,9 @@ contains
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @brief allocates all neccessary fields, reads information from material configuration file
|
!> @brief allocates all neccessary fields, reads information from material configuration file
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
module subroutine mech_isostrain_init
|
module subroutine mechanical_isostrain_init
|
||||||
|
|
||||||
integer :: &
|
integer :: &
|
||||||
Ninstances, &
|
|
||||||
h, &
|
h, &
|
||||||
Nmaterialpoints
|
Nmaterialpoints
|
||||||
class(tNode), pointer :: &
|
class(tNode), pointer :: &
|
||||||
|
@ -37,19 +36,18 @@ module subroutine mech_isostrain_init
|
||||||
homog, &
|
homog, &
|
||||||
homogMech
|
homogMech
|
||||||
|
|
||||||
print'(/,a)', ' <<<+- homogenization_mech_isostrain init -+>>>'
|
print'(/,a)', ' <<<+- homogenization:mechanical:isostrain init -+>>>'
|
||||||
|
|
||||||
Ninstances = count(homogenization_type == HOMOGENIZATION_ISOSTRAIN_ID)
|
print'(a,i2)', ' # instances: ',count(homogenization_type == HOMOGENIZATION_ISOSTRAIN_ID); flush(IO_STDOUT)
|
||||||
print'(a,i2)', ' # instances: ',Ninstances; flush(IO_STDOUT)
|
|
||||||
|
|
||||||
allocate(param(Ninstances)) ! one container of parameters per instance
|
|
||||||
|
|
||||||
material_homogenization => config_material%get('homogenization')
|
material_homogenization => config_material%get('homogenization')
|
||||||
|
allocate(param(material_homogenization%length)) ! one container of parameters per homog
|
||||||
|
|
||||||
do h = 1, size(homogenization_type)
|
do h = 1, size(homogenization_type)
|
||||||
if (homogenization_type(h) /= HOMOGENIZATION_ISOSTRAIN_ID) cycle
|
if (homogenization_type(h) /= HOMOGENIZATION_ISOSTRAIN_ID) cycle
|
||||||
homog => material_homogenization%get(h)
|
homog => material_homogenization%get(h)
|
||||||
homogMech => homog%get('mechanics')
|
homogMech => homog%get('mechanics')
|
||||||
associate(prm => param(homogenization_typeInstance(h)))
|
associate(prm => param(h))
|
||||||
|
|
||||||
prm%N_constituents = homogenization_Nconstituents(h)
|
prm%N_constituents = homogenization_Nconstituents(h)
|
||||||
select case(homogMech%get_asString('mapping',defaultVal = 'sum'))
|
select case(homogMech%get_asString('mapping',defaultVal = 'sum'))
|
||||||
|
@ -58,26 +56,25 @@ module subroutine mech_isostrain_init
|
||||||
case ('avg')
|
case ('avg')
|
||||||
prm%mapping = average_ID
|
prm%mapping = average_ID
|
||||||
case default
|
case default
|
||||||
call IO_error(211,ext_msg='sum'//' (mech_isostrain)')
|
call IO_error(211,ext_msg='sum'//' (mechanical_isostrain)')
|
||||||
end select
|
end select
|
||||||
|
|
||||||
Nmaterialpoints = count(material_homogenizationAt == h)
|
Nmaterialpoints = count(material_homogenizationAt == h)
|
||||||
homogState(h)%sizeState = 0
|
homogState(h)%sizeState = 0
|
||||||
allocate(homogState(h)%state0 (0,Nmaterialpoints))
|
allocate(homogState(h)%state0 (0,Nmaterialpoints))
|
||||||
allocate(homogState(h)%subState0(0,Nmaterialpoints))
|
|
||||||
allocate(homogState(h)%state (0,Nmaterialpoints))
|
allocate(homogState(h)%state (0,Nmaterialpoints))
|
||||||
|
|
||||||
end associate
|
end associate
|
||||||
|
|
||||||
enddo
|
enddo
|
||||||
|
|
||||||
end subroutine mech_isostrain_init
|
end subroutine mechanical_isostrain_init
|
||||||
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @brief partitions the deformation gradient onto the constituents
|
!> @brief partitions the deformation gradient onto the constituents
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
module subroutine mech_isostrain_partitionDeformation(F,avgF)
|
module subroutine mechanical_isostrain_partitionDeformation(F,avgF)
|
||||||
|
|
||||||
real(pReal), dimension (:,:,:), intent(out) :: F !< partitioned deformation gradient
|
real(pReal), dimension (:,:,:), intent(out) :: F !< partitioned deformation gradient
|
||||||
|
|
||||||
|
@ -85,22 +82,22 @@ module subroutine mech_isostrain_partitionDeformation(F,avgF)
|
||||||
|
|
||||||
F = spread(avgF,3,size(F,3))
|
F = spread(avgF,3,size(F,3))
|
||||||
|
|
||||||
end subroutine mech_isostrain_partitionDeformation
|
end subroutine mechanical_isostrain_partitionDeformation
|
||||||
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @brief derive average stress and stiffness from constituent quantities
|
!> @brief derive average stress and stiffness from constituent quantities
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
module subroutine mech_isostrain_averageStressAndItsTangent(avgP,dAvgPdAvgF,P,dPdF,instance)
|
module subroutine mechanical_isostrain_averageStressAndItsTangent(avgP,dAvgPdAvgF,P,dPdF,ho)
|
||||||
|
|
||||||
real(pReal), dimension (3,3), intent(out) :: avgP !< average stress at material point
|
real(pReal), dimension (3,3), intent(out) :: avgP !< average stress at material point
|
||||||
real(pReal), dimension (3,3,3,3), intent(out) :: dAvgPdAvgF !< average stiffness at material point
|
real(pReal), dimension (3,3,3,3), intent(out) :: dAvgPdAvgF !< average stiffness at material point
|
||||||
|
|
||||||
real(pReal), dimension (:,:,:), intent(in) :: P !< partitioned stresses
|
real(pReal), dimension (:,:,:), intent(in) :: P !< partitioned stresses
|
||||||
real(pReal), dimension (:,:,:,:,:), intent(in) :: dPdF !< partitioned stiffnesses
|
real(pReal), dimension (:,:,:,:,:), intent(in) :: dPdF !< partitioned stiffnesses
|
||||||
integer, intent(in) :: instance
|
integer, intent(in) :: ho
|
||||||
|
|
||||||
associate(prm => param(instance))
|
associate(prm => param(ho))
|
||||||
|
|
||||||
select case (prm%mapping)
|
select case (prm%mapping)
|
||||||
case (parallel_ID)
|
case (parallel_ID)
|
||||||
|
@ -113,6 +110,6 @@ module subroutine mech_isostrain_averageStressAndItsTangent(avgP,dAvgPdAvgF,P,dP
|
||||||
|
|
||||||
end associate
|
end associate
|
||||||
|
|
||||||
end subroutine mech_isostrain_averageStressAndItsTangent
|
end subroutine mechanical_isostrain_averageStressAndItsTangent
|
||||||
|
|
||||||
end submodule homogenization_mech_isostrain
|
end submodule isostrain
|
|
@ -4,21 +4,21 @@
|
||||||
!> @author Martin Diehl, Max-Planck-Institut für Eisenforschung GmbH
|
!> @author Martin Diehl, Max-Planck-Institut für Eisenforschung GmbH
|
||||||
!> @brief dummy homogenization homogenization scheme for 1 constituent per material point
|
!> @brief dummy homogenization homogenization scheme for 1 constituent per material point
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
submodule(homogenization:homogenization_mech) homogenization_mech_none
|
submodule(homogenization:mechanical) none
|
||||||
|
|
||||||
contains
|
contains
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @brief allocates all necessary fields, reads information from material configuration file
|
!> @brief allocates all necessary fields, reads information from material configuration file
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
module subroutine mech_none_init
|
module subroutine mechanical_pass_init
|
||||||
|
|
||||||
integer :: &
|
integer :: &
|
||||||
Ninstances, &
|
Ninstances, &
|
||||||
h, &
|
h, &
|
||||||
Nmaterialpoints
|
Nmaterialpoints
|
||||||
|
|
||||||
print'(/,a)', ' <<<+- homogenization_mech_none init -+>>>'
|
print'(/,a)', ' <<<+- homogenization:mechanical:pass init -+>>>'
|
||||||
|
|
||||||
Ninstances = count(homogenization_type == HOMOGENIZATION_NONE_ID)
|
Ninstances = count(homogenization_type == HOMOGENIZATION_NONE_ID)
|
||||||
print'(a,i2)', ' # instances: ',Ninstances; flush(IO_STDOUT)
|
print'(a,i2)', ' # instances: ',Ninstances; flush(IO_STDOUT)
|
||||||
|
@ -27,16 +27,15 @@ module subroutine mech_none_init
|
||||||
if(homogenization_type(h) /= HOMOGENIZATION_NONE_ID) cycle
|
if(homogenization_type(h) /= HOMOGENIZATION_NONE_ID) cycle
|
||||||
|
|
||||||
if(homogenization_Nconstituents(h) /= 1) &
|
if(homogenization_Nconstituents(h) /= 1) &
|
||||||
call IO_error(211,ext_msg='N_constituents (mech_none)')
|
call IO_error(211,ext_msg='N_constituents (mechanical_pass)')
|
||||||
|
|
||||||
Nmaterialpoints = count(material_homogenizationAt == h)
|
Nmaterialpoints = count(material_homogenizationAt == h)
|
||||||
homogState(h)%sizeState = 0
|
homogState(h)%sizeState = 0
|
||||||
allocate(homogState(h)%state0 (0,Nmaterialpoints))
|
allocate(homogState(h)%state0 (0,Nmaterialpoints))
|
||||||
allocate(homogState(h)%subState0(0,Nmaterialpoints))
|
|
||||||
allocate(homogState(h)%state (0,Nmaterialpoints))
|
allocate(homogState(h)%state (0,Nmaterialpoints))
|
||||||
|
|
||||||
enddo
|
enddo
|
||||||
|
|
||||||
end subroutine mech_none_init
|
end subroutine mechanical_pass_init
|
||||||
|
|
||||||
end submodule homogenization_mech_none
|
end submodule none
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue