Merge branch 'MiscImprovements' into development

This commit is contained in:
Martin Diehl 2020-03-22 09:38:22 +01:00
commit d920efb8fe
140 changed files with 4873 additions and 7133 deletions

3
.gitignore vendored
View File

@ -1,6 +1,3 @@
*.pyc
*.hdf5
*.xdmf
*.bak *.bak
*~ *~
.DS_Store .DS_Store

View File

@ -77,9 +77,9 @@ variables:
IntelMarc: "$IntelCompiler17_8" IntelMarc: "$IntelCompiler17_8"
HDF5Marc: "HDF5/1.10.5/Intel-17.8" HDF5Marc: "HDF5/1.10.5/Intel-17.8"
# ++++++++++++ Documentation ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # ++++++++++++ Documentation ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Doxygen1_8_15: "Documentation/Doxygen/1.8.15" Doxygen1_8_17: "Documentation/Doxygen/1.8.17"
# ------------ Defaults ---------------------------------------------- # ------------ Defaults ----------------------------------------------
Doxygen: "$Doxygen1_8_15" Doxygen: "$Doxygen1_8_17"
################################################################################################### ###################################################################################################
@ -490,7 +490,7 @@ GridSolver:
stage: createDocumentation stage: createDocumentation
script: script:
- module load $IntelCompiler $MPICH_Intel $PETSc_MPICH_Intel $Doxygen - module load $IntelCompiler $MPICH_Intel $PETSc_MPICH_Intel $Doxygen
- $DAMASKROOT/PRIVATE/documenting/runDoxygen.sh $DAMASKROOT spectral - $DAMASKROOT/PRIVATE/documenting/runDoxygen.sh $DAMASKROOT grid
except: except:
- master - master
- release - release

View File

@ -8,13 +8,13 @@ all: grid mesh processing
.PHONY: grid .PHONY: grid
grid: build/grid grid: build/grid
@(cd build/grid;make -j4 all install;) @(cd build/grid;make -j${DAMASK_NUM_THREADS} all install;)
.PHONY: spectral .PHONY: spectral
spectral: grid spectral: grid
.PHONY: mesh .PHONY: mesh
mesh: build/mesh mesh: build/mesh
@(cd build/mesh; make -j4 all install;) @(cd build/mesh; make -j${DAMASK_NUM_THREADS} all install;)
.PHONY: FEM .PHONY: FEM
FEM: mesh FEM: mesh

@ -1 +1 @@
Subproject commit d0d5b5a22be9778187b100214c782747793bb956 Subproject commit 62bd5ede5260cd4e0e3d1c3930c474c1e045aeef

9
examples/.gitignore vendored
View File

@ -1,9 +1,8 @@
*.C_ref *.C_ref
*.mesh *.hdf5
*.outputConstitutive *.xdmf
*.outputCrystallite
*.outputHomogenization
*.spectralOut
*.sta *.sta
*.vt* *.vt*
*.geom
*.seeds
postProc postProc

View File

@ -3,23 +3,16 @@
elasticity hooke elasticity hooke
plasticity dislotwin plasticity dislotwin
#(output) edge_density (output) rho_mob
#(output) dipole_density (output) rho_dip
#(output) shearrate_slip (output) gamma_sl
#(output) accumulated_shear_slip (output) lambda_sl
#(output) mfp_slip (output) tau_pass
#(output) resolved_stress_slip (output) f_tw
#(output) threshold_stress_slip (output) lambda_tw
#(output) twin_fraction (output) tau_hat_tw
#(output) shearrate_twin (output) f_tr
#(output) accumulated_shear_twin
#(output) mfp_twin
#(output) resolved_stress_twin
#(output) threshold_stress_twin
#(output) shearrate_shearband
#(output) resolved_stress_shearband
#(output) sb_eigenvalues
#(output) sb_eigenvectors
### Material parameters ### ### Material parameters ###
lattice_structure fcc lattice_structure fcc
@ -45,7 +38,6 @@ D0 4.0e-5 # Vacancy diffusion prefactor [m**2/s]
Qsd 4.5e-19 # Activation energy for climb [J] Qsd 4.5e-19 # Activation energy for climb [J]
Catomicvolume 1.0 # Adj. parameter controlling the atomic volume [in b^3] Catomicvolume 1.0 # Adj. parameter controlling the atomic volume [in b^3]
Cedgedipmindistance 1.0 # Adj. parameter controlling the minimum dipole distance [in b] Cedgedipmindistance 1.0 # Adj. parameter controlling the minimum dipole distance [in b]
atol_rho 1.0
interactionSlipSlip 0.122 0.122 0.625 0.07 0.137 0.122 # Interaction coefficients (Kubin et al. 2008) interactionSlipSlip 0.122 0.122 0.625 0.07 0.137 0.122 # Interaction coefficients (Kubin et al. 2008)
### Shearband parameters ### ### Shearband parameters ###
@ -68,6 +60,5 @@ Cmfptwin 1.0 # Adj. parameter controlling twin mean free
Cthresholdtwin 1.0 # Adj. parameter controlling twin threshold stress Cthresholdtwin 1.0 # Adj. parameter controlling twin threshold stress
interactionSlipTwin 0.0 1.0 1.0 # Dislocation-Twin interaction coefficients interactionSlipTwin 0.0 1.0 1.0 # Dislocation-Twin interaction coefficients
interactionTwinTwin 0.0 1.0 # Twin-Twin interaction coefficients interactionTwinTwin 0.0 1.0 # Twin-Twin interaction coefficients
atol_twinFrac 1.0e-7
SFE_0K -0.0396 # stacking fault energy at zero K; TWIP steel: -0.0526; Cu: -0.0396 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 dSFE_dT 0.0002 # temperature dependance of stacking fault energy

View File

@ -18,4 +18,3 @@ n 20
h0 75e6 h0 75e6
tausat 63e6 tausat 63e6
a 2.25 a 2.25
atol_resistance 1

View File

@ -22,4 +22,3 @@ h0 1e6
n 5 n 5
m 3 m 3
a 2 a 2
atol_resistance 1

View File

@ -66,6 +66,4 @@ cutoffRadius 1e-3 # cutoff radius for dislocation
CFLfactor 2.0 # safety factor for CFL flux check (numerical parameter) CFLfactor 2.0 # safety factor for CFL flux check (numerical parameter)
significantRho 1e6 # minimum dislocation density considered relevant in m/m**3 significantRho 1e6 # minimum dislocation density considered relevant in m/m**3
#significantN 0.1 # minimum dislocation number per ip considered relevant #significantN 0.1 # minimum dislocation number per ip considered relevant
aTol_density 1e4 # absolute tolerance for dislocation density in m/m**3
aTol_shear 1e-20 # absolute tolerance for plasgtic shear
randomMultiplication 0 # switch for probabilistic extension of multiplication rate randomMultiplication 0 # switch for probabilistic extension of multiplication rate

View File

@ -27,7 +27,7 @@ Nslip 12 # number of slip systems per family
c11 246.5e9 c11 246.5e9
c12 147.3e9 c12 147.3e9
c44 124.7e9 c44 124.7e9
burgers 2.48e-10 0 0 0 # Burgers vector in m burgers 2.48e-10 # Burgers vector in m
rhoSglEdgePos0 6e10 # Initial positive edge single dislocation density in m/m**3 rhoSglEdgePos0 6e10 # Initial positive edge single dislocation density in m/m**3
rhoSglEdgeNeg0 6e10 # Initial negative edge single dislocation density in m/m**3 rhoSglEdgeNeg0 6e10 # Initial negative edge single dislocation density in m/m**3
rhoSglScrewPos0 6e10 # Initial positive screw single dislocation density in m/m**3 rhoSglScrewPos0 6e10 # Initial positive screw single dislocation density in m/m**3
@ -55,8 +55,6 @@ q 1 # exponent for thermal barrier
attackFrequency 50e9 # attack frequency in Hz attackFrequency 50e9 # attack frequency in Hz
surfaceTransmissivity 1.0 # transmissivity of free surfaces for dislocation flux surfaceTransmissivity 1.0 # transmissivity of free surfaces for dislocation flux
grainBoundaryTransmissivity 0.0 grainBoundaryTransmissivity 0.0
aTol_rho 1e100 # absolute tolerance for dislocation density in m/m**3
aTol_shear 1e10 # absolute tolerance for dislocation density in m/m**3
significantRho 1e8 # dislocation density considered relevant in m/m**3 significantRho 1e8 # dislocation density considered relevant in m/m**3
significantN 1 significantN 1
shortRangeStressCorrection 0 shortRangeStressCorrection 0

View File

@ -3,13 +3,10 @@ elasticity hooke
plasticity phenopowerlaw plasticity phenopowerlaw
(output) resistance_slip (output) resistance_slip
(output) shearrate_slip (output) accumulatedshear_slip
(output) resolvedstress_slip
(output) accumulated_shear_slip
lattice_structure fcc lattice_structure fcc
Nslip 12 # per family Nslip 12 # per family
Ntwin 0 # per family
c11 106.75e9 c11 106.75e9
c12 60.41e9 c12 60.41e9
@ -22,4 +19,3 @@ tausat_slip 63e6 # per family
a_slip 2.25 a_slip 2.25
h0_slipslip 75e6 h0_slipslip 75e6
interaction_slipslip 1 1 1.4 1.4 1.4 1.4 interaction_slipslip 1 1 1.4 1.4 1.4 1.4
atol_resistance 1

View File

@ -1,5 +1,3 @@
# parameters fitted by D. Ma to: # parameters fitted by D. Ma to:
# I. Kovács, G. Vörös # I. Kovács, G. Vörös
# On the mathematical description of the tensile stress-strain curves of polycrystalline face centered cubic metals # On the mathematical description of the tensile stress-strain curves of polycrystalline face centered cubic metals
@ -7,20 +5,13 @@
# DOI: 10.1016/S0749-6419(95)00043-7 # DOI: 10.1016/S0749-6419(95)00043-7
[gold_phenopowerlaw] [gold_phenopowerlaw]
# slip only
elasticity hooke elasticity hooke
plasticity phenopowerlaw plasticity phenopowerlaw
(output) resistance_slip (output) resistance_slip
(output) shearrate_slip
(output) resolvedstress_slip
(output) resistance_twin
(output) shearrate_twin
(output) resolvedstress_twin
lattice_structure fcc lattice_structure fcc
Nslip 12 # per family Nslip 12 # per family
Ntwin 0 # per family
c11 191.0e9 c11 191.0e9
c12 162.0e9 c12 162.0e9
@ -31,9 +22,6 @@ n_slip 83.3
tau0_slip 26.25e6 # per family tau0_slip 26.25e6 # per family
tausat_slip 53.00e6 # per family tausat_slip 53.00e6 # per family
a_slip 1.0 a_slip 1.0
gdot0_twin 0.001
n_twin 20
h0_slipslip 75e6 h0_slipslip 75e6
interaction_slipslip 1 1 1.4 1.4 1.4 1.4 interaction_slipslip 1 1 1.4 1.4 1.4 1.4
atol_resistance 1

View File

@ -7,11 +7,7 @@ plasticity phenopowerlaw
elasticity hooke elasticity hooke
(output) resistance_slip (output) resistance_slip
(output) shearrate_slip
(output) resolvedstress_slip
(output) resistance_twin (output) resistance_twin
(output) shearrate_twin
(output) resolvedstress_twin
lattice_structure hex lattice_structure hex
c/a 1.62350 # from Tromans 2011, Elastic Anisotropy of HCP Metal Crystals and Polycrystals c/a 1.62350 # from Tromans 2011, Elastic Anisotropy of HCP Metal Crystals and Polycrystals
@ -45,9 +41,6 @@ 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 # open for discussion
#################################################### ####################################################
atol_resistance 1
atol_shear 1e-6
atol_twinfrac 1e-6
n_twin 20 n_twin 20
n_slip 20 n_slip 20

View File

@ -2,13 +2,6 @@
plasticity phenopowerlaw plasticity phenopowerlaw
elasticity hooke elasticity hooke
# (output) resistance_slip
# (output) shearrate_slip
# (output) resolvedstress_slip
# (output) resistance_twin
# (output) shearrate_twin
# (output) resolvedstress_twin
lattice_structure hex lattice_structure hex
covera_ratio 1.587 covera_ratio 1.587
@ -21,28 +14,10 @@ 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 # 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 gdot0_slip 0.001
n_slip 20 n_slip 20
nslip 3 3 0 6 0 0 nslip 3 3 0 6
tau0_slip 349.3e6 150e6 0 1107.9e6 0 0 tau0_slip 349.3e6 150e6 0 1107.9e6
tausat_slip 568.6e6 1502.2e6 0 3420.1e6 0 0 tausat_slip 568.6e6 1502.2e6 0 3420.1e6
a_slip 2 a_slip 2
ntwin 0 0 0 0
gdot0_twin 0.001 0 0 0
n_twin 20
tau0_twin 31e6 0 0 0 0
s_pr 0
twin_b 0
twin_c 0
twin_d 0
twin_e 0
h0_slipslip 15e6 h0_slipslip 15e6
h0_twinslip 15e6
h0_twintwin 15e6
atol_resistance 1
#atol_shear 1e-6
#atol_twinfrac 1e-7
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 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
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
interaction_twintwin 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
#nonschmid_coefficients 0

View File

@ -14,7 +14,6 @@ plasticity phenopowerlaw
lattice_structure fcc lattice_structure fcc
Nslip 12 # per family Nslip 12 # per family
Ntwin 0 # per family
c11 106.75e9 c11 106.75e9
c12 60.41e9 c12 60.41e9
@ -25,22 +24,8 @@ n_slip 20
tau0_slip 31e6 # per family tau0_slip 31e6 # per family
tausat_slip 63e6 # per family tausat_slip 63e6 # per family
a_slip 2.25 a_slip 2.25
gdot0_twin 0.001
n_twin 20
tau0_twin 31e6 # per family
s_pr 0 # push-up factor for slip saturation due to twinning
twin_b 0
twin_c 0
twin_d 0
twin_e 0
h0_slipslip 75e6 h0_slipslip 75e6
h0_twinslip 0
h0_twintwin 0
interaction_slipslip 1 1 1.4 1.4 1.4 1.4 interaction_slipslip 1 1 1.4 1.4 1.4 1.4
interaction_sliptwin 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
interaction_twintwin 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
atol_resistance 1
(output) f (output) f
(output) p (output) p

View File

@ -1,8 +1,7 @@
4 header 3 header
grid a 16 b 16 c 16 grid a 16 b 16 c 16
microstructures 20
random seed 0 random seed 0
1_pos 2_pos 3_pos 1_eulerangels 2_eulerangels 3_eulerangels 1_pos 2_pos 3_pos 1_euler 2_euler 3_euler
0.375488 0.161813 0.891040 197.572861 16.816409 129.422844 0.375488 0.161813 0.891040 197.572861 16.816409 129.422844
0.187988 0.849313 0.953540 257.468172 53.250534 157.331503 0.187988 0.849313 0.953540 257.468172 53.250534 157.331503
0.750488 0.349313 0.953540 216.994815 94.418518 251.147231 0.750488 0.349313 0.953540 216.994815 94.418518 251.147231

View File

@ -12,16 +12,7 @@ mech none
elasticity hooke elasticity hooke
plasticity phenopowerlaw plasticity phenopowerlaw
(output) resistance_slip (output) resistance_slip
(output) shearrate_slip
(output) resolvedstress_slip
(output) accumulatedshear_slip
(output) resistance_twin
(output) shearrate_twin
(output) resolvedstress_twin
(output) accumulatedshear_twin
# only for HDF5 out
(output) orientation # quaternion (output) orientation # quaternion
(output) F # deformation gradient tensor (output) F # deformation gradient tensor
(output) Fe # elastic deformation gradient tensor (output) Fe # elastic deformation gradient tensor
@ -32,7 +23,6 @@ plasticity phenopowerlaw
lattice_structure fcc lattice_structure fcc
Nslip 12 # per family Nslip 12 # per family
Ntwin 0 # per family
c11 106.75e9 c11 106.75e9
c12 60.41e9 c12 60.41e9
@ -45,7 +35,6 @@ tausat_slip 63e6 # per family
a_slip 2.25 a_slip 2.25
h0_slipslip 75e6 h0_slipslip 75e6
interaction_slipslip 1 1 1.4 1.4 1.4 1.4 interaction_slipslip 1 1 1.4 1.4 1.4 1.4
atol_resistance 1
#-------------------# #-------------------#
<microstructure> <microstructure>

View File

@ -15,10 +15,6 @@ scriptID = ' '.join([scriptName,damask.version])
# -------------------------------------------------------------------- # --------------------------------------------------------------------
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
#ToDo: We need to decide on a way of handling arguments of variable lentght
#https://stackoverflow.com/questions/15459997/passing-integer-lists-to-python
#parser.add_argument('--version', action='version', version='%(prog)s {}'.format(scriptID))
parser.add_argument('filenames', nargs='+', parser.add_argument('filenames', nargs='+',
help='DADF5 files') help='DADF5 files')
parser.add_argument('-d','--dir', dest='dir',default='postProc',metavar='string', parser.add_argument('-d','--dir', dest='dir',default='postProc',metavar='string',
@ -33,42 +29,35 @@ options = parser.parse_args()
if options.mat is None: options.mat=[] if options.mat is None: options.mat=[]
if options.con is None: options.con=[] if options.con is None: options.con=[]
# --- loop over input files ------------------------------------------------------------------------
for filename in options.filenames: for filename in options.filenames:
results = damask.DADF5(filename) results = damask.Result(filename)
if not results.structured: continue if not results.structured: continue
if results.version_major == 0 and results.version_minor >= 5:
coords = damask.grid_filters.cell_coord0(results.grid,results.size,results.origin) coords = damask.grid_filters.cell_coord0(results.grid,results.size,results.origin)
else:
coords = damask.grid_filters.cell_coord0(results.grid,results.size)
N_digits = int(np.floor(np.log10(int(results.increments[-1][3:]))))+1 N_digits = int(np.floor(np.log10(int(results.increments[-1][3:]))))+1
N_digits = 5 # hack to keep test intact N_digits = 5 # hack to keep test intact
for i,inc in enumerate(results.iter_visible('increments')): for inc in damask.util.show_progress(results.iterate('increments'),len(results.increments)):
print('Output step {}/{}'.format(i+1,len(results.increments))) table = damask.Table(np.ones(np.product(results.grid),dtype=int)*int(inc[3:]),{'inc':(1,)})
table.add('pos',coords.reshape(-1,3))
table = damask.Table(np.ones(np.product(results.grid),dtype=int)*int(inc[3:]),{'inc':(1,)}) results.pick('materialpoints',False)
table.add('pos',coords.reshape((-1,3))) results.pick('constituents', True)
for label in options.con:
x = results.get_dataset_location(label)
if len(x) != 0:
table.add(label,results.read_dataset(x,0,plain=True).reshape(results.grid.prod(),-1))
results.pick('materialpoints',False) results.pick('constituents', False)
results.pick('constituents', True) results.pick('materialpoints',True)
for label in options.con: 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:
table.add(label,results.read_dataset(x,0,plain=True).reshape((results.grid.prod(),-1))) table.add(label,results.read_dataset(x,0,plain=True).reshape(results.grid.prod(),-1))
results.pick('constituents', False) dirname = os.path.abspath(os.path.join(os.path.dirname(filename),options.dir))
results.pick('materialpoints',True) if not os.path.isdir(dirname):
for label in options.mat: os.mkdir(dirname,0o755)
x = results.get_dataset_location(label) file_out = '{}_inc{}.txt'.format(os.path.splitext(os.path.split(filename)[-1])[0],
if len(x) != 0: inc[3:].zfill(N_digits))
table.add(label,results.read_dataset(x,0,plain=True).reshape((results.grid.prod(),-1))) table.to_ASCII(os.path.join(dirname,file_out))
dirname = os.path.abspath(os.path.join(os.path.dirname(filename),options.dir))
if not os.path.isdir(dirname):
os.mkdir(dirname,0o755)
file_out = '{}_inc{}.txt'.format(os.path.splitext(os.path.split(filename)[-1])[0],
inc[3:].zfill(N_digits))
table.to_ASCII(os.path.join(dirname,file_out))

View File

@ -48,101 +48,91 @@ Phase_types = {'Primary': 0} #further additions to these can be done by looking
# MAIN # MAIN
# -------------------------------------------------------------------- # --------------------------------------------------------------------
parser = argparse.ArgumentParser(description='Creating a file for DREAM3D from DAMASK data') parser = argparse.ArgumentParser(description='Creating a file for DREAM3D from DAMASK data')
parser.add_argument('filenames',nargs='+',help='HDF5 based output file') parser.add_argument('filenames', nargs='+',
parser.add_argument('--inc',nargs='+',help='Increment for which DREAM3D to be used, eg. 25',type=int) help='DADF5 files')
parser.add_argument('-d','--dir', dest='dir',default='postProc',metavar='string', parser.add_argument('-d','--dir', dest='dir',default='postProc',metavar='string',
help='name of subdirectory to hold output') help='name of subdirectory relative to the location of the DADF5 file to hold output')
parser.add_argument('--inc',nargs='+',
help='Increment for which DREAM3D to be used, eg. 25',type=int)
options = parser.parse_args() options = parser.parse_args()
# --------------------------------------------------------------------
# loop over input files
for filename in options.filenames: for filename in options.filenames:
f = damask.DADF5(filename) #DAMASK output file f = damask.Result(filename)
for increment in options.inc: N_digits = int(np.floor(np.log10(int(f.increments[-1][3:]))))+1
f.set_by_increment(increment,increment)
if len(f.visible['increments']) == 0:
continue
#-------output file creation------------------------------------- f.pick('increments',options.inc)
dirname = os.path.abspath(os.path.join(os.path.dirname(filename),options.dir)) for inc in damask.util.show_progress(f.iterate('increments'),len(f.selection['increments'])):
try: dirname = os.path.abspath(os.path.join(os.path.dirname(filename),options.dir))
os.mkdir(dirname) try:
except FileExistsError: os.mkdir(dirname)
pass except FileExistsError:
pass
o = h5py.File(dirname + '/' + os.path.splitext(filename)[0] + '_{}.dream3D'.format(increment),'w') o = h5py.File(dirname + '/' + os.path.splitext(filename)[0] \
#----------------------------------------------------------------- + '_inc_{}.dream3D'.format(inc[3:].zfill(N_digits)),'w')
o.attrs['DADF5toDREAM3D'] = '1.0' o.attrs['DADF5toDREAM3D'] = '1.0'
o.attrs['FileVersion'] = '7.0' o.attrs['FileVersion'] = '7.0'
#-----------------------------------------------------------------
for g in ['DataContainerBundles','Pipeline']: # empty groups (needed)
o.create_group(g)
for g in ['DataContainerBundles','Pipeline']: # empty groups (needed) data_container_label = 'DataContainers/ImageDataContainer'
o.create_group(g) cell_data_label = data_container_label + '/CellData'
data_container_label = 'DataContainers/ImageDataContainer' # Phase information of DREAM.3D is constituent ID in DAMASK
cell_data_label = data_container_label + '/CellData' o[cell_data_label + '/Phases'] = f.get_constituent_ID().reshape(tuple(f.grid)+(1,))
DAMASK_quaternion = f.read_dataset(f.get_dataset_location('orientation'))
# Convert: DAMASK uses P = -1, DREAM.3D uses P = +1. Also change position of imagninary part
DREAM_3D_quaternion = np.hstack((-DAMASK_quaternion['x'],-DAMASK_quaternion['y'],-DAMASK_quaternion['z'],
DAMASK_quaternion['w'])).astype(np.float32)
o[cell_data_label + '/Quats'] = DREAM_3D_quaternion.reshape(tuple(f.grid)+(4,))
# Attributes to CellData group
o[cell_data_label].attrs['AttributeMatrixType'] = np.array([3],np.uint32)
o[cell_data_label].attrs['TupleDimensions'] = f.grid.astype(np.uint64)
# Phase information of DREAM.3D is constituent ID in DAMASK # Common Attributes for groups in CellData
o[cell_data_label + '/Phases'] = f.get_constituent_ID().reshape(tuple(f.grid)+(1,)) for group in ['/Phases','/Quats']:
# Data quaternions o[cell_data_label + group].attrs['DataArrayVersion'] = np.array([2],np.int32)
DAMASK_quaternion = f.read_dataset(f.get_dataset_location('orientation')) o[cell_data_label + group].attrs['Tuple Axis Dimensions'] = 'x={},y={},z={}'.format(*f.grid)
# Convert: DAMASK uses P = -1, DREAM.3D uses P = +1. Also change position of imagninary part
DREAM_3D_quaternion = np.hstack((-DAMASK_quaternion['x'],-DAMASK_quaternion['y'],-DAMASK_quaternion['z'],
DAMASK_quaternion['w'])).astype(np.float32)
o[cell_data_label + '/Quats'] = DREAM_3D_quaternion.reshape(tuple(f.grid)+(4,))
# Attributes to CellData group o[cell_data_label + '/Phases'].attrs['ComponentDimensions'] = np.array([1],np.uint64)
o[cell_data_label].attrs['AttributeMatrixType'] = np.array([3],np.uint32) o[cell_data_label + '/Phases'].attrs['ObjectType'] = 'DataArray<int32_t>'
o[cell_data_label].attrs['TupleDimensions'] = f.grid.astype(np.uint64) o[cell_data_label + '/Phases'].attrs['TupleDimensions'] = f.grid.astype(np.uint64)
# Common Attributes for groups in CellData o[cell_data_label + '/Quats'].attrs['ComponentDimensions'] = np.array([4],np.uint64)
for group in ['/Phases','/Quats']: o[cell_data_label + '/Quats'].attrs['ObjectType'] = 'DataArray<float>'
o[cell_data_label + group].attrs['DataArrayVersion'] = np.array([2],np.int32) o[cell_data_label + '/Quats'].attrs['TupleDimensions'] = f.grid.astype(np.uint64)
o[cell_data_label + group].attrs['Tuple Axis Dimensions'] = 'x={},y={},z={}'.format(*f.grid)
# phase attributes # Create EnsembleAttributeMatrix
o[cell_data_label + '/Phases'].attrs['ComponentDimensions'] = np.array([1],np.uint64) ensemble_label = data_container_label + '/EnsembleAttributeMatrix'
o[cell_data_label + '/Phases'].attrs['ObjectType'] = 'DataArray<int32_t>'
o[cell_data_label + '/Phases'].attrs['TupleDimensions'] = f.grid.astype(np.uint64)
# Quats attributes # Data CrystalStructures
o[cell_data_label + '/Quats'].attrs['ComponentDimensions'] = np.array([4],np.uint64) o[ensemble_label + '/CrystalStructures'] = np.uint32(np.array([999,\
o[cell_data_label + '/Quats'].attrs['ObjectType'] = 'DataArray<float>' Crystal_structures[f.get_crystal_structure()]])).reshape(2,1)
o[cell_data_label + '/Quats'].attrs['TupleDimensions'] = f.grid.astype(np.uint64) o[ensemble_label + '/PhaseTypes'] = np.uint32(np.array([999,Phase_types['Primary']])).reshape(2,1) # ToDo
# Create EnsembleAttributeMatrix # Attributes Ensemble Matrix
ensemble_label = data_container_label + '/EnsembleAttributeMatrix' o[ensemble_label].attrs['AttributeMatrixType'] = np.array([11],np.uint32)
o[ensemble_label].attrs['TupleDimensions'] = np.array([2], np.uint64)
# Data CrystalStructures # Attributes for data in Ensemble matrix
o[ensemble_label + '/CrystalStructures'] = np.uint32(np.array([999,\ for group in ['CrystalStructures','PhaseTypes']: # 'PhaseName' not required MD: But would be nice to take the phase name mapping
Crystal_structures[f.get_crystal_structure()]])).reshape((2,1)) o[ensemble_label+'/'+group].attrs['ComponentDimensions'] = np.array([1],np.uint64)
o[ensemble_label + '/PhaseTypes'] = np.uint32(np.array([999,Phase_types['Primary']])).reshape((2,1)) # ToDo o[ensemble_label+'/'+group].attrs['Tuple Axis Dimensions'] = 'x=2'
o[ensemble_label+'/'+group].attrs['DataArrayVersion'] = np.array([2],np.int32)
o[ensemble_label+'/'+group].attrs['ObjectType'] = 'DataArray<uint32_t>'
o[ensemble_label+'/'+group].attrs['TupleDimensions'] = np.array([2],np.uint64)
# Attributes Ensemble Matrix geom_label = data_container_label + '/_SIMPL_GEOMETRY'
o[ensemble_label].attrs['AttributeMatrixType'] = np.array([11],np.uint32)
o[ensemble_label].attrs['TupleDimensions'] = np.array([2], np.uint64)
# Attributes for data in Ensemble matrix o[geom_label + '/DIMENSIONS'] = np.int64(f.grid)
for group in ['CrystalStructures','PhaseTypes']: # 'PhaseName' not required MD: But would be nice to take the phase name mapping o[geom_label + '/ORIGIN'] = np.float32(np.zeros(3))
o[ensemble_label+'/'+group].attrs['ComponentDimensions'] = np.array([1],np.uint64) o[geom_label + '/SPACING'] = np.float32(f.size)
o[ensemble_label+'/'+group].attrs['Tuple Axis Dimensions'] = 'x=2'
o[ensemble_label+'/'+group].attrs['DataArrayVersion'] = np.array([2],np.int32)
o[ensemble_label+'/'+group].attrs['ObjectType'] = 'DataArray<uint32_t>'
o[ensemble_label+'/'+group].attrs['TupleDimensions'] = np.array([2],np.uint64)
o[geom_label].attrs['GeometryName'] = 'ImageGeometry'
# Create geometry info o[geom_label].attrs['GeometryTypeName'] = 'ImageGeometry'
geom_label = data_container_label + '/_SIMPL_GEOMETRY' o[geom_label].attrs['GeometryType'] = np.array([0],np.uint32)
o[geom_label].attrs['SpatialDimensionality'] = np.array([3],np.uint32)
o[geom_label + '/DIMENSIONS'] = np.int64(f.grid) o[geom_label].attrs['UnitDimensionality'] = np.array([3],np.uint32)
o[geom_label + '/ORIGIN'] = np.float32(np.zeros(3))
o[geom_label + '/SPACING'] = np.float32(f.size)
o[geom_label].attrs['GeometryName'] = 'ImageGeometry'
o[geom_label].attrs['GeometryTypeName'] = 'ImageGeometry'
o[geom_label].attrs['GeometryType'] = np.array([0],np.uint32)
o[geom_label].attrs['SpatialDimensionality'] = np.array([3],np.uint32)
o[geom_label].attrs['UnitDimensionality'] = np.array([3],np.uint32)

View File

@ -40,7 +40,7 @@ def volTetrahedron(coords):
# Get all the squares of all side lengths from the differences between # Get all the squares of all side lengths from the differences between
# the 6 different pairs of vertex positions # the 6 different pairs of vertex positions
vertices = np.concatenate((coords[0],coords[1],coords[2],coords[3])).reshape([4,3]) vertices = np.concatenate((coords[0],coords[1],coords[2],coords[3])).reshape(4,3)
vertex1, vertex2 = vertex_pair_indexes[:,0], vertex_pair_indexes[:,1] vertex1, vertex2 = vertex_pair_indexes[:,0], vertex_pair_indexes[:,1]
sides_squared = np.sum((vertices[vertex1] - vertices[vertex2])**2,axis=-1) sides_squared = np.sum((vertices[vertex1] - vertices[vertex2])**2,axis=-1)
@ -185,13 +185,13 @@ for name in filenames:
centers = damask.grid_filters.cell_coord(size,F) centers = damask.grid_filters.cell_coord(size,F)
shapeMismatch = shapeMismatch( size,table.get(options.defgrad).reshape(grid[2],grid[1],grid[0],3,3),nodes,centers) shapeMismatch = shapeMismatch( size,table.get(options.defgrad).reshape(grid[2],grid[1],grid[0],3,3),nodes,centers)
table.add('shapeMismatch(({}))'.format(options.defgrad), table.add('shapeMismatch(({}))'.format(options.defgrad),
shapeMismatch.reshape((-1,1)), shapeMismatch.reshape(-1,1),
scriptID+' '+' '.join(sys.argv[1:])) scriptID+' '+' '.join(sys.argv[1:]))
if options.volume: if options.volume:
volumeMismatch = volumeMismatch(size,table.get(options.defgrad).reshape(grid[2],grid[1],grid[0],3,3),nodes) volumeMismatch = volumeMismatch(size,table.get(options.defgrad).reshape(grid[2],grid[1],grid[0],3,3),nodes)
table.add('volMismatch(({}))'.format(options.defgrad), table.add('volMismatch(({}))'.format(options.defgrad),
volumeMismatch.reshape((-1,1)), volumeMismatch.reshape(-1,1),
scriptID+' '+' '.join(sys.argv[1:])) scriptID+' '+' '.join(sys.argv[1:]))
table.to_ASCII(sys.stdout if name is None else name) table.to_ASCII(sys.stdout if name is None else name)

View File

@ -51,7 +51,7 @@ for name in filenames:
shape = (3,) if np.prod(field.shape)//np.prod(grid) == 3 else (3,3) # vector or tensor shape = (3,) if np.prod(field.shape)//np.prod(grid) == 3 else (3,3) # vector or tensor
field = field.reshape(np.append(grid[::-1],shape)) field = field.reshape(np.append(grid[::-1],shape))
table.add('curlFFT({})'.format(label), table.add('curlFFT({})'.format(label),
damask.grid_filters.curl(size[::-1],field).reshape((-1,np.prod(shape))), damask.grid_filters.curl(size[::-1],field).reshape(-1,np.prod(shape)),
scriptID+' '+' '.join(sys.argv[1:])) scriptID+' '+' '.join(sys.argv[1:]))
table.to_ASCII(sys.stdout if name is None else name) table.to_ASCII(sys.stdout if name is None else name)

View File

@ -41,7 +41,7 @@ for name in filenames:
table = damask.Table.from_ASCII(StringIO(''.join(sys.stdin.read())) if name is None else name) table = damask.Table.from_ASCII(StringIO(''.join(sys.stdin.read())) if name is None else name)
for tensor in options.tensor: for tensor in options.tensor:
table.add('dev({})'.format(tensor), table.add('dev({})'.format(tensor),
damask.mechanics.deviatoric_part(table.get(tensor).reshape(-1,3,3)).reshape((-1,9)), damask.mechanics.deviatoric_part(table.get(tensor).reshape(-1,3,3)).reshape(-1,9),
scriptID+' '+' '.join(sys.argv[1:])) scriptID+' '+' '.join(sys.argv[1:]))
if options.spherical: if options.spherical:
table.add('sph({})'.format(tensor), table.add('sph({})'.format(tensor),

View File

@ -54,20 +54,20 @@ for name in filenames:
F = table.get(options.f).reshape(np.append(grid[::-1],(3,3))) F = table.get(options.f).reshape(np.append(grid[::-1],(3,3)))
if options.nodal: if options.nodal:
table = damask.Table(damask.grid_filters.node_coord0(grid[::-1],size[::-1]).reshape((-1,3)), table = damask.Table(damask.grid_filters.node_coord0(grid[::-1],size[::-1]).reshape(-1,3),
{'pos':(3,)}) {'pos':(3,)})
table.add('avg({}).{}'.format(options.f,options.pos), table.add('avg({}).{}'.format(options.f,options.pos),
damask.grid_filters.node_displacement_avg(size[::-1],F).reshape((-1,3)), damask.grid_filters.node_displacement_avg(size[::-1],F).reshape(-1,3),
scriptID+' '+' '.join(sys.argv[1:])) scriptID+' '+' '.join(sys.argv[1:]))
table.add('fluct({}).{}'.format(options.f,options.pos), table.add('fluct({}).{}'.format(options.f,options.pos),
damask.grid_filters.node_displacement_fluct(size[::-1],F).reshape((-1,3)), damask.grid_filters.node_displacement_fluct(size[::-1],F).reshape(-1,3),
scriptID+' '+' '.join(sys.argv[1:])) scriptID+' '+' '.join(sys.argv[1:]))
table.to_ASCII(sys.stdout if name is None else os.path.splitext(name)[0]+'_nodal.txt') table.to_ASCII(sys.stdout if name is None else os.path.splitext(name)[0]+'_nodal.txt')
else: else:
table.add('avg({}).{}'.format(options.f,options.pos), table.add('avg({}).{}'.format(options.f,options.pos),
damask.grid_filters.cell_displacement_avg(size[::-1],F).reshape((-1,3)), damask.grid_filters.cell_displacement_avg(size[::-1],F).reshape(-1,3),
scriptID+' '+' '.join(sys.argv[1:])) scriptID+' '+' '.join(sys.argv[1:]))
table.add('fluct({}).{}'.format(options.f,options.pos), table.add('fluct({}).{}'.format(options.f,options.pos),
damask.grid_filters.cell_displacement_fluct(size[::-1],F).reshape((-1,3)), damask.grid_filters.cell_displacement_fluct(size[::-1],F).reshape(-1,3),
scriptID+' '+' '.join(sys.argv[1:])) scriptID+' '+' '.join(sys.argv[1:]))
table.to_ASCII(sys.stdout if name is None else name) table.to_ASCII(sys.stdout if name is None else name)

View File

@ -51,7 +51,7 @@ for name in filenames:
shape = (3,) if np.prod(field.shape)//np.prod(grid) == 3 else (3,3) # vector or tensor shape = (3,) if np.prod(field.shape)//np.prod(grid) == 3 else (3,3) # vector or tensor
field = field.reshape(np.append(grid[::-1],shape)) field = field.reshape(np.append(grid[::-1],shape))
table.add('divFFT({})'.format(label), table.add('divFFT({})'.format(label),
damask.grid_filters.divergence(size[::-1],field).reshape((-1,np.prod(shape)//3)), damask.grid_filters.divergence(size[::-1],field).reshape(-1,np.prod(shape)//3),
scriptID+' '+' '.join(sys.argv[1:])) scriptID+' '+' '.join(sys.argv[1:]))
table.to_ASCII(sys.stdout if name is None else name) table.to_ASCII(sys.stdout if name is None else name)

View File

@ -68,7 +68,7 @@ for name in filenames:
for label in options.labels: for label in options.labels:
table.add('Gauss{}({})'.format(options.sigma,label), table.add('Gauss{}({})'.format(options.sigma,label),
ndimage.filters.gaussian_filter(table.get(label).reshape((-1)), ndimage.filters.gaussian_filter(table.get(label).reshape(-1),
options.sigma,options.order, options.sigma,options.order,
mode = 'wrap' if options.periodic else 'nearest'), mode = 'wrap' if options.periodic else 'nearest'),
scriptID+' '+' '.join(sys.argv[1:])) scriptID+' '+' '.join(sys.argv[1:]))

View File

@ -51,7 +51,7 @@ for name in filenames:
shape = (1,) if np.prod(field.shape)//np.prod(grid) == 1 else (3,) # scalar or vector shape = (1,) if np.prod(field.shape)//np.prod(grid) == 1 else (3,) # scalar or vector
field = field.reshape(np.append(grid[::-1],shape)) field = field.reshape(np.append(grid[::-1],shape))
table.add('gradFFT({})'.format(label), table.add('gradFFT({})'.format(label),
damask.grid_filters.gradient(size[::-1],field).reshape((-1,np.prod(shape)*3)), damask.grid_filters.gradient(size[::-1],field).reshape(-1,np.prod(shape)*3),
scriptID+' '+' '.join(sys.argv[1:])) scriptID+' '+' '.join(sys.argv[1:]))
table.to_ASCII(sys.stdout if name is None else name) table.to_ASCII(sys.stdout if name is None else name)

View File

@ -59,6 +59,6 @@ for name in filenames:
idx = np.reshape(table.get(options.index).astype(int) + options.offset,(-1))-1 idx = np.reshape(table.get(options.index).astype(int) + options.offset,(-1))-1
for data in options.label: for data in options.label:
table.add(data+'addIndexed',indexedTable.get(data)[idx],scriptID+' '+' '.join(sys.argv[1:])) table.add(data+'_addIndexed',indexedTable.get(data)[idx],scriptID+' '+' '.join(sys.argv[1:]))
table.to_ASCII(sys.stdout if name is None else name) table.to_ASCII(sys.stdout if name is None else name)

View File

@ -203,13 +203,11 @@ for name in filenames:
# ------------------------------------------ assemble header --------------------------------------- # ------------------------------------------ assemble header ---------------------------------------
table.info_append(scriptID + '\t' + ' '.join(sys.argv[1:])) table.info_append(scriptID + '\t' + ' '.join(sys.argv[1:]))
table.labels_append(['{id}_' table.labels_append(['S[{direction[0]:.1g}_{direction[1]:.1g}_{direction[2]:.1g}]'
'S[{direction[0]:.1g}_{direction[1]:.1g}_{direction[2]:.1g}]'
'({normal[0]:.1g}_{normal[1]:.1g}_{normal[2]:.1g})'\ '({normal[0]:.1g}_{normal[1]:.1g}_{normal[2]:.1g})'\
.format( id = i+1, .format(normal = theNormal,
normal = theNormal,
direction = theDirection, direction = theDirection,
) for i,(theNormal,theDirection) in enumerate(zip(slip_normal,slip_direction))]) ) for theNormal,theDirection in zip(slip_normal,slip_direction)])
table.head_write() table.head_write()
# ------------------------------------------ process data ------------------------------------------ # ------------------------------------------ process data ------------------------------------------

View File

@ -50,11 +50,9 @@ for name in filenames:
if options.rh: v[np.linalg.det(v) < 0.0,:,2] *= -1.0 if options.rh: v[np.linalg.det(v) < 0.0,:,2] *= -1.0
for i,o in enumerate(['Min','Mid','Max']): for i,o in enumerate(['Min','Mid','Max']):
table.add('eigval{}({})'.format(o,tensor),u[:,i], table.add('eigval{}({})'.format(o,tensor),u[:,i], scriptID+' '+' '.join(sys.argv[1:]))
scriptID+' '+' '.join(sys.argv[1:]))
for i,o in enumerate(['Min','Mid','Max']): for i,o in enumerate(['Min','Mid','Max']):
table.add('eigvec{}({})'.format(o,tensor),v[:,:,i], table.add('eigvec{}({})'.format(o,tensor),v[:,:,i],scriptID+' '+' '.join(sys.argv[1:]))
scriptID+' '+' '.join(sys.argv[1:]))
table.to_ASCII(sys.stdout if name is None else name) table.to_ASCII(sys.stdout if name is None else name)

View File

@ -86,13 +86,13 @@ for name in filenames:
table = damask.Table.from_ASCII(StringIO(''.join(sys.stdin.read())) if name is None else name) table = damask.Table.from_ASCII(StringIO(''.join(sys.stdin.read())) if name is None else name)
for defgrad in options.defgrad: for defgrad in options.defgrad:
F = table.get(defgrad).reshape((-1,3,3)) F = table.get(defgrad).reshape(-1,3,3)
for theStretch in stretches: for theStretch in stretches:
for theStrain in strains: for theStrain in strains:
(t,m) = parameters(theStretch,theStrain) (t,m) = parameters(theStretch,theStrain)
label = '{}({}){}'.format(theStrain,theStretch,defgrad if defgrad != 'f' else '') label = '{}({}){}'.format(theStrain,theStretch,defgrad if defgrad != 'f' else '')
table.add(label, table.add(label,
damask.mechanics.strain_tensor(F,t,m).reshape((-1,9)), damask.mechanics.strain_tensor(F,t,m).reshape(-1,9),
scriptID+' '+' '.join(sys.argv[1:])) scriptID+' '+' '.join(sys.argv[1:]))
table.to_ASCII(sys.stdout if name is None else name) table.to_ASCII(sys.stdout if name is None else name)

View File

@ -91,7 +91,7 @@ for name in filenames:
table = damask.Table(averagedDown,table.shapes,table.comments) table = damask.Table(averagedDown,table.shapes,table.comments)
coords = damask.grid_filters.cell_coord0(packedGrid,size,shift/packedGrid*size+origin) coords = damask.grid_filters.cell_coord0(packedGrid,size,shift/packedGrid*size+origin)
table.set(options.pos, coords.reshape((-1,3))) table.set(options.pos, coords.reshape(-1,3))
outname = os.path.join(os.path.dirname(name),prefix+os.path.basename(name)) outname = os.path.join(os.path.dirname(name),prefix+os.path.basename(name))

View File

@ -2,6 +2,7 @@
import os import os
import sys import sys
from io import StringIO
from optparse import OptionParser from optparse import OptionParser
import numpy as np import numpy as np
@ -71,60 +72,30 @@ parser.set_defaults(bins = (10,10),
) )
(options,filenames) = parser.parse_args() (options,filenames) = parser.parse_args()
if filenames == []: filenames = [None]
minmax = np.array([np.array(options.xrange), minmax = np.array([options.xrange,options.yrange,options.zrange])
np.array(options.yrange), result = np.empty((options.bins[0],options.bins[1],3),'f')
np.array(options.zrange)])
grid = np.zeros(options.bins,'f')
result = np.zeros((options.bins[0],options.bins[1],3),'f')
if options.data is None: parser.error('no data columns specified.') if options.data is None: parser.error('no data columns specified.')
labels = list(options.data)
if options.weight is not None: labels += [options.weight] # prevent character splitting of single string value
# --- loop over input files -------------------------------------------------------------------------
if filenames == []: filenames = [None]
for name in filenames: for name in filenames:
try:
table = damask.ASCIItable(name = name,
outname = os.path.join(os.path.dirname(name),
'binned-{}-{}_'.format(*options.data) +
('weighted-{}_'.format(options.weight) if options.weight else '') +
os.path.basename(name)) if name else name)
except IOError:
continue
damask.util.report(scriptName,name) damask.util.report(scriptName,name)
# ------------------------------------------ read header ------------------------------------------ table = damask.Table.from_ASCII(StringIO(''.join(sys.stdin.read())) if name is None else name)
data = np.hstack((table.get(options.data[0]),table.get(options.data[1])))
table.head_read()
# ------------------------------------------ sanity checks ----------------------------------------
missing_labels = table.data_readArray(labels)
if len(missing_labels) > 0:
damask.util.croak('column{} {} not found.'.format('s' if len(missing_labels) > 1 else '',', '.join(missing_labels)))
table.close(dismiss = True)
continue
for c in (0,1): # check data minmax for x and y (i = 0 and 1) for c in (0,1): # check data minmax for x and y (i = 0 and 1)
if (minmax[c] == 0.0).all(): minmax[c] = [table.data[:,c].min(),table.data[:,c].max()] if (minmax[c] == 0.0).all(): minmax[c] = [data[:,c].min(),data[:,c].max()]
if options.type[c].lower() == 'log': # if log scale if options.type[c].lower() == 'log': # if log scale
table.data[:,c] = np.log(table.data[:,c]) # change x,y coordinates to log data[:,c] = np.log(data[:,c]) # change x,y coordinates to log
minmax[c] = np.log(minmax[c]) # change minmax to log, too minmax[c] = np.log(minmax[c]) # change minmax to log, too
delta = minmax[:,1]-minmax[:,0] delta = minmax[:,1]-minmax[:,0]
(grid,xedges,yedges) = np.histogram2d(table.data[:,0],table.data[:,1], (grid,xedges,yedges) = np.histogram2d(data[:,0],data[:,1],
bins=options.bins, bins=options.bins,
range=minmax[:2], range=minmax[:2],
weights=None if options.weight is None else table.data[:,2]) weights=table.get(options.weight) if options.weight else None)
if options.normCol: if options.normCol:
for x in range(options.bins[0]): for x in range(options.bins[0]):
sum = np.sum(grid[x,:]) sum = np.sum(grid[x,:])
@ -153,24 +124,20 @@ for name in filenames:
for y in range(options.bins[1]): for y in range(options.bins[1]):
result[x,y,:] = [minmax[0,0]+delta[0]/options.bins[0]*(x+0.5), result[x,y,:] = [minmax[0,0]+delta[0]/options.bins[0]*(x+0.5),
minmax[1,0]+delta[1]/options.bins[1]*(y+0.5), minmax[1,0]+delta[1]/options.bins[1]*(y+0.5),
min(1.0,max(0.0,(grid[x,y]-minmax[2,0])/delta[2]))] np.clip((grid[x,y]-minmax[2,0])/delta[2],0.0,1.0)]
for c in (0,1): for c in (0,1):
if options.type[c].lower() == 'log': result[:,:,c] = np.exp(result[:,:,c]) if options.type[c].lower() == 'log': result[:,:,c] = np.exp(result[:,:,c])
if options.invert: result[:,:,2] = 1.0 - result[:,:,2] if options.invert: result[:,:,2] = 1.0 - result[:,:,2]
# --- assemble header ------------------------------------------------------------------------------- comments = scriptID + '\t' + ' '.join(sys.argv[1:])
shapes = {'bin_%s'%options.data[0]:(1,),'bin_%s'%options.data[1]:(1,),'z':(1,)}
table.info_clear() table = damask.Table(result.reshape(options.bins[0]*options.bins[1],3),shapes,[comments])
table.info_append(scriptID + '\t' + ' '.join(sys.argv[1:])) if name:
table.labels_clear() outname = os.path.join(os.path.dirname(name),'binned-{}-{}_'.format(*options.data) +
table.labels_append(['bin_%s'%options.data[0],'bin_%s'%options.data[1],'z']) ('weighted-{}_'.format(options.weight) if options.weight else '') +
table.head_write() os.path.basename(name))
table.to_ASCII(outname)
# --- output result --------------------------------------------------------------------------------- else:
table.to_ASCII(sys.stdout)
table.data = result.reshape(options.bins[0]*options.bins[1],3)
table.data_writeArray()
table.close()

View File

@ -60,12 +60,12 @@ for name in filenames:
outSize = grid*packing outSize = grid*packing
data = table.data.values.reshape(tuple(grid)+(-1,)) data = table.data.values.reshape(tuple(grid)+(-1,))
blownUp = ndimage.interpolation.zoom(data,tuple(packing)+(1,),order=0,mode='nearest').reshape((outSize.prod(),-1)) blownUp = ndimage.interpolation.zoom(data,tuple(packing)+(1,),order=0,mode='nearest').reshape(outSize.prod(),-1)
table = damask.Table(blownUp,table.shapes,table.comments) table = damask.Table(blownUp,table.shapes,table.comments)
coords = damask.grid_filters.cell_coord0(outSize,size,origin) coords = damask.grid_filters.cell_coord0(outSize,size,origin)
table.set(options.pos,coords.reshape((-1,3))) table.set(options.pos,coords.reshape(-1,3))
table.set('elem',np.arange(1,outSize.prod()+1)) table.set('elem',np.arange(1,outSize.prod()+1))
outname = os.path.join(os.path.dirname(name),prefix+os.path.basename(name)) outname = os.path.join(os.path.dirname(name),prefix+os.path.basename(name))

View File

@ -1,146 +0,0 @@
#!/usr/bin/env python2.7
import os
import sys
from optparse import OptionParser
import numpy as np
import damask
scriptName = os.path.splitext(os.path.basename(__file__))[0]
scriptID = ' '.join([scriptName,damask.version])
# --------------------------------------------------------------------
# MAIN
# --------------------------------------------------------------------
parser = OptionParser(option_class=damask.extendableOption, usage='%prog options [file[s]]', description = """
Generate histogram of N bins in given data range.
""", version = scriptID)
parser.add_option('-d','--data',
dest = 'data',
type = 'string', metavar = 'string',
help = 'column heading for data')
parser.add_option('-w','--weights',
dest = 'weights',
type = 'string', metavar = 'string',
help = 'column heading for weights')
parser.add_option('--range',
dest = 'range',
type = 'float', nargs = 2, metavar = 'float float',
help = 'data range of histogram [min - max]')
parser.add_option('-N',
dest = 'N',
type = 'int', metavar = 'int',
help = 'number of bins')
parser.add_option('--density',
dest = 'density',
action = 'store_true',
help = 'report probability density')
parser.add_option('--logarithmic',
dest = 'log',
action = 'store_true',
help = 'logarithmically spaced bins')
parser.set_defaults(data = None,
weights = None,
range = None,
N = None,
density = False,
log = False,
)
(options,filenames) = parser.parse_args()
if not options.data: parser.error('no data specified.')
if not options.N: parser.error('no bin number specified.')
if options.log:
def forward(x):
return np.log(x)
def reverse(x):
return np.exp(x)
else:
def forward(x):
return x
def reverse(x):
return x
# --- loop over input files ------------------------------------------------------------------------
if filenames == []: filenames = [None]
for name in filenames:
try:
table = damask.ASCIItable(name = name, readonly = True)
except IOError:
continue
damask.util.report(scriptName,name)
# ------------------------------------------ read header ------------------------------------------
table.head_read()
# ------------------------------------------ sanity checks ----------------------------------------
errors = []
remarks = []
if table.label_dimension(options.data) != 1: errors.append('data {} are not scalar.'.format(options.data))
if options.weights and \
table.label_dimension(options.data) != 1: errors.append('weights {} are not scalar.'.format(options.weights))
if remarks != []: damask.util.croak(remarks)
if errors != []:
damask.util.croak(errors)
table.close(dismiss = True)
continue
# --------------- read data ----------------------------------------------------------------
table.data_readArray([options.data,options.weights])
# --------------- auto range ---------------------------------------------------------------
if options.range is None:
rangeMin,rangeMax = min(table.data[:,0]),max(table.data[:,0])
else:
rangeMin,rangeMax = min(options.range),max(options.range)
# --------------- bin data ----------------------------------------------------------------
count,edges = np.histogram(table.data[:,0],
bins = reverse(forward(rangeMin) + np.arange(options.N+1) *
(forward(rangeMax)-forward(rangeMin))/options.N),
range = (rangeMin,rangeMax),
weights = None if options.weights is None else table.data[:,1],
density = options.density,
)
bincenter = reverse(forward(rangeMin) + (0.5+np.arange(options.N)) *
(forward(rangeMax)-forward(rangeMin))/options.N) # determine center of bins
# ------------------------------------------ assemble header ---------------------------------------
table.info_clear()
table.info_append([scriptID + '\t' + ' '.join(sys.argv[1:]),
scriptID + ':\t' +
'data range {} -- {}'.format(rangeMin,rangeMax) +
(' (log)' if options.log else ''),
])
table.labels_clear()
table.labels_append(['bincenter','count'])
table.head_write()
# ------------------------------------------ output result -----------------------------------------
table.data = np.squeeze(np.dstack((bincenter,count)))
table.data_writeArray()
# ------------------------------------------ output finalization -----------------------------------
table.close() # close ASCII tables

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python2.7 #!/usr/bin/env python3
import os import os
import sys import sys
@ -102,6 +102,7 @@ parser.set_defaults(label = None,
) )
(options,filenames) = parser.parse_args() (options,filenames) = parser.parse_args()
if filenames == []: filenames = [None]
if options.pixelsize > 1: (options.pixelsizex,options.pixelsizey) = [options.pixelsize]*2 if options.pixelsize > 1: (options.pixelsizex,options.pixelsizey) = [options.pixelsize]*2
@ -112,9 +113,6 @@ if options.invert: theMap = theMap.invert()
theColors = np.uint8(np.array(theMap.export(format = 'list',steps = 256))*255) theColors = np.uint8(np.array(theMap.export(format = 'list',steps = 256))*255)
# --- loop over input files ------------------------------------------------------------------------- # --- loop over input files -------------------------------------------------------------------------
if filenames == []: filenames = [None]
for name in filenames: for name in filenames:
try: try:
table = damask.ASCIItable(name = name, labeled = options.label is not None, readonly = True) table = damask.ASCIItable(name = name, labeled = options.label is not None, readonly = True)

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python2.7 #!/usr/bin/env python3
import os import os
import sys import sys
@ -95,6 +95,7 @@ parser.set_defaults(label = None,
) )
(options,filenames) = parser.parse_args() (options,filenames) = parser.parse_args()
if filenames == []: filenames = [None]
options.size = np.array(options.size) options.size = np.array(options.size)
options.dimension = np.array(options.dimension) options.dimension = np.array(options.dimension)
@ -109,16 +110,12 @@ if options.invert: theMap = theMap.invert()
theColors = np.uint8(np.array(theMap.export(format='list',steps=256))*255) theColors = np.uint8(np.array(theMap.export(format='list',steps=256))*255)
# --- loop over input files ------------------------------------------------------------------------- # --- loop over input files -------------------------------------------------------------------------
if filenames == []: filenames = [None]
for name in filenames: for name in filenames:
try: try:
table = damask.ASCIItable(name = name, readonly = True, table = damask.ASCIItable(name = name, labeled = options.label is not None, readonly = True)
labeled = options.label is not None)
except IOError: except IOError:
continue continue
table.report_name(scriptName,name) damask.util.report(scriptName,name)
# ------------------------------------------ read header ------------------------------------------ # ------------------------------------------ read header ------------------------------------------

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python2.7 #!/usr/bin/env python3
import os import os
import sys import sys
@ -72,18 +72,15 @@ parser.set_defaults(label = None,
) )
(options,filenames) = parser.parse_args() (options,filenames) = parser.parse_args()
if filenames == []: filenames = [None]
if options.dimension == []: parser.error('dimension of data array missing') if options.dimension == []: parser.error('dimension of data array missing')
if options.pixelsize > 1: (options.pixelsizex,options.pixelsizey) = [options.pixelsize]*2 if options.pixelsize > 1: (options.pixelsizex,options.pixelsizey) = [options.pixelsize]*2
# --- loop over input files ------------------------------------------------------------------------- # --- loop over input files -------------------------------------------------------------------------
if filenames == []: filenames = [None]
for name in filenames: for name in filenames:
try: try:
table = damask.ASCIItable(name = name, readonly = True, table = damask.ASCIItable(name = name, labeled = options.label is not None, readonly = True)
labeled = options.label is not None)
except IOError: except IOError:
continue continue
damask.util.report(scriptName,name) damask.util.report(scriptName,name)

View File

@ -44,9 +44,7 @@ for name in filenames:
damask.util.report(scriptName,name) damask.util.report(scriptName,name)
table = damask.Table.from_ASCII(StringIO(''.join(sys.stdin.read())) if name is None else name) table = damask.Table.from_ASCII(StringIO(''.join(sys.stdin.read())) if name is None else name)
for i,label in enumerate(options.label): for label,substitute in zip(options.label,options.substitute):
table.rename(label, table.rename(label,substitute,scriptID+' '+' '.join(sys.argv[1:]))
options.substitute[i],
scriptID+' '+' '.join(sys.argv[1:]))
table.to_ASCII(sys.stdout if name is None else name) table.to_ASCII(sys.stdout if name is None else name)

View File

@ -2,10 +2,9 @@
import os import os
import sys import sys
from io import StringIO
from optparse import OptionParser from optparse import OptionParser
import numpy as np
import damask import damask
@ -40,65 +39,25 @@ parser.set_defaults(rotation = (1.,1.,1.,0),
) )
(options,filenames) = parser.parse_args() (options,filenames) = parser.parse_args()
if filenames == []: filenames = [None]
if options.data is None: if options.data is None:
parser.error('no data column specified.') parser.error('no data column specified.')
r = damask.Rotation.fromAxisAngle(np.array(options.rotation),options.degrees,normalise=True) r = damask.Rotation.fromAxisAngle(options.rotation,options.degrees,normalise=True)
# --- loop over input files -------------------------------------------------------------------------
if filenames == []: filenames = [None]
for name in filenames: for name in filenames:
try: damask.util.report(scriptName,name)
table = damask.ASCIItable(name = name)
except IOError:
continue
damask.util.report(scriptName,name)
# --- interpret header ---------------------------------------------------------------------------- table = damask.Table.from_ASCII(StringIO(''.join(sys.stdin.read())) if name is None else name)
table.head_read() for data in options.data:
d = table.get(data)
if table.shapes[data] == (9,): d=d.reshape(-1,3,3)
for i,l in enumerate(d):
d[i] = r*l
if table.shapes[data] == (9,): d=d.reshape(-1,9)
errors = [] table.set(data,d,scriptID+' '+' '.join(sys.argv[1:]))
remarks = []
active = {'vector':[],'tensor':[]}
for i,dim in enumerate(table.label_dimension(options.data)): table.to_ASCII(sys.stdout if name is None else name)
label = options.data[i]
if dim == -1:
remarks.append('"{}" not found...'.format(label))
elif dim == 3:
remarks.append('adding vector "{}"...'.format(label))
active['vector'].append(label)
elif dim == 9:
remarks.append('adding tensor "{}"...'.format(label))
active['tensor'].append(label)
if remarks != []: damask.util.croak(remarks)
if errors != []:
damask.util.croak(errors)
table.close(dismiss = True)
continue
# ------------------------------------------ assemble header --------------------------------------
table.info_append(scriptID + '\t' + ' '.join(sys.argv[1:]))
table.head_write()
# ------------------------------------------ process data ------------------------------------------
outputAlive = True
while outputAlive and table.data_read(): # read next data line of ASCII table
for v in active['vector']:
column = table.label_index(v)
table.data[column:column+3] = r * np.array(list(map(float,table.data[column:column+3])))
for t in active['tensor']:
column = table.label_index(t)
table.data[column:column+9] = (r * np.array(list(map(float,table.data[column:column+9]))).reshape((3,3))).reshape(9)
outputAlive = table.data_write() # output processed line
# ------------------------------------------ output finalization -----------------------------------
table.close() # close ASCII tables

View File

@ -43,9 +43,7 @@ for name in filenames:
damask.util.report(scriptName,name) damask.util.report(scriptName,name)
table = damask.Table.from_ASCII(StringIO(''.join(sys.stdin.read())) if name is None else name) table = damask.Table.from_ASCII(StringIO(''.join(sys.stdin.read())) if name is None else name)
for i,label in enumerate(options.labels): for label,factor in zip(options.labels,options.factor):
table.set(label, table.set(label,table.get(label)*float(factor),scriptID+' '+' '.join(sys.argv[1:]))
table.get(label)*float(options.factor[i]),
scriptID+' '+' '.join(sys.argv[1:]))
table.to_ASCII(sys.stdout if name is None else name) table.to_ASCII(sys.stdout if name is None else name)

View File

@ -43,9 +43,7 @@ for name in filenames:
damask.util.report(scriptName,name) damask.util.report(scriptName,name)
table = damask.Table.from_ASCII(StringIO(''.join(sys.stdin.read())) if name is None else name) table = damask.Table.from_ASCII(StringIO(''.join(sys.stdin.read())) if name is None else name)
for i,label in enumerate(options.labels): for label,offset in zip(options.labels,options.offset):
table.set(label, table.set(label,table.get(label)+float(offset),scriptID+' '+' '.join(sys.argv[1:]))
table.get(label)+float(options.offset[i]),
scriptID+' '+' '.join(sys.argv[1:]))
table.to_ASCII(sys.stdout if name is None else name) table.to_ASCII(sys.stdout if name is None else name)

65
processing/post/vtk_addData.py Executable file
View File

@ -0,0 +1,65 @@
#!/usr/bin/env python3
import os
import sys
from io import StringIO
from optparse import OptionParser
import numpy as np
import damask
scriptName = os.path.splitext(os.path.basename(__file__))[0]
scriptID = ' '.join([scriptName,damask.version])
# --------------------------------------------------------------------
# MAIN
# --------------------------------------------------------------------
parser = OptionParser(option_class=damask.extendableOption,
usage='%prog options [ASCIItable(s)]',
description = 'Add scalars/vectors, tensors, and/or a RGB tuples from ASCIItable '
+ 'to existing VTK file (.vtr/.vtu/.vtp).',
version = scriptID)
parser.add_option( '--vtk',
dest = 'vtk',
type = 'string', metavar = 'string',
help = 'VTK file name')
parser.add_option('-d', '--data',
dest = 'data',
action = 'extend', metavar = '<string LIST>',
help = 'scalar/vector value(s) label(s)')
parser.add_option('-t', '--tensor',
dest = 'tensor',
action = 'extend', metavar = '<string LIST>',
help = 'tensor (3x3) value label(s)')
parser.add_option('-c', '--color',
dest = 'color',
action = 'extend', metavar = '<string LIST>',
help = 'RGB color tuple label')
parser.set_defaults(data = [],
tensor = [],
color = [],
)
(options, filenames) = parser.parse_args()
if filenames == []: filenames = [None]
if not options.vtk:
parser.error('No VTK file specified.')
for name in filenames:
damask.util.report(scriptName,name)
table = damask.Table.from_ASCII(StringIO(''.join(sys.stdin.read())) if name is None else name)
vtk = damask.VTK.from_file(options.vtk)
for data in options.data+options.tensor:
vtk.add(table.get(data),data)
for color in options.color:
vtk.add((table.get(color)*255).astype(np.uint8),color)
vtk.write(options.vtk)

View File

@ -1,162 +0,0 @@
#!/usr/bin/env python3
import os
import sys
from io import StringIO
from optparse import OptionParser
import vtk
from vtk.util import numpy_support
import damask
scriptName = os.path.splitext(os.path.basename(__file__))[0]
scriptID = ' '.join([scriptName,damask.version])
# --------------------------------------------------------------------
# MAIN
# --------------------------------------------------------------------
parser = OptionParser(option_class=damask.extendableOption,
usage='%prog options [ASCIItable(s)]',
description = "Add scalars, vectors, tensors, and/or an RGB tuple from ASCIItable "
+ "to existing VTK grid (.vtr/.vtk/.vtu).",
version = scriptID)
parser.add_option( '--vtk',
dest = 'vtk',
type = 'string', metavar = 'string',
help = 'VTK file name')
parser.add_option('-r', '--render',
dest = 'render',
action = 'store_true',
help = 'open output in VTK render window')
parser.add_option('-d', '--data',
dest = 'data',
action = 'extend', metavar = '<string LIST>',
help = 'scalar/vector value(s) label(s)')
parser.add_option('-t', '--tensor',
dest = 'tensor',
action = 'extend', metavar = '<string LIST>',
help = 'tensor (3x3) value label(s)')
parser.add_option('-c', '--color',
dest = 'color',
action = 'extend', metavar = '<string LIST>',
help = 'RGB color tuple label')
parser.set_defaults(data = [],
tensor = [],
color = [],
)
(options, filenames) = parser.parse_args()
if filenames == []: filenames = [None]
if not options.vtk: parser.error('No VTK file specified.')
if not os.path.exists(options.vtk): parser.error('VTK file does not exist.')
vtk_file,vtk_ext = os.path.splitext(options.vtk)
if vtk_ext == '.vtr':
reader = vtk.vtkXMLRectilinearGridReader()
reader.SetFileName(options.vtk)
reader.Update()
rGrid = reader.GetOutput()
writer = vtk.vtkXMLRectilinearGridWriter()
elif vtk_ext == '.vtk':
reader = vtk.vtkGenericDataObjectReader()
reader.SetFileName(options.vtk)
reader.Update()
rGrid = reader.GetRectilinearGridOutput()
writer = vtk.vtkXMLRectilinearGridWriter()
elif vtk_ext == '.vtu':
reader = vtk.vtkXMLUnstructuredGridReader()
reader.SetFileName(options.vtk)
reader.Update()
rGrid = reader.GetOutput()
writer = vtk.vtkXMLUnstructuredGridWriter()
else:
parser.error('Unsupported VTK file type extension.')
writer.SetFileName(vtk_file+'.'+writer.GetDefaultFileExtension())
Npoints = rGrid.GetNumberOfPoints()
Ncells = rGrid.GetNumberOfCells()
damask.util.croak('{}: {} points and {} cells...'.format(options.vtk,Npoints,Ncells))
for name in filenames:
damask.util.report(scriptName,name)
table = damask.Table.from_ASCII(StringIO(''.join(sys.stdin.read())) if name is None else name)
VTKarray = {}
for data in options.data:
VTKarray[data] = numpy_support.numpy_to_vtk(table.get(data).copy(),
deep=True,array_type=vtk.VTK_DOUBLE)
VTKarray[data].SetName(data)
for color in options.color:
VTKarray[color] = numpy_support.numpy_to_vtk((table.get(color)*255).astype(int).copy(),
deep=True,array_type=vtk.VTK_UNSIGNED_CHAR)
VTKarray[color].SetName(color)
for tensor in options.tensor:
data = damask.mechanics.symmetric(table.get(tensor).reshape((-1,3,3))).reshape((-1,9))
VTKarray[tensor] = numpy_support.numpy_to_vtk(data.copy(),
deep=True,array_type=vtk.VTK_DOUBLE)
VTKarray[tensor].SetName(tensor)
# ------------------------------------------ add data ---------------------------------------
if len(table.data) == Npoints: mode = 'point'
elif len(table.data) == Ncells: mode = 'cell'
else:
damask.util.croak('Data count is incompatible with grid...')
continue
damask.util.croak('{} mode...'.format(mode))
for data in VTKarray:
if mode == 'cell': rGrid.GetCellData().AddArray(VTKarray[data])
elif mode == 'point': rGrid.GetPointData().AddArray(VTKarray[data])
rGrid.Modified()
# ------------------------------------------ output result ---------------------------------------
writer.SetDataModeToBinary()
writer.SetCompressorTypeToZLib()
writer.SetInputData(rGrid)
writer.Write()
# ------------------------------------------ render result ---------------------------------------
if options.render:
mapper = vtk.vtkDataSetMapper()
mapper.SetInputData(rGrid)
actor = vtk.vtkActor()
actor.SetMapper(mapper)
# Create the graphics structure. The renderer renders into the
# render window. The render window interactively captures mouse events
# and will perform appropriate camera or actor manipulation
# depending on the nature of the events.
ren = vtk.vtkRenderer()
renWin = vtk.vtkRenderWindow()
renWin.AddRenderer(ren)
ren.AddActor(actor)
ren.SetBackground(1, 1, 1)
renWin.SetSize(200, 200)
iren = vtk.vtkRenderWindowInteractor()
iren.SetRenderWindow(renWin)
iren.Initialize()
renWin.Render()
iren.Start()

View File

@ -1,147 +0,0 @@
#!/usr/bin/env python3
import os
import sys
from io import StringIO
from optparse import OptionParser
import vtk
from vtk.util import numpy_support
import damask
scriptName = os.path.splitext(os.path.basename(__file__))[0]
scriptID = ' '.join([scriptName,damask.version])
# --------------------------------------------------------------------
# MAIN
# --------------------------------------------------------------------
parser = OptionParser(option_class=damask.extendableOption,
usage='%prog options [ASCIItable(s)]',
description = "Add scalars, vectors, tensors, and/or an RGB tuple from ASCIItable "
+ "VTK point cloud (.vtp).",
version = scriptID)
parser.add_option( '--vtk',
dest = 'vtk',
type = 'string', metavar = 'string',
help = 'VTK file name')
parser.add_option('-r', '--render',
dest = 'render',
action = 'store_true',
help = 'open output in VTK render window')
parser.add_option('-d', '--data',
dest = 'data',
action = 'extend', metavar = '<string LIST>',
help = 'scalar/vector value(s) label(s)')
parser.add_option('-t', '--tensor',
dest = 'tensor',
action = 'extend', metavar = '<string LIST>',
help = 'tensor (3x3) value label(s)')
parser.add_option('-c', '--color',
dest = 'color',
action = 'extend', metavar = '<string LIST>',
help = 'RGB color tuple label')
parser.set_defaults(data = [],
tensor = [],
color = [],
)
(options, filenames) = parser.parse_args()
if filenames == []: filenames = [None]
if not options.vtk: parser.error('No VTK file specified.')
if not os.path.exists(options.vtk): parser.error('VTK file does not exist.')
vtk_file,vtk_ext = os.path.splitext(options.vtk)
if vtk_ext == '.vtp':
reader = vtk.vtkXMLPolyDataReader()
reader.SetFileName(options.vtk)
reader.Update()
Polydata = reader.GetOutput()
elif vtk_ext == '.vtk':
reader = vtk.vtkGenericDataObjectReader()
reader.SetFileName(options.vtk)
reader.Update()
Polydata = reader.GetPolyDataOutput()
else:
parser.error('unsupported VTK file type extension.')
Npoints = Polydata.GetNumberOfPoints()
Ncells = Polydata.GetNumberOfCells()
Nvertices = Polydata.GetNumberOfVerts()
if Npoints != Ncells or Npoints != Nvertices:
parser.error('number of points, cells, and vertices in VTK differ from each other.')
damask.util.croak('{}: {} points/vertices/cells...'.format(options.vtk,Npoints))
for name in filenames:
damask.util.report(scriptName,name)
table = damask.Table.from_ASCII(StringIO(''.join(sys.stdin.read())) if name is None else name)
VTKarray = {}
for data in options.data:
VTKarray[data] = numpy_support.numpy_to_vtk(table.get(data).copy(),
deep=True,array_type=vtk.VTK_DOUBLE)
VTKarray[data].SetName(data)
for color in options.color:
VTKarray[color] = numpy_support.numpy_to_vtk((table.get(color)*255).astype(int).copy(),
deep=True,array_type=vtk.VTK_UNSIGNED_CHAR)
VTKarray[color].SetName(color)
for tensor in options.tensor:
data = damask.mechanics.symmetric(table.get(tensor).reshape((-1,3,3))).reshape((-1,9))
VTKarray[tensor] = numpy_support.numpy_to_vtk(data.copy(),
deep=True,array_type=vtk.VTK_DOUBLE)
VTKarray[tensor].SetName(tensor)
for data in VTKarray:
Polydata.GetPointData().AddArray(VTKarray[data])
Polydata.Modified()
# ------------------------------------------ output result ---------------------------------------
writer = vtk.vtkXMLPolyDataWriter()
writer.SetDataModeToBinary()
writer.SetCompressorTypeToZLib()
writer.SetFileName(vtk_file+'.'+writer.GetDefaultFileExtension())
writer.SetInputData(Polydata)
writer.Write()
# ------------------------------------------ render result ---------------------------------------
if options.render:
mapper = vtk.vtkDataSetMapper()
mapper.SetInputData(Polydata)
actor = vtk.vtkActor()
actor.SetMapper(mapper)
# Create the graphics structure. The renderer renders into the
# render window. The render window interactively captures mouse events
# and will perform appropriate camera or actor manipulation
# depending on the nature of the events.
ren = vtk.vtkRenderer()
renWin = vtk.vtkRenderWindow()
renWin.AddRenderer(ren)
ren.AddActor(actor)
ren.SetBackground(1, 1, 1)
renWin.SetSize(200, 200)
iren = vtk.vtkRenderWindowInteractor()
iren.SetRenderWindow(renWin)
iren.Initialize()
renWin.Render()
iren.Start()

View File

@ -5,8 +5,6 @@ import sys
from io import StringIO from io import StringIO
from optparse import OptionParser from optparse import OptionParser
import vtk
import damask import damask
@ -36,42 +34,12 @@ parser.set_defaults(pos = 'pos',
if filenames == []: filenames = [None] if filenames == []: filenames = [None]
for name in filenames: for name in filenames:
damask.util.report(scriptName,name) damask.util.report(scriptName,name)
table = damask.Table.from_ASCII(StringIO(''.join(sys.stdin.read())) if name is None else name) table = damask.Table.from_ASCII(StringIO(''.join(sys.stdin.read())) if name is None else name)
v = damask.VTK.from_polyData(table.get(options.pos))
# ------------------------------------------ process data --------------------------------------- if name:
v.write(os.path.splitext(name)[0])
Polydata = vtk.vtkPolyData() else:
Points = vtk.vtkPoints() sys.stdout.write(v.__repr__())
Vertices = vtk.vtkCellArray()
for p in table.get(options.pos):
pointID = Points.InsertNextPoint(p)
Vertices.InsertNextCell(1)
Vertices.InsertCellPoint(pointID)
Polydata.SetPoints(Points)
Polydata.SetVerts(Vertices)
Polydata.Modified()
# ------------------------------------------ output result ---------------------------------------
if name:
writer = vtk.vtkXMLPolyDataWriter()
writer.SetCompressorTypeToZLib()
writer.SetDataModeToBinary()
writer.SetFileName(os.path.join(os.path.split(name)[0],
os.path.splitext(os.path.split(name)[1])[0] +
'.' + writer.GetDefaultFileExtension()))
else:
writer = vtk.vtkDataSetWriter()
writer.SetHeader('# powered by '+scriptID)
writer.WriteToOutputStringOn()
writer.SetInputData(Polydata)
writer.Write()
if name is None: sys.stdout.write(writer.GetOutputString())

View File

@ -5,9 +5,6 @@ import sys
from io import StringIO from io import StringIO
from optparse import OptionParser from optparse import OptionParser
import vtk
import numpy as np
import damask import damask
@ -44,54 +41,18 @@ parser.set_defaults(mode = 'cell',
if filenames == []: filenames = [None] if filenames == []: filenames = [None]
for name in filenames: for name in filenames:
damask.util.report(scriptName,name) damask.util.report(scriptName,name)
table = damask.Table.from_ASCII(StringIO(''.join(sys.stdin.read())) if name is None else name) table = damask.Table.from_ASCII(StringIO(''.join(sys.stdin.read())) if name is None else name)
coords = [np.unique(table.get(options.pos)[:,i]) for i in range(3)] if options.mode == 'cell':
if options.mode == 'cell': grid, size, origin = damask.grid_filters.cell_coord0_gridSizeOrigin(table.get(options.pos))
coords = [0.5 * np.array([3.0 * coords[i][0] - coords[i][0 + int(len(coords[i]) > 1)]] + \ elif options.mode == 'point':
[coords[i][j-1] + coords[i][j] for j in range(1,len(coords[i]))] + \ grid, size, origin = damask.grid_filters.node_coord0_gridSizeOrigin(table.get(options.pos))
[3.0 * coords[i][-1] - coords[i][-1 - int(len(coords[i]) > 1)]]) for i in range(3)]
grid = np.array(list(map(len,coords)),'i') v = damask.VTK.from_rectilinearGrid(grid,size,origin)
N = grid.prod() if options.mode == 'point' else (grid-1).prod()
# ------------------------------------------ process data --------------------------------------- if name:
v.write('{}_{}({})'.format(os.path.splitext(name)[0],options.pos,options.mode))
rGrid = vtk.vtkRectilinearGrid() else:
coordArray = [vtk.vtkDoubleArray(), sys.stdout.write(v.__repr__())
vtk.vtkDoubleArray(),
vtk.vtkDoubleArray(),
]
rGrid.SetDimensions(*grid)
for i,points in enumerate(coords):
for point in points:
coordArray[i].InsertNextValue(point)
rGrid.SetXCoordinates(coordArray[0])
rGrid.SetYCoordinates(coordArray[1])
rGrid.SetZCoordinates(coordArray[2])
# ------------------------------------------ output result ---------------------------------------
if name:
writer = vtk.vtkXMLRectilinearGridWriter()
writer.SetCompressorTypeToZLib()
writer.SetDataModeToBinary()
writer.SetFileName(os.path.join(os.path.split(name)[0],
os.path.splitext(os.path.split(name)[1])[0] +
'_{}({})'.format(options.pos, options.mode) +
'.' + writer.GetDefaultFileExtension()))
else:
writer = vtk.vtkDataSetWriter()
writer.SetHeader('# powered by '+scriptID)
writer.WriteToOutputStringOn()
writer.SetInputData(rGrid)
writer.Write()
if name is None: sys.stdout.write(writer.GetOutputString())

View File

@ -22,18 +22,16 @@ Writes vtk file for visualization.
""", version = scriptID) """, version = scriptID)
(options, filenames) = parser.parse_args() (options, filenames) = parser.parse_args()
if filenames == []: filenames = [None] if filenames == []: filenames = [None]
for name in filenames: for name in filenames:
damask.util.report(scriptName,name) damask.util.report(scriptName,name)
geom = damask.Geom.from_file(StringIO(''.join(sys.stdin.read())) if name is None else name) geom = damask.Geom.from_file(StringIO(''.join(sys.stdin.read())) if name is None else name)
damask.util.croak(geom) damask.util.croak(geom)
if name is None: if name:
sys.stdout.write(geom.to_vtk()) geom.to_vtk(os.path.splitext(name)[0])
else: else:
geom.to_vtk(os.path.splitext(name)[0]) sys.stdout.write(geom.to_vtk())

View File

@ -3,6 +3,8 @@
import os import os
import sys import sys
import multiprocessing import multiprocessing
from io import StringIO
from functools import partial
from optparse import OptionParser,OptionGroup from optparse import OptionParser,OptionGroup
import numpy as np import numpy as np
@ -15,73 +17,40 @@ scriptName = os.path.splitext(os.path.basename(__file__))[0]
scriptID = ' '.join([scriptName,damask.version]) scriptID = ' '.join([scriptName,damask.version])
def laguerreTessellation(undeformed, coords, weights, grains, periodic = True, cpus = 2): def findClosestSeed(seeds, weights, point):
return np.argmin(np.sum((np.broadcast_to(point,(len(seeds),3))-seeds)**2,axis=1) - weights)
def findClosestSeed(fargs):
point, seeds, myWeights = fargs
tmp = np.repeat(point.reshape(3,1), len(seeds), axis=1).T
dist = np.sum((tmp - seeds)**2,axis=1) -myWeights
return np.argmin(dist) # seed point closest to point
copies = \ def Laguerre_tessellation(grid, seeds, grains, size, periodic, weights, cpus):
np.array([
[ -1,-1,-1 ],
[ 0,-1,-1 ],
[ 1,-1,-1 ],
[ -1, 0,-1 ],
[ 0, 0,-1 ],
[ 1, 0,-1 ],
[ -1, 1,-1 ],
[ 0, 1,-1 ],
[ 1, 1,-1 ],
[ -1,-1, 0 ],
[ 0,-1, 0 ],
[ 1,-1, 0 ],
[ -1, 0, 0 ],
[ 0, 0, 0 ],
[ 1, 0, 0 ],
[ -1, 1, 0 ],
[ 0, 1, 0 ],
[ 1, 1, 0 ],
[ -1,-1, 1 ],
[ 0,-1, 1 ],
[ 1,-1, 1 ],
[ -1, 0, 1 ],
[ 0, 0, 1 ],
[ 1, 0, 1 ],
[ -1, 1, 1 ],
[ 0, 1, 1 ],
[ 1, 1, 1 ],
]).astype(float)*info['size'] if periodic else \
np.array([
[ 0, 0, 0 ],
]).astype(float)
repeatweights = np.tile(weights,len(copies)).flatten(order='F') # Laguerre weights (1,2,3,1,2,3,...,1,2,3) if periodic:
for i,vec in enumerate(copies): # periodic copies of seed points ... weights_p = np.tile(weights,27).flatten(order='F') # Laguerre weights (1,2,3,1,2,3,...,1,2,3)
try: seeds = np.append(seeds, coords+vec, axis=0) # ... (1+a,2+a,3+a,...,1+z,2+z,3+z) seeds_p = np.vstack((seeds -np.array([size[0],0.,0.]),seeds, seeds +np.array([size[0],0.,0.])))
except NameError: seeds = coords+vec seeds_p = np.vstack((seeds_p-np.array([0.,size[1],0.]),seeds_p,seeds_p+np.array([0.,size[1],0.])))
seeds_p = np.vstack((seeds_p-np.array([0.,0.,size[2]]),seeds_p,seeds_p+np.array([0.,0.,size[2]])))
if (repeatweights == 0.0).all(): # standard Voronoi (no weights, KD tree)
myKDTree = spatial.cKDTree(seeds)
devNull,closestSeeds = myKDTree.query(undeformed)
else:
damask.util.croak('...using {} cpu{}'.format(options.cpus, 's' if options.cpus > 1 else ''))
arguments = [[arg,seeds,repeatweights] for arg in list(undeformed)]
if cpus > 1: # use multithreading
pool = multiprocessing.Pool(processes = cpus) # initialize workers
result = pool.map_async(findClosestSeed, arguments) # evaluate function in parallel
pool.close()
pool.join()
closestSeeds = np.array(result.get()).flatten()
else: else:
closestSeeds = np.zeros(len(arguments),dtype='i') weights_p = weights.flatten()
for i,arg in enumerate(arguments): seeds_p = seeds
closestSeeds[i] = findClosestSeed(arg)
# closestSeed is modulo number of original seed points (i.e. excluding periodic copies) if cpus > 1:
return grains[closestSeeds%coords.shape[0]] default_args = partial(findClosestSeed,seeds_p,weights_p)
pool = multiprocessing.Pool(processes = cpus) # initialize workers
result = pool.map_async(default_args, [point for point in grid]) # evaluate function in parallel
pool.close()
pool.join()
closestSeeds = np.array(result.get()).flatten()
else:
closestSeeds= np.array([findClosestSeed(seeds_p,weights_p,point) for point in grid])
return grains[closestSeeds%seeds.shape[0]]
def Voronoi_tessellation(grid, seeds, grains, size, periodic = True):
KDTree = spatial.cKDTree(seeds,boxsize=size) if periodic else spatial.cKDTree(seeds)
devNull,closestSeeds = KDTree.query(grid)
return grains[closestSeeds]
# -------------------------------------------------------------------- # --------------------------------------------------------------------
@ -123,16 +92,12 @@ group.add_option('-s',
'--size', '--size',
dest = 'size', dest = 'size',
type = 'float', nargs = 3, metavar=' '.join(['float']*3), type = 'float', nargs = 3, metavar=' '.join(['float']*3),
help = 'x,y,z size of hexahedral box') help = 'x,y,z size of hexahedral box [1.0 1.0 1.0]')
group.add_option('-o', group.add_option('-o',
'--origin', '--origin',
dest = 'origin', dest = 'origin',
type = 'float', nargs = 3, metavar=' '.join(['float']*3), type = 'float', nargs = 3, metavar=' '.join(['float']*3),
help = 'origin of grid') help = 'origin of grid [0.0 0.0 0.0]')
group.add_option('--nonnormalized',
dest = 'normalized',
action = 'store_false',
help = 'seed coordinates are not normalized to a unit cube')
parser.add_option_group(group) parser.add_option_group(group)
@ -191,114 +156,73 @@ parser.set_defaults(pos = 'pos',
cpus = 2, cpus = 2,
laguerre = False, laguerre = False,
periodic = True, periodic = True,
normalized = True,
config = True, config = True,
) )
(options,filenames) = parser.parse_args() (options,filenames) = parser.parse_args()
if filenames == []: filenames = [None] if filenames == []: filenames = [None]
for name in filenames: for name in filenames:
damask.util.report(scriptName,name) damask.util.report(scriptName,name)
table = damask.ASCIItable(name = name, readonly = True) table = damask.Table.from_ASCII(StringIO(''.join(sys.stdin.read())) if name is None else name)
size = np.ones(3)
origin = np.zeros(3)
for line in table.comments:
items = line.lower().strip().split()
key = items[0] if items else ''
if key == 'grid':
grid = np.array([ int(dict(zip(items[1::2],items[2::2]))[i]) for i in ['a','b','c']])
elif key == 'size':
size = np.array([float(dict(zip(items[1::2],items[2::2]))[i]) for i in ['x','y','z']])
elif key == 'origin':
origin = np.array([float(dict(zip(items[1::2],items[2::2]))[i]) for i in ['x','y','z']])
if options.grid: grid = np.array(options.grid)
if options.size: size = np.array(options.size)
if options.origin: origin = np.array(options.origin)
# --- read header ---------------------------------------------------------------------------- seeds = table.get(options.pos)
table.head_read() grains = table.get(options.microstructure) if options.microstructure in table.labels else np.arange(len(seeds))+1
info,extra_header = table.head_getGeom() grainIDs = np.unique(grains).astype('i')
NgrainIDs = len(grainIDs)
if options.grid is not None: info['grid'] = options.grid if options.eulers in table.labels:
if options.size is not None: info['size'] = options.size eulers = table.get(options.eulers)
if options.origin is not None: info['origin'] = options.origin
# ------------------------------------------ sanity checks --------------------------------------- coords = damask.grid_filters.cell_coord0(grid,size,-origin).reshape(-1,3,order='F')
remarks = [] if options.laguerre:
errors = [] indices = Laguerre_tessellation(coords,seeds,grains,size,options.periodic,
labels = [] table.get(options.weight),options.cpus)
else:
indices = Voronoi_tessellation (coords,seeds,grains,size,options.periodic)
hasGrains = table.label_dimension(options.microstructure) == 1 config_header = []
hasEulers = table.label_dimension(options.eulers) == 3 if options.config:
hasWeights = table.label_dimension(options.weight) == 1 and options.laguerre
for i in range(3): if options.eulers in table.labels:
if info['size'][i] <= 0.0: # any invalid size? config_header += ['<texture>']
info['size'][i] = float(info['grid'][i])/max(info['grid']) # normalize to grid for ID in grainIDs:
remarks.append('rescaling size {} to {}...'.format(['x','y','z'][i],info['size'][i])) eulerID = np.nonzero(grains == ID)[0][0] # find first occurrence of this grain id
config_header += ['[Grain{}]'.format(ID),
'(gauss)\tphi1 {:.2f}\tPhi {:.2f}\tphi2 {:.2f}'.format(*eulers[eulerID])
]
if options.axes: config_header += ['axes\t{} {} {}'.format(*options.axes)]
if table.label_dimension(options.pos) != 3: config_header += ['<microstructure>']
errors.append('seed positions "{}" have dimension {}.'.format(options.pos, for ID in grainIDs:
table.label_dimension(options.pos))) config_header += ['[Grain{}]'.format(ID),
else: '(constituent)\tphase {}\ttexture {}\tfraction 1.0'.format(options.phase,ID)
labels += [options.pos] ]
if not options.normalized: remarks.append('using real-space seed coordinates...') config_header += ['<!skip>']
if not hasEulers: remarks.append('missing seed orientations...')
else: labels += [options.eulers]
if not hasGrains: remarks.append('missing seed microstructure indices...')
else: labels += [options.microstructure]
if options.laguerre and not hasWeights: remarks.append('missing seed weights...')
else: labels += [options.weight]
if remarks != []: damask.util.croak(remarks) header = [scriptID + ' ' + ' '.join(sys.argv[1:])]\
if errors != []: + config_header
damask.util.croak(errors) geom = damask.Geom(indices.reshape(grid),size,origin,
table.close(dismiss=True) homogenization=options.homogenization,comments=header)
continue damask.util.croak(geom)
# ------------------------------------------ read seeds --------------------------------------- geom.to_file(sys.stdout if name is None else os.path.splitext(name)[0]+'.geom',pack=False)
table.data_readArray(labels)
coords = table.data[:,table.label_indexrange(options.pos)] * info['size'] if options.normalized \
else table.data[:,table.label_indexrange(options.pos)] - info['origin']
eulers = table.data[:,table.label_indexrange(options.eulers)] if hasEulers \
else np.zeros(3*len(coords))
grains = table.data[:,table.label_indexrange(options.microstructure)].astype(int) if hasGrains \
else 1+np.arange(len(coords))
weights = table.data[:,table.label_indexrange(options.weight)] if hasWeights \
else np.zeros(len(coords))
grainIDs = np.unique(grains).astype('i')
NgrainIDs = len(grainIDs)
# --- tessellate microstructure ------------------------------------------------------------
x = (np.arange(info['grid'][0])+0.5)*info['size'][0]/info['grid'][0]
y = (np.arange(info['grid'][1])+0.5)*info['size'][1]/info['grid'][1]
z = (np.arange(info['grid'][2])+0.5)*info['size'][2]/info['grid'][2]
X,Y,Z = np.meshgrid(x, y, z,indexing='ij')
grid = np.stack((X,Y,Z),axis=-1).reshape((np.prod(info['grid']),3),order='F')
damask.util.croak('tessellating...')
indices = laguerreTessellation(grid, coords, weights, grains, options.periodic, options.cpus)
config_header = []
if options.config:
if hasEulers:
config_header += ['<texture>']
for ID in grainIDs:
eulerID = np.nonzero(grains == ID)[0][0] # find first occurrence of this grain id
config_header += ['[Grain{}]'.format(ID),
'(gauss)\tphi1 {:.2f}\tPhi {:.2f}\tphi2 {:.2f}'.format(*eulers[eulerID])
]
if options.axes is not None: config_header += ['axes\t{} {} {}'.format(*options.axes)]
config_header += ['<microstructure>']
for ID in grainIDs:
config_header += ['[Grain{}]'.format(ID),
'(constituent)\tphase {}\ttexture {}\tfraction 1.0'.format(options.phase,ID)
]
config_header += ['<!skip>']
header = [scriptID + ' ' + ' '.join(sys.argv[1:])]\
+ config_header
geom = damask.Geom(indices.reshape(info['grid'],order='F'),info['size'],info['origin'],
homogenization=options.homogenization,comments=header)
damask.util.croak(geom)
geom.to_file(sys.stdout if name is None else os.path.splitext(name)[0]+'.geom',pack=False)

View File

@ -30,17 +30,16 @@ for name in filenames:
geom = damask.Geom.from_file(StringIO(''.join(sys.stdin.read())) if name is None else name) geom = damask.Geom.from_file(StringIO(''.join(sys.stdin.read())) if name is None else name)
damask.util.croak(geom) damask.util.croak(geom)
coord0 = damask.grid_filters.cell_coord0(geom.grid,geom.size,geom.origin).reshape((-1,3)) coord0 = damask.grid_filters.cell_coord0(geom.grid,geom.size,geom.origin).reshape(-1,3)
comments = geom.comments \ comments = geom.comments \
+ [scriptID + ' ' + ' '.join(sys.argv[1:]), + [scriptID + ' ' + ' '.join(sys.argv[1:]),
"grid\ta {}\tb {}\tc {}".format(*geom.grid), 'grid\ta {}\tb {}\tc {}'.format(*geom.grid),
"size\tx {}\ty {}\tz {}".format(*geom.size), 'size\tx {}\ty {}\tz {}'.format(*geom.size),
"origin\tx {}\ty {}\tz {}".format(*geom.origin), 'origin\tx {}\ty {}\tz {}'.format(*geom.origin),
"homogenization\t{}".format(geom.homogenization)] 'homogenization\t{}'.format(geom.homogenization)]
table = damask.Table(coord0,{'pos':(3,)},comments) table = damask.Table(coord0,{'pos':(3,)},comments)
table.add('microstructure',geom.microstructure.reshape((-1,1),order='F')) table.add('microstructure',geom.microstructure.reshape((-1,1),order='F'))
table.to_ASCII(sys.stdout if name is None else \ table.to_ASCII(sys.stdout if name is None else os.path.splitext(name)[0]+'.txt')
os.path.splitext(name)[0]+'.txt')

View File

@ -1,11 +1,17 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: UTF-8 no BOM -*-
import os
import sys
import math
import random
from io import StringIO
from optparse import OptionParser from optparse import OptionParser
import damask
import os,sys,math,random
import numpy as np import numpy as np
import damask
scriptName = os.path.splitext(os.path.basename(__file__))[0] scriptName = os.path.splitext(os.path.basename(__file__))[0]
scriptID = ' '.join([scriptName,damask.version]) scriptID = ' '.join([scriptName,damask.version])
@ -223,54 +229,29 @@ parser.set_defaults(randomSeed = None,
) )
(options,filenames) = parser.parse_args() (options,filenames) = parser.parse_args()
nSamples = options.number
methods = [options.algorithm]
# --- loop over input files -------------------------------------------------------------------------
if filenames == []: filenames = [None] if filenames == []: filenames = [None]
for name in filenames: for name in filenames:
try:
table = damask.ASCIItable(name = name, readonly=True)
except IOError:
continue
damask.util.report(scriptName,name) damask.util.report(scriptName,name)
randomSeed = int(os.urandom(4).hex(), 16) if options.randomSeed is None else options.randomSeed # random seed per file for second phase table = damask.Table.from_ASCII(StringIO(''.join(sys.stdin.read())) if name is None else name)
randomSeed = int(os.urandom(4).hex(),16) if options.randomSeed is None else options.randomSeed # random seed per file
random.seed(randomSeed) random.seed(randomSeed)
# ------------------------------------------ read header and data ---------------------------------
table.head_read()
errors = []
labels = ['1_euler','2_euler','3_euler','intensity']
for i,index in enumerate(table.label_index(labels)):
if index < 0: errors.append('label {} not present.'.format(labels[i]))
if errors != []:
damask.util.croak(errors)
table.close(dismiss = True)
continue
table.data_readArray(labels)
# --------------- figure out limits (left/right), delta, and interval ----------------------------- # --------------- figure out limits (left/right), delta, and interval -----------------------------
ODF = {} ODF = {}
limits = np.array([np.min(table.data[:,0:3],axis=0), eulers = table.get('euler')
np.max(table.data[:,0:3],axis=0)]) # min/max euler angles in degrees limits = np.array([np.min(eulers,axis=0),np.max(eulers,axis=0)]) # min/max euler angles in degrees
ODF['limit'] = np.radians(limits[1,:]) # right hand limits in radians ODF['limit'] = np.radians(limits[1,:]) # right hand limits in radians
ODF['center'] = 0.0 if all(limits[0,:]<1e-8) else 0.5 # vertex or cell centered ODF['center'] = 0.0 if all(limits[0,:]<1e-8) else 0.5 # vertex or cell centered
ODF['interval'] = np.array(list(map(len,[np.unique(table.data[:,i]) for i in range(3)])),'i') # steps are number of distict values ODF['interval'] = np.array(list(map(len,[np.unique(eulers[:,i]) for i in range(3)])),'i') # steps are number of distict values
ODF['nBins'] = ODF['interval'].prod() ODF['nBins'] = ODF['interval'].prod()
ODF['delta'] = np.radians(np.array(limits[1,0:3]-limits[0,0:3])/(ODF['interval']-1)) # step size ODF['delta'] = np.radians(np.array(limits[1,0:3]-limits[0,0:3])/(ODF['interval']-1)) # step size
if table.data.shape[0] != ODF['nBins']: if eulers.shape[0] != ODF['nBins']:
damask.util.croak('expecting %i values but got %i'%(ODF['nBins'],table.data.shape[0])) damask.util.croak('expecting %i values but got %i'%(ODF['nBins'],eulers.shape[0]))
continue continue
# ----- build binnedODF array and normalize ------------------------------------------------------ # ----- build binnedODF array and normalize ------------------------------------------------------
@ -278,9 +259,10 @@ for name in filenames:
ODF['dV_V'] = [None]*ODF['nBins'] ODF['dV_V'] = [None]*ODF['nBins']
ODF['nNonZero'] = 0 ODF['nNonZero'] = 0
dg = ODF['delta'][0]*2.0*math.sin(ODF['delta'][1]/2.0)*ODF['delta'][2] dg = ODF['delta'][0]*2.0*math.sin(ODF['delta'][1]/2.0)*ODF['delta'][2]
intensity = table.get('intensity')
for b in range(ODF['nBins']): for b in range(ODF['nBins']):
ODF['dV_V'][b] = \ ODF['dV_V'][b] = \
max(0.0,table.data[b,table.label_index('intensity')]) * dg * \ max(0.0,intensity[b,0]) * dg * \
math.sin(((b//ODF['interval'][2])%ODF['interval'][1]+ODF['center'])*ODF['delta'][1]) math.sin(((b//ODF['interval'][2])%ODF['interval'][1]+ODF['center'])*ODF['delta'][1])
if ODF['dV_V'][b] > 0.0: if ODF['dV_V'][b] > 0.0:
sumdV_V += ODF['dV_V'][b] sumdV_V += ODF['dV_V'][b]
@ -296,11 +278,10 @@ for name in filenames:
'Reference Integral: %12.11f\n'%(ODF['limit'][0]*ODF['limit'][2]*(1-math.cos(ODF['limit'][1]))), 'Reference Integral: %12.11f\n'%(ODF['limit'][0]*ODF['limit'][2]*(1-math.cos(ODF['limit'][1]))),
]) ])
# call methods
Functions = {'IA': 'directInversion', 'STAT': 'TothVanHoutteSTAT', 'MC': 'MonteCarloBins'} Functions = {'IA': 'directInversion', 'STAT': 'TothVanHoutteSTAT', 'MC': 'MonteCarloBins'}
method = Functions[options.algorithm] method = Functions[options.algorithm]
Orientations, ReconstructedODF = (globals()[method])(ODF,nSamples) Orientations, ReconstructedODF = (globals()[method])(ODF,options.number)
# calculate accuracy of sample # calculate accuracy of sample
squaredDiff = {'orig':0.0,method:0.0} squaredDiff = {'orig':0.0,method:0.0}
@ -319,7 +300,7 @@ for name in filenames:
indivSum['orig'] += ODF['dV_V'][bin] indivSum['orig'] += ODF['dV_V'][bin]
indivSquaredSum['orig'] += ODF['dV_V'][bin]**2 indivSquaredSum['orig'] += ODF['dV_V'][bin]**2
damask.util.croak(['sqrt(N*)RMSD of ODFs:\t %12.11f'% math.sqrt(nSamples*squaredDiff[method]), damask.util.croak(['sqrt(N*)RMSD of ODFs:\t %12.11f'% math.sqrt(options.number*squaredDiff[method]),
'RMSrD of ODFs:\t %12.11f'%math.sqrt(squaredRelDiff[method]), 'RMSrD of ODFs:\t %12.11f'%math.sqrt(squaredRelDiff[method]),
'rMSD of ODFs:\t %12.11f'%(squaredDiff[method]/indivSquaredSum['orig']), 'rMSD of ODFs:\t %12.11f'%(squaredDiff[method]/indivSquaredSum['orig']),
'nNonZero correlation slope:\t %12.11f'\ 'nNonZero correlation slope:\t %12.11f'\
@ -331,10 +312,10 @@ for name in filenames:
(indivSquaredSum[method]/ODF['nNonZero']-(indivSum[method]/ODF['nNonZero'])**2)))), (indivSquaredSum[method]/ODF['nNonZero']-(indivSum[method]/ODF['nNonZero'])**2)))),
]) ])
if method == 'IA' and nSamples < ODF['nNonZero']: if method == 'IA' and options.number < ODF['nNonZero']:
strOpt = '(%i)'%ODF['nNonZero'] strOpt = '(%i)'%ODF['nNonZero']
formatwidth = 1+int(math.log10(nSamples)) formatwidth = 1+int(math.log10(options.number))
materialConfig = [ materialConfig = [
'#' + scriptID + ' ' + ' '.join(sys.argv[1:]), '#' + scriptID + ' ' + ' '.join(sys.argv[1:]),
@ -344,7 +325,7 @@ for name in filenames:
'#-------------------#', '#-------------------#',
] ]
for i,ID in enumerate(range(nSamples)): for i,ID in enumerate(range(options.number)):
materialConfig += ['[Grain%s]'%(str(ID+1).zfill(formatwidth)), materialConfig += ['[Grain%s]'%(str(ID+1).zfill(formatwidth)),
'(constituent) phase %i texture %s fraction 1.0'%(options.phase,str(ID+1).rjust(formatwidth)), '(constituent) phase %i texture %s fraction 1.0'%(options.phase,str(ID+1).rjust(formatwidth)),
] ]
@ -355,7 +336,7 @@ for name in filenames:
'#-------------------#', '#-------------------#',
] ]
for ID in range(nSamples): for ID in range(options.number):
eulers = Orientations[ID] eulers = Orientations[ID]
materialConfig += ['[Grain%s]'%(str(ID+1).zfill(formatwidth)), materialConfig += ['[Grain%s]'%(str(ID+1).zfill(formatwidth)),
@ -364,7 +345,5 @@ for name in filenames:
#--- output finalization -------------------------------------------------------------------------- #--- output finalization --------------------------------------------------------------------------
with (open(os.path.splitext(name)[0]+'_'+method+'_'+str(nSamples)+'_material.config','w')) as outfile: with (open(os.path.splitext(name)[0]+'_'+method+'_'+str(options.number)+'_material.config','w')) as outfile:
outfile.write('\n'.join(materialConfig)+'\n') outfile.write('\n'.join(materialConfig)+'\n')
table.close()

File diff suppressed because it is too large Load Diff

39
processing/pre/seeds_check.py Executable file
View File

@ -0,0 +1,39 @@
#!/usr/bin/env python3
import os
import sys
from io import StringIO
from optparse import OptionParser
import damask
scriptName = os.path.splitext(os.path.basename(__file__))[0]
scriptID = ' '.join([scriptName,damask.version])
#--------------------------------------------------------------------------------------------------
# MAIN
#--------------------------------------------------------------------------------------------------
parser = OptionParser(option_class=damask.extendableOption, usage='%prog [seedfile(s)]', description = """
Writes vtk file for visualization.
""", version = scriptID)
(options, filenames) = parser.parse_args()
if filenames == []: filenames = [None]
for name in filenames:
damask.util.report(scriptName,name)
seeds = damask.Table.from_ASCII(StringIO(''.join(sys.stdin.read())) if name is None else name)
v = damask.VTK.from_polyData(seeds.get('pos'))
for label in seeds.shapes.keys():
if label == 'pos': pass
v.add(seeds.get(label),label)
if name:
v.write(os.path.splitext(name)[0])
else:
sys.stdout.write(v.__repr__())

View File

@ -1,11 +0,0 @@
#!/usr/bin/env bash
for seeds in "$@"
do
vtk_pointCloud $seeds
vtk_addPointCloudData $seeds \
--data microstructure,weight \
--vtk ${seeds%.*}.vtp \
done

View File

@ -1,9 +1,15 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import threading,time,os,sys,random import threading
import numpy as np import time
import os
import sys
import random
from optparse import OptionParser from optparse import OptionParser
from io import StringIO from io import StringIO
import numpy as np
import damask import damask
scriptName = os.path.splitext(os.path.basename(__file__))[0] scriptName = os.path.splitext(os.path.basename(__file__))[0]
@ -49,12 +55,11 @@ class myThread (threading.Thread):
s.acquire() # ensure only one thread acces global data s.acquire() # ensure only one thread acces global data
if bestSeedsUpdate > knownSeedsUpdate: # write best fit to virtual file if bestSeedsUpdate > knownSeedsUpdate: # write best fit to virtual file
knownSeedsUpdate = bestSeedsUpdate knownSeedsUpdate = bestSeedsUpdate
bestSeedsVFile.reset() bestSeedsVFile.seek(0)
myBestSeedsVFile.close() myBestSeedsVFile.close()
myBestSeedsVFile = StringIO() myBestSeedsVFile = StringIO()
i=0 i=0
for line in bestSeedsVFile: myBestSeedsVFile.writelines(bestSeedsVFile.readlines())
myBestSeedsVFile.write(line)
s.release() s.release()
if randReset: # new direction because current one led to worse fit if randReset: # new direction because current one led to worse fit
@ -67,46 +72,38 @@ class myThread (threading.Thread):
for i in range(NmoveGrains): for i in range(NmoveGrains):
selectedMs.append(random.randrange(1,nMicrostructures)) selectedMs.append(random.randrange(1,nMicrostructures))
direction.append(np.array(((random.random()-0.5)*delta[0], direction.append((np.random.random()-0.5)*delta)
(random.random()-0.5)*delta[1],
(random.random()-0.5)*delta[2])))
perturbedSeedsVFile.close() # reset virtual file perturbedSeedsVFile.close() # reset virtual file
perturbedSeedsVFile = StringIO() perturbedSeedsVFile = StringIO()
myBestSeedsVFile.reset() myBestSeedsVFile.seek(0)
perturbedSeedsTable = damask.ASCIItable(myBestSeedsVFile,perturbedSeedsVFile,labeled=True) # write best fit to perturbed seed file perturbedSeedsTable = damask.Table.from_ASCII(myBestSeedsVFile)
perturbedSeedsTable.head_read() coords = perturbedSeedsTable.get('pos')
perturbedSeedsTable.head_write()
outputAlive=True
ms = 1
i = 0 i = 0
while outputAlive and perturbedSeedsTable.data_read(): # perturbe selected microstructure for ms,coord in enumerate(coords):
if ms in selectedMs: if ms in selectedMs:
newCoords=np.array(tuple(map(float,perturbedSeedsTable.data[0:3]))+direction[i]) newCoords=coord+direction[i]
newCoords=np.where(newCoords>=1.0,newCoords-1.0,newCoords) # ensure that the seeds remain in the box newCoords=np.where(newCoords>=1.0,newCoords-1.0,newCoords) # ensure that the seeds remain in the box
newCoords=np.where(newCoords <0.0,newCoords+1.0,newCoords) newCoords=np.where(newCoords <0.0,newCoords+1.0,newCoords)
perturbedSeedsTable.data[0:3]=[format(f, '8.6f') for f in newCoords] coords[i]=newCoords
direction[i]*=2. direction[i]*=2.
i+= 1 i+= 1
ms+=1 perturbedSeedsTable.set('pos',coords)
perturbedSeedsTable.data_write() perturbedSeedsTable.to_ASCII(perturbedSeedsVFile)
#--- do tesselation with perturbed seed file ----------------------------------------------------------
#--- do tesselation with perturbed seed file ------------------------------------------------------
perturbedGeomVFile.close() perturbedGeomVFile.close()
perturbedGeomVFile = StringIO() perturbedGeomVFile = StringIO()
perturbedSeedsVFile.reset() perturbedSeedsVFile.seek(0)
perturbedGeomVFile.write(damask.util.execute('geom_fromVoronoiTessellation '+ perturbedGeomVFile.write(damask.util.execute('geom_fromVoronoiTessellation '+
' -g '+' '.join(list(map(str, options.grid))),streamIn=perturbedSeedsVFile)[0]) ' -g '+' '.join(list(map(str, options.grid))),streamIn=perturbedSeedsVFile)[0])
perturbedGeomVFile.reset() perturbedGeomVFile.seek(0)
#--- evaluate current seeds file ---------------------------------------------------------------------- #--- evaluate current seeds file ------------------------------------------------------------------
perturbedGeomTable = damask.ASCIItable(perturbedGeomVFile,None,labeled=False,readonly=True) perturbedGeom = damask.Geom.from_file(perturbedGeomVFile)
perturbedGeomTable.head_read() myNmicrostructures = len(np.unique(perturbedGeom.microstructure))
for i in perturbedGeomTable.info: currentData=np.bincount(perturbedGeom.microstructure.ravel())[1:]/points
if i.startswith('microstructures'): myNmicrostructures = int(i.split('\t')[1])
perturbedGeomTable.data_readArray()
perturbedGeomTable.output_flush()
currentData=np.bincount(perturbedGeomTable.data.astype(int).ravel())[1:]/points
currentError=[] currentError=[]
currentHist=[] currentHist=[]
for i in range(nMicrostructures): # calculate the deviation in all bins per histogram for i in range(nMicrostructures): # calculate the deviation in all bins per histogram
@ -137,7 +134,7 @@ class myThread (threading.Thread):
damask.util.croak(' target: '+np.array_str(target[i]['histogram'])) damask.util.croak(' target: '+np.array_str(target[i]['histogram']))
damask.util.croak(' best: '+np.array_str(currentHist[i])) damask.util.croak(' best: '+np.array_str(currentHist[i]))
currentSeedsName = baseFile+'_'+str(bestSeedsUpdate).replace('.','-') # name of new seed file (use time as unique identifier) currentSeedsName = baseFile+'_'+str(bestSeedsUpdate).replace('.','-') # name of new seed file (use time as unique identifier)
perturbedSeedsVFile.reset() perturbedSeedsVFile.seek(0)
bestSeedsVFile.close() bestSeedsVFile.close()
bestSeedsVFile = StringIO() bestSeedsVFile = StringIO()
sys.stdout.flush() sys.stdout.flush()
@ -154,11 +151,10 @@ class myThread (threading.Thread):
break break
if i == min(nMicrostructures,myMatch+options.bins)-1: # same quality as before: take it to keep on moving if i == min(nMicrostructures,myMatch+options.bins)-1: # same quality as before: take it to keep on moving
bestSeedsUpdate = time.time() bestSeedsUpdate = time.time()
perturbedSeedsVFile.reset() perturbedSeedsVFile.seek(0)
bestSeedsVFile.close() bestSeedsVFile.close()
bestSeedsVFile = StringIO() bestSeedsVFile = StringIO()
for line in perturbedSeedsVFile: bestSeedsVFile.writelines(perturbedSeedsVFile.readlines())
bestSeedsVFile.write(line)
for j in range(nMicrostructures): for j in range(nMicrostructures):
target[j]['error'] = currentError[j] target[j]['error'] = currentError[j]
randReset = True randReset = True
@ -216,7 +212,7 @@ damask.util.report(scriptName,options.seedFile)
if options.randomSeed is None: if options.randomSeed is None:
options.randomSeed = int(os.urandom(4).hex(),16) options.randomSeed = int(os.urandom(4).hex(),16)
damask.util.croak(options.randomSeed) damask.util.croak(options.randomSeed)
delta = (options.scale/options.grid[0],options.scale/options.grid[1],options.scale/options.grid[2]) delta = options.scale/np.array(options.grid)
baseFile=os.path.splitext(os.path.basename(options.seedFile))[0] baseFile=os.path.splitext(os.path.basename(options.seedFile))[0]
points = np.array(options.grid).prod().astype('float') points = np.array(options.grid).prod().astype('float')

View File

@ -54,17 +54,16 @@ for name in filenames:
np.in1d(microstructure,options.blacklist,invert=True) if options.blacklist else \ np.in1d(microstructure,options.blacklist,invert=True) if options.blacklist else \
np.full(geom.grid.prod(),True,dtype=bool)) np.full(geom.grid.prod(),True,dtype=bool))
seeds = np.concatenate((damask.grid_filters.cell_coord0(geom.grid,geom.size).reshape((-1,3)), seeds = damask.grid_filters.cell_coord0(geom.grid,geom.size).reshape(-1,3)
microstructure),
axis=1)[mask]
comments = geom.comments \ comments = geom.comments \
+ [scriptID + ' ' + ' '.join(sys.argv[1:]), + [scriptID + ' ' + ' '.join(sys.argv[1:]),
"grid\ta {}\tb {}\tc {}".format(*geom.grid), 'grid\ta {}\tb {}\tc {}'.format(*geom.grid),
"size\tx {}\ty {}\tz {}".format(*geom.size), 'size\tx {}\ty {}\tz {}'.format(*geom.size),
"origin\tx {}\ty {}\tz {}".format(*geom.origin), 'origin\tx {}\ty {}\tz {}'.format(*geom.origin),
"homogenization\t{}".format(geom.homogenization)] 'homogenization\t{}'.format(geom.homogenization)]
table = damask.Table(seeds,{'pos':(3,),'microstructure':(1,)},comments) table = damask.Table(seeds[mask],{'pos':(3,)},comments)
table.add('microstructure',microstructure[mask])
table.to_ASCII(sys.stdout if name is None else \ table.to_ASCII(sys.stdout if name is None else \
os.path.splitext(name)[0]+'.seeds') os.path.splitext(name)[0]+'.seeds')

View File

@ -64,8 +64,8 @@ for name in filenames:
damask.util.croak('poking {} x {} x {} in box {} {} {}...'.format(Nx,Ny,Nz,*box)) damask.util.croak('poking {} x {} x {} in box {} {} {}...'.format(Nx,Ny,Nz,*box))
seeds = np.zeros((Nx*Ny*Nz,4),'d') seeds = np.zeros((Nx*Ny*Nz,4))
g = np.zeros(3,'i') g = np.zeros(3,dtype=np.int)
n = 0 n = 0
for i in range(Nx): for i in range(Nx):
@ -84,12 +84,13 @@ for name in filenames:
comments = geom.comments \ comments = geom.comments \
+ [scriptID + ' ' + ' '.join(sys.argv[1:]), + [scriptID + ' ' + ' '.join(sys.argv[1:]),
"poking\ta {}\tb {}\tc {}".format(Nx,Ny,Nz), 'poking\ta {}\tb {}\tc {}'.format(Nx,Ny,Nz),
"grid\ta {}\tb {}\tc {}".format(*geom.grid), 'grid\ta {}\tb {}\tc {}'.format(*geom.grid),
"size\tx {}\ty {}\tz {}".format(*geom.size), 'size\tx {}\ty {}\tz {}'.format(*geom.size),
"origin\tx {}\ty {}\tz {}".format(*geom.origin), 'origin\tx {}\ty {}\tz {}'.format(*geom.origin),
"homogenization\t{}".format(geom.homogenization)] 'homogenization\t{}'.format(geom.homogenization)]
table = damask.Table(seeds,{'pos':(3,),'microstructure':(1,)},comments) table = damask.Table(seeds,{'pos':(3,),'microstructure':(1,)},comments)
table.set('microstructure',table.get('microstructure').astype(np.int))
table.to_ASCII(sys.stdout if name is None else \ table.to_ASCII(sys.stdout if name is None else \
os.path.splitext(name)[0]+'_poked_{}.seeds'.format(options.N)) os.path.splitext(name)[0]+'_poked_{}.seeds'.format(options.N))

View File

@ -1,36 +1,25 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: UTF-8 no BOM -*-
import os,sys,math,random import os
import numpy as np import sys
import damask
from optparse import OptionParser,OptionGroup from optparse import OptionParser,OptionGroup
import numpy as np
from scipy import spatial from scipy import spatial
import damask
scriptName = os.path.splitext(os.path.basename(__file__))[0] scriptName = os.path.splitext(os.path.basename(__file__))[0]
scriptID = ' '.join([scriptName,damask.version]) scriptID = ' '.join([scriptName,damask.version])
# ------------------------------------------ aux functions ---------------------------------
def kdtree_search(cloud, queryPoints):
"""Find distances to nearest neighbor among cloud (N,d) for each of the queryPoints (n,d)."""
n = queryPoints.shape[0]
distances = np.zeros(n,dtype=float)
tree = spatial.cKDTree(cloud)
for i in range(n):
distances[i], index = tree.query(queryPoints[i])
return distances
# -------------------------------------------------------------------- # --------------------------------------------------------------------
# MAIN # MAIN
# -------------------------------------------------------------------- # --------------------------------------------------------------------
parser = OptionParser(option_class=damask.extendableOption, usage='%prog options', description = """ parser = OptionParser(option_class=damask.extendableOption, usage='%prog options', description = """
Distribute given number of points randomly within (a fraction of) the three-dimensional cube [0.0,0.0,0.0]--[1.0,1.0,1.0]. Distribute given number of points randomly within rectangular cuboid.
Reports positions with random crystal orientations in seeds file format to STDOUT. Reports positions with random crystal orientations in seeds file format to STDOUT.
""", version = scriptID) """, version = scriptID)
@ -39,11 +28,11 @@ parser.add_option('-N',
dest = 'N', dest = 'N',
type = 'int', metavar = 'int', type = 'int', metavar = 'int',
help = 'number of seed points [%default]') help = 'number of seed points [%default]')
parser.add_option('-f', parser.add_option('-s',
'--fraction', '--size',
dest = 'fraction', dest = 'size',
type = 'float', nargs = 3, metavar = 'float float float', type = 'float', nargs = 3, metavar = 'float float float',
help='fractions along x,y,z of unit cube to fill %default') help='size x,y,z of unit cube to fill %default')
parser.add_option('-g', parser.add_option('-g',
'--grid', '--grid',
dest = 'grid', dest = 'grid',
@ -58,9 +47,6 @@ parser.add_option('-r',
'--rnd', '--rnd',
dest = 'randomSeed', type = 'int', metavar = 'int', dest = 'randomSeed', type = 'int', metavar = 'int',
help = 'seed of random number generator [%default]') help = 'seed of random number generator [%default]')
parser.add_option('--format',
dest = 'format', type = 'string', metavar = 'string',
help = 'output number format [auto]')
group = OptionGroup(parser, "Laguerre Tessellation", group = OptionGroup(parser, "Laguerre Tessellation",
"Parameters determining shape of weight distribution of seed points" "Parameters determining shape of weight distribution of seed points"
@ -87,8 +73,7 @@ parser.add_option_group(group)
group = OptionGroup(parser, "Selective Seeding", group = OptionGroup(parser, "Selective Seeding",
"More uniform distribution of seed points using Mitchell's Best Candidate Algorithm" "More uniform distribution of seed points using Mitchell's Best Candidate Algorithm"
) )
group.add_option( '-s', group.add_option( '--selective',
'--selective',
action = 'store_true', action = 'store_true',
dest = 'selective', dest = 'selective',
help = 'selective picking of seed points from random seed points') help = 'selective picking of seed points from random seed points')
@ -104,7 +89,7 @@ parser.add_option_group(group)
parser.set_defaults(randomSeed = None, parser.set_defaults(randomSeed = None,
grid = (16,16,16), grid = (16,16,16),
fraction = (1.0,1.0,1.0), size = (1.0,1.0,1.0),
N = 20, N = 20,
weights = False, weights = False,
max = 0.0, max = 0.0,
@ -114,116 +99,67 @@ parser.set_defaults(randomSeed = None,
selective = False, selective = False,
distance = 0.2, distance = 0.2,
numCandidates = 10, numCandidates = 10,
format = None,
) )
(options,filenames) = parser.parse_args() (options,filenames) = parser.parse_args()
options.fraction = np.array(options.fraction)
options.grid = np.array(options.grid)
gridSize = options.grid.prod()
if options.randomSeed is None: options.randomSeed = int(os.urandom(4).hex(), 16)
np.random.seed(options.randomSeed) # init random generators
random.seed(options.randomSeed)
# --- loop over output files -------------------------------------------------------------------------
if filenames == []: filenames = [None] if filenames == []: filenames = [None]
size = np.array(options.size)
grid = np.array(options.grid)
np.random.seed(int(os.urandom(4).hex(),16) if options.randomSeed is None else options.randomSeed)
for name in filenames: for name in filenames:
try: damask.util.report(scriptName,name)
table = damask.ASCIItable(outname = name)
except IOError:
continue
damask.util.report(scriptName,name)
# --- sanity checks ------------------------------------------------------------------------- if options.N > np.prod(grid):
damask.util.croak('More seeds than grid positions.')
sys.exit()
if options.selective and options.distance < min(size/grid):
damask.util.croak('Distance must be larger than grid spacing.')
sys.exit()
if options.selective and options.distance**3*options.N > 0.5*np.prod(size):
damask.util.croak('Number of seeds for given size and distance should be < {}.'\
.format(int(0.5*np.prod(size)/options.distance**3)))
remarks = [] eulers = np.random.rand(options.N,3) # create random Euler triplets
errors = [] eulers[:,0] *= 360.0 # phi_1 is uniformly distributed
if gridSize == 0: eulers[:,1] = np.degrees(np.arccos(2*eulers[:,1]-1.0)) # cos(Phi) is uniformly distributed
errors.append('zero grid dimension for {}.'.format(', '.join([['a','b','c'][x] for x in np.where(options.grid == 0)[0]]))) eulers[:,2] *= 360.0 # phi_2 is uniformly distributed
if options.N > gridSize/10.:
remarks.append('seed count exceeds 0.1 of grid points.')
if options.selective and 4./3.*math.pi*(options.distance/2.)**3*options.N > 0.5:
remarks.append('maximum recommended seed point count for given distance is {}.{}'.
format(int(3./8./math.pi/(options.distance/2.)**3)))
if remarks != []: damask.util.croak(remarks)
if errors != []:
damask.util.croak(errors)
sys.exit()
# --- do work ------------------------------------------------------------------------------------ if not options.selective:
coords = damask.grid_filters.cell_coord0(grid,size).reshape(-1,3)
seeds = coords[np.random.choice(np.prod(grid), options.N, replace=False)] \
+ np.broadcast_to(size/grid,(options.N,3))*(np.random.rand(options.N,3)*.5-.25) # wobble without leaving grid
else:
seeds = np.empty((options.N,3))
seeds[0] = np.random.random(3) * size
grainEuler = np.random.rand(3,options.N) # create random Euler triplets i = 1
grainEuler[0,:] *= 360.0 # phi_1 is uniformly distributed progress = damask.util._ProgressBar(options.N,'',50)
grainEuler[1,:] = np.degrees(np.arccos(2*grainEuler[1,:]-1)) # cos(Phi) is uniformly distributed while i < options.N:
grainEuler[2,:] *= 360.0 # phi_2 is uniformly distributed candidates = np.random.rand(options.numCandidates,3)*np.broadcast_to(size,(options.numCandidates,3))
tree = spatial.cKDTree(seeds[:i])
distances, dev_null = tree.query(candidates)
best = distances.argmax()
if distances[best] > options.distance: # require minimum separation
seeds[i] = candidates[best] # maximum separation to existing point cloud
i += 1
progress.update(i)
if not options.selective:
n = np.maximum(np.ones(3),np.array(options.grid*options.fraction),
dtype=int,casting='unsafe') # find max grid indices within fraction
meshgrid = np.meshgrid(*map(np.arange,n),indexing='ij') # create a meshgrid within fraction
coords = np.vstack((meshgrid[0],meshgrid[1],meshgrid[2])).reshape(3,n.prod()).T # assemble list of 3D coordinates
seeds = ((random.sample(list(coords),options.N)+np.random.random(options.N*3).reshape(options.N,3))\
/ \
(n/options.fraction)).T # pick options.N of those, rattle position,
# and rescale to fall within fraction
else:
seeds = np.zeros((options.N,3),dtype=float) # seed positions array
seeds[0] = np.random.random(3)*options.grid/max(options.grid)
i = 1 # start out with one given point
if i%(options.N/100.) < 1: damask.util.croak('.',False)
while i < options.N: comments = [scriptID + ' ' + ' '.join(sys.argv[1:]),
candidates = np.random.random(options.numCandidates*3).reshape(options.numCandidates,3) 'grid\ta {}\tb {}\tc {}'.format(*grid),
distances = kdtree_search(seeds[:i],candidates) 'size\tx {}\ty {}\tz {}'.format(*size),
best = distances.argmax() 'randomSeed\t{}'.format(options.randomSeed),
if distances[best] > options.distance: # require minimum separation ]
seeds[i] = candidates[best] # maximum separation to existing point cloud
i += 1
if i%(options.N/100.) < 1: damask.util.croak('.',False)
damask.util.croak('') table = damask.Table(np.hstack((seeds,eulers)),{'pos':(3,),'euler':(3,)},comments)
seeds = seeds.T # prepare shape for stacking table.add('microstructure',np.arange(options.microstructure,options.microstructure + options.N,dtype=int))
if options.weights: if options.weights:
weights = [np.random.uniform(low = 0, high = options.max, size = options.N)] if options.max > 0.0 \ weights = np.random.uniform(low = 0, high = options.max, size = options.N) if options.max > 0.0 \
else [np.random.normal(loc = options.mean, scale = options.sigma, size = options.N)] else np.random.normal(loc = options.mean, scale = options.sigma, size = options.N)
else: table.add('weight',weights)
weights = []
seeds = np.transpose(np.vstack(tuple([seeds,
grainEuler,
np.arange(options.microstructure,
options.microstructure + options.N),
] + weights
)))
# ------------------------------------------ assemble header --------------------------------------- table.to_ASCII(sys.stdout if name is None else name)
table.info_clear()
table.info_append([
scriptID + ' ' + ' '.join(sys.argv[1:]),
"grid\ta {}\tb {}\tc {}".format(*options.grid),
"microstructures\t{}".format(options.N),
"randomSeed\t{}".format(options.randomSeed),
])
table.labels_clear()
table.labels_append( ['{dim}_{label}'.format(dim = 1+k,label = 'pos') for k in range(3)] +
['{dim}_{label}'.format(dim = 1+k,label = 'euler') for k in range(3)] +
['microstructure'] +
(['weight'] if options.weights else []))
table.head_write()
table.output_flush()
# --- write seeds information ------------------------------------------------------------
table.data = seeds
table.data_writeArray(fmt = options.format)
# --- output finalization --------------------------------------------------------------------------
table.close() # close ASCII table

1
python/.gitignore vendored
View File

@ -1,2 +1,3 @@
*.pyc
dist dist
damask.egg-info damask.egg-info

View File

@ -36,7 +36,7 @@ sc = np.pi**(1./6.)/6.**(1./6.)
beta = np.pi**(5./6.)/6.**(1./6.)/2. beta = np.pi**(5./6.)/6.**(1./6.)/2.
R1 = (3.*np.pi/4.)**(1./3.) R1 = (3.*np.pi/4.)**(1./3.)
def CubeToBall(cube): def cube_to_ball(cube):
""" """
Map a point in a uniform refinable cubical grid to a point on a uniform refinable grid on a ball. Map a point in a uniform refinable cubical grid to a point on a uniform refinable grid on a ball.
@ -59,7 +59,7 @@ def CubeToBall(cube):
ball = np.zeros(3) ball = np.zeros(3)
else: else:
# get pyramide and scale by grid parameter ratio # get pyramide and scale by grid parameter ratio
p = get_order(cube) p = _get_order(cube)
XYZ = cube[p] * sc XYZ = cube[p] * sc
# intercept all the points along the z-axis # intercept all the points along the z-axis
@ -87,7 +87,7 @@ def CubeToBall(cube):
return ball return ball
def BallToCube(ball): def ball_to_cube(ball):
""" """
Map a point on a uniform refinable grid on a ball to a point in a uniform refinable cubical grid. Map a point on a uniform refinable grid on a ball to a point in a uniform refinable cubical grid.
@ -109,7 +109,7 @@ def BallToCube(ball):
if np.allclose(ball,0.0,rtol=0.0,atol=1.0e-300): if np.allclose(ball,0.0,rtol=0.0,atol=1.0e-300):
cube = np.zeros(3) cube = np.zeros(3)
else: else:
p = get_order(ball) p = _get_order(ball)
xyz3 = ball[p] xyz3 = ball[p]
# inverse M_3 # inverse M_3
@ -137,7 +137,7 @@ def BallToCube(ball):
return cube return cube
def get_order(xyz): def _get_order(xyz):
""" """
Get order of the coordinates. Get order of the coordinates.

View File

@ -1,37 +1,25 @@
"""Main aggregator.""" """Main aggregator."""
import os import os as _os
import re import re as _re
name = 'damask' name = 'damask'
with open(os.path.join(os.path.dirname(__file__),'VERSION')) as f: with open(_os.path.join(_os.path.dirname(__file__),'VERSION')) as _f:
version = re.sub(r'^v','',f.readline().strip()) version = _re.sub(r'^v','',_f.readline().strip())
# classes # classes
from .environment import Environment # noqa from ._environment import Environment # noqa
from .table import Table # noqa from ._table import Table # noqa
from .ktv import VTK # noqa from ._vtk import VTK # noqa
from .colormaps import Colormap, Color # noqa from ._colormaps import Colormap, Color # noqa
from .rotation import Rotation # noqa from ._rotation import Rotation # noqa
from .lattice import Symmetry, Lattice# noqa from ._lattice import Symmetry, Lattice# noqa
from .orientation import Orientation # noqa from ._orientation import Orientation # noqa
from .result import Result # noqa from ._result import Result # noqa
from .geom import Geom # noqa from ._geom import Geom # noqa
from .solver import Solver # noqa from . import solver # noqa
# compatibility hack
from .result import Result as DADF5 # noqa
# deprecated # deprecated
from .asciitable import ASCIItable # noqa from ._asciitable import ASCIItable # noqa
from .util import extendableOption # noqa from ._test import Test # noqa
from .config import Material # noqa from .config import Material # noqa
from .test import Test # noqa from .util import extendableOption # noqa
# functions in modules
from . import mechanics # noqa
from . import grid_filters # noqa
# clean temporary variables
del os
del re
del f

View File

@ -14,11 +14,9 @@ class ASCIItable():
# ------------------------------------------------------------------ # ------------------------------------------------------------------
def __init__(self, def __init__(self,
name = None, name,
outname = None, labeled = True, # assume table has labels
buffered = False, # is ignored, only exists for compatibility reasons readonly = False, # no reading from file
labeled = True, # assume table has labels
readonly = False, # no reading from file
): ):
"""Read and write to ASCII tables.""" """Read and write to ASCII tables."""
self.__IO__ = {'output': [], self.__IO__ = {'output': [],
@ -27,8 +25,9 @@ class ASCIItable():
'dataStart': 0, 'dataStart': 0,
} }
self.__IO__['inPlace'] = not outname and name and not readonly self.__IO__['inPlace'] = name and not readonly
if self.__IO__['inPlace']: outname = name + self.tmpext # transparently create tmp file outname = name + self.tmpext if self.__IO__['inPlace'] else None # transparently create tmp file
try: try:
self.__IO__['in'] = (open( name,'r') if os.access( name, os.R_OK) else None) if name else sys.stdin self.__IO__['in'] = (open( name,'r') if os.access( name, os.R_OK) else None) if name else sys.stdin
except TypeError: except TypeError:
@ -166,42 +165,6 @@ class ASCIItable():
return self.output_write(head) return self.output_write(head)
# ------------------------------------------------------------------
def head_getGeom(self):
"""Interpret geom header."""
identifiers = {
'grid': ['a','b','c'],
'size': ['x','y','z'],
'origin': ['x','y','z'],
}
mappings = {
'grid': lambda x: int(x),
'size': lambda x: float(x),
'origin': lambda x: float(x),
}
info = {
'grid': np.zeros(3,'i'),
'size': np.zeros(3,'d'),
'origin': np.zeros(3,'d'),
}
extra_header = []
for header in self.info:
headitems = list(map(str.lower,header.split()))
if len(headitems) == 0: continue # skip blank lines
if headitems[0] in list(mappings.keys()):
if headitems[0] in list(identifiers.keys()):
for i in range(len(identifiers[headitems[0]])):
info[headitems[0]][i] = \
mappings[headitems[0]](headitems[headitems.index(identifiers[headitems[0]][i])+1])
else:
info[headitems[0]] = mappings[headitems[0]](headitems[1])
else:
extra_header.append(header)
return info,extra_header
# ------------------------------------------------------------------ # ------------------------------------------------------------------
def labels_append(self, def labels_append(self,
what, what,
@ -424,29 +387,26 @@ class ASCIItable():
return labels_missing return labels_missing
# ------------------------------------------------------------------ # ------------------------------------------------------------------
def data_write(self, def data_write(self):
delimiter = '\t'):
"""Write current data array and report alive output back.""" """Write current data array and report alive output back."""
if len(self.data) == 0: return True if len(self.data) == 0: return True
if isinstance(self.data[0],list): if isinstance(self.data[0],list):
return self.output_write([delimiter.join(map(self._quote,items)) for items in self.data]) return self.output_write(['\t'.join(map(self._quote,items)) for items in self.data])
else: else:
return self.output_write( delimiter.join(map(self._quote,self.data))) return self.output_write( '\t'.join(map(self._quote,self.data)))
# ------------------------------------------------------------------ # ------------------------------------------------------------------
def data_writeArray(self, def data_writeArray(self):
fmt = None,
delimiter = '\t'):
"""Write whole numpy array data.""" """Write whole numpy array data."""
for row in self.data: for row in self.data:
try: try:
output = [fmt % value for value in row] if fmt else list(map(repr,row)) output = list(map(repr,row))
except Exception: except Exception:
output = [fmt % row] if fmt else [repr(row)] output = [repr(row)]
try: try:
self.__IO__['out'].write(delimiter.join(output) + '\n') self.__IO__['out'].write('\t'.join(output) + '\n')
except Exception: except Exception:
pass pass

541
python/damask/_colormaps.py Normal file
View File

@ -0,0 +1,541 @@
import numpy as np
class Color:
"""Color representation in and conversion between different color-spaces."""
__slots__ = [
'model',
'color',
'__dict__',
]
def __init__(self,
model = 'RGB',
color = np.zeros(3)):
"""
Create a Color object.
Parameters
----------
model : string
color model
color : numpy.ndarray
vector representing the color according to the selected model
"""
self.__transforms__ = \
{'HSV': {'index': 0, 'next': self._HSV2HSL},
'HSL': {'index': 1, 'next': self._HSL2RGB, 'prev': self._HSL2HSV},
'RGB': {'index': 2, 'next': self._RGB2XYZ, 'prev': self._RGB2HSL},
'XYZ': {'index': 3, 'next': self._XYZ2CIELAB, 'prev': self._XYZ2RGB},
'CIELAB': {'index': 4, 'next': self._CIELAB2MSH, 'prev': self._CIELAB2XYZ},
'MSH': {'index': 5, 'prev': self._MSH2CIELAB},
}
model = model.upper()
if model not in list(self.__transforms__.keys()): model = 'RGB'
if model == 'RGB' and max(color) > 1.0: # are we RGB255 ?
for i in range(3):
color[i] /= 255.0 # rescale to RGB
if model == 'HSL': # are we HSL ?
if abs(color[0]) > 1.0: color[0] /= 360.0 # with angular hue?
while color[0] >= 1.0: color[0] -= 1.0 # rewind to proper range
while color[0] < 0.0: color[0] += 1.0 # rewind to proper range
self.model = model
self.color = np.array(color,'d')
def __repr__(self):
"""Color model and values."""
return 'Model: %s Color: %s'%(self.model,str(self.color))
def __str__(self):
"""Color model and values."""
return self.__repr__()
def convert_to(self,toModel = 'RGB'):
"""
Change the color model permanently.
Parameters
----------
toModel : string
color model
"""
toModel = toModel.upper()
if toModel not in list(self.__transforms__.keys()): return
sourcePos = self.__transforms__[self.model]['index']
targetPos = self.__transforms__[toModel]['index']
while sourcePos < targetPos:
self.__transforms__[self.model]['next']()
sourcePos += 1
while sourcePos > targetPos:
self.__transforms__[self.model]['prev']()
sourcePos -= 1
return self
def express_as(self,asModel = 'RGB'):
"""
Return the color in a different model.
Parameters
----------
asModel : string
color model
"""
return self.__class__(self.model,self.color).convert_to(asModel)
def _HSV2HSL(self):
"""
Convert H(ue) S(aturation) V(alue or brightness) to H(ue) S(aturation) L(uminance).
All values are in the range [0,1]
http://codeitdown.com/hsl-hsb-hsv-color
"""
if self.model != 'HSV': return
converted = Color('HSL',np.array([
self.color[0],
1. if self.color[2] == 0.0 or (self.color[1] == 0.0 and self.color[2] == 1.0) \
else self.color[1]*self.color[2]/(1.-abs(self.color[2]*(2.-self.color[1])-1.)),
0.5*self.color[2]*(2.-self.color[1]),
]))
self.model = converted.model
self.color = converted.color
def _HSL2HSV(self):
"""
Convert H(ue) S(aturation) L(uminance) to H(ue) S(aturation) V(alue or brightness).
All values are in the range [0,1]
http://codeitdown.com/hsl-hsb-hsv-color
"""
if self.model != 'HSL': return
h = self.color[0]
b = self.color[2]+0.5*(self.color[1]*(1.-abs(2*self.color[2]-1)))
s = 1.0 if b == 0.0 else 2.*(b-self.color[2])/b
converted = Color('HSV',np.array([h,s,b]))
self.model = converted.model
self.color = converted.color
def _HSL2RGB(self):
"""
Convert H(ue) S(aturation) L(uminance) to R(red) G(reen) B(lue).
All values are in the range [0,1]
from http://en.wikipedia.org/wiki/HSL_and_HSV
"""
if self.model != 'HSL': return
sextant = self.color[0]*6.0
c = (1.0 - abs(2.0 * self.color[2] - 1.0))*self.color[1]
x = c*(1.0 - abs(sextant%2 - 1.0))
m = self.color[2] - 0.5*c
converted = Color('RGB',np.array([
[c+m, x+m, m],
[x+m, c+m, m],
[m, c+m, x+m],
[m, x+m, c+m],
[x+m, m, c+m],
[c+m, m, x+m],
][int(sextant)]))
self.model = converted.model
self.color = converted.color
def _RGB2HSL(self):
"""
Convert R(ed) G(reen) B(lue) to H(ue) S(aturation) L(uminance).
All values are in the range [0,1]
from http://130.113.54.154/~monger/hsl-rgb.html
"""
if self.model != 'RGB': return
HSL = np.zeros(3)
maxcolor = self.color.max()
mincolor = self.color.min()
HSL[2] = (maxcolor + mincolor)/2.0
if(mincolor == maxcolor):
HSL[0] = 0.0
HSL[1] = 0.0
else:
if (HSL[2]<0.5):
HSL[1] = (maxcolor - mincolor)/(maxcolor + mincolor)
else:
HSL[1] = (maxcolor - mincolor)/(2.0 - maxcolor - mincolor)
if (maxcolor == self.color[0]):
HSL[0] = 0.0 + (self.color[1] - self.color[2])/(maxcolor - mincolor)
elif (maxcolor == self.color[1]):
HSL[0] = 2.0 + (self.color[2] - self.color[0])/(maxcolor - mincolor)
elif (maxcolor == self.color[2]):
HSL[0] = 4.0 + (self.color[0] - self.color[1])/(maxcolor - mincolor)
HSL[0] = HSL[0]*60.0 # scaling to 360 might be dangerous for small values
if (HSL[0] < 0.0):
HSL[0] = HSL[0] + 360.0
HSL[1:] = np.clip(HSL[1:],0.0,1.0)
converted = Color('HSL', HSL)
self.model = converted.model
self.color = converted.color
def _RGB2XYZ(self):
"""
Convert R(ed) G(reen) B(lue) to CIE XYZ.
All values are in the range [0,1]
from http://www.cs.rit.edu/~ncs/color/t_convert.html
"""
if self.model != 'RGB': return
XYZ = np.zeros(3)
RGB_lin = np.zeros(3)
convert = np.array([[0.412453,0.357580,0.180423],
[0.212671,0.715160,0.072169],
[0.019334,0.119193,0.950227]])
for i in range(3):
if (self.color[i] > 0.04045): RGB_lin[i] = ((self.color[i]+0.0555)/1.0555)**2.4
else: RGB_lin[i] = self.color[i] /12.92
XYZ = np.dot(convert,RGB_lin)
XYZ = np.clip(XYZ,0.0,None)
converted = Color('XYZ', XYZ)
self.model = converted.model
self.color = converted.color
def _XYZ2RGB(self):
"""
Convert CIE XYZ to R(ed) G(reen) B(lue).
All values are in the range [0,1]
from http://www.cs.rit.edu/~ncs/color/t_convert.html
"""
if self.model != 'XYZ': return
convert = np.array([[ 3.240479,-1.537150,-0.498535],
[-0.969256, 1.875992, 0.041556],
[ 0.055648,-0.204043, 1.057311]])
RGB_lin = np.dot(convert,self.color)
RGB = np.zeros(3)
for i in range(3):
if (RGB_lin[i] > 0.0031308): RGB[i] = ((RGB_lin[i])**(1.0/2.4))*1.0555-0.0555
else: RGB[i] = RGB_lin[i] *12.92
RGB = np.clip(RGB,0.0,1.0)
maxVal = max(RGB) # clipping colors according to the display gamut
if (maxVal > 1.0): RGB /= maxVal
converted = Color('RGB', RGB)
self.model = converted.model
self.color = converted.color
def _CIELAB2XYZ(self):
"""
Convert CIE Lab to CIE XYZ.
All values are in the range [0,1]
from http://www.easyrgb.com/index.php?X=MATH&H=07#text7
"""
if self.model != 'CIELAB': return
ref_white = np.array([.95047, 1.00000, 1.08883]) # Observer = 2, Illuminant = D65
XYZ = np.zeros(3)
XYZ[1] = (self.color[0] + 16.0 ) / 116.0
XYZ[0] = XYZ[1] + self.color[1]/ 500.0
XYZ[2] = XYZ[1] - self.color[2]/ 200.0
for i in range(len(XYZ)):
if (XYZ[i] > 6./29. ): XYZ[i] = XYZ[i]**3.
else: XYZ[i] = 108./841. * (XYZ[i] - 4./29.)
converted = Color('XYZ', XYZ*ref_white)
self.model = converted.model
self.color = converted.color
def _XYZ2CIELAB(self):
"""
Convert CIE XYZ to CIE Lab.
All values are in the range [0,1]
from http://en.wikipedia.org/wiki/Lab_color_space,
http://www.cs.rit.edu/~ncs/color/t_convert.html
"""
if self.model != 'XYZ': return
ref_white = np.array([.95047, 1.00000, 1.08883]) # Observer = 2, Illuminant = D65
XYZ = self.color/ref_white
for i in range(len(XYZ)):
if (XYZ[i] > 216./24389 ): XYZ[i] = XYZ[i]**(1.0/3.0)
else: XYZ[i] = (841./108. * XYZ[i]) + 16.0/116.0
converted = Color('CIELAB', np.array([ 116.0 * XYZ[1] - 16.0,
500.0 * (XYZ[0] - XYZ[1]),
200.0 * (XYZ[1] - XYZ[2]) ]))
self.model = converted.model
self.color = converted.color
def _CIELAB2MSH(self):
"""
Convert CIE Lab to Msh colorspace.
from http://www.cs.unm.edu/~kmorel/documents/ColorMaps/DivergingColorMapWorkshop.xls
"""
if self.model != 'CIELAB': return
Msh = np.zeros(3)
Msh[0] = np.sqrt(np.dot(self.color,self.color))
if (Msh[0] > 0.001):
Msh[1] = np.arccos(self.color[0]/Msh[0])
if (self.color[1] != 0.0):
Msh[2] = np.arctan2(self.color[2],self.color[1])
converted = Color('MSH', Msh)
self.model = converted.model
self.color = converted.color
def _MSH2CIELAB(self):
"""
Convert Msh colorspace to CIE Lab.
with s,h in radians
from http://www.cs.unm.edu/~kmorel/documents/ColorMaps/DivergingColorMapWorkshop.xls
"""
if self.model != 'MSH': return
Lab = np.zeros(3)
Lab[0] = self.color[0] * np.cos(self.color[1])
Lab[1] = self.color[0] * np.sin(self.color[1]) * np.cos(self.color[2])
Lab[2] = self.color[0] * np.sin(self.color[1]) * np.sin(self.color[2])
converted = Color('CIELAB', Lab)
self.model = converted.model
self.color = converted.color
class Colormap:
"""Perceptually uniform diverging or sequential colormap."""
__slots__ = [
'left',
'right',
'interpolate',
]
__predefined__ = {
'gray': {'left': Color('HSL',[0,1,1]),
'right': Color('HSL',[0,0,0.15]),
'interpolate': 'perceptualuniform'},
'grey': {'left': Color('HSL',[0,1,1]),
'right': Color('HSL',[0,0,0.15]),
'interpolate': 'perceptualuniform'},
'red': {'left': Color('HSL',[0,1,0.14]),
'right': Color('HSL',[0,0.35,0.91]),
'interpolate': 'perceptualuniform'},
'green': {'left': Color('HSL',[0.33333,1,0.14]),
'right': Color('HSL',[0.33333,0.35,0.91]),
'interpolate': 'perceptualuniform'},
'blue': {'left': Color('HSL',[0.66,1,0.14]),
'right': Color('HSL',[0.66,0.35,0.91]),
'interpolate': 'perceptualuniform'},
'seaweed': {'left': Color('HSL',[0.78,1.0,0.1]),
'right': Color('HSL',[0.40000,0.1,0.9]),
'interpolate': 'perceptualuniform'},
'bluebrown': {'left': Color('HSL',[0.65,0.53,0.49]),
'right': Color('HSL',[0.11,0.75,0.38]),
'interpolate': 'perceptualuniform'},
'redgreen': {'left': Color('HSL',[0.97,0.96,0.36]),
'right': Color('HSL',[0.33333,1.0,0.14]),
'interpolate': 'perceptualuniform'},
'bluered': {'left': Color('HSL',[0.65,0.53,0.49]),
'right': Color('HSL',[0.97,0.96,0.36]),
'interpolate': 'perceptualuniform'},
'blueredrainbow':{'left': Color('HSL',[2.0/3.0,1,0.5]),
'right': Color('HSL',[0,1,0.5]),
'interpolate': 'linear' },
'orientation': {'left': Color('RGB',[0.933334,0.878432,0.878431]),
'right': Color('RGB',[0.250980,0.007843,0.000000]),
'interpolate': 'perceptualuniform'},
'strain': {'left': Color('RGB',[0.941177,0.941177,0.870588]),
'right': Color('RGB',[0.266667,0.266667,0.000000]),
'interpolate': 'perceptualuniform'},
'stress': {'left': Color('RGB',[0.878432,0.874511,0.949019]),
'right': Color('RGB',[0.000002,0.000000,0.286275]),
'interpolate': 'perceptualuniform'},
}
def __init__(self,
left = Color('RGB',[1,1,1]),
right = Color('RGB',[0,0,0]),
interpolate = 'perceptualuniform',
predefined = None
):
"""
Create a Colormap object.
Parameters
----------
left : Color
left color (minimum value)
right : Color
right color (maximum value)
interpolate : str
interpolation scheme (either 'perceptualuniform' or 'linear')
predefined : bool
ignore other arguments and use predefined definition
"""
if predefined is not None:
left = self.__predefined__[predefined.lower()]['left']
right= self.__predefined__[predefined.lower()]['right']
interpolate = self.__predefined__[predefined.lower()]['interpolate']
if left.__class__.__name__ != 'Color':
left = Color()
if right.__class__.__name__ != 'Color':
right = Color()
self.left = left
self.right = right
self.interpolate = interpolate
def __repr__(self):
"""Left and right value of colormap."""
return 'Left: %s Right: %s'%(self.left,self.right)
def invert(self):
"""Switch left/minimum with right/maximum."""
(self.left, self.right) = (self.right, self.left)
return self
def show_predefined(self):
"""Show the labels of the predefined colormaps."""
print('\n'.join(self.__predefined__.keys()))
def color(self,fraction = 0.5):
def interpolate_Msh(lo, hi, frac):
def rad_diff(a,b):
return abs(a[2]-b[2])
def adjust_hue(Msh_sat, Msh_unsat):
"""If saturation of one of the two colors is too less than the other, hue of the less."""
if Msh_sat[0] >= Msh_unsat[0]:
return Msh_sat[2]
else:
hSpin = Msh_sat[1]/np.sin(Msh_sat[1])*np.sqrt(Msh_unsat[0]**2.0-Msh_sat[0]**2)/Msh_sat[0]
if Msh_sat[2] < - np.pi/3.0: hSpin *= -1.0
return Msh_sat[2] + hSpin
Msh1 = np.array(lo[:])
Msh2 = np.array(hi[:])
if (Msh1[1] > 0.05 and Msh2[1] > 0.05 and rad_diff(Msh1,Msh2) > np.pi/3.0):
M_mid = max(Msh1[0],Msh2[0],88.0)
if frac < 0.5:
Msh2 = np.array([M_mid,0.0,0.0])
frac *= 2.0
else:
Msh1 = np.array([M_mid,0.0,0.0])
frac = 2.0*frac - 1.0
if Msh1[1] < 0.05 and Msh2[1] > 0.05: Msh1[2] = adjust_hue(Msh2,Msh1)
elif Msh1[1] > 0.05 and Msh2[1] < 0.05: Msh2[2] = adjust_hue(Msh1,Msh2)
Msh = (1.0 - frac) * Msh1 + frac * Msh2
return Color('MSH',Msh)
def interpolate_linear(lo, hi, frac):
"""Linear interpolation between lo and hi color at given fraction; output in model of lo color."""
interpolation = (1.0 - frac) * np.array(lo.color[:]) \
+ frac * np.array(hi.express_as(lo.model).color[:])
return Color(lo.model,interpolation)
if self.interpolate == 'perceptualuniform':
return interpolate_Msh(self.left.express_as('MSH').color,
self.right.express_as('MSH').color,fraction)
elif self.interpolate == 'linear':
return interpolate_linear(self.left,self.right,fraction)
else:
raise NameError('unknown color interpolation method')
def export(self,name = 'uniformPerceptualColorMap',\
format = 'paraview',\
steps = 2,\
crop = [-1.0,1.0],
model = 'RGB'):
"""
[RGB] colormap for use in paraview or gmsh, or as raw string, or array.
Arguments: name, format, steps, crop.
Format is one of (paraview, gmsh, raw, list).
Crop selects a (sub)range in [-1.0,1.0].
Generates sequential map if one limiting color is either white or black,
diverging map otherwise.
"""
format = format.lower() # consistent comparison basis
frac = 0.5*(np.array(crop) + 1.0) # rescale crop range to fractions
colors = [self.color(float(i)/(steps-1)*(frac[1]-frac[0])+frac[0]).express_as(model).color for i in range(steps)]
if format == 'paraview':
colormap = ['[\n {{\n "ColorSpace": "RGB", "Name": "{}", "DefaultMap": true,\n "RGBPoints" : ['.format(name)] \
+ [' {:4d},{:8.6f},{:8.6f},{:8.6f},'.format(i,color[0],color[1],color[2],) \
for i,color in enumerate(colors[:-1])] \
+ [' {:4d},{:8.6f},{:8.6f},{:8.6f} '.format(len(colors),colors[-1][0],colors[-1][1],colors[-1][2],)] \
+ [' ]\n }\n]']
elif format == 'gmsh':
colormap = ['View.ColorTable = {'] \
+ [',\n'.join(['{%s}'%(','.join([str(x*255.0) for x in color])) for color in colors])] \
+ ['}']
elif format == 'gom':
colormap = ['1 1 ' + str(name)
+ ' 9 ' + str(name)
+ ' 0 1 0 3 0 0 -1 9 \\ 0 0 0 255 255 255 0 0 255 '
+ '30 NO_UNIT 1 1 64 64 64 255 1 0 0 0 0 0 0 3 0 ' + str(len(colors))
+ ' '.join([' 0 %s 255 1'%(' '.join([str(int(x*255.0)) for x in color])) for color in reversed(colors)])]
elif format == 'raw':
colormap = ['\t'.join(map(str,color)) for color in colors]
elif format == 'list':
colormap = colors
else:
raise NameError('unknown color export format')
return '\n'.join(colormap) + '\n' if type(colormap[0]) is str else colormap

View File

@ -1,16 +1,17 @@
import os import os
import tkinter
class Environment(): class Environment:
def __init__(self): def __init__(self):
"""Read and provide values of DAMASK configuration.""" """Read and provide values of DAMASK configuration."""
self.options = self._get_options() self.options = self._get_options()
try: try:
import tkinter
tk = tkinter.Tk() tk = tkinter.Tk()
self.screen_width = tk.winfo_screenwidth() self.screen_width = tk.winfo_screenwidth()
self.screen_height = tk.winfo_screenheight() self.screen_height = tk.winfo_screenheight()
except Exception: tk.destroy()
except tkinter.TclError:
self.screen_width = 1024 self.screen_width = 1024
self.screen_height = 768 self.screen_height = 768

View File

@ -8,7 +8,7 @@ from . import VTK
from . import util from . import util
class Geom(): class Geom:
"""Geometry definition for grid solvers.""" """Geometry definition for grid solvers."""
def __init__(self,microstructure,size,origin=[0.0,0.0,0.0],homogenization=1,comments=[]): def __init__(self,microstructure,size,origin=[0.0,0.0,0.0],homogenization=1,comments=[]):
@ -47,6 +47,7 @@ class Geom():
'max microstructure: {}'.format(np.nanmax(self.microstructure)), 'max microstructure: {}'.format(np.nanmax(self.microstructure)),
]) ])
def update(self,microstructure=None,size=None,origin=None,rescale=False): def update(self,microstructure=None,size=None,origin=None,rescale=False):
""" """
Updates microstructure and size. Updates microstructure and size.
@ -109,6 +110,7 @@ class Geom():
return util.return_message(message) return util.return_message(message)
def set_comments(self,comments): def set_comments(self,comments):
""" """
Replaces all existing comments. Replaces all existing comments.
@ -122,6 +124,7 @@ class Geom():
self.comments = [] self.comments = []
self.add_comments(comments) self.add_comments(comments)
def add_comments(self,comments): def add_comments(self,comments):
""" """
Appends comments to existing comments. Appends comments to existing comments.
@ -134,6 +137,7 @@ class Geom():
""" """
self.comments += [str(c) for c in comments] if isinstance(comments,list) else [str(comments)] self.comments += [str(c) for c in comments] if isinstance(comments,list) else [str(comments)]
def set_microstructure(self,microstructure): def set_microstructure(self,microstructure):
""" """
Replaces the existing microstructure representation. Replaces the existing microstructure representation.
@ -152,6 +156,7 @@ class Geom():
else: else:
self.microstructure = np.copy(microstructure) self.microstructure = np.copy(microstructure)
def set_size(self,size): def set_size(self,size):
""" """
Replaces the existing size information. Replaces the existing size information.
@ -171,6 +176,7 @@ class Geom():
else: else:
self.size = np.array(size) self.size = np.array(size)
def set_origin(self,origin): def set_origin(self,origin):
""" """
Replaces the existing origin information. Replaces the existing origin information.
@ -187,6 +193,7 @@ class Geom():
else: else:
self.origin = np.array(origin) self.origin = np.array(origin)
def set_homogenization(self,homogenization): def set_homogenization(self,homogenization):
""" """
Replaces the existing homogenization index. Replaces the existing homogenization index.
@ -203,34 +210,47 @@ class Geom():
else: else:
self.homogenization = homogenization self.homogenization = homogenization
@property @property
def grid(self): def grid(self):
return self.get_grid() return self.get_grid()
@property
def N_microstructure(self):
return len(np.unique(self.microstructure))
def get_microstructure(self): def get_microstructure(self):
"""Return the microstructure representation.""" """Return the microstructure representation."""
return np.copy(self.microstructure) return np.copy(self.microstructure)
def get_size(self): def get_size(self):
"""Return the physical size in meter.""" """Return the physical size in meter."""
return np.copy(self.size) return np.copy(self.size)
def get_origin(self): def get_origin(self):
"""Return the origin in meter.""" """Return the origin in meter."""
return np.copy(self.origin) return np.copy(self.origin)
def get_grid(self): def get_grid(self):
"""Return the grid discretization.""" """Return the grid discretization."""
return np.array(self.microstructure.shape) return np.array(self.microstructure.shape)
def get_homogenization(self): def get_homogenization(self):
"""Return the homogenization index.""" """Return the homogenization index."""
return self.homogenization return self.homogenization
def get_comments(self): def get_comments(self):
"""Return the comments.""" """Return the comments."""
return self.comments[:] return self.comments[:]
def get_header(self): def get_header(self):
"""Return the full header (grid, size, origin, homogenization, comments).""" """Return the full header (grid, size, origin, homogenization, comments)."""
header = ['{} header'.format(len(self.comments)+4)] + self.comments header = ['{} header'.format(len(self.comments)+4)] + self.comments
@ -240,6 +260,7 @@ class Geom():
header.append('homogenization {}'.format(self.get_homogenization())) header.append('homogenization {}'.format(self.get_homogenization()))
return header return header
@staticmethod @staticmethod
def from_file(fname): def from_file(fname):
""" """
@ -425,8 +446,8 @@ class Geom():
if 'x' in directions: if 'x' in directions:
ms = np.concatenate([ms,ms[limits[0]:limits[1]:-1,:,:]],0) ms = np.concatenate([ms,ms[limits[0]:limits[1]:-1,:,:]],0)
#self.add_comments('geom.py:mirror v{}'.format(version)
return self.update(ms,rescale=True) return self.update(ms,rescale=True)
#self.add_comments('tbd')
def scale(self,grid): def scale(self,grid):
@ -439,6 +460,7 @@ class Geom():
new grid dimension new grid dimension
""" """
#self.add_comments('geom.py:scale v{}'.format(version)
return self.update( return self.update(
ndimage.interpolation.zoom( ndimage.interpolation.zoom(
self.microstructure, self.microstructure,
@ -449,7 +471,6 @@ class Geom():
prefilter=False prefilter=False
) )
) )
#self.add_comments('tbd')
def clean(self,stencil=3): def clean(self,stencil=3):
@ -466,13 +487,13 @@ class Geom():
unique, inverse = np.unique(arr, return_inverse=True) unique, inverse = np.unique(arr, return_inverse=True)
return unique[np.argmax(np.bincount(inverse))] return unique[np.argmax(np.bincount(inverse))]
#self.add_comments('geom.py:clean v{}'.format(version)
return self.update(ndimage.filters.generic_filter( return self.update(ndimage.filters.generic_filter(
self.microstructure, self.microstructure,
mostFrequent, mostFrequent,
size=(stencil,)*3 size=(stencil,)*3
).astype(self.microstructure.dtype) ).astype(self.microstructure.dtype)
) )
#self.add_comments('tbd')
def renumber(self): def renumber(self):
@ -481,5 +502,5 @@ class Geom():
for i, oldID in enumerate(np.unique(self.microstructure)): for i, oldID in enumerate(np.unique(self.microstructure)):
renumbered = np.where(self.microstructure == oldID, i+1, renumbered) renumbered = np.where(self.microstructure == oldID, i+1, renumbered)
#self.add_comments('geom.py:renumber v{}'.format(version)
return self.update(renumbered) return self.update(renumbered)
#self.add_comments('tbd')

View File

@ -1,10 +1,8 @@
import numpy as np import numpy as np
from .rotation import Rotation from . import Rotation
P = -1
# ******************************************************************************************
class Symmetry: class Symmetry:
""" """
Symmetry operations for lattice systems. Symmetry operations for lattice systems.

View File

@ -1,7 +1,7 @@
import numpy as np import numpy as np
from .lattice import Lattice from . import Lattice
from .rotation import Rotation from . import Rotation
class Orientation: class Orientation:
""" """
@ -50,23 +50,23 @@ class Orientation:
Look into A. Heinz and P. Neumann 1991 for cases with differing sym.) Look into A. Heinz and P. Neumann 1991 for cases with differing sym.)
""" """
if self.lattice.symmetry != other.lattice.symmetry: if self.lattice.symmetry != other.lattice.symmetry:
raise NotImplementedError('disorientation between different symmetry classes not supported yet.') raise NotImplementedError('disorientation between different symmetry classes not supported yet.')
mySymEqs = self.equivalentOrientations() if SST else self.equivalentOrientations([0]) # take all or only first sym operation mySymEqs = self.equivalentOrientations() if SST else self.equivalentOrientations([0]) # take all or only first sym operation
otherSymEqs = other.equivalentOrientations() otherSymEqs = other.equivalentOrientations()
for i,sA in enumerate(mySymEqs): for i,sA in enumerate(mySymEqs):
aInv = sA.rotation.inversed() aInv = sA.rotation.inversed()
for j,sB in enumerate(otherSymEqs): for j,sB in enumerate(otherSymEqs):
b = sB.rotation b = sB.rotation
r = b*aInv r = b*aInv
for k in range(2): for k in range(2):
r.inverse() r.inverse()
breaker = self.lattice.symmetry.inFZ(r.asRodrigues(vector=True)) \ breaker = self.lattice.symmetry.inFZ(r.asRodrigues(vector=True)) \
and (not SST or other.lattice.symmetry.inDisorientationSST(r.asRodrigues(vector=True))) and (not SST or other.lattice.symmetry.inDisorientationSST(r.asRodrigues(vector=True)))
if breaker: break if breaker: break
if breaker: break
if breaker: break if breaker: break
if breaker: break
return (Orientation(r,self.lattice), i,j, k == 1) if symmetries else r # disorientation ... return (Orientation(r,self.lattice), i,j, k == 1) if symmetries else r # disorientation ...
# ... own sym, other sym, # ... own sym, other sym,
@ -78,11 +78,11 @@ class Orientation:
def equivalentOrientations(self,members=[]): def equivalentOrientations(self,members=[]):
"""List of orientations which are symmetrically equivalent.""" """List of orientations which are symmetrically equivalent."""
try: try:
iter(members) # asking for (even empty) list of members? iter(members) # asking for (even empty) list of members?
except TypeError: except TypeError:
return self.__class__(self.lattice.symmetry.symmetryOperations(members)*self.rotation,self.lattice) # no, return rotation object return self.__class__(self.lattice.symmetry.symmetryOperations(members)*self.rotation,self.lattice) # no, return rotation object
else: else:
return [self.__class__(q*self.rotation,self.lattice) \ return [self.__class__(q*self.rotation,self.lattice) \
for q in self.lattice.symmetry.symmetryOperations(members)] # yes, return list of rotations for q in self.lattice.symmetry.symmetryOperations(members)] # yes, return list of rotations
def relatedOrientations(self,model): def relatedOrientations(self,model):
@ -94,7 +94,7 @@ class Orientation:
def reduced(self): def reduced(self):
"""Transform orientation to fall into fundamental zone according to symmetry.""" """Transform orientation to fall into fundamental zone according to symmetry."""
for me in self.equivalentOrientations(): for me in self.equivalentOrientations():
if self.lattice.symmetry.inFZ(me.rotation.asRodrigues(vector=True)): break if self.lattice.symmetry.inFZ(me.rotation.asRodrigues(vector=True)): break
return self.__class__(me.rotation,self.lattice) return self.__class__(me.rotation,self.lattice)
@ -105,11 +105,11 @@ class Orientation:
SST = True): SST = True):
"""Axis rotated according to orientation (using crystal symmetry to ensure location falls into SST).""" """Axis rotated according to orientation (using crystal symmetry to ensure location falls into SST)."""
if SST: # pole requested to be within SST if SST: # pole requested to be within SST
for i,o in enumerate(self.equivalentOrientations()): # test all symmetric equivalent quaternions for i,o in enumerate(self.equivalentOrientations()): # test all symmetric equivalent quaternions
pole = o.rotation*axis # align crystal direction to axis pole = o.rotation*axis # align crystal direction to axis
if self.lattice.symmetry.inSST(pole,proper): break # found SST version if self.lattice.symmetry.inSST(pole,proper): break # found SST version
else: else:
pole = self.rotation*axis # align crystal direction to axis pole = self.rotation*axis # align crystal direction to axis
return (pole,i if SST else 0) return (pole,i if SST else 0)
@ -119,9 +119,9 @@ class Orientation:
color = np.zeros(3,'d') color = np.zeros(3,'d')
for o in self.equivalentOrientations(): for o in self.equivalentOrientations():
pole = o.rotation*axis # align crystal direction to axis pole = o.rotation*axis # align crystal direction to axis
inSST,color = self.lattice.symmetry.inSST(pole,color=True) inSST,color = self.lattice.symmetry.inSST(pole,color=True)
if inSST: break if inSST: break
return color return color
@ -131,15 +131,15 @@ class Orientation:
weights = []): weights = []):
"""Create orientation from average of list of orientations.""" """Create orientation from average of list of orientations."""
if not all(isinstance(item, Orientation) for item in orientations): if not all(isinstance(item, Orientation) for item in orientations):
raise TypeError("Only instances of Orientation can be averaged.") raise TypeError("Only instances of Orientation can be averaged.")
closest = [] closest = []
ref = orientations[0] ref = orientations[0]
for o in orientations: for o in orientations:
closest.append(o.equivalentOrientations( closest.append(o.equivalentOrientations(
ref.disorientation(o, ref.disorientation(o,
SST = False, # select (o[ther]'s) sym orientation SST = False, # select (o[ther]'s) sym orientation
symmetries = True)[2]).rotation) # with lowest misorientation symmetries = True)[2]).rotation) # with lowest misorientation
return Orientation(Rotation.fromAverage(closest,weights),ref.lattice) return Orientation(Rotation.fromAverage(closest,weights),ref.lattice)

View File

@ -22,7 +22,7 @@ class Result:
""" """
Read and write to DADF5 files. Read and write to DADF5 files.
DADF5 (DAKMASK HDF5) files contain DAMASK results. DADF5 (DAMASK HDF5) files contain DAMASK results.
""" """
def __init__(self,fname): def __init__(self,fname):
@ -32,7 +32,7 @@ class Result:
Parameters Parameters
---------- ----------
fname : str fname : str
name of the DADF5 file to be openend. name of the DADF5 file to be openend.
""" """
with h5py.File(fname,'r') as f: with h5py.File(fname,'r') as f:
@ -85,7 +85,14 @@ class Result:
def __repr__(self): def __repr__(self):
"""Show selected data.""" """Show selected data."""
return util.srepr(self.list_data()) all_selected_increments = self.selection['increments']
self.pick('increments',all_selected_increments[0:1])
first = self.list_data()
self.pick('increments',all_selected_increments[-1:])
last = self.list_data()
self.pick('increments',all_selected_increments)
in_between = ''.join(['\n{}\n ...\n'.format(inc) for inc in all_selected_increments[1:-2]])
return util.srepr(first+ in_between + last)
def _manage_selection(self,action,what,datasets): def _manage_selection(self,action,what,datasets):
@ -95,12 +102,12 @@ class Result:
Parameters Parameters
---------- ----------
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.selection)
datasets : list of str or Boolean datasets : list of str or Boolean
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 []
""" """
# allow True/False and string arguments # allow True/False and string arguments
@ -167,17 +174,17 @@ class Result:
Parameters Parameters
---------- ----------
what : str what : str
attribute to change (must be from self.selection) attribute to change (must be from self.selection)
""" """
datasets = self.selection[what] datasets = self.selection[what]
last_datasets = datasets.copy() last_selection = datasets.copy()
for dataset in datasets: for dataset in datasets:
if last_datasets != self.selection[what]: if last_selection != self.selection[what]:
self._manage_selection('set',what,datasets) self._manage_selection('set',what,datasets)
raise Exception raise Exception
self._manage_selection('set',what,dataset) self._manage_selection('set',what,dataset)
last_datasets = self.selection[what] last_selection = self.selection[what]
yield dataset yield dataset
self._manage_selection('set',what,datasets) self._manage_selection('set',what,datasets)
@ -189,10 +196,10 @@ class Result:
Parameters Parameters
---------- ----------
what : str what : str
attribute to change (must be from self.selection) attribute to change (must be from self.selection)
datasets : list of str or Boolean datasets : list of str or Boolean
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_selection('set',what,datasets)
@ -205,10 +212,10 @@ class Result:
Parameters Parameters
---------- ----------
what : str what : str
attribute to change (must be from self.selection) attribute to change (must be from self.selection)
datasets : list of str or Boolean datasets : list of str or Boolean
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_selection('add',what,datasets)
@ -221,10 +228,10 @@ class Result:
Parameters Parameters
---------- ----------
what : str what : str
attribute to change (must be from self.selection) attribute to change (must be from self.selection)
datasets : list of str or Boolean datasets : list of str or Boolean
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_selection('del',what,datasets)
@ -248,13 +255,13 @@ class Result:
---------- ----------
datasets : iterable or str datasets : iterable or str
component : int component : int
homogenization component to consider for constituent data homogenization component to consider for constituent data
tagged : Boolean tagged : Boolean
tag Table.column name with '#component' tag Table.column name with '#component'
defaults to False defaults to False
split : Boolean split : Boolean
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) \ sets = datasets if hasattr(datasets,'__iter__') and not isinstance(datasets,str) \
@ -313,17 +320,17 @@ class Result:
Parameters Parameters
---------- ----------
datasets : iterable or str or Boolean datasets : iterable or str or Boolean
Examples Examples
-------- --------
datasets = False matches no group datasets = False matches no group
datasets = True matches all groups datasets = True matches all groups
datasets = ['F','P'] matches a group with ['F','P','sigma'] datasets = ['F','P'] matches a group with ['F','P','sigma']
datasets = ['*','P'] matches a group with ['F','P'] datasets = ['*','P'] matches a group with ['F','P']
datasets = ['*'] does not match a group with ['F','P','sigma'] datasets = ['*'] does not match a group with ['F','P','sigma']
datasets = ['*','*'] does not match a group with ['F','P','sigma'] datasets = ['*','*'] does not match a group with ['F','P','sigma']
datasets = ['*','*','*'] matches a group with ['F','P','sigma'] datasets = ['*','*','*'] matches a group with ['F','P','sigma']
""" """
if datasets is False: return [] if datasets is False: return []
@ -471,7 +478,7 @@ class Result:
Parameters Parameters
---------- ----------
x : str x : str
Label of scalar, vector, or tensor dataset to take absolute value of. Label of scalar, vector, or tensor dataset to take absolute value of.
""" """
self._add_generic_pointwise(self._add_absolute,{'x':x}) self._add_generic_pointwise(self._add_absolute,{'x':x})
@ -501,13 +508,13 @@ class Result:
label : str label : str
Label of resulting dataset. Label of resulting dataset.
formula : str formula : str
Formula to calculate resulting dataset. Existing datasets are referenced by #TheirLabel#. Formula to calculate resulting dataset. Existing datasets are referenced by #TheirLabel#.
unit : str, optional unit : str, optional
Physical unit of the result. Physical unit of the result.
description : str, optional description : str, optional
Human-readable description of the result. Human-readable description of the result.
vectorized : bool, optional vectorized : bool, optional
Indicate whether the formula can be used in vectorized form. Defaults to True. Indicate whether the formula can be used in vectorized form. Defaults to True.
""" """
if not vectorized: if not vectorized:
@ -538,9 +545,9 @@ class Result:
Parameters Parameters
---------- ----------
P : str, optional P : str, optional
Label of the dataset containing the first Piola-Kirchhoff stress. Defaults to P. Label of the dataset containing the first Piola-Kirchhoff stress. Defaults to P.
F : str, optional F : str, optional
Label of the dataset containing the deformation gradient. Defaults to F. Label of the dataset containing the deformation gradient. Defaults to F.
""" """
self._add_generic_pointwise(self._add_Cauchy,{'P':P,'F':F}) self._add_generic_pointwise(self._add_Cauchy,{'P':P,'F':F})
@ -564,7 +571,7 @@ class Result:
Parameters Parameters
---------- ----------
T : str T : str
Label of tensor dataset. Label of tensor dataset.
""" """
self._add_generic_pointwise(self._add_determinant,{'T':T}) self._add_generic_pointwise(self._add_determinant,{'T':T})
@ -591,7 +598,7 @@ class Result:
Parameters Parameters
---------- ----------
T : str T : str
Label of tensor dataset. Label of tensor dataset.
""" """
self._add_generic_pointwise(self._add_deviator,{'T':T}) self._add_generic_pointwise(self._add_deviator,{'T':T})
@ -615,7 +622,7 @@ class Result:
Parameters Parameters
---------- ----------
T_sym : str T_sym : str
Label of symmetric tensor dataset. Label of symmetric tensor dataset.
""" """
self._add_generic_pointwise(self._add_eigenvalue,{'T_sym':T_sym}) self._add_generic_pointwise(self._add_eigenvalue,{'T_sym':T_sym})
@ -639,7 +646,7 @@ class Result:
Parameters Parameters
---------- ----------
T_sym : str T_sym : str
Label of symmetric tensor dataset. Label of symmetric tensor dataset.
""" """
self._add_generic_pointwise(self._add_eigenvector,{'T_sym':T_sym}) self._add_generic_pointwise(self._add_eigenvector,{'T_sym':T_sym})
@ -664,7 +671,7 @@ class Result:
'meta' : { 'meta' : {
'Unit': 'RGB (8bit)', 'Unit': 'RGB (8bit)',
'Lattice': lattice, 'Lattice': lattice,
'Description': 'Inverse Pole Figure (IPF) colors for direction/plane [{} {} {})'.format(*m), 'Description': 'Inverse Pole Figure (IPF) colors along sample direction [{} {} {}]'.format(*m),
'Creator': 'result.py:add_IPFcolor v{}'.format(version) 'Creator': 'result.py:add_IPFcolor v{}'.format(version)
} }
} }
@ -675,9 +682,9 @@ class Result:
Parameters Parameters
---------- ----------
q : str q : str
Label of the dataset containing the crystallographic orientation as quaternions. Label of the dataset containing the crystallographic orientation as quaternions.
l : numpy.array of shape (3) l : numpy.array of shape (3)
Lab frame direction for inverse pole figure. Lab frame direction for inverse pole figure.
""" """
self._add_generic_pointwise(self._add_IPFcolor,{'q':q},{'l':l}) self._add_generic_pointwise(self._add_IPFcolor,{'q':q},{'l':l})
@ -701,7 +708,7 @@ class Result:
Parameters Parameters
---------- ----------
T_sym : str T_sym : str
Label of symmetric tensor dataset. Label of symmetric tensor dataset.
""" """
self._add_generic_pointwise(self._add_maximum_shear,{'T_sym':T_sym}) self._add_generic_pointwise(self._add_maximum_shear,{'T_sym':T_sym})
@ -728,7 +735,7 @@ class Result:
Parameters Parameters
---------- ----------
T_sym : str T_sym : str
Label of symmetric tensorial stress or strain dataset. Label of symmetric tensorial stress or strain dataset.
""" """
self._add_generic_pointwise(self._add_Mises,{'T_sym':T_sym}) self._add_generic_pointwise(self._add_Mises,{'T_sym':T_sym})
@ -764,9 +771,9 @@ class Result:
Parameters Parameters
---------- ----------
x : str x : str
Label of vector or tensor dataset. Label of vector or tensor dataset.
ord : {non-zero int, inf, -inf, fro, nuc}, optional ord : {non-zero int, inf, -inf, fro, nuc}, optional
Order of the norm. inf means NumPys inf object. For details refer to numpy.linalg.norm. Order of the norm. inf means NumPys inf object. For details refer to numpy.linalg.norm.
""" """
self._add_generic_pointwise(self._add_norm,{'x':x},{'ord':ord}) self._add_generic_pointwise(self._add_norm,{'x':x},{'ord':ord})
@ -792,9 +799,9 @@ class Result:
Parameters Parameters
---------- ----------
P : str, optional P : str, optional
Label first Piola-Kirchhoff stress dataset. Defaults to P. Label first Piola-Kirchhoff stress dataset. Defaults to P.
F : str, optional F : str, optional
Label of deformation gradient dataset. Defaults to F. Label of deformation gradient dataset. Defaults to F.
""" """
self._add_generic_pointwise(self._add_PK2,{'P':P,'F':F}) self._add_generic_pointwise(self._add_PK2,{'P':P,'F':F})
@ -830,11 +837,11 @@ class Result:
Parameters Parameters
---------- ----------
q : str q : str
Label of the dataset containing the crystallographic orientation as quaternions. Label of the dataset containing the crystallographic orientation as quaternions.
p : numpy.array of shape (3) p : numpy.array of shape (3)
Crystallographic direction or plane. Crystallographic direction or plane.
polar : bool, optional polar : bool, optional
Give pole in polar coordinates. Defaults to False. Give pole in polar coordinates. Defaults to False.
""" """
self._add_generic_pointwise(self._add_pole,{'q':q},{'p':p,'polar':polar}) self._add_generic_pointwise(self._add_pole,{'q':q},{'p':p,'polar':polar})
@ -860,7 +867,7 @@ class Result:
Parameters Parameters
---------- ----------
F : str, optional F : str, optional
Label of deformation gradient dataset. Label of deformation gradient dataset.
""" """
self._add_generic_pointwise(self._add_rotational_part,{'F':F}) self._add_generic_pointwise(self._add_rotational_part,{'F':F})
@ -887,7 +894,7 @@ class Result:
Parameters Parameters
---------- ----------
T : str T : str
Label of tensor dataset. Label of tensor dataset.
""" """
self._add_generic_pointwise(self._add_spherical,{'T':T}) self._add_generic_pointwise(self._add_spherical,{'T':T})
@ -916,12 +923,12 @@ class Result:
Parameters Parameters
---------- ----------
F : str, optional F : str, optional
Label of deformation gradient dataset. Defaults to F. Label of deformation gradient dataset. Defaults to F.
t : {V, U}, optional t : {V, U}, optional
Type of the polar decomposition, V for left stretch tensor and U for right stretch tensor. Type of the polar decomposition, V for left stretch tensor and U for right stretch tensor.
Defaults to V. Defaults to V.
m : float, optional m : float, optional
Order of the strain calculation. Defaults to 0.0. Order of the strain calculation. Defaults to 0.0.
""" """
self._add_generic_pointwise(self._add_strain_tensor,{'F':F},{'t':t,'m':m}) self._add_generic_pointwise(self._add_strain_tensor,{'F':F},{'t':t,'m':m})
@ -949,10 +956,10 @@ class Result:
Parameters Parameters
---------- ----------
F : str, optional F : str, optional
Label of deformation gradient dataset. Defaults to F. Label of deformation gradient dataset. Defaults to F.
t : {V, U}, optional t : {V, U}, optional
Type of the polar decomposition, V for left stretch tensor and U for right stretch tensor. Type of the polar decomposition, V for left stretch tensor and U for right stretch tensor.
Defaults to V. Defaults to V.
""" """
self._add_generic_pointwise(self._add_stretch_tensor,{'F':F},{'t':t}) self._add_generic_pointwise(self._add_stretch_tensor,{'F':F},{'t':t})
@ -984,11 +991,11 @@ class Result:
Parameters Parameters
---------- ----------
func : function func : function
Callback function that calculates a new dataset from one or more datasets per HDF5 group. Callback function that calculates a new dataset from one or more datasets per HDF5 group.
datasets : dictionary datasets : dictionary
Details of the datasets to be used: label (in HDF5 file) and arg (argument to which the data is parsed in func). Details of the datasets to be used: label (in HDF5 file) and arg (argument to which the data is parsed in func).
args : dictionary, optional args : dictionary, optional
Arguments parsed to func. Arguments parsed to func.
""" """
pool = multiprocessing.Pool(int(Environment().options['DAMASK_NUM_THREADS'])) pool = multiprocessing.Pool(int(Environment().options['DAMASK_NUM_THREADS']))
@ -1014,17 +1021,17 @@ class Result:
pool.join() pool.join()
def to_vtk(self,labels,mode='cell'): def to_vtk(self,labels=[],mode='cell'):
""" """
Export to vtk cell/point data. Export to vtk cell/point data.
Parameters Parameters
---------- ----------
labels : str or list of labels : str or list of, optional
Labels of the datasets to be exported. Labels of the datasets to be exported.
mode : str, either 'cell' or 'point' mode : str, either 'cell' or 'point'
Export in cell format or point format. Export in cell format or point format.
Defaults to 'cell'. Defaults to 'cell'.
""" """
if mode.lower()=='cell': if mode.lower()=='cell':
@ -1039,7 +1046,7 @@ class Result:
elif mode.lower()=='point': elif mode.lower()=='point':
v = VTK.from_polyData(self.cell_coordinates()) v = VTK.from_polyData(self.cell_coordinates())
N_digits = int(np.floor(np.log10(min(int(self.increments[-1][3:]),1))))+1 N_digits = int(np.floor(np.log10(int(self.increments[-1][3:]))))+1
for i,inc in enumerate(util.show_progress(self.iterate('increments'),len(self.selection['increments']))): for i,inc in enumerate(util.show_progress(self.iterate('increments'),len(self.selection['increments']))):
@ -1093,9 +1100,6 @@ class Result:
################################################################################################### ###################################################################################################
# BEGIN DEPRECATED # BEGIN DEPRECATED
iter_visible = iterate
iter_selection = iterate
def _time_to_inc(self,start,end): def _time_to_inc(self,start,end):
selected = [] selected = []
@ -1118,21 +1122,3 @@ class Result:
""" """
self._manage_selection('set','increments',self._time_to_inc(start,end)) self._manage_selection('set','increments',self._time_to_inc(start,end))
def set_by_increment(self,start,end):
"""
Set active time increments based on start and end increment.
Parameters
----------
start : int
start increment (included)
end : int
end increment (included)
"""
if self.version_minor >= 4:
self._manage_selection('set','increments',[ 'inc{}'.format(i) for i in range(start,end+1)])
else:
self._manage_selection('set','increments',['inc{:05d}'.format(i) for i in range(start,end+1)])

View File

@ -1,6 +1,6 @@
import numpy as np import numpy as np
from . import Lambert from ._Lambert import ball_to_cube, cube_to_ball
P = -1 P = -1
@ -304,7 +304,7 @@ class Rotation:
reciprocal = False, reciprocal = False,
): ):
om = basis if isinstance(basis, np.ndarray) else np.array(basis).reshape((3,3)) om = basis if isinstance(basis, np.ndarray) else np.array(basis).reshape(3,3)
if reciprocal: if reciprocal:
om = np.linalg.inv(om.T/np.pi) # transform reciprocal basis set om = np.linalg.inv(om.T/np.pi) # transform reciprocal basis set
orthonormal = False # contains stretch orthonormal = False # contains stretch
@ -338,7 +338,7 @@ class Rotation:
if not np.isclose(np.linalg.norm(ro[0:3]), 1.0): if not np.isclose(np.linalg.norm(ro[0:3]), 1.0):
raise ValueError('Rodrigues rotation axis is not of unit length.\n{} {} {}'.format(*ro[0:3])) raise ValueError('Rodrigues rotation axis is not of unit length.\n{} {} {}'.format(*ro[0:3]))
if ro[3] < 0.0: if ro[3] < 0.0:
raise ValueError('Rodriques rotation angle not positive.\n'.format(ro[3])) raise ValueError('Rodrigues rotation angle not positive.\n'.format(ro[3]))
return Rotation(Rotation.ro2qu(ro)) return Rotation(Rotation.ro2qu(ro))
@ -492,7 +492,7 @@ class Rotation:
@staticmethod @staticmethod
def qu2ro(qu): def qu2ro(qu):
"""Quaternion to Rodriques-Frank vector.""" """Quaternion to Rodrigues-Frank vector."""
if iszero(qu[0]): if iszero(qu[0]):
ro = [qu[1], qu[2], qu[3], np.inf] ro = [qu[1], qu[2], qu[3], np.inf]
else: else:
@ -567,7 +567,7 @@ class Rotation:
@staticmethod @staticmethod
def om2ro(om): def om2ro(om):
"""Rotation matrix to Rodriques-Frank vector.""" """Rotation matrix to Rodrigues-Frank vector."""
return Rotation.eu2ro(Rotation.om2eu(om)) return Rotation.eu2ro(Rotation.om2eu(om))
@staticmethod @staticmethod
@ -628,7 +628,7 @@ class Rotation:
@staticmethod @staticmethod
def eu2ro(eu): def eu2ro(eu):
"""Bunge-Euler angles to Rodriques-Frank vector.""" """Bunge-Euler angles to Rodrigues-Frank vector."""
ro = Rotation.eu2ax(eu) # convert to axis angle pair representation ro = Rotation.eu2ax(eu) # convert to axis angle pair representation
if ro[3] >= np.pi: # Differs from original implementation. check convention 5 if ro[3] >= np.pi: # Differs from original implementation. check convention 5
ro[3] = np.inf ro[3] = np.inf
@ -682,7 +682,7 @@ class Rotation:
@staticmethod @staticmethod
def ax2ro(ax): def ax2ro(ax):
"""Axis angle pair to Rodriques-Frank vector.""" """Axis angle pair to Rodrigues-Frank vector."""
if iszero(ax[3]): if iszero(ax[3]):
ro = [ 0.0, 0.0, P, 0.0 ] ro = [ 0.0, 0.0, P, 0.0 ]
else: else:
@ -708,7 +708,7 @@ class Rotation:
#---------- Rodrigues-Frank vector ---------- #---------- Rodrigues-Frank vector ----------
@staticmethod @staticmethod
def ro2qu(ro): def ro2qu(ro):
"""Rodriques-Frank vector to quaternion.""" """Rodrigues-Frank vector to quaternion."""
return Rotation.ax2qu(Rotation.ro2ax(ro)) return Rotation.ax2qu(Rotation.ro2ax(ro))
@staticmethod @staticmethod
@ -718,12 +718,12 @@ class Rotation:
@staticmethod @staticmethod
def ro2eu(ro): def ro2eu(ro):
"""Rodriques-Frank vector to Bunge-Euler angles.""" """Rodrigues-Frank vector to Bunge-Euler angles."""
return Rotation.om2eu(Rotation.ro2om(ro)) return Rotation.om2eu(Rotation.ro2om(ro))
@staticmethod @staticmethod
def ro2ax(ro): def ro2ax(ro):
"""Rodriques-Frank vector to axis angle pair.""" """Rodrigues-Frank vector to axis angle pair."""
ta = ro[3] ta = ro[3]
if iszero(ta): if iszero(ta):
@ -738,7 +738,7 @@ class Rotation:
@staticmethod @staticmethod
def ro2ho(ro): def ro2ho(ro):
"""Rodriques-Frank vector to homochoric vector.""" """Rodrigues-Frank vector to homochoric vector."""
if iszero(np.sum(ro[0:3]**2.0)): if iszero(np.sum(ro[0:3]**2.0)):
ho = [ 0.0, 0.0, 0.0 ] ho = [ 0.0, 0.0, 0.0 ]
else: else:
@ -748,7 +748,7 @@ class Rotation:
@staticmethod @staticmethod
def ro2cu(ro): def ro2cu(ro):
"""Rodriques-Frank vector to cubochoric vector.""" """Rodrigues-Frank vector to cubochoric vector."""
return Rotation.ho2cu(Rotation.ro2ho(ro)) return Rotation.ho2cu(Rotation.ro2ho(ro))
@ -796,13 +796,13 @@ class Rotation:
@staticmethod @staticmethod
def ho2ro(ho): def ho2ro(ho):
"""Axis angle pair to Rodriques-Frank vector.""" """Axis angle pair to Rodrigues-Frank vector."""
return Rotation.ax2ro(Rotation.ho2ax(ho)) return Rotation.ax2ro(Rotation.ho2ax(ho))
@staticmethod @staticmethod
def ho2cu(ho): def ho2cu(ho):
"""Homochoric vector to cubochoric vector.""" """Homochoric vector to cubochoric vector."""
return Lambert.BallToCube(ho) return ball_to_cube(ho)
#---------- Cubochoric ---------- #---------- Cubochoric ----------
@ -828,10 +828,10 @@ class Rotation:
@staticmethod @staticmethod
def cu2ro(cu): def cu2ro(cu):
"""Cubochoric vector to Rodriques-Frank vector.""" """Cubochoric vector to Rodrigues-Frank vector."""
return Rotation.ho2ro(Rotation.cu2ho(cu)) return Rotation.ho2ro(Rotation.cu2ho(cu))
@staticmethod @staticmethod
def cu2ho(cu): def cu2ho(cu):
"""Cubochoric vector to homochoric vector.""" """Cubochoric vector to homochoric vector."""
return Lambert.CubeToBall(cu) return cube_to_ball(cu)

View File

@ -5,7 +5,7 @@ import numpy as np
from . import version from . import version
class Table(): class Table:
"""Store spreadsheet-like data.""" """Store spreadsheet-like data."""
def __init__(self,data,shapes,comments=None): def __init__(self,data,shapes,comments=None):
@ -25,10 +25,10 @@ class Table():
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 = shapes self.shapes = shapes
self.__label_condensed() self._label_condensed()
def __label_flat(self): def _label_flat(self):
"""Label data individually, e.g. v v v ==> 1_v 2_v 3_v.""" """Label data individually, e.g. v v v ==> 1_v 2_v 3_v."""
labels = [] labels = []
for label,shape in self.shapes.items(): for label,shape in self.shapes.items():
@ -37,7 +37,7 @@ class Table():
self.data.columns = labels self.data.columns = labels
def __label_condensed(self): def _label_condensed(self):
"""Label data condensed, e.g. 1_v 2_v 3_v ==> v v v.""" """Label data condensed, e.g. 1_v 2_v 3_v ==> v v v."""
labels = [] labels = []
for label,shape in self.shapes.items(): for label,shape in self.shapes.items():
@ -45,11 +45,10 @@ class Table():
self.data.columns = labels self.data.columns = labels
def __add_comment(self,label,shape,info): def _add_comment(self,label,shape,info):
if info is not None: if info is not None:
self.comments.append('{}{}: {}'.format(label, c = '{}{}: {}'.format(label,' '+str(shape) if np.prod(shape,dtype=int) > 1 else '',info)
' '+str(shape) if np.prod(shape,dtype=int) > 1 else '', self.comments.append(c)
info))
@staticmethod @staticmethod
@ -57,7 +56,8 @@ class Table():
""" """
Create table from ASCII file. Create table from ASCII file.
The first line needs to indicate the number of subsequent header lines as 'n header'. The first line can indicate the number of subsequent header lines as 'n header',
alternatively first line is the header and comments are marked by '#' ('new style').
Vector data column labels are indicated by '1_v, 2_v, ..., n_v'. Vector data column labels are indicated by '1_v, 2_v, ..., n_v'.
Tensor data column labels are indicated by '3x3:1_T, 3x3:2_T, ..., 3x3:9_T'. Tensor data column labels are indicated by '3x3:1_T, 3x3:2_T, ..., 3x3:9_T'.
@ -167,7 +167,7 @@ class Table():
""" """
if re.match(r'[0-9]*?_',label): if re.match(r'[0-9]*?_',label):
idx,key = label.split('_',1) idx,key = label.split('_',1)
data = self.data[key].to_numpy()[:,int(idx)-1].reshape((-1,1)) data = self.data[key].to_numpy()[:,int(idx)-1].reshape(-1,1)
else: else:
data = self.data[label].to_numpy().reshape((-1,)+self.shapes[label]) data = self.data[label].to_numpy().reshape((-1,)+self.shapes[label])
@ -188,7 +188,7 @@ class Table():
Human-readable information about the new data. Human-readable information about the new data.
""" """
self.__add_comment(label,data.shape[1:],info) self._add_comment(label,data.shape[1:],info)
if re.match(r'[0-9]*?_',label): if re.match(r'[0-9]*?_',label):
idx,key = label.split('_',1) idx,key = label.split('_',1)
@ -212,7 +212,7 @@ class Table():
Human-readable information about the modified data. Human-readable information about the modified data.
""" """
self.__add_comment(label,data.shape[1:],info) self._add_comment(label,data.shape[1:],info)
self.shapes[label] = data.shape[1:] if len(data.shape) > 1 else (1,) self.shapes[label] = data.shape[1:] if len(data.shape) > 1 else (1,)
size = np.prod(data.shape[1:],dtype=int) size = np.prod(data.shape[1:],dtype=int)
@ -251,12 +251,8 @@ class Table():
""" """
self.data.rename(columns={label_old:label_new},inplace=True) self.data.rename(columns={label_old:label_new},inplace=True)
c = '{} => {}{}'.format(label_old,label_new,'' if info is None else ': {}'.format(info))
self.comments.append('{} => {}{}'.format(label_old, self.comments.append(c)
label_new,
'' if info is None else ': {}'.format(info),
))
self.shapes = {(label if label != label_old else label_new):self.shapes[label] for label in self.shapes} self.shapes = {(label if label != label_old else label_new):self.shapes[label] for label in self.shapes}
@ -272,9 +268,9 @@ class Table():
Set sort order. Set sort order.
""" """
self.__label_flat() self._label_flat()
self.data.sort_values(labels,axis=0,inplace=True,ascending=ascending) self.data.sort_values(labels,axis=0,inplace=True,ascending=ascending)
self.__label_condensed() self._label_condensed()
self.comments.append('sorted by [{}]'.format(', '.join(labels))) self.comments.append('sorted by [{}]'.format(', '.join(labels)))
@ -287,7 +283,7 @@ class Table():
Parameters Parameters
---------- ----------
other : Table other : Table
Table to append Table to append.
""" """
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):
@ -305,7 +301,7 @@ class Table():
Parameters Parameters
---------- ----------
other : Table other : Table
Table to join Table to join.
""" """
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]:
@ -316,14 +312,16 @@ class Table():
self.shapes[key] = other.shapes[key] self.shapes[key] = other.shapes[key]
def to_ASCII(self,fname,new=False): def to_ASCII(self,fname,new_style=False):
""" """
Store as plain text file. Store as plain text file.
Parameters Parameters
---------- ----------
fname : file, str, or pathlib.Path fname : file, str, or pathlib.Path
Filename or file for reading. Filename or file for writing.
new_style : Boolean, optional
Write table in new style, indicating header lines by comment sign ('#') only.
""" """
seen = set() seen = set()
@ -338,7 +336,7 @@ class Table():
labels += ['{}:{}_{}'.format('x'.join([str(d) for d in self.shapes[l]]),i+1,l) \ labels += ['{}:{}_{}'.format('x'.join([str(d) for d in self.shapes[l]]),i+1,l) \
for i in range(np.prod(self.shapes[l]))] for i in range(np.prod(self.shapes[l]))]
if new: if new_style:
header = ['# {}'.format(comment) for comment in self.comments] header = ['# {}'.format(comment) for comment in self.comments]
else: else:
header = ['{} header'.format(len(self.comments)+1)] \ header = ['{} header'.format(len(self.comments)+1)] \

View File

@ -1,11 +1,16 @@
import os,sys,shutil import os
import logging,logging.config import sys
import damask import shutil
import numpy as np import logging
import logging.config
from collections.abc import Iterable from collections.abc import Iterable
from optparse import OptionParser from optparse import OptionParser
class Test(): import numpy as np
import damask
class Test:
""" """
General class for testing. General class for testing.
@ -282,12 +287,10 @@ class Test():
import numpy as np import numpy as np
logging.info('\n '.join(['comparing',File1,File2])) logging.info('\n '.join(['comparing',File1,File2]))
table1 = damask.ASCIItable(name=File1,readonly=True) table = damask.Table.from_ASCII(File1)
table1.head_read() len1=len(table.comments)+2
len1=len(table1.info)+2 table = damask.Table.from_ASCII(File2)
table2 = damask.ASCIItable(name=File2,readonly=True) len2=len(table.comments)+2
table2.head_read()
len2=len(table2.info)+2
refArray = np.nan_to_num(np.genfromtxt(File1,missing_values='n/a',skip_header = len1,autostrip=True)) 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)) curArray = np.nan_to_num(np.genfromtxt(File2,missing_values='n/a',skip_header = len2,autostrip=True))
@ -445,15 +448,15 @@ class Test():
if not (isinstance(files, Iterable) and not isinstance(files, str)): # check whether list of files is requested if not (isinstance(files, Iterable) and not isinstance(files, str)): # check whether list of files is requested
files = [str(files)] files = [str(files)]
tables = [damask.ASCIItable(name = filename,readonly = True) for filename in files] tables = [damask.Table.from_ASCII(filename) for filename in files]
for table in tables: for table in tables:
table.head_read() table._label_flat()
columns += [columns[0]]*(len(files)-len(columns)) # extend to same length as files columns += [columns[0]]*(len(files)-len(columns)) # extend to same length as files
columns = columns[:len(files)] # truncate to same length as files columns = columns[:len(files)] # truncate to same length as files
for i,column in enumerate(columns): for i,column in enumerate(columns):
if column is None: columns[i] = tables[i].labels(raw = True) # if no column is given, read all if column is None: columns[i] = list(tables[i].data.columns) # if no column is given, read all
logging.info('comparing ASCIItables statistically') logging.info('comparing ASCIItables statistically')
for i in range(len(columns)): for i in range(len(columns)):
@ -467,9 +470,8 @@ class Test():
data = [] data = []
for table,labels in zip(tables,columns): for table,labels in zip(tables,columns):
table.data_readArray(labels) table._label_condensed()
data.append(table.data) data.append(np.hstack(list(table.get(label) for label in labels)))
table.close()
for i in range(1,len(data)): for i in range(1,len(data)):
@ -497,15 +499,13 @@ class Test():
if len(files) < 2: return True # single table is always close to itself... if len(files) < 2: return True # single table is always close to itself...
tables = [damask.ASCIItable(name = filename,readonly = True) for filename in files] tables = [damask.Table.from_ASCII(filename) for filename in files]
for table in tables:
table.head_read()
columns += [columns[0]]*(len(files)-len(columns)) # extend to same length as files columns += [columns[0]]*(len(files)-len(columns)) # extend to same length as files
columns = columns[:len(files)] # truncate to same length as files columns = columns[:len(files)] # truncate to same length as files
for i,column in enumerate(columns): for i,column in enumerate(columns):
if column is None: columns[i] = tables[i].labels(raw = False) # if no column is given, use all if column is None: columns[i] = list(tables[i].shapes.keys()) # if no column is given, use all
logging.info('comparing ASCIItables') logging.info('comparing ASCIItables')
for i in range(len(columns)): for i in range(len(columns)):
@ -515,22 +515,20 @@ class Test():
) )
logging.info(files[i]+': '+','.join(columns[i])) logging.info(files[i]+': '+','.join(columns[i]))
dimensions = tables[0].label_dimension(columns[0]) # width of each requested column 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 maximum = np.zeros_like(columns[0],dtype=float) # one magnitude per column entry
data = [] # list of feature table extracted from each file (ASCII table) data = [] # list of feature table extracted from each file (ASCII table)
for i,(table,labels) in enumerate(zip(tables,columns)): for i,(table,labels) in enumerate(zip(tables,columns)):
if np.any(dimensions != table.label_dimension(labels)): # check data object consistency if np.any(dimensions != [np.prod(table.shapes[c]) for c in labels]): # check data object consistency
logging.critical('Table {} differs in data layout.'.format(files[i])) logging.critical('Table {} differs in data layout.'.format(files[i]))
return False return False
table.data_readArray(labels) # read data, ... data.append(np.hstack(list(table.get(label) for label in labels)).astype(np.float)) # store
data.append(table.data) # ... store, ...
table.close() # ... close
for j,label in enumerate(labels): # iterate over object labels for j,label in enumerate(labels): # iterate over object labels
maximum[j] = np.maximum( maximum[j] = np.maximum(
maximum[j], maximum[j],
np.amax(np.linalg.norm(table.data[:,table.label_indexrange(label)], np.amax(np.linalg.norm(table.get(label),
axis=1)) axis=1))
) # find maximum Euclidean norm across rows ) # find maximum Euclidean norm across rows
@ -552,8 +550,6 @@ class Test():
logging.info('data : {}'.format(np.absolute(data[1][j])[culprits])) logging.info('data : {}'.format(np.absolute(data[1][j])[culprits]))
logging.info('deviation: {}'.format(np.absolute(data[0][j]-data[1][j])[goodguys])) logging.info('deviation: {}'.format(np.absolute(data[0][j]-data[1][j])[goodguys]))
logging.info('data : {}'.format(np.absolute(data[1][j])[goodguys])) logging.info('data : {}'.format(np.absolute(data[1][j])[goodguys]))
# for ok,valA,valB in zip(allclose,data[0],data[1]):
# logging.debug('{}:\n{}\n{}'.format(ok,valA,valB))
allclose = True # start optimistic allclose = True # start optimistic
for i in range(1,len(data)): for i in range(1,len(data)):

View File

@ -3,7 +3,8 @@ import os
import pandas as pd import pandas as pd
import numpy as np import numpy as np
import vtk import vtk
from vtk.util.numpy_support import numpy_to_vtk as np_to_vtk from vtk.util.numpy_support import numpy_to_vtk as np_to_vtk
from vtk.util.numpy_support import numpy_to_vtkIdTypeArray as np_to_vtkIdTypeArray
from . import Table from . import Table
from . import Environment from . import Environment
@ -24,12 +25,13 @@ class VTK:
Parameters Parameters
---------- ----------
geom : subclass of vtk.vtkDataSet geom : subclass of vtk.vtkDataSet
Description of geometry and topology. Valid types are vtk.vtkRectilinearGrid, Description of geometry and topology. Valid types are vtk.vtkRectilinearGrid,
vtk.vtkUnstructuredGrid, or vtk.vtkPolyData. vtk.vtkUnstructuredGrid, or vtk.vtkPolyData.
""" """
self.geom = geom self.geom = geom
@staticmethod @staticmethod
def from_rectilinearGrid(grid,size,origin=np.zeros(3)): def from_rectilinearGrid(grid,size,origin=np.zeros(3)):
""" """
@ -40,23 +42,18 @@ class VTK:
Parameters Parameters
---------- ----------
grid : numpy.ndarray of shape (3) of np.dtype = int grid : numpy.ndarray of shape (3) of np.dtype = int
Number of cells. Number of cells.
size : numpy.ndarray of shape (3) size : numpy.ndarray of shape (3)
Physical length. Physical length.
origin : numpy.ndarray of shape (3), optional origin : numpy.ndarray of shape (3), optional
Spatial origin. Spatial origin.
""" """
coordArray = [vtk.vtkDoubleArray(),vtk.vtkDoubleArray(),vtk.vtkDoubleArray()]
for dim in [0,1,2]:
coords = np.linspace(origin[dim],origin[dim]+size[dim],grid[dim]+1)
coordArray[dim].SetArray(np_to_vtk(coords),grid[dim]+1,1)
geom = vtk.vtkRectilinearGrid() geom = vtk.vtkRectilinearGrid()
geom.SetDimensions(*(grid+1)) geom.SetDimensions(*(grid+1))
geom.SetXCoordinates(coordArray[0]) geom.SetXCoordinates(np_to_vtk(np.linspace(origin[0],origin[0]+size[0],grid[0]+1),deep=True))
geom.SetYCoordinates(coordArray[1]) geom.SetYCoordinates(np_to_vtk(np.linspace(origin[1],origin[1]+size[1],grid[1]+1),deep=True))
geom.SetZCoordinates(coordArray[2]) geom.SetZCoordinates(np_to_vtk(np.linspace(origin[2],origin[2]+size[2],grid[2]+1),deep=True))
return VTK(geom) return VTK(geom)
@ -71,11 +68,11 @@ class VTK:
Parameters Parameters
---------- ----------
nodes : numpy.ndarray of shape (:,3) nodes : numpy.ndarray of shape (:,3)
Spatial position of the nodes. Spatial position of the nodes.
connectivity : numpy.ndarray of np.dtype = int connectivity : numpy.ndarray of np.dtype = int
Cell connectivity (0-based), first dimension determines #Cells, second dimension determines #Nodes/Cell. Cell connectivity (0-based), first dimension determines #Cells, second dimension determines #Nodes/Cell.
cell_type : str cell_type : str
Name of the vtk.vtkCell subclass. Tested for TRIANGLE, QUAD, and HEXAHEDRON. Name of the vtk.vtkCell subclass. Tested for TRIANGLE, QUAD, and HEXAHEDRON.
""" """
vtk_nodes = vtk.vtkPoints() vtk_nodes = vtk.vtkPoints()
@ -84,7 +81,7 @@ class VTK:
cells.SetNumberOfCells(connectivity.shape[0]) cells.SetNumberOfCells(connectivity.shape[0])
T = np.concatenate((np.ones((connectivity.shape[0],1),dtype=np.int64)*connectivity.shape[1], T = np.concatenate((np.ones((connectivity.shape[0],1),dtype=np.int64)*connectivity.shape[1],
connectivity),axis=1).ravel() connectivity),axis=1).ravel()
cells.SetCells(connectivity.shape[0],np_to_vtk(T, deep=True, array_type=vtk.VTK_ID_TYPE)) cells.SetCells(connectivity.shape[0],np_to_vtkIdTypeArray(T,deep=True))
geom = vtk.vtkUnstructuredGrid() geom = vtk.vtkUnstructuredGrid()
geom.SetPoints(vtk_nodes) geom.SetPoints(vtk_nodes)
@ -103,7 +100,7 @@ class VTK:
Parameters Parameters
---------- ----------
points : numpy.ndarray of shape (:,3) points : numpy.ndarray of shape (:,3)
Spatial position of the points. Spatial position of the points.
""" """
vtk_points= vtk.vtkPoints() vtk_points= vtk.vtkPoints()
@ -123,10 +120,10 @@ class VTK:
Parameters Parameters
---------- ----------
fname : str fname : str
Filename for reading. Valid extensions are .vtk, .vtr, .vtu, and .vtp. Filename for reading. Valid extensions are *.vtr, *.vtu, *.vtp, and *.vtk.
dataset_type : str, optional dataset_type : str, optional
Name of the vtk.vtkDataSet subclass when opening an .vtk file. Valid types are vtkRectilinearGrid, Name of the vtk.vtkDataSet subclass when opening an *.vtk file. Valid types are vtkRectilinearGrid,
vtkUnstructuredGrid, and vtkPolyData. vtkUnstructuredGrid, and vtkPolyData.
""" """
ext = os.path.splitext(fname)[1] ext = os.path.splitext(fname)[1]
@ -134,11 +131,13 @@ class VTK:
reader = vtk.vtkGenericDataObjectReader() reader = vtk.vtkGenericDataObjectReader()
reader.SetFileName(fname) reader.SetFileName(fname)
reader.Update() reader.Update()
if 'rectilineargrid' in dataset_type.lower(): if dataset_type is None:
raise TypeError('Dataset type for *.vtk file not given.')
elif dataset_type.lower().endswith('rectilineargrid'):
geom = reader.GetRectilinearGridOutput() geom = reader.GetRectilinearGridOutput()
elif 'unstructuredgrid' in dataset_type.lower(): elif dataset_type.lower().endswith('unstructuredgrid'):
geom = reader.GetUnstructuredGridOutput() geom = reader.GetUnstructuredGridOutput()
elif 'polydata' in dataset_type.lower(): elif dataset_type.lower().endswith('polydata'):
geom = reader.GetPolyDataOutput() geom = reader.GetPolyDataOutput()
else: else:
raise TypeError('Unknown dataset type for vtk file {}'.format(dataset_type)) raise TypeError('Unknown dataset type for vtk file {}'.format(dataset_type))
@ -159,7 +158,6 @@ class VTK:
return VTK(geom) return VTK(geom)
# ToDo: If extension is given, check for consistency.
def write(self,fname): def write(self,fname):
""" """
Write to file. Write to file.
@ -167,7 +165,7 @@ class VTK:
Parameters Parameters
---------- ----------
fname : str fname : str
Filename for writing. Filename for writing.
""" """
if (isinstance(self.geom,vtk.vtkRectilinearGrid)): if (isinstance(self.geom,vtk.vtkRectilinearGrid)):
@ -177,8 +175,11 @@ class VTK:
elif(isinstance(self.geom,vtk.vtkPolyData)): elif(isinstance(self.geom,vtk.vtkPolyData)):
writer = vtk.vtkXMLPolyDataWriter() writer = vtk.vtkXMLPolyDataWriter()
writer.SetFileName('{}.{}'.format(os.path.splitext(fname)[0], default_ext = writer.GetDefaultFileExtension()
writer.GetDefaultFileExtension())) name, ext = os.path.splitext(fname)
if ext and ext != '.'+default_ext:
raise ValueError('Given extension {} is not .{}'.format(ext,default_ext))
writer.SetFileName('{}.{}'.format(name,default_ext))
writer.SetCompressorTypeToZLib() writer.SetCompressorTypeToZLib()
writer.SetDataModeToBinary() writer.SetDataModeToBinary()
writer.SetInputData(self.geom) writer.SetInputData(self.geom)
@ -195,15 +196,19 @@ class VTK:
if isinstance(data,np.ndarray): if isinstance(data,np.ndarray):
d = np_to_vtk(num_array=data.reshape(data.shape[0],-1),deep=True) d = np_to_vtk(num_array=data.reshape(data.shape[0],-1),deep=True)
if label is None:
raise ValueError('No label defined for numpy.ndarray')
d.SetName(label) d.SetName(label)
if data.shape[0] == N_cells: if data.shape[0] == N_cells:
self.geom.GetCellData().AddArray(d) self.geom.GetCellData().AddArray(d)
elif data.shape[0] == N_points: elif data.shape[0] == N_points:
self.geom.GetPointData().AddArray(d) self.geom.GetPointData().AddArray(d)
elif isinstance(data,pd.DataFrame): elif isinstance(data,pd.DataFrame):
pass raise NotImplementedError('pd.DataFrame')
elif isinstance(data,Table): elif isinstance(data,Table):
pass raise NotImplementedError('damask.Table')
else:
raise TypeError
def __repr__(self): def __repr__(self):

View File

@ -1,556 +0,0 @@
import numpy as np
class Color():
"""Color representation in and conversion between different color-spaces."""
__slots__ = [
'model',
'color',
'__dict__',
]
def __init__(self,
model = 'RGB',
color = np.zeros(3,'d')):
"""
Create a Color object.
Parameters
----------
model : string
color model
color : numpy.ndarray
vector representing the color according to the selected model
"""
self.__transforms__ = \
{'HSV': {'index': 0, 'next': self._HSV2HSL},
'HSL': {'index': 1, 'next': self._HSL2RGB, 'prev': self._HSL2HSV},
'RGB': {'index': 2, 'next': self._RGB2XYZ, 'prev': self._RGB2HSL},
'XYZ': {'index': 3, 'next': self._XYZ2CIELAB, 'prev': self._XYZ2RGB},
'CIELAB': {'index': 4, 'next': self._CIELAB2MSH, 'prev': self._CIELAB2XYZ},
'MSH': {'index': 5, 'prev': self._MSH2CIELAB},
}
model = model.upper()
if model not in list(self.__transforms__.keys()): model = 'RGB'
if model == 'RGB' and max(color) > 1.0: # are we RGB255 ?
for i in range(3):
color[i] /= 255.0 # rescale to RGB
if model == 'HSL': # are we HSL ?
if abs(color[0]) > 1.0: color[0] /= 360.0 # with angular hue?
while color[0] >= 1.0: color[0] -= 1.0 # rewind to proper range
while color[0] < 0.0: color[0] += 1.0 # rewind to proper range
self.model = model
self.color = np.array(color,'d')
def __repr__(self):
"""Color model and values."""
return 'Model: %s Color: %s'%(self.model,str(self.color))
def __str__(self):
"""Color model and values."""
return self.__repr__()
def convert_to(self,toModel = 'RGB'):
"""
Change the color model permanently.
Parameters
----------
toModel : string
color model
"""
toModel = toModel.upper()
if toModel not in list(self.__transforms__.keys()): return
sourcePos = self.__transforms__[self.model]['index']
targetPos = self.__transforms__[toModel]['index']
while sourcePos < targetPos:
self.__transforms__[self.model]['next']()
sourcePos += 1
while sourcePos > targetPos:
self.__transforms__[self.model]['prev']()
sourcePos -= 1
return self
def express_as(self,asModel = 'RGB'):
"""
Return the color in a different model.
Parameters
----------
asModel : string
color model
"""
return self.__class__(self.model,self.color).convert_to(asModel)
def _HSV2HSL(self):
"""
Convert H(ue) S(aturation) V(alue or brightness) to H(ue) S(aturation) L(uminance).
All values are in the range [0,1]
http://codeitdown.com/hsl-hsb-hsv-color
"""
if self.model != 'HSV': return
converted = Color('HSL',np.array([
self.color[0],
1. if self.color[2] == 0.0 or (self.color[1] == 0.0 and self.color[2] == 1.0) \
else self.color[1]*self.color[2]/(1.-abs(self.color[2]*(2.-self.color[1])-1.)),
0.5*self.color[2]*(2.-self.color[1]),
]))
self.model = converted.model
self.color = converted.color
def _HSL2HSV(self):
"""
Convert H(ue) S(aturation) L(uminance) to H(ue) S(aturation) V(alue or brightness).
All values are in the range [0,1]
http://codeitdown.com/hsl-hsb-hsv-color
"""
if self.model != 'HSL': return
h = self.color[0]
b = self.color[2]+0.5*(self.color[1]*(1.-abs(2*self.color[2]-1)))
s = 1.0 if b == 0.0 else 2.*(b-self.color[2])/b
converted = Color('HSV',np.array([h,s,b]))
self.model = converted.model
self.color = converted.color
def _HSL2RGB(self):
"""
Convert H(ue) S(aturation) L(uminance) to R(red) G(reen) B(lue).
All values are in the range [0,1]
from http://en.wikipedia.org/wiki/HSL_and_HSV
"""
if self.model != 'HSL': return
sextant = self.color[0]*6.0
c = (1.0 - abs(2.0 * self.color[2] - 1.0))*self.color[1]
x = c*(1.0 - abs(sextant%2 - 1.0))
m = self.color[2] - 0.5*c
converted = Color('RGB',np.array([
[c+m, x+m, m],
[x+m, c+m, m],
[m, c+m, x+m],
[m, x+m, c+m],
[x+m, m, c+m],
[c+m, m, x+m],
][int(sextant)],'d'))
self.model = converted.model
self.color = converted.color
def _RGB2HSL(self):
"""
Convert R(ed) G(reen) B(lue) to H(ue) S(aturation) L(uminance).
All values are in the range [0,1]
from http://130.113.54.154/~monger/hsl-rgb.html
"""
if self.model != 'RGB': return
HSL = np.zeros(3,'d')
maxcolor = self.color.max()
mincolor = self.color.min()
HSL[2] = (maxcolor + mincolor)/2.0
if(mincolor == maxcolor):
HSL[0] = 0.0
HSL[1] = 0.0
else:
if (HSL[2]<0.5):
HSL[1] = (maxcolor - mincolor)/(maxcolor + mincolor)
else:
HSL[1] = (maxcolor - mincolor)/(2.0 - maxcolor - mincolor)
if (maxcolor == self.color[0]):
HSL[0] = 0.0 + (self.color[1] - self.color[2])/(maxcolor - mincolor)
elif (maxcolor == self.color[1]):
HSL[0] = 2.0 + (self.color[2] - self.color[0])/(maxcolor - mincolor)
elif (maxcolor == self.color[2]):
HSL[0] = 4.0 + (self.color[0] - self.color[1])/(maxcolor - mincolor)
HSL[0] = HSL[0]*60.0 # scaling to 360 might be dangerous for small values
if (HSL[0] < 0.0):
HSL[0] = HSL[0] + 360.0
for i in range(2):
HSL[i+1] = min(HSL[i+1],1.0)
HSL[i+1] = max(HSL[i+1],0.0)
converted = Color('HSL', HSL)
self.model = converted.model
self.color = converted.color
def _RGB2XYZ(self):
"""
Convert R(ed) G(reen) B(lue) to CIE XYZ.
All values are in the range [0,1]
from http://www.cs.rit.edu/~ncs/color/t_convert.html
"""
if self.model != 'RGB': return
XYZ = np.zeros(3,'d')
RGB_lin = np.zeros(3,'d')
convert = np.array([[0.412453,0.357580,0.180423],
[0.212671,0.715160,0.072169],
[0.019334,0.119193,0.950227]])
for i in range(3):
if (self.color[i] > 0.04045): RGB_lin[i] = ((self.color[i]+0.0555)/1.0555)**2.4
else: RGB_lin[i] = self.color[i] /12.92
XYZ = np.dot(convert,RGB_lin)
for i in range(3):
XYZ[i] = max(XYZ[i],0.0)
converted = Color('XYZ', XYZ)
self.model = converted.model
self.color = converted.color
def _XYZ2RGB(self):
"""
Convert CIE XYZ to R(ed) G(reen) B(lue).
All values are in the range [0,1]
from http://www.cs.rit.edu/~ncs/color/t_convert.html
"""
if self.model != 'XYZ':
return
convert = np.array([[ 3.240479,-1.537150,-0.498535],
[-0.969256, 1.875992, 0.041556],
[ 0.055648,-0.204043, 1.057311]])
RGB_lin = np.dot(convert,self.color)
RGB = np.zeros(3,'d')
for i in range(3):
if (RGB_lin[i] > 0.0031308): RGB[i] = ((RGB_lin[i])**(1.0/2.4))*1.0555-0.0555
else: RGB[i] = RGB_lin[i] *12.92
for i in range(3):
RGB[i] = min(RGB[i],1.0)
RGB[i] = max(RGB[i],0.0)
maxVal = max(RGB) # clipping colors according to the display gamut
if (maxVal > 1.0): RGB /= maxVal
converted = Color('RGB', RGB)
self.model = converted.model
self.color = converted.color
def _CIELAB2XYZ(self):
"""
Convert CIE Lab to CIE XYZ.
All values are in the range [0,1]
from http://www.easyrgb.com/index.php?X=MATH&H=07#text7
"""
if self.model != 'CIELAB': return
ref_white = np.array([.95047, 1.00000, 1.08883],'d') # Observer = 2, Illuminant = D65
XYZ = np.zeros(3,'d')
XYZ[1] = (self.color[0] + 16.0 ) / 116.0
XYZ[0] = XYZ[1] + self.color[1]/ 500.0
XYZ[2] = XYZ[1] - self.color[2]/ 200.0
for i in range(len(XYZ)):
if (XYZ[i] > 6./29. ): XYZ[i] = XYZ[i]**3.
else: XYZ[i] = 108./841. * (XYZ[i] - 4./29.)
converted = Color('XYZ', XYZ*ref_white)
self.model = converted.model
self.color = converted.color
def _XYZ2CIELAB(self):
"""
Convert CIE XYZ to CIE Lab.
All values are in the range [0,1]
from http://en.wikipedia.org/wiki/Lab_color_space,
http://www.cs.rit.edu/~ncs/color/t_convert.html
"""
if self.model != 'XYZ': return
ref_white = np.array([.95047, 1.00000, 1.08883],'d') # Observer = 2, Illuminant = D65
XYZ = self.color/ref_white
for i in range(len(XYZ)):
if (XYZ[i] > 216./24389 ): XYZ[i] = XYZ[i]**(1.0/3.0)
else: XYZ[i] = (841./108. * XYZ[i]) + 16.0/116.0
converted = Color('CIELAB', np.array([ 116.0 * XYZ[1] - 16.0,
500.0 * (XYZ[0] - XYZ[1]),
200.0 * (XYZ[1] - XYZ[2]) ]))
self.model = converted.model
self.color = converted.color
def _CIELAB2MSH(self):
"""
Convert CIE Lab to Msh colorspace.
from http://www.cs.unm.edu/~kmorel/documents/ColorMaps/DivergingColorMapWorkshop.xls
"""
if self.model != 'CIELAB': return
Msh = np.zeros(3,'d')
Msh[0] = np.sqrt(np.dot(self.color,self.color))
if (Msh[0] > 0.001):
Msh[1] = np.arccos(self.color[0]/Msh[0])
if (self.color[1] != 0.0):
Msh[2] = np.arctan2(self.color[2],self.color[1])
converted = Color('MSH', Msh)
self.model = converted.model
self.color = converted.color
def _MSH2CIELAB(self):
"""
Convert Msh colorspace to CIE Lab.
with s,h in radians
from http://www.cs.unm.edu/~kmorel/documents/ColorMaps/DivergingColorMapWorkshop.xls
"""
if self.model != 'MSH': return
Lab = np.zeros(3,'d')
Lab[0] = self.color[0] * np.cos(self.color[1])
Lab[1] = self.color[0] * np.sin(self.color[1]) * np.cos(self.color[2])
Lab[2] = self.color[0] * np.sin(self.color[1]) * np.sin(self.color[2])
converted = Color('CIELAB', Lab)
self.model = converted.model
self.color = converted.color
class Colormap():
"""Perceptually uniform diverging or sequential colormap."""
__slots__ = [
'left',
'right',
'interpolate',
]
__predefined__ = {
'gray': {'left': Color('HSL',[0,1,1]),
'right': Color('HSL',[0,0,0.15]),
'interpolate': 'perceptualuniform'},
'grey': {'left': Color('HSL',[0,1,1]),
'right': Color('HSL',[0,0,0.15]),
'interpolate': 'perceptualuniform'},
'red': {'left': Color('HSL',[0,1,0.14]),
'right': Color('HSL',[0,0.35,0.91]),
'interpolate': 'perceptualuniform'},
'green': {'left': Color('HSL',[0.33333,1,0.14]),
'right': Color('HSL',[0.33333,0.35,0.91]),
'interpolate': 'perceptualuniform'},
'blue': {'left': Color('HSL',[0.66,1,0.14]),
'right': Color('HSL',[0.66,0.35,0.91]),
'interpolate': 'perceptualuniform'},
'seaweed': {'left': Color('HSL',[0.78,1.0,0.1]),
'right': Color('HSL',[0.40000,0.1,0.9]),
'interpolate': 'perceptualuniform'},
'bluebrown': {'left': Color('HSL',[0.65,0.53,0.49]),
'right': Color('HSL',[0.11,0.75,0.38]),
'interpolate': 'perceptualuniform'},
'redgreen': {'left': Color('HSL',[0.97,0.96,0.36]),
'right': Color('HSL',[0.33333,1.0,0.14]),
'interpolate': 'perceptualuniform'},
'bluered': {'left': Color('HSL',[0.65,0.53,0.49]),
'right': Color('HSL',[0.97,0.96,0.36]),
'interpolate': 'perceptualuniform'},
'blueredrainbow':{'left': Color('HSL',[2.0/3.0,1,0.5]),
'right': Color('HSL',[0,1,0.5]),
'interpolate': 'linear' },
'orientation': {'left': Color('RGB',[0.933334,0.878432,0.878431]),
'right': Color('RGB',[0.250980,0.007843,0.000000]),
'interpolate': 'perceptualuniform'},
'strain': {'left': Color('RGB',[0.941177,0.941177,0.870588]),
'right': Color('RGB',[0.266667,0.266667,0.000000]),
'interpolate': 'perceptualuniform'},
'stress': {'left': Color('RGB',[0.878432,0.874511,0.949019]),
'right': Color('RGB',[0.000002,0.000000,0.286275]),
'interpolate': 'perceptualuniform'},
}
# ------------------------------------------------------------------
def __init__(self,
left = Color('RGB',[1,1,1]),
right = Color('RGB',[0,0,0]),
interpolate = 'perceptualuniform',
predefined = None
):
"""
Create a Colormap object.
Parameters
----------
left : Color
left color (minimum value)
right : Color
right color (maximum value)
interpolate : str
interpolation scheme (either 'perceptualuniform' or 'linear')
predefined : bool
ignore other arguments and use predefined definition
"""
if predefined is not None:
left = self.__predefined__[predefined.lower()]['left']
right= self.__predefined__[predefined.lower()]['right']
interpolate = self.__predefined__[predefined.lower()]['interpolate']
if left.__class__.__name__ != 'Color':
left = Color()
if right.__class__.__name__ != 'Color':
right = Color()
self.left = left
self.right = right
self.interpolate = interpolate
# ------------------------------------------------------------------
def __repr__(self):
"""Left and right value of colormap."""
return 'Left: %s Right: %s'%(self.left,self.right)
# ------------------------------------------------------------------
def invert(self):
"""Switch left/minimum with right/maximum."""
(self.left, self.right) = (self.right, self.left)
return self
# ------------------------------------------------------------------
def show_predefined(self):
"""Show the labels of the predefined colormaps."""
print('\n'.join(self.__predefined__.keys()))
# ------------------------------------------------------------------
def color(self,fraction = 0.5):
def interpolate_Msh(lo, hi, frac):
def rad_diff(a,b):
return abs(a[2]-b[2])
# if saturation of one of the two colors is too less than the other, hue of the less
def adjust_hue(Msh_sat, Msh_unsat):
if Msh_sat[0] >= Msh_unsat[0]:
return Msh_sat[2]
else:
hSpin = Msh_sat[1]/np.sin(Msh_sat[1])*np.sqrt(Msh_unsat[0]**2.0-Msh_sat[0]**2)/Msh_sat[0]
if Msh_sat[2] < - np.pi/3.0: hSpin *= -1.0
return Msh_sat[2] + hSpin
Msh1 = np.array(lo[:])
Msh2 = np.array(hi[:])
if (Msh1[1] > 0.05 and Msh2[1] > 0.05 and rad_diff(Msh1,Msh2) > np.pi/3.0):
M_mid = max(Msh1[0],Msh2[0],88.0)
if frac < 0.5:
Msh2 = np.array([M_mid,0.0,0.0],'d')
frac *= 2.0
else:
Msh1 = np.array([M_mid,0.0,0.0],'d')
frac = 2.0*frac - 1.0
if Msh1[1] < 0.05 and Msh2[1] > 0.05: Msh1[2] = adjust_hue(Msh2,Msh1)
elif Msh1[1] > 0.05 and Msh2[1] < 0.05: Msh2[2] = adjust_hue(Msh1,Msh2)
Msh = (1.0 - frac) * Msh1 + frac * Msh2
return Color('MSH',Msh)
def interpolate_linear(lo, hi, frac):
"""Linear interpolation between lo and hi color at given fraction; output in model of lo color."""
interpolation = (1.0 - frac) * np.array(lo.color[:]) \
+ frac * np.array(hi.express_as(lo.model).color[:])
return Color(lo.model,interpolation)
if self.interpolate == 'perceptualuniform':
return interpolate_Msh(self.left.express_as('MSH').color,
self.right.express_as('MSH').color,fraction)
elif self.interpolate == 'linear':
return interpolate_linear(self.left,
self.right,fraction)
else:
raise NameError('unknown color interpolation method')
# ------------------------------------------------------------------
def export(self,name = 'uniformPerceptualColorMap',\
format = 'paraview',\
steps = 2,\
crop = [-1.0,1.0],
model = 'RGB'):
"""
[RGB] colormap for use in paraview or gmsh, or as raw string, or array.
Arguments: name, format, steps, crop.
Format is one of (paraview, gmsh, raw, list).
Crop selects a (sub)range in [-1.0,1.0].
Generates sequential map if one limiting color is either white or black,
diverging map otherwise.
"""
format = format.lower() # consistent comparison basis
frac = 0.5*(np.array(crop) + 1.0) # rescale crop range to fractions
colors = [self.color(float(i)/(steps-1)*(frac[1]-frac[0])+frac[0]).express_as(model).color for i in range(steps)]
if format == 'paraview':
colormap = ['[\n {{\n "ColorSpace": "RGB", "Name": "{}", "DefaultMap": true,\n "RGBPoints" : ['.format(name)] \
+ [' {:4d},{:8.6f},{:8.6f},{:8.6f},'.format(i,color[0],color[1],color[2],) \
for i,color in enumerate(colors[:-1])] \
+ [' {:4d},{:8.6f},{:8.6f},{:8.6f} '.format(len(colors),colors[-1][0],colors[-1][1],colors[-1][2],)] \
+ [' ]\n }\n]']
elif format == 'gmsh':
colormap = ['View.ColorTable = {'] \
+ [',\n'.join(['{%s}'%(','.join([str(x*255.0) for x in color])) for color in colors])] \
+ ['}']
elif format == 'gom':
colormap = ['1 1 ' + str(name)
+ ' 9 ' + str(name)
+ ' 0 1 0 3 0 0 -1 9 \\ 0 0 0 255 255 255 0 0 255 '
+ '30 NO_UNIT 1 1 64 64 64 255 1 0 0 0 0 0 0 3 0 ' + str(len(colors))
+ ' '.join([' 0 %s 255 1'%(' '.join([str(int(x*255.0)) for x in color])) for color in reversed(colors)])]
elif format == 'raw':
colormap = ['\t'.join(map(str,color)) for color in colors]
elif format == 'list':
colormap = colors
else:
raise NameError('unknown color export format')
return '\n'.join(colormap) + '\n' if type(colormap[0]) is str else colormap

View File

@ -1,5 +1,3 @@
# -*- coding: UTF-8 no BOM -*- """Aggregator for configuration file handling."""
"""Aggregator for configuration file handling"""
from .material import Material # noqa from .material import Material # noqa

View File

@ -1,11 +1,10 @@
# -*- coding: UTF-8 no BOM -*-
import re import re
import os import os
class Section(): class Section():
def __init__(self,data = {'__order__':[]},part = ''): def __init__(self,data = {'__order__':[]},part = ''):
"""New material.config section."""
classes = { classes = {
'homogenization':Homogenization, 'homogenization':Homogenization,
'microstructure':Microstructure, 'microstructure':Microstructure,
@ -35,26 +34,31 @@ class Section():
class Homogenization(Section): class Homogenization(Section):
def __init__(self,data = {'__order__':[]}): def __init__(self,data = {'__order__':[]}):
"""New material.config <homogenization> section."""
Section.__init__(self,data) Section.__init__(self,data)
class Crystallite(Section): class Crystallite(Section):
def __init__(self,data = {'__order__':[]}): def __init__(self,data = {'__order__':[]}):
"""New material.config <crystallite> section."""
Section.__init__(self,data) Section.__init__(self,data)
class Phase(Section): class Phase(Section):
def __init__(self,data = {'__order__':[]}): def __init__(self,data = {'__order__':[]}):
"""New material.config <Phase> section."""
Section.__init__(self,data) Section.__init__(self,data)
class Microstructure(Section): class Microstructure(Section):
def __init__(self,data = {'__order__':[]}): def __init__(self,data = {'__order__':[]}):
"""New material.config <microstructure> section."""
Section.__init__(self,data) Section.__init__(self,data)
class Texture(Section): class Texture(Section):
def __init__(self,data = {'__order__':[]}): def __init__(self,data = {'__order__':[]}):
"""New material.config <texture> section."""
Section.__init__(self,data) Section.__init__(self,data)
def add_component(self,theType,properties): def add_component(self,theType,properties):
@ -79,10 +83,10 @@ class Texture(Section):
class Material(): class Material():
"""Reads, manipulates and writes material.config files""" """Read, manipulate, and write material.config files."""
def __init__(self,verbose=True): def __init__(self,verbose=True):
"""Generates ordered list of parts""" """Generates ordered list of parts."""
self.parts = [ self.parts = [
'homogenization', 'homogenization',
'crystallite', 'crystallite',
@ -100,7 +104,7 @@ class Material():
self.verbose = verbose self.verbose = verbose
def __repr__(self): def __repr__(self):
"""Returns current data structure in material.config format""" """Returns current data structure in material.config format."""
me = [] me = []
for part in self.parts: for part in self.parts:
if self.verbose: print('processing <{}>'.format(part)) if self.verbose: print('processing <{}>'.format(part))
@ -158,9 +162,9 @@ class Material():
def read(self,filename=None): def read(self,filename=None):
"""Reads material.config file""" """Read material.config file."""
def recursiveRead(filename): def recursiveRead(filename):
"""Takes care of include statements like '{}'""" """Takes care of include statements like '{}'."""
result = [] result = []
re_include = re.compile(r'^{(.+)}$') re_include = re.compile(r'^{(.+)}$')
with open(filename) as f: lines = f.readlines() with open(filename) as f: lines = f.readlines()
@ -176,7 +180,7 @@ class Material():
self.parse(part=p, content=c) self.parse(part=p, content=c)
def write(self,filename='material.config', overwrite=False): def write(self,filename='material.config', overwrite=False):
"""Writes to material.config""" """Write to material.config."""
i = 0 i = 0
outname = filename outname = filename
while os.path.exists(outname) and not overwrite: while os.path.exists(outname) and not overwrite:
@ -189,7 +193,7 @@ class Material():
return outname return outname
def add_section(self, part=None, section=None, initialData=None, merge=False): def add_section(self, part=None, section=None, initialData=None, merge=False):
"""adding/updating""" """Add Update."""
part = part.lower() part = part.lower()
section = section.lower() section = section.lower()
if part not in self.parts: raise Exception('invalid part {}'.format(part)) if part not in self.parts: raise Exception('invalid part {}'.format(part))

View File

@ -98,17 +98,12 @@ def cell_coord0(grid,size,origin=np.zeros(3)):
size : numpy.ndarray size : numpy.ndarray
physical size of the periodic field. physical size of the periodic field.
origin : numpy.ndarray, optional origin : numpy.ndarray, optional
physical origin of the periodic field. Default is [0.0,0.0,0.0]. physical origin of the periodic field. Defaults to [0.0,0.0,0.0].
""" """
start = origin + size/grid*.5 start = origin + size/grid*.5
end = origin - size/grid*.5 + size end = origin + size - size/grid*.5
x, y, z = np.meshgrid(np.linspace(start[2],end[2],grid[2]), return np.mgrid[start[0]:end[0]:grid[0]*1j,start[1]:end[1]:grid[1]*1j,start[2]:end[2]:grid[2]*1j].T
np.linspace(start[1],end[1],grid[1]),
np.linspace(start[0],end[0],grid[0]),
indexing = 'ij')
return np.concatenate((z[:,:,:,None],y[:,:,:,None],x[:,:,:,None]),axis = 3)
def cell_displacement_fluct(size,F): def cell_displacement_fluct(size,F):
@ -180,7 +175,7 @@ def cell_coord(size,F,origin=np.zeros(3)):
F : numpy.ndarray F : numpy.ndarray
deformation gradient field. deformation gradient field.
origin : numpy.ndarray, optional origin : numpy.ndarray, optional
physical origin of the periodic field. Default is [0.0,0.0,0.0]. physical origin of the periodic field. Defaults to [0.0,0.0,0.0].
""" """
return cell_coord0(F.shape[:3][::-1],size,origin) + cell_displacement(size,F) return cell_coord0(F.shape[:3][::-1],size,origin) + cell_displacement(size,F)
@ -251,15 +246,12 @@ def node_coord0(grid,size,origin=np.zeros(3)):
size : numpy.ndarray size : numpy.ndarray
physical size of the periodic field. physical size of the periodic field.
origin : numpy.ndarray, optional origin : numpy.ndarray, optional
physical origin of the periodic field. Default is [0.0,0.0,0.0]. physical origin of the periodic field. Defaults to [0.0,0.0,0.0].
""" """
x, y, z = np.meshgrid(np.linspace(origin[2],size[2]+origin[2],1+grid[2]), return np.mgrid[origin[0]:size[0]+origin[0]:(grid[0]+1)*1j,
np.linspace(origin[1],size[1]+origin[1],1+grid[1]), origin[1]:size[1]+origin[1]:(grid[1]+1)*1j,
np.linspace(origin[0],size[0]+origin[0],1+grid[0]), origin[2]:size[2]+origin[2]:(grid[2]+1)*1j].T
indexing = 'ij')
return np.concatenate((z[:,:,:,None],y[:,:,:,None],x[:,:,:,None]),axis = 3)
def node_displacement_fluct(size,F): def node_displacement_fluct(size,F):
@ -319,7 +311,7 @@ def node_coord(size,F,origin=np.zeros(3)):
F : numpy.ndarray F : numpy.ndarray
deformation gradient field. deformation gradient field.
origin : numpy.ndarray, optional origin : numpy.ndarray, optional
physical origin of the periodic field. Default is [0.0,0.0,0.0]. physical origin of the periodic field. Defaults to [0.0,0.0,0.0].
""" """
return node_coord0(F.shape[:3][::-1],size,origin) + node_displacement(size,F) return node_coord0(F.shape[:3][::-1],size,origin) + node_displacement(size,F)
@ -399,5 +391,5 @@ def regrid(size,F,new_grid):
c[np.where(c[:,:,:,d]<0)] += outer[d] c[np.where(c[:,:,:,d]<0)] += outer[d]
c[np.where(c[:,:,:,d]>outer[d])] -= outer[d] c[np.where(c[:,:,:,d]>outer[d])] -= outer[d]
tree = spatial.cKDTree(c.reshape((-1,3)),boxsize=outer) tree = spatial.cKDTree(c.reshape(-1,3),boxsize=outer)
return tree.query(cell_coord0(new_grid,outer))[1].flatten() return tree.query(cell_coord0(new_grid,outer))[1].flatten()

View File

@ -8,10 +8,10 @@ def Cauchy(P,F):
Parameters Parameters
---------- ----------
F : numpy.array of shape (:,3,3) or (3,3) F : numpy.ndarray of shape (:,3,3) or (3,3)
Deformation gradient. Deformation gradient.
P : numpy.array of shape (:,3,3) or (3,3) P : numpy.ndarray of shape (:,3,3) or (3,3)
1. Piola-Kirchhoff stress. First Piola-Kirchhoff stress.
""" """
if np.shape(F) == np.shape(P) == (3,3): if np.shape(F) == np.shape(P) == (3,3):
@ -27,8 +27,8 @@ def deviatoric_part(T):
Parameters Parameters
---------- ----------
T : numpy.array of shape (:,3,3) or (3,3) T : numpy.ndarray of shape (:,3,3) or (3,3)
Tensor of which the deviatoric part is computed. Tensor of which the deviatoric part is computed.
""" """
return T - np.eye(3)*spherical_part(T) if np.shape(T) == (3,3) else \ return T - np.eye(3)*spherical_part(T) if np.shape(T) == (3,3) else \
@ -44,8 +44,8 @@ def eigenvalues(T_sym):
Parameters Parameters
---------- ----------
T_sym : numpy.array of shape (:,3,3) or (3,3) T_sym : numpy.ndarray of shape (:,3,3) or (3,3)
Symmetric tensor of which the eigenvalues are computed. Symmetric tensor of which the eigenvalues are computed.
""" """
return np.linalg.eigvalsh(symmetric(T_sym)) return np.linalg.eigvalsh(symmetric(T_sym))
@ -59,10 +59,10 @@ def eigenvectors(T_sym,RHS=False):
Parameters Parameters
---------- ----------
T_sym : numpy.array of shape (:,3,3) or (3,3) T_sym : numpy.ndarray of shape (:,3,3) or (3,3)
Symmetric tensor of which the eigenvectors are computed. Symmetric tensor of which the eigenvectors are computed.
RHS: bool, optional RHS: bool, optional
Enforce right-handed coordinate system. Default is False. Enforce right-handed coordinate system. Default is False.
""" """
(u,v) = np.linalg.eigh(symmetric(T_sym)) (u,v) = np.linalg.eigh(symmetric(T_sym))
@ -81,11 +81,11 @@ def left_stretch(T):
Parameters Parameters
---------- ----------
T : numpy.array of shape (:,3,3) or (3,3) T : numpy.ndarray of shape (:,3,3) or (3,3)
Tensor of which the left stretch is computed. Tensor of which the left stretch is computed.
""" """
return __polar_decomposition(T,'V')[0] return _polar_decomposition(T,'V')[0]
def maximum_shear(T_sym): def maximum_shear(T_sym):
@ -94,8 +94,8 @@ def maximum_shear(T_sym):
Parameters Parameters
---------- ----------
T_sym : numpy.array of shape (:,3,3) or (3,3) T_sym : numpy.ndarray of shape (:,3,3) or (3,3)
Symmetric tensor of which the maximum shear is computed. Symmetric tensor of which the maximum shear is computed.
""" """
w = eigenvalues(T_sym) w = eigenvalues(T_sym)
@ -109,11 +109,11 @@ def Mises_strain(epsilon):
Parameters Parameters
---------- ----------
epsilon : numpy.array of shape (:,3,3) or (3,3) epsilon : numpy.ndarray of shape (:,3,3) or (3,3)
Symmetric strain tensor of which the von Mises equivalent is computed. Symmetric strain tensor of which the von Mises equivalent is computed.
""" """
return __Mises(epsilon,2.0/3.0) return _Mises(epsilon,2.0/3.0)
def Mises_stress(sigma): def Mises_stress(sigma):
@ -122,11 +122,11 @@ def Mises_stress(sigma):
Parameters Parameters
---------- ----------
sigma : numpy.array of shape (:,3,3) or (3,3) sigma : numpy.ndarray of shape (:,3,3) or (3,3)
Symmetric stress tensor of which the von Mises equivalent is computed. Symmetric stress tensor of which the von Mises equivalent is computed.
""" """
return __Mises(sigma,3.0/2.0) return _Mises(sigma,3.0/2.0)
def PK2(P,F): def PK2(P,F):
@ -135,10 +135,10 @@ def PK2(P,F):
Parameters Parameters
---------- ----------
P : numpy.array of shape (:,3,3) or (3,3) P : numpy.ndarray of shape (:,3,3) or (3,3)
1. Piola-Kirchhoff stress. First Piola-Kirchhoff stress.
F : numpy.array of shape (:,3,3) or (3,3) F : numpy.ndarray of shape (:,3,3) or (3,3)
Deformation gradient. Deformation gradient.
""" """
if np.shape(F) == np.shape(P) == (3,3): if np.shape(F) == np.shape(P) == (3,3):
@ -154,11 +154,11 @@ def right_stretch(T):
Parameters Parameters
---------- ----------
T : numpy.array of shape (:,3,3) or (3,3) T : numpy.ndarray of shape (:,3,3) or (3,3)
Tensor of which the right stretch is computed. Tensor of which the right stretch is computed.
""" """
return __polar_decomposition(T,'U')[0] return _polar_decomposition(T,'U')[0]
def rotational_part(T): def rotational_part(T):
@ -167,11 +167,11 @@ def rotational_part(T):
Parameters Parameters
---------- ----------
T : numpy.array of shape (:,3,3) or (3,3) T : numpy.ndarray of shape (:,3,3) or (3,3)
Tensor of which the rotational part is computed. Tensor of which the rotational part is computed.
""" """
return __polar_decomposition(T,'R')[0] return _polar_decomposition(T,'R')[0]
def spherical_part(T,tensor=False): def spherical_part(T,tensor=False):
@ -180,10 +180,10 @@ def spherical_part(T,tensor=False):
Parameters Parameters
---------- ----------
T : numpy.array of shape (:,3,3) or (3,3) T : numpy.ndarray of shape (:,3,3) or (3,3)
Tensor of which the hydrostatic part is computed. Tensor of which the hydrostatic part is computed.
tensor : bool, optional tensor : bool, optional
Map spherical part onto identity tensor. Default is false Map spherical part onto identity tensor. Default is false
""" """
if T.shape == (3,3): if T.shape == (3,3):
@ -206,15 +206,15 @@ def strain_tensor(F,t,m):
Parameters Parameters
---------- ----------
F : numpy.array of shape (:,3,3) or (3,3) F : numpy.ndarray of shape (:,3,3) or (3,3)
Deformation gradient. Deformation gradient.
t : {V, U} t : {V, U}
Type of the polar decomposition, V for left stretch tensor and U for right stretch tensor. Type of the polar decomposition, V for left stretch tensor and U for right stretch tensor.
m : float m : float
Order of the strain. Order of the strain.
""" """
F_ = F.reshape((1,3,3)) if F.shape == (3,3) else F F_ = F.reshape(1,3,3) if F.shape == (3,3) else F
if t == 'V': if t == 'V':
B = np.matmul(F_,transpose(F_)) B = np.matmul(F_,transpose(F_))
w,n = np.linalg.eigh(B) w,n = np.linalg.eigh(B)
@ -231,7 +231,7 @@ def strain_tensor(F,t,m):
else: else:
eps = np.matmul(n,np.einsum('ij,ikj->ijk',0.5*np.log(w),n)) eps = np.matmul(n,np.einsum('ij,ikj->ijk',0.5*np.log(w),n))
return eps.reshape((3,3)) if np.shape(F) == (3,3) else \ return eps.reshape(3,3) if np.shape(F) == (3,3) else \
eps eps
@ -241,8 +241,8 @@ def symmetric(T):
Parameters Parameters
---------- ----------
T : numpy.array of shape (:,3,3) or (3,3) T : numpy.ndarray of shape (:,3,3) or (3,3)
Tensor of which the symmetrized values are computed. Tensor of which the symmetrized values are computed.
""" """
return (T+transpose(T))*0.5 return (T+transpose(T))*0.5
@ -254,25 +254,25 @@ def transpose(T):
Parameters Parameters
---------- ----------
T : numpy.array of shape (:,3,3) or (3,3) T : numpy.ndarray of shape (:,3,3) or (3,3)
Tensor of which the transpose is computed. Tensor of which the transpose is computed.
""" """
return T.T if np.shape(T) == (3,3) else \ return T.T if np.shape(T) == (3,3) else \
np.transpose(T,(0,2,1)) np.transpose(T,(0,2,1))
def __polar_decomposition(T,requested): def _polar_decomposition(T,requested):
""" """
Singular value decomposition. Singular value decomposition.
Parameters Parameters
---------- ----------
T : numpy.array of shape (:,3,3) or (3,3) T : numpy.ndarray of shape (:,3,3) or (3,3)
Tensor of which the singular values are computed. Tensor of which the singular values are computed.
requested : iterable of str requested : iterable of str
Requested outputs: R for the rotation tensor, Requested outputs: R for the rotation tensor,
V for left stretch tensor and U for right stretch tensor. V for left stretch tensor and U for right stretch tensor.
""" """
u, s, vh = np.linalg.svd(T) u, s, vh = np.linalg.svd(T)
@ -290,16 +290,16 @@ def __polar_decomposition(T,requested):
return tuple(output) return tuple(output)
def __Mises(T_sym,s): def _Mises(T_sym,s):
""" """
Base equation for Mises equivalent of a stres or strain tensor. Base equation for Mises equivalent of a stres or strain tensor.
Parameters Parameters
---------- ----------
T_sym : numpy.array of shape (:,3,3) or (3,3) T_sym : numpy.ndarray of shape (:,3,3) or (3,3)
Symmetric tensor of which the von Mises equivalent is computed. Symmetric tensor of which the von Mises equivalent is computed.
s : float s : float
Scaling factor (2/3 for strain, 3/2 for stress). Scaling factor (2/3 for strain, 3/2 for stress).
""" """
d = deviatoric_part(T_sym) d = deviatoric_part(T_sym)

View File

@ -1,4 +1,3 @@
"""Tools to control the various solvers.""" """Tools to control the various solvers."""
from .solver import Solver # noqa from ._marc import Marc # noqa
from .marc import Marc # noqa

View File

@ -3,13 +3,12 @@ import subprocess
import shlex import shlex
import string import string
from .solver import Solver from .._environment import Environment
import damask
class Marc(Solver): class Marc:
"""Wrapper to run DAMASK with MSCMarc.""" """Wrapper to run DAMASK with MSCMarc."""
def __init__(self,version=damask.Environment().options['MARC_VERSION']): def __init__(self,version=Environment().options['MARC_VERSION']):
""" """
Create a Marc solver object. Create a Marc solver object.
@ -29,7 +28,7 @@ class Marc(Solver):
#-------------------------- #--------------------------
def libraryPath(self): def libraryPath(self):
path_MSC = damask.Environment().options['MSC_ROOT'] path_MSC = Environment().options['MSC_ROOT']
path_lib = '{}/mentat{}/shlib/linux64'.format(path_MSC,self.version) path_lib = '{}/mentat{}/shlib/linux64'.format(path_MSC,self.version)
return path_lib if os.path.exists(path_lib) else '' return path_lib if os.path.exists(path_lib) else ''
@ -38,7 +37,7 @@ class Marc(Solver):
#-------------------------- #--------------------------
def toolsPath(self): def toolsPath(self):
path_MSC = damask.Environment().options['MSC_ROOT'] path_MSC = Environment().options['MSC_ROOT']
path_tools = '{}/marc{}/tools'.format(path_MSC,self.version) path_tools = '{}/marc{}/tools'.format(path_MSC,self.version)
return path_tools if os.path.exists(path_tools) else '' return path_tools if os.path.exists(path_tools) else ''
@ -54,7 +53,7 @@ class Marc(Solver):
): ):
damaskEnv = damask.Environment() damaskEnv = Environment()
user = os.path.join(damaskEnv.relPath('src'),'DAMASK_marc{}.{}'.format(self.version,'f90' if compile else 'marc')) user = os.path.join(damaskEnv.relPath('src'),'DAMASK_marc{}.{}'.format(self.version,'f90' if compile else 'marc'))
if not os.path.isfile(user): if not os.path.isfile(user):

View File

@ -1,6 +0,0 @@
class Solver():
"""
General class for solver specific functionality.
Sub-classed by the individual solvers.
"""

View File

@ -47,9 +47,9 @@ def srepr(arg,glue = '\n'):
Parameters Parameters
---------- ----------
arg : iterable arg : iterable
Items to join. Items to join.
glue : str, optional glue : str, optional
Defaults to \n. Defaults to \n.
""" """
if (not hasattr(arg, "strip") and if (not hasattr(arg, "strip") and
@ -66,12 +66,12 @@ def croak(what, newline = True):
Parameters Parameters
---------- ----------
what : str or iterable what : str or iterable
Content to be displayed Content to be displayed.
newline : bool, optional newline : bool, optional
Separate items of what by newline. Defaults to True. Separate items of what by newline. Defaults to True.
""" """
if not what: if what is not None:
sys.stderr.write(srepr(what,glue = '\n') + ('\n' if newline else '')) sys.stderr.write(srepr(what,glue = '\n') + ('\n' if newline else ''))
sys.stderr.flush() sys.stderr.flush()
@ -117,13 +117,13 @@ def execute(cmd,
Parameters Parameters
---------- ----------
cmd : str cmd : str
Command to be executed. Command to be executed.
streanIn :, optional streanIn :, optional
Input (via pipe) for executed process. Input (via pipe) for executed process.
wd : str, optional wd : str, optional
Working directory of process. Defaults to ./ . Working directory of process. Defaults to ./ .
env : env : dict, optional
Environment Environment for execution.
""" """
initialPath = os.getcwd() initialPath = os.getcwd()
@ -140,7 +140,7 @@ def execute(cmd,
error = error.decode('utf-8').replace('\x08','') error = error.decode('utf-8').replace('\x08','')
os.chdir(initialPath) os.chdir(initialPath)
if process.returncode != 0: if process.returncode != 0:
raise RuntimeError('{} failed with returncode {}'.format(cmd,process.returncode)) raise RuntimeError('{} failed with returncode {}'.format(cmd,process.returncode))
return out,error return out,error
@ -158,11 +158,11 @@ class extendableOption(Option):
ALWAYS_TYPED_ACTIONS = Option.ALWAYS_TYPED_ACTIONS + ("extend",) ALWAYS_TYPED_ACTIONS = Option.ALWAYS_TYPED_ACTIONS + ("extend",)
def take_action(self, action, dest, opt, value, values, parser): def take_action(self, action, dest, opt, value, values, parser):
if action == "extend": if action == "extend":
lvalue = value.split(",") lvalue = value.split(",")
values.ensure_value(dest, []).extend(lvalue) values.ensure_value(dest, []).extend(lvalue)
else: else:
Option.take_action(self, action, dest, opt, value, values, parser) Option.take_action(self, action, dest, opt, value, values, parser)
class _ProgressBar: class _ProgressBar:
@ -179,11 +179,11 @@ class _ProgressBar:
Parameters Parameters
---------- ----------
total : int total : int
Total # of iterations. Total # of iterations.
prefix : str prefix : str
Prefix string. Prefix string.
bar_length : int bar_length : int
Character length of bar. Character length of bar.
""" """
self.total = total self.total = total
@ -224,13 +224,13 @@ def show_progress(iterable,N_iter=None,prefix='',bar_length=50):
Parameters Parameters
---------- ----------
iterable : iterable/function with yield statement iterable : iterable/function with yield statement
Iterable (or function with yield statement) to be decorated. Iterable (or function with yield statement) to be decorated.
N_iter : int N_iter : int
Total # of iterations. Needed if number of iterations can not be obtained as len(iterable). Total # of iterations. Needed if number of iterations can not be obtained as len(iterable).
prefix : str, optional. prefix : str, optional.
Prefix string. Prefix string.
bar_length : int, optional bar_length : int, optional
Character length of bar. Defaults to 50. Character length of bar. Defaults to 50.
""" """
status = _ProgressBar(N_iter if N_iter else len(iterable),prefix,bar_length) status = _ProgressBar(N_iter if N_iter else len(iterable),prefix,bar_length)
@ -258,7 +258,7 @@ def scale_to_coprime(v):
return m//reduce(np.gcd,m) return m//reduce(np.gcd,m)
class return_message(): class return_message:
"""Object with formatted return message.""" """Object with formatted return message."""
def __init__(self,message): def __init__(self,message):
@ -268,7 +268,7 @@ class return_message():
Parameters Parameters
---------- ----------
message : str or list of str message : str or list of str
message for output to screen message for output to screen
""" """
self.message = message self.message = message

View File

@ -18,7 +18,7 @@ def default():
x=np.concatenate((np.ones(40,dtype=int), x=np.concatenate((np.ones(40,dtype=int),
np.arange(2,42), np.arange(2,42),
np.ones(40,dtype=int)*2, np.ones(40,dtype=int)*2,
np.arange(1,41))).reshape((8,5,4)) np.arange(1,41))).reshape(8,5,4)
return Geom(x,[8e-6,5e-6,4e-6]) return Geom(x,[8e-6,5e-6,4e-6])
@pytest.fixture @pytest.fixture

View File

@ -27,7 +27,7 @@ class TestResult:
def test_time_increments(self,default): def test_time_increments(self,default):
shape = default.read_dataset(default.get_dataset_location('F'),0).shape shape = default.read_dataset(default.get_dataset_location('F'),0).shape
default.set_by_time(0.0,20.0) default.set_by_time(0.0,20.0)
for i in default.iter_visible('increments'): for i in default.iterate('increments'):
assert shape == default.read_dataset(default.get_dataset_location('F'),0).shape assert shape == default.read_dataset(default.get_dataset_location('F'),0).shape
@ -61,7 +61,7 @@ class TestResult:
default.add_determinant('P') default.add_determinant('P')
loc = {'P': default.get_dataset_location('P'), loc = {'P': default.get_dataset_location('P'),
'det(P)':default.get_dataset_location('det(P)')} 'det(P)':default.get_dataset_location('det(P)')}
in_memory = np.linalg.det(default.read_dataset(loc['P'],0)).reshape((-1,1)) in_memory = np.linalg.det(default.read_dataset(loc['P'],0)).reshape(-1,1)
in_file = default.read_dataset(loc['det(P)'],0) in_file = default.read_dataset(loc['det(P)'],0)
assert np.allclose(in_memory,in_file) assert np.allclose(in_memory,in_file)

View File

@ -49,7 +49,7 @@ class TestTable:
def test_write_read_new_style(self,default,tmpdir): def test_write_read_new_style(self,default,tmpdir):
with open(tmpdir.join('new_style.txt'),'w') as f: with open(tmpdir.join('new_style.txt'),'w') as f:
default.to_ASCII(f,new=True) default.to_ASCII(f,new_style=True)
with open(tmpdir.join('new_style.txt')) as f: with open(tmpdir.join('new_style.txt')) as f:
new = Table.from_ASCII(f) new = Table.from_ASCII(f)
assert all(default.data==new.data) and default.shapes == new.shapes assert all(default.data==new.data) and default.shapes == new.shapes
@ -173,4 +173,4 @@ class TestTable:
['test data']) ['test data'])
t.add('s',np.array(['b','a'])) t.add('s',np.array(['b','a']))
t.sort_by('s') t.sort_by('s')
assert np.all(t.get('1_v') == np.array([2,0]).reshape((2,1))) assert np.all(t.get('1_v') == np.array([2,0]).reshape(2,1))

View File

@ -31,7 +31,7 @@ class TestGridFilters:
size = np.random.random(3) size = np.random.random(3)
origin = np.random.random(3) origin = np.random.random(3)
coord0 = eval('grid_filters.{}_coord0(grid,size,origin)'.format(mode)) # noqa coord0 = eval('grid_filters.{}_coord0(grid,size,origin)'.format(mode)) # noqa
_grid,_size,_origin = eval('grid_filters.{}_coord0_gridSizeOrigin(coord0.reshape((-1,3)))'.format(mode)) _grid,_size,_origin = eval('grid_filters.{}_coord0_gridSizeOrigin(coord0.reshape(-1,3))'.format(mode))
assert np.allclose(grid,_grid) and np.allclose(size,_size) and np.allclose(origin,_origin) assert np.allclose(grid,_grid) and np.allclose(size,_size) and np.allclose(origin,_origin)
def test_displacement_fluct_equivalence(self): def test_displacement_fluct_equivalence(self):

3
src/.gitignore vendored
View File

@ -1,4 +1 @@
Makefile
cmake_install.cmake
quit__genmod.f90
*.marc *.marc

View File

@ -9,13 +9,11 @@ file(GLOB damask-sources *.f90 *.c)
# probably we should have a subfolder for MSC.Marc # probably we should have a subfolder for MSC.Marc
list(FILTER damask-sources EXCLUDE REGEX ".*CPFEM.f90") list(FILTER damask-sources EXCLUDE REGEX ".*CPFEM.f90")
list(FILTER damask-sources EXCLUDE REGEX ".*DAMASK_marc.*.f90") list(FILTER damask-sources EXCLUDE REGEX ".*DAMASK_marc.*.f90")
list(FILTER damask-sources EXCLUDE REGEX ".*mesh_marc.*.f90")
list(FILTER damask-sources EXCLUDE REGEX ".*commercialFEM_fileList.*.f90") list(FILTER damask-sources EXCLUDE REGEX ".*commercialFEM_fileList.*.f90")
if (PROJECT_NAME STREQUAL "damask-grid") if (PROJECT_NAME STREQUAL "damask-grid")
list(FILTER damask-sources EXCLUDE REGEX ".*mesh_FEM.*.f90")
file(GLOB grid-sources grid/*.f90) file(GLOB grid-sources grid/*.f90)
if(NOT CMAKE_BUILD_TYPE STREQUAL "SYNTAXONLY") if(NOT CMAKE_BUILD_TYPE STREQUAL "SYNTAXONLY")
@ -30,7 +28,6 @@ if (PROJECT_NAME STREQUAL "damask-grid")
elseif (PROJECT_NAME STREQUAL "damask-mesh") elseif (PROJECT_NAME STREQUAL "damask-mesh")
list(FILTER damask-sources EXCLUDE REGEX ".*mesh_grid.*.f90")
file(GLOB mesh-sources mesh/*.f90) file(GLOB mesh-sources mesh/*.f90)
add_executable(DAMASK_FEM ${damask-sources} ${mesh-sources}) add_executable(DAMASK_FEM ${damask-sources} ${mesh-sources})

View File

@ -10,7 +10,7 @@ module CPFEM
use FEsolving use FEsolving
use math use math
use rotations use rotations
use mesh use discretization_marc
use material use material
use config use config
use crystallite use crystallite
@ -85,7 +85,7 @@ subroutine CPFEM_initAll(el,ip)
call rotations_init call rotations_init
call HDF5_utilities_init call HDF5_utilities_init
call results_init call results_init
call mesh_init(ip, el) call discretization_marc_init(ip, el)
call lattice_init call lattice_init
call material_init call material_init
call constitutive_init call constitutive_init
@ -126,208 +126,201 @@ end subroutine CPFEM_init
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
subroutine CPFEM_general(mode, parallelExecution, ffn, ffn1, temperature_inp, dt, elFE, ip, cauchyStress, jacobian) subroutine CPFEM_general(mode, parallelExecution, ffn, ffn1, temperature_inp, dt, elFE, ip, cauchyStress, jacobian)
integer(pInt), intent(in) :: elFE, & !< FE element number integer(pInt), intent(in) :: elFE, & !< FE element number
ip !< integration point number ip !< integration point number
real(pReal), intent(in) :: dt !< time increment real(pReal), intent(in) :: dt !< time increment
real(pReal), dimension (3,3), intent(in) :: ffn, & !< deformation gradient for t=t0 real(pReal), dimension (3,3), intent(in) :: ffn, & !< deformation gradient for t=t0
ffn1 !< deformation gradient for t=t1 ffn1 !< deformation gradient for t=t1
integer(pInt), intent(in) :: mode !< computation mode 1: regular computation plus aging of results integer(pInt), intent(in) :: mode !< computation mode 1: regular computation plus aging of results
real(pReal), intent(in) :: temperature_inp !< temperature real(pReal), intent(in) :: temperature_inp !< temperature
logical, intent(in) :: parallelExecution !< flag indicating parallel computation of requested IPs logical, intent(in) :: parallelExecution !< flag indicating parallel computation of requested IPs
real(pReal), dimension(6), intent(out) :: cauchyStress !< stress as 6 vector real(pReal), dimension(6), intent(out) :: cauchyStress !< stress as 6 vector
real(pReal), dimension(6,6), intent(out) :: jacobian !< jacobian as 66 tensor (Consistent tangent dcs/dE) real(pReal), dimension(6,6), intent(out) :: jacobian !< jacobian as 66 tensor (Consistent tangent dcs/dE)
real(pReal) J_inverse, & ! inverse of Jacobian real(pReal) J_inverse, & ! inverse of Jacobian
rnd rnd
real(pReal), dimension (3,3) :: Kirchhoff, & ! Piola-Kirchhoff stress in Matrix notation real(pReal), dimension (3,3) :: Kirchhoff, & ! Piola-Kirchhoff stress
cauchyStress33 ! stress vector in Matrix notation cauchyStress33 ! stress vector
real(pReal), dimension (3,3,3,3) :: H_sym, & real(pReal), dimension (3,3,3,3) :: H_sym, &
H, & H, &
jacobian3333 ! jacobian in Matrix notation jacobian3333 ! jacobian in Matrix notation
integer(pInt) elCP, & ! crystal plasticity element number integer(pInt) elCP, & ! crystal plasticity element number
i, j, k, l, m, n, ph, homog, mySource i, j, k, l, m, n, ph, homog, mySource
logical updateJaco ! flag indicating if Jacobian has to be updated logical updateJaco ! flag indicating if Jacobian has to be updated
real(pReal), parameter :: ODD_STRESS = 1e15_pReal, & !< return value for stress in case of ping pong dummy cycle real(pReal), parameter :: ODD_STRESS = 1e15_pReal, & !< return value for stress in case of ping pong dummy cycle
ODD_JACOBIAN = 1e50_pReal !< return value for jacobian in case of ping pong dummy cycle ODD_JACOBIAN = 1e50_pReal !< return value for jacobian in case of ping pong dummy cycle
elCP = mesh_FEM2DAMASK_elem(elFE) elCP = mesh_FEM2DAMASK_elem(elFE)
if (iand(debug_level(debug_CPFEM), debug_levelBasic) /= 0_pInt & if (iand(debug_level(debug_CPFEM), debug_levelBasic) /= 0_pInt &
.and. elCP == debug_e .and. ip == debug_i) then .and. elCP == debug_e .and. ip == debug_i) then
write(6,'(/,a)') '#############################################' write(6,'(/,a)') '#############################################'
write(6,'(a1,a22,1x,i8,a13)') '#','element', elCP, '#' write(6,'(a1,a22,1x,i8,a13)') '#','element', elCP, '#'
write(6,'(a1,a22,1x,i8,a13)') '#','ip', ip, '#' write(6,'(a1,a22,1x,i8,a13)') '#','ip', ip, '#'
write(6,'(a1,a22,1x,f15.7,a6)') '#','theTime', theTime, '#' write(6,'(a1,a22,1x,f15.7,a6)') '#','theTime', theTime, '#'
write(6,'(a1,a22,1x,f15.7,a6)') '#','theDelta', theDelta, '#' write(6,'(a1,a22,1x,f15.7,a6)') '#','theDelta', theDelta, '#'
write(6,'(a1,a22,1x,i8,a13)') '#','theInc', theInc, '#' write(6,'(a1,a22,1x,i8,a13)') '#','theInc', theInc, '#'
write(6,'(a1,a22,1x,i8,a13)') '#','cycleCounter', cycleCounter, '#' write(6,'(a1,a22,1x,i8,a13)') '#','cycleCounter', cycleCounter, '#'
write(6,'(a1,a22,1x,i8,a13)') '#','computationMode',mode, '#' write(6,'(a1,a22,1x,i8,a13)') '#','computationMode',mode, '#'
if (terminallyIll) & if (terminallyIll) &
write(6,'(a,/)') '# --- terminallyIll --- #' write(6,'(a,/)') '# --- terminallyIll --- #'
write(6,'(a,/)') '#############################################'; flush (6) write(6,'(a,/)') '#############################################'; flush (6)
endif endif
if (iand(mode, CPFEM_BACKUPJACOBIAN) /= 0_pInt) & if (iand(mode, CPFEM_BACKUPJACOBIAN) /= 0_pInt) &
CPFEM_dcsde_knownGood = CPFEM_dcsde CPFEM_dcsde_knownGood = CPFEM_dcsde
if (iand(mode, CPFEM_RESTOREJACOBIAN) /= 0_pInt) & if (iand(mode, CPFEM_RESTOREJACOBIAN) /= 0_pInt) &
CPFEM_dcsde = CPFEM_dcsde_knownGood CPFEM_dcsde = CPFEM_dcsde_knownGood
!*** age results !*** age results
if (iand(mode, CPFEM_AGERESULTS) /= 0_pInt) call CPFEM_forward if (iand(mode, CPFEM_AGERESULTS) /= 0_pInt) call CPFEM_forward
!*** collection of FEM input with returning of randomize odd stress and jacobian !*** collection of FEM input with returning of randomize odd stress and jacobian
!* If no parallel execution is required, there is no need to collect FEM input !* If no parallel execution is required, there is no need to collect FEM input
if (.not. parallelExecution) then
chosenThermal1: select case (thermal_type(material_homogenizationAt(elCP)))
case (THERMAL_conduction_ID) chosenThermal1
temperature(material_homogenizationAt(elCP))%p(thermalMapping(material_homogenizationAt(elCP))%p(ip,elCP)) = &
temperature_inp
end select chosenThermal1
materialpoint_F0(1:3,1:3,ip,elCP) = ffn
materialpoint_F(1:3,1:3,ip,elCP) = ffn1
if (.not. parallelExecution) then elseif (iand(mode, CPFEM_COLLECT) /= 0_pInt) then
chosenThermal1: select case (thermal_type(material_homogenizationAt(elCP))) call random_number(rnd)
case (THERMAL_conduction_ID) chosenThermal1 if (rnd < 0.5_pReal) rnd = rnd - 1.0_pReal
temperature(material_homogenizationAt(elCP))%p(thermalMapping(material_homogenizationAt(elCP))%p(ip,elCP)) = & CPFEM_cs(1:6,ip,elCP) = rnd * ODD_STRESS
temperature_inp CPFEM_dcsde(1:6,1:6,ip,elCP) = ODD_JACOBIAN * math_identity2nd(6)
end select chosenThermal1 chosenThermal2: select case (thermal_type(material_homogenizationAt(elCP)))
materialpoint_F0(1:3,1:3,ip,elCP) = ffn case (THERMAL_conduction_ID) chosenThermal2
materialpoint_F(1:3,1:3,ip,elCP) = ffn1 temperature(material_homogenizationAt(elCP))%p(thermalMapping(material_homogenizationAt(elCP))%p(ip,elCP)) = &
temperature_inp
elseif (iand(mode, CPFEM_COLLECT) /= 0_pInt) then end select chosenThermal2
call random_number(rnd) materialpoint_F0(1:3,1:3,ip,elCP) = ffn
if (rnd < 0.5_pReal) rnd = rnd - 1.0_pReal materialpoint_F(1:3,1:3,ip,elCP) = ffn1
CPFEM_cs(1:6,ip,elCP) = rnd * ODD_STRESS CPFEM_calc_done = .false.
CPFEM_dcsde(1:6,1:6,ip,elCP) = ODD_JACOBIAN * math_identity2nd(6) endif
chosenThermal2: select case (thermal_type(material_homogenizationAt(elCP)))
case (THERMAL_conduction_ID) chosenThermal2
temperature(material_homogenizationAt(elCP))%p(thermalMapping(material_homogenizationAt(elCP))%p(ip,elCP)) = &
temperature_inp
end select chosenThermal2
materialpoint_F0(1:3,1:3,ip,elCP) = ffn
materialpoint_F(1:3,1:3,ip,elCP) = ffn1
CPFEM_calc_done = .false.
endif ! collection
!*** calculation of stress and jacobian
if (iand(mode, CPFEM_CALCRESULTS) /= 0_pInt) then
!*** calculation of stress and jacobian !*** deformation gradient outdated or any actual deformation gradient differs more than relevantStrain from the stored one
validCalculation: if (terminallyIll &
.or. outdatedFFN1 &
.or. any(abs(ffn1 - materialpoint_F(1:3,1:3,ip,elCP)) > defgradTolerance)) then
if (any(abs(ffn1 - materialpoint_F(1:3,1:3,ip,elCP)) > defgradTolerance)) then
if (iand(debug_level(debug_CPFEM), debug_levelBasic) /= 0_pInt) then
write(6,'(a,1x,i8,1x,i2)') '<< CPFEM >> OUTDATED at elFE ip',elFE,ip
write(6,'(a,/,3(12x,3(f10.6,1x),/))') '<< CPFEM >> FFN1 old:',&
transpose(materialpoint_F(1:3,1:3,ip,elCP))
write(6,'(a,/,3(12x,3(f10.6,1x),/))') '<< CPFEM >> FFN1 now:',transpose(ffn1)
endif
outdatedFFN1 = .true.
endif
call random_number(rnd)
if (rnd < 0.5_pReal) rnd = rnd - 1.0_pReal
CPFEM_cs(1:6,ip,elCP) = ODD_STRESS * rnd
CPFEM_dcsde(1:6,1:6,ip,elCP) = ODD_JACOBIAN * math_identity2nd(6)
if (iand(mode, CPFEM_CALCRESULTS) /= 0_pInt) then !*** deformation gradient is not outdated
else validCalculation
updateJaco = mod(cycleCounter,iJacoStiffness) == 0
!* no parallel computation, so we use just one single elFE and ip for computation
if (.not. parallelExecution) then
FEsolving_execElem = elCP
FEsolving_execIP = ip
if (iand(debug_level(debug_CPFEM), debug_levelExtensive) /= 0_pInt) &
write(6,'(a,i8,1x,i2)') '<< CPFEM >> calculation for elFE ip ',elFE,ip
call materialpoint_stressAndItsTangent(updateJaco, dt)
!*** deformation gradient outdated or any actual deformation gradient differs more than relevantStrain from the stored one !* parallel computation and calulation not yet done
validCalculation: if (terminallyIll & elseif (.not. CPFEM_calc_done) then
.or. outdatedFFN1 & if (iand(debug_level(debug_CPFEM), debug_levelExtensive) /= 0_pInt) &
.or. any(abs(ffn1 - materialpoint_F(1:3,1:3,ip,elCP)) > defgradTolerance)) then write(6,'(a,i8,a,i8)') '<< CPFEM >> calculation for elements ',FEsolving_execElem(1),&
if (any(abs(ffn1 - materialpoint_F(1:3,1:3,ip,elCP)) > defgradTolerance)) then ' to ',FEsolving_execElem(2)
if (iand(debug_level(debug_CPFEM), debug_levelBasic) /= 0_pInt) then call materialpoint_stressAndItsTangent(updateJaco, dt)
write(6,'(a,1x,i8,1x,i2)') '<< CPFEM >> OUTDATED at elFE ip',elFE,ip CPFEM_calc_done = .true.
write(6,'(a,/,3(12x,3(f10.6,1x),/))') '<< CPFEM >> FFN1 old:',& endif
transpose(materialpoint_F(1:3,1:3,ip,elCP))
write(6,'(a,/,3(12x,3(f10.6,1x),/))') '<< CPFEM >> FFN1 now:',transpose(ffn1)
endif
outdatedFFN1 = .true.
endif
call random_number(rnd)
if (rnd < 0.5_pReal) rnd = rnd - 1.0_pReal
CPFEM_cs(1:6,ip,elCP) = ODD_STRESS * rnd
CPFEM_dcsde(1:6,1:6,ip,elCP) = ODD_JACOBIAN * math_identity2nd(6)
!*** deformation gradient is not outdated !* map stress and stiffness (or return odd values if terminally ill)
terminalIllness: if (terminallyIll) then
else validCalculation call random_number(rnd)
updateJaco = mod(cycleCounter,iJacoStiffness) == 0 if (rnd < 0.5_pReal) rnd = rnd - 1.0_pReal
!* no parallel computation, so we use just one single elFE and ip for computation CPFEM_cs(1:6,ip,elCP) = ODD_STRESS * rnd
CPFEM_dcsde(1:6,1:6,ip,elCP) = ODD_JACOBIAN * math_identity2nd(6)
if (.not. parallelExecution) then else terminalIllness
FEsolving_execElem = elCP
FEsolving_execIP = ip
if (iand(debug_level(debug_CPFEM), debug_levelExtensive) /= 0_pInt) &
write(6,'(a,i8,1x,i2)') '<< CPFEM >> calculation for elFE ip ',elFE,ip
call materialpoint_stressAndItsTangent(updateJaco, dt) ! calculate stress and its tangent
!* parallel computation and calulation not yet done ! translate from P to CS
Kirchhoff = matmul(materialpoint_P(1:3,1:3,ip,elCP), transpose(materialpoint_F(1:3,1:3,ip,elCP)))
J_inverse = 1.0_pReal / math_det33(materialpoint_F(1:3,1:3,ip,elCP))
CPFEM_cs(1:6,ip,elCP) = math_sym33to6(J_inverse * Kirchhoff,weighted=.false.)
elseif (.not. CPFEM_calc_done) then ! translate from dP/dF to dCS/dE
if (iand(debug_level(debug_CPFEM), debug_levelExtensive) /= 0_pInt) & H = 0.0_pReal
write(6,'(a,i8,a,i8)') '<< CPFEM >> calculation for elements ',FEsolving_execElem(1),& do i=1,3; do j=1,3; do k=1,3; do l=1,3; do m=1,3; do n=1,3
' to ',FEsolving_execElem(2) H(i,j,k,l) = H(i,j,k,l) &
call materialpoint_stressAndItsTangent(updateJaco, dt) ! calculate stress and its tangent (parallel execution inside) + materialpoint_F(j,m,ip,elCP) * materialpoint_F(l,n,ip,elCP) &
CPFEM_calc_done = .true. * materialpoint_dPdF(i,m,k,n,ip,elCP) &
endif - math_delta(j,l) * materialpoint_F(i,m,ip,elCP) * materialpoint_P(k,m,ip,elCP) &
+ 0.5_pReal * ( Kirchhoff(j,l)*math_delta(i,k) + Kirchhoff(i,k)*math_delta(j,l) &
+ Kirchhoff(j,k)*math_delta(i,l) + Kirchhoff(i,l)*math_delta(j,k))
enddo; enddo; enddo; enddo; enddo; enddo
!* map stress and stiffness (or return odd values if terminally ill) forall(i=1:3, j=1:3,k=1:3,l=1:3) &
terminalIllness: if ( terminallyIll ) then H_sym(i,j,k,l) = 0.25_pReal * (H(i,j,k,l) + H(j,i,k,l) + H(i,j,l,k) + H(j,i,l,k))
call random_number(rnd) CPFEM_dcsde(1:6,1:6,ip,elCP) = math_sym3333to66(J_inverse * H_sym,weighted=.false.)
if (rnd < 0.5_pReal) rnd = rnd - 1.0_pReal
CPFEM_cs(1:6,ip,elCP) = ODD_STRESS * rnd
CPFEM_dcsde(1:6,1:6,ip,elCP) = ODD_JACOBIAN * math_identity2nd(6)
else terminalIllness endif terminalIllness
endif validCalculation
!* report stress and stiffness
if ((iand(debug_level(debug_CPFEM), debug_levelExtensive) /= 0_pInt) &
.and. ((debug_e == elCP .and. debug_i == ip) &
.or. .not. iand(debug_level(debug_CPFEM), debug_levelSelective) /= 0_pInt)) then
write(6,'(a,i8,1x,i2,/,12x,6(f10.3,1x)/)') &
'<< CPFEM >> stress/MPa at elFE ip ', elFE, ip, CPFEM_cs(1:6,ip,elCP)*1.0e-6_pReal
write(6,'(a,i8,1x,i2,/,6(12x,6(f10.3,1x)/))') &
'<< CPFEM >> Jacobian/GPa at elFE ip ', elFE, ip, transpose(CPFEM_dcsdE(1:6,1:6,ip,elCP))*1.0e-9_pReal
flush(6)
endif
endif
!*** warn if stiffness close to zero
if (all(abs(CPFEM_dcsdE(1:6,1:6,ip,elCP)) < 1e-10_pReal)) call IO_warning(601,elCP,ip)
!*** copy to output if using commercial FEM solver
cauchyStress = CPFEM_cs (1:6, ip,elCP)
jacobian = CPFEM_dcsdE(1:6,1:6,ip,elCP)
! translate from P to CS !*** remember extreme values of stress ...
Kirchhoff = matmul(materialpoint_P(1:3,1:3,ip,elCP), transpose(materialpoint_F(1:3,1:3,ip,elCP))) cauchyStress33 = math_6toSym33(CPFEM_cs(1:6,ip,elCP),weighted=.false.)
J_inverse = 1.0_pReal / math_det33(materialpoint_F(1:3,1:3,ip,elCP)) if (maxval(cauchyStress33) > debug_stressMax) then
CPFEM_cs(1:6,ip,elCP) = math_sym33to6(J_inverse * Kirchhoff,weighted=.false.) debug_stressMaxLocation = [elCP, ip]
debug_stressMax = maxval(cauchyStress33)
! translate from dP/dF to dCS/dE endif
H = 0.0_pReal if (minval(cauchyStress33) < debug_stressMin) then
do i=1,3; do j=1,3; do k=1,3; do l=1,3; do m=1,3; do n=1,3 debug_stressMinLocation = [elCP, ip]
H(i,j,k,l) = H(i,j,k,l) & debug_stressMin = minval(cauchyStress33)
+ materialpoint_F(j,m,ip,elCP) * materialpoint_F(l,n,ip,elCP) & endif
* materialpoint_dPdF(i,m,k,n,ip,elCP) & !*** ... and Jacobian
- math_delta(j,l) * materialpoint_F(i,m,ip,elCP) * materialpoint_P(k,m,ip,elCP) & jacobian3333 = math_66toSym3333(CPFEM_dcsdE(1:6,1:6,ip,elCP),weighted=.false.)
+ 0.5_pReal * ( Kirchhoff(j,l)*math_delta(i,k) + Kirchhoff(i,k)*math_delta(j,l) & if (maxval(jacobian3333) > debug_jacobianMax) then
+ Kirchhoff(j,k)*math_delta(i,l) + Kirchhoff(i,l)*math_delta(j,k)) debug_jacobianMaxLocation = [elCP, ip]
enddo; enddo; enddo; enddo; enddo; enddo debug_jacobianMax = maxval(jacobian3333)
endif
forall(i=1:3, j=1:3,k=1:3,l=1:3) & if (minval(jacobian3333) < debug_jacobianMin) then
H_sym(i,j,k,l) = 0.25_pReal * (H(i,j,k,l) + H(j,i,k,l) + H(i,j,l,k) + H(j,i,l,k)) debug_jacobianMinLocation = [elCP, ip]
debug_jacobianMin = minval(jacobian3333)
CPFEM_dcsde(1:6,1:6,ip,elCP) = math_sym3333to66(J_inverse * H_sym,weighted=.false.) endif
endif terminalIllness
endif validCalculation
!* report stress and stiffness
if ((iand(debug_level(debug_CPFEM), debug_levelExtensive) /= 0_pInt) &
.and. ((debug_e == elCP .and. debug_i == ip) &
.or. .not. iand(debug_level(debug_CPFEM), debug_levelSelective) /= 0_pInt)) then
write(6,'(a,i8,1x,i2,/,12x,6(f10.3,1x)/)') &
'<< CPFEM >> stress/MPa at elFE ip ', elFE, ip, CPFEM_cs(1:6,ip,elCP)*1.0e-6_pReal
write(6,'(a,i8,1x,i2,/,6(12x,6(f10.3,1x)/))') &
'<< CPFEM >> Jacobian/GPa at elFE ip ', elFE, ip, transpose(CPFEM_dcsdE(1:6,1:6,ip,elCP))*1.0e-9_pReal
flush(6)
endif
endif
!*** warn if stiffness close to zero
if (all(abs(CPFEM_dcsdE(1:6,1:6,ip,elCP)) < 1e-10_pReal)) call IO_warning(601,elCP,ip)
!*** copy to output if using commercial FEM solver
cauchyStress = CPFEM_cs (1:6, ip,elCP)
jacobian = CPFEM_dcsdE(1:6,1:6,ip,elCP)
!*** remember extreme values of stress ...
cauchyStress33 = math_6toSym33(CPFEM_cs(1:6,ip,elCP),weighted=.false.)
if (maxval(cauchyStress33) > debug_stressMax) then
debug_stressMaxLocation = [elCP, ip]
debug_stressMax = maxval(cauchyStress33)
endif
if (minval(cauchyStress33) < debug_stressMin) then
debug_stressMinLocation = [elCP, ip]
debug_stressMin = minval(cauchyStress33)
endif
!*** ... and Jacobian
jacobian3333 = math_66toSym3333(CPFEM_dcsdE(1:6,1:6,ip,elCP),weighted=.false.)
if (maxval(jacobian3333) > debug_jacobianMax) then
debug_jacobianMaxLocation = [elCP, ip]
debug_jacobianMax = maxval(jacobian3333)
endif
if (minval(jacobian3333) < debug_jacobianMin) then
debug_jacobianMinLocation = [elCP, ip]
debug_jacobianMin = minval(jacobian3333)
endif
end subroutine CPFEM_general end subroutine CPFEM_general

View File

@ -21,11 +21,11 @@ module CPFEM2
use homogenization use homogenization
use constitutive use constitutive
use crystallite use crystallite
#ifdef FEM #if defined(FEM)
use FEM_Zoo use FEM_quadrature
use mesh use discretization_mesh
#else #elif defined(Grid)
use mesh_grid use discretization_grid
#endif #endif
implicit none implicit none
@ -43,7 +43,7 @@ subroutine CPFEM_initAll
call prec_init call prec_init
call IO_init call IO_init
#ifdef FEM #ifdef FEM
call FEM_Zoo_init call FEM_quadrature_init
#endif #endif
call numerics_init call numerics_init
call debug_init call debug_init
@ -53,7 +53,11 @@ subroutine CPFEM_initAll
call lattice_init call lattice_init
call HDF5_utilities_init call HDF5_utilities_init
call results_init call results_init
call mesh_init #if defined(FEM)
call discretization_mesh_init
#elif defined(Grid)
call discretization_grid_init
#endif
call material_init call material_init
call constitutive_init call constitutive_init
call crystallite_init call crystallite_init
@ -68,7 +72,7 @@ end subroutine CPFEM_initAll
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
subroutine CPFEM_init subroutine CPFEM_init
write(6,'(/,a)') ' <<<+- CPFEM init -+>>>'; flush(6) write(6,'(/,a)') ' <<<+- CPFEM init -+>>>'; flush(6)
if (interface_restartInc > 0) call crystallite_restartRead if (interface_restartInc > 0) call crystallite_restartRead

View File

@ -178,7 +178,7 @@ subroutine hypela2(d,g,e,de,s,t,dt,ngens,m,nn,kcus,matus,ndi,nshear,disp, &
use numerics use numerics
use FEsolving use FEsolving
use debug use debug
use mesh use discretization_marc
use CPFEM use CPFEM
implicit none implicit none
@ -233,8 +233,8 @@ subroutine hypela2(d,g,e,de,s,t,dt,ngens,m,nn,kcus,matus,ndi,nshear,disp, &
! Marc common blocks are in fixed format so they have to be reformated to free format (f90) ! Marc common blocks are in fixed format so they have to be reformated to free format (f90)
! Beware of changes in newer Marc versions ! Beware of changes in newer Marc versions
#include QUOTE(PASTE(./MarcInclude/concom,Marc4DAMASK)) ! concom is needed for inc, lovl #include QUOTE(PASTE(./marc/include/concom,Marc4DAMASK)) ! concom is needed for inc, lovl
#include QUOTE(PASTE(./MarcInclude/creeps,Marc4DAMASK)) ! creeps is needed for timinc (time increment) #include QUOTE(PASTE(./marc/include/creeps,Marc4DAMASK)) ! creeps is needed for timinc (time increment)
logical :: cutBack logical :: cutBack
real(pReal), dimension(6) :: stress real(pReal), dimension(6) :: stress
@ -378,7 +378,7 @@ end subroutine hypela2
subroutine flux(f,ts,n,time) subroutine flux(f,ts,n,time)
use prec use prec
use thermal_conduction use thermal_conduction
use mesh use discretization_marc
implicit none implicit none
real(pReal), dimension(6), intent(in) :: & real(pReal), dimension(6), intent(in) :: &
@ -408,7 +408,7 @@ subroutine uedinc(inc,incsub)
implicit none implicit none
integer, intent(in) :: inc, incsub integer, intent(in) :: inc, incsub
integer, save :: inc_written integer, save :: inc_written
#include QUOTE(PASTE(./MarcInclude/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
call CPFEM_results(inc,cptim) call CPFEM_results(inc,cptim)

View File

@ -525,10 +525,10 @@ end subroutine HDF5_setLink
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
subroutine HDF5_read_real1(loc_id,dataset,datasetName,parallel) subroutine HDF5_read_real1(loc_id,dataset,datasetName,parallel)
real(pReal), intent(inout), dimension(:) :: dataset real(pReal), intent(out), dimension(:) :: dataset !< data read from 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 logical, intent(in), optional :: parallel !< dataset is distributed over multiple processes
integer(HID_T) :: dset_id, filespace_id, memspace_id, plist_id, aplist_id integer(HID_T) :: dset_id, filespace_id, memspace_id, plist_id, aplist_id
integer(HSIZE_T), dimension(size(shape(dataset))) :: & ! ToDo: Fortran 2018 size(shape(A)) = rank(A) integer(HSIZE_T), dimension(size(shape(dataset))) :: & ! ToDo: Fortran 2018 size(shape(A)) = rank(A)
@ -565,10 +565,10 @@ end subroutine HDF5_read_real1
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
subroutine HDF5_read_real2(loc_id,dataset,datasetName,parallel) subroutine HDF5_read_real2(loc_id,dataset,datasetName,parallel)
real(pReal), intent(inout), dimension(:,:) :: dataset real(pReal), intent(out), dimension(:,:) :: dataset !< data read from 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 logical, intent(in), optional :: parallel !< dataset is distributed over multiple processes
integer(HID_T) :: dset_id, filespace_id, memspace_id, plist_id, aplist_id integer(HID_T) :: dset_id, filespace_id, memspace_id, plist_id, aplist_id
integer(HSIZE_T), dimension(size(shape(dataset))) :: & integer(HSIZE_T), dimension(size(shape(dataset))) :: &
@ -605,10 +605,10 @@ end subroutine HDF5_read_real2
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
subroutine HDF5_read_real3(loc_id,dataset,datasetName,parallel) subroutine HDF5_read_real3(loc_id,dataset,datasetName,parallel)
real(pReal), intent(inout), dimension(:,:,:) :: dataset real(pReal), intent(out), dimension(:,:,:) :: dataset !< data read from 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 logical, intent(in), optional :: parallel !< dataset is distributed over multiple processes
integer(HID_T) :: dset_id, filespace_id, memspace_id, plist_id, aplist_id integer(HID_T) :: dset_id, filespace_id, memspace_id, plist_id, aplist_id
integer(HSIZE_T), dimension(size(shape(dataset))) :: & integer(HSIZE_T), dimension(size(shape(dataset))) :: &
@ -645,10 +645,10 @@ end subroutine HDF5_read_real3
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
subroutine HDF5_read_real4(loc_id,dataset,datasetName,parallel) subroutine HDF5_read_real4(loc_id,dataset,datasetName,parallel)
real(pReal), intent(inout), dimension(:,:,:,:) :: dataset real(pReal), intent(out), dimension(:,:,:,:) :: dataset !< read data
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 logical, intent(in), optional :: parallel !< dataset is distributed over multiple processes
integer(HID_T) :: dset_id, filespace_id, memspace_id, plist_id, aplist_id integer(HID_T) :: dset_id, filespace_id, memspace_id, plist_id, aplist_id
integer(HSIZE_T), dimension(size(shape(dataset))) :: & integer(HSIZE_T), dimension(size(shape(dataset))) :: &
@ -685,10 +685,10 @@ end subroutine HDF5_read_real4
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
subroutine HDF5_read_real5(loc_id,dataset,datasetName,parallel) subroutine HDF5_read_real5(loc_id,dataset,datasetName,parallel)
real(pReal), intent(inout), dimension(:,:,:,:,:) :: dataset real(pReal), intent(out), dimension(:,:,:,:,:) :: dataset !< data read from 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 logical, intent(in), optional :: parallel !< dataset is distributed over multiple processes
integer(HID_T) :: dset_id, filespace_id, memspace_id, plist_id, aplist_id integer(HID_T) :: dset_id, filespace_id, memspace_id, plist_id, aplist_id
integer(HSIZE_T), dimension(size(shape(dataset))) :: & integer(HSIZE_T), dimension(size(shape(dataset))) :: &
@ -725,10 +725,10 @@ end subroutine HDF5_read_real5
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
subroutine HDF5_read_real6(loc_id,dataset,datasetName,parallel) subroutine HDF5_read_real6(loc_id,dataset,datasetName,parallel)
real(pReal), intent(inout), dimension(:,:,:,:,:,:) :: dataset real(pReal), intent(out), dimension(:,:,:,:,:,:) :: dataset !< data read from 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 logical, intent(in), optional :: parallel !< dataset is distributed over multiple processes
integer(HID_T) :: dset_id, filespace_id, memspace_id, plist_id, aplist_id integer(HID_T) :: dset_id, filespace_id, memspace_id, plist_id, aplist_id
integer(HSIZE_T), dimension(size(shape(dataset))) :: & integer(HSIZE_T), dimension(size(shape(dataset))) :: &
@ -765,10 +765,10 @@ end subroutine HDF5_read_real6
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
subroutine HDF5_read_real7(loc_id,dataset,datasetName,parallel) subroutine HDF5_read_real7(loc_id,dataset,datasetName,parallel)
real(pReal), intent(inout), dimension(:,:,:,:,:,:,:) :: dataset real(pReal), intent(out), dimension(:,:,:,:,:,:,:) :: dataset !< data read from 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 logical, intent(in), optional :: parallel !< dataset is distributed over multiple processes
integer(HID_T) :: dset_id, filespace_id, memspace_id, plist_id, aplist_id integer(HID_T) :: dset_id, filespace_id, memspace_id, plist_id, aplist_id
integer(HSIZE_T), dimension(size(shape(dataset))) :: & integer(HSIZE_T), dimension(size(shape(dataset))) :: &
@ -806,10 +806,11 @@ end subroutine HDF5_read_real7
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
subroutine HDF5_read_int1(loc_id,dataset,datasetName,parallel) subroutine HDF5_read_int1(loc_id,dataset,datasetName,parallel)
integer, intent(inout), dimension(:) :: dataset integer, intent(out), dimension(:) :: dataset !< data read from 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 logical, intent(in), optional :: parallel !< dataset is distributed over multiple processes
integer(HID_T) :: dset_id, filespace_id, memspace_id, plist_id, aplist_id integer(HID_T) :: dset_id, filespace_id, memspace_id, plist_id, aplist_id
integer(HSIZE_T), dimension(size(shape(dataset))) :: & integer(HSIZE_T), dimension(size(shape(dataset))) :: &
@ -846,10 +847,10 @@ end subroutine HDF5_read_int1
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
subroutine HDF5_read_int2(loc_id,dataset,datasetName,parallel) subroutine HDF5_read_int2(loc_id,dataset,datasetName,parallel)
integer, intent(inout), dimension(:,:) :: dataset integer, intent(out), dimension(:,:) :: dataset !< data read from 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 logical, intent(in), optional :: parallel !< dataset is distributed over multiple processes
integer(HID_T) :: dset_id, filespace_id, memspace_id, plist_id, aplist_id integer(HID_T) :: dset_id, filespace_id, memspace_id, plist_id, aplist_id
integer(HSIZE_T), dimension(size(shape(dataset))) :: & integer(HSIZE_T), dimension(size(shape(dataset))) :: &
@ -886,10 +887,10 @@ end subroutine HDF5_read_int2
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
subroutine HDF5_read_int3(loc_id,dataset,datasetName,parallel) subroutine HDF5_read_int3(loc_id,dataset,datasetName,parallel)
integer, intent(inout), dimension(:,:,:) :: dataset integer, intent(out), dimension(:,:,:) :: dataset !< data read from 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 logical, intent(in), optional :: parallel !< dataset is distributed over multiple processes
integer(HID_T) :: dset_id, filespace_id, memspace_id, plist_id, aplist_id integer(HID_T) :: dset_id, filespace_id, memspace_id, plist_id, aplist_id
integer(HSIZE_T), dimension(size(shape(dataset))) :: & integer(HSIZE_T), dimension(size(shape(dataset))) :: &
@ -926,10 +927,10 @@ end subroutine HDF5_read_int3
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
subroutine HDF5_read_int4(loc_id,dataset,datasetName,parallel) subroutine HDF5_read_int4(loc_id,dataset,datasetName,parallel)
integer, intent(inout), dimension(:,:,:,:) :: dataset integer, intent(out), dimension(:,:,:,:) :: dataset !< data read from 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 logical, intent(in), optional :: parallel !< dataset is distributed over multiple processes
integer(HID_T) :: dset_id, filespace_id, memspace_id, plist_id, aplist_id integer(HID_T) :: dset_id, filespace_id, memspace_id, plist_id, aplist_id
integer(HSIZE_T), dimension(size(shape(dataset))) :: & integer(HSIZE_T), dimension(size(shape(dataset))) :: &
@ -966,10 +967,10 @@ end subroutine HDF5_read_int4
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
subroutine HDF5_read_int5(loc_id,dataset,datasetName,parallel) subroutine HDF5_read_int5(loc_id,dataset,datasetName,parallel)
integer, intent(inout), dimension(:,:,:,:,:) :: dataset integer, intent(out), dimension(:,:,:,:,:) :: dataset !< data read from 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 logical, intent(in), optional :: parallel !< dataset is distributed over multiple processes
integer(HID_T) :: dset_id, filespace_id, memspace_id, plist_id, aplist_id integer(HID_T) :: dset_id, filespace_id, memspace_id, plist_id, aplist_id
integer(HSIZE_T), dimension(size(shape(dataset))) :: & integer(HSIZE_T), dimension(size(shape(dataset))) :: &
@ -1006,10 +1007,10 @@ end subroutine HDF5_read_int5
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
subroutine HDF5_read_int6(loc_id,dataset,datasetName,parallel) subroutine HDF5_read_int6(loc_id,dataset,datasetName,parallel)
integer, intent(inout), dimension(:,:,:,:,:,:) :: dataset integer, intent(out), dimension(:,:,:,:,:,:) :: dataset !< data read from 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 logical, intent(in), optional :: parallel !< dataset is distributed over multiple processes
integer(HID_T) :: dset_id, filespace_id, memspace_id, plist_id, aplist_id integer(HID_T) :: dset_id, filespace_id, memspace_id, plist_id, aplist_id
integer(HSIZE_T), dimension(size(shape(dataset))) :: & integer(HSIZE_T), dimension(size(shape(dataset))) :: &
@ -1046,10 +1047,10 @@ end subroutine HDF5_read_int6
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
subroutine HDF5_read_int7(loc_id,dataset,datasetName,parallel) subroutine HDF5_read_int7(loc_id,dataset,datasetName,parallel)
integer, intent(inout), dimension(:,:,:,:,:,:,:) :: dataset integer, intent(out), dimension(:,:,:,:,:,:,:) :: dataset !< data read from 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 logical, intent(in), optional :: parallel !< dataset is distributed over multiple processes
integer(HID_T) :: dset_id, filespace_id, memspace_id, plist_id, aplist_id integer(HID_T) :: dset_id, filespace_id, memspace_id, plist_id, aplist_id
integer(HSIZE_T), dimension(size(shape(dataset))) :: & integer(HSIZE_T), dimension(size(shape(dataset))) :: &
@ -1087,10 +1088,10 @@ 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 real(pReal), intent(inout), 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 logical, intent(in), optional :: parallel !< dataset is distributed over multiple processes
integer :: hdferr integer :: hdferr
@ -1128,10 +1129,10 @@ 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 real(pReal), intent(inout), 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 logical, intent(in), optional :: parallel !< dataset is distributed over multiple processes
integer :: hdferr integer :: hdferr
@ -1169,10 +1170,10 @@ 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 real(pReal), intent(inout), 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 logical, intent(in), optional :: parallel !< dataset is distributed over multiple processes
integer :: hdferr integer :: hdferr
@ -1210,10 +1211,10 @@ 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 real(pReal), intent(inout), 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 logical, intent(in), optional :: parallel !< dataset is distributed over multiple processes
integer :: hdferr integer :: hdferr
@ -1252,10 +1253,10 @@ 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 real(pReal), intent(inout), 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 logical, intent(in), optional :: parallel !< dataset is distributed over multiple processes
integer :: hdferr integer :: hdferr
@ -1293,10 +1294,10 @@ 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 real(pReal), intent(inout), 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 logical, intent(in), optional :: parallel !< dataset is distributed over multiple processes
integer :: hdferr integer :: hdferr
@ -1334,10 +1335,10 @@ 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 real(pReal), intent(inout), 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 logical, intent(in), optional :: parallel !< dataset is distributed over multiple processes
integer :: hdferr integer :: hdferr
@ -1376,10 +1377,10 @@ 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 integer, intent(inout), 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 logical, intent(in), optional :: parallel !< dataset is distributed over multiple processes
integer :: hdferr integer :: hdferr
@ -1417,10 +1418,10 @@ 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 integer, intent(inout), 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 logical, intent(in), optional :: parallel !< dataset is distributed over multiple processes
integer :: hdferr integer :: hdferr
@ -1458,10 +1459,10 @@ 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 integer, intent(inout), 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 logical, intent(in), optional :: parallel !< dataset is distributed over multiple processes
integer :: hdferr integer :: hdferr
@ -1499,10 +1500,10 @@ 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 integer, intent(inout), 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 logical, intent(in), optional :: parallel !< dataset is distributed over multiple processes
integer :: hdferr integer :: hdferr
@ -1540,10 +1541,10 @@ 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 integer, intent(inout), 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 logical, intent(in), optional :: parallel !< dataset is distributed over multiple processes
integer :: hdferr integer :: hdferr
@ -1581,10 +1582,10 @@ 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 integer, intent(inout), 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 logical, intent(in), optional :: parallel !< dataset is distributed over multiple processes
integer :: hdferr integer :: hdferr
@ -1622,10 +1623,10 @@ 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 integer, intent(inout), 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 logical, intent(in), optional :: parallel !< dataset is distributed over multiple processes
integer :: hdferr integer :: hdferr
@ -1666,7 +1667,7 @@ end subroutine HDF5_write_int7
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
subroutine HDF5_write_rotation(loc_id,dataset,datasetName,parallel) subroutine HDF5_write_rotation(loc_id,dataset,datasetName,parallel)
type(rotation), intent(in), dimension(:) :: dataset type(rotation), 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 logical, intent(in), optional :: parallel

View File

@ -7,14 +7,15 @@
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
module IO module IO
use prec use prec
use DAMASK_interface
implicit none implicit none
private private
character(len=*), parameter, public :: & character(len=*), parameter, public :: &
IO_EOF = '#EOF#' !< end of file string IO_EOF = '#EOF#', & !< end of file string
IO_WHITESPACE = achar(44)//achar(32)//achar(9)//achar(10)//achar(13) !< whitespace characters
character, parameter, public :: & character, parameter, public :: &
IO_EOL = new_line(' ') !< end of line str IO_EOL = new_line('DAMASK'), & !< end of line character
IO_COMMENT = '#'
character(len=*), parameter, private :: & character(len=*), parameter, private :: &
IO_DIVIDER = '───────────────────'//& IO_DIVIDER = '───────────────────'//&
'───────────────────'//& '───────────────────'//&
@ -23,7 +24,7 @@ module IO
public :: & public :: &
IO_init, & IO_init, &
IO_read_ASCII, & IO_read_ASCII, &
IO_open_jobFile_binary, & IO_open_binary, &
IO_isBlank, & IO_isBlank, &
IO_getTag, & IO_getTag, &
IO_stringPos, & IO_stringPos, &
@ -43,6 +44,7 @@ contains
subroutine IO_init subroutine IO_init
write(6,'(/,a)') ' <<<+- IO init -+>>>'; flush(6) write(6,'(/,a)') ' <<<+- IO init -+>>>'; flush(6)
call unitTest call unitTest
end subroutine IO_init end subroutine IO_init
@ -114,24 +116,6 @@ function IO_read_ASCII(fileName) result(fileContent)
end function IO_read_ASCII end function IO_read_ASCII
!--------------------------------------------------------------------------------------------------
!> @brief opens an existing file for reading or a new file for writing. Name is the job name
!> @details replaces an existing file when writing
!--------------------------------------------------------------------------------------------------
integer function IO_open_jobFile_binary(extension,mode)
character(len=*), intent(in) :: extension
character, intent(in), optional :: mode
if (present(mode)) then
IO_open_jobFile_binary = IO_open_binary(trim(getSolverJobName())//'.'//trim(extension),mode)
else
IO_open_jobFile_binary = IO_open_binary(trim(getSolverJobName())//'.'//trim(extension))
endif
end function IO_open_jobFile_binary
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief opens an existing file for reading or a new file for writing. !> @brief opens an existing file for reading or a new file for writing.
!> @details replaces an existing file when writing !> @details replaces an existing file when writing
@ -172,14 +156,10 @@ logical pure function IO_isBlank(string)
character(len=*), intent(in) :: string !< string to check for content character(len=*), intent(in) :: string !< string to check for content
character(len=*), parameter :: blankChar = achar(32)//achar(9)//achar(10)//achar(13) ! whitespaces integer :: posNonBlank
character(len=*), parameter :: comment = achar(35) ! comment id '#'
integer :: posNonBlank, posComment posNonBlank = verify(string,IO_WHITESPACE)
IO_isBlank = posNonBlank == 0 .or. posNonBlank == scan(string,IO_COMMENT)
posNonBlank = verify(string,blankChar)
posComment = scan(string,comment)
IO_isBlank = posNonBlank == 0 .or. posNonBlank == posComment
end function IO_isBlank end function IO_isBlank
@ -194,18 +174,14 @@ pure function IO_getTag(string,openChar,closeChar)
closeChar !< indicates end of tag closeChar !< indicates end of tag
character(len=:), allocatable :: IO_getTag character(len=:), allocatable :: IO_getTag
character(len=*), parameter :: SEP=achar(32)//achar(9)//achar(10)//achar(13) ! whitespaces
integer :: left,right integer :: left,right
if (openChar /= closeChar) then left = scan(string,openChar)
left = scan(string,openChar) right = merge(scan(string,closeChar), &
right = scan(string,closeChar) left + merge(scan(string(left+1:),openChar),0,len(string) > left), &
else openChar /= closeChar)
left = scan(string,openChar)
right = left + merge(scan(string(left+1:),openChar),0,len(string) > left)
endif
foundTag: if (left == verify(string,SEP) .and. right > left) then foundTag: if (left == verify(string,IO_WHITESPACE) .and. right > left) then
IO_getTag = string(left+1:right-1) IO_getTag = string(left+1:right-1)
else foundTag else foundTag
IO_getTag = '' IO_getTag = ''
@ -215,8 +191,8 @@ end function IO_getTag
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief locates all space-separated chunks in given string and returns array containing number !> @brief locates all whitespace-separated chunks in given string and returns array containing
!! them and the left/right position to be used by IO_xxxVal !! number them and the left/right position to be used by IO_xxxVal
!! Array size is dynamically adjusted to number of chunks found in string !! Array size is dynamically adjusted to number of chunks found in string
!! IMPORTANT: first element contains number of chunks! !! IMPORTANT: first element contains number of chunks!
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
@ -225,16 +201,15 @@ pure function IO_stringPos(string)
character(len=*), intent(in) :: string !< string in which chunk positions are searched for character(len=*), intent(in) :: string !< string in which chunk positions are searched for
integer, dimension(:), allocatable :: IO_stringPos integer, dimension(:), allocatable :: IO_stringPos
character(len=*), parameter :: SEP=achar(44)//achar(32)//achar(9)//achar(10)//achar(13) ! comma and whitespaces
integer :: left, right integer :: left, right
allocate(IO_stringPos(1), source=0) allocate(IO_stringPos(1), source=0)
right = 0 right = 0
do while (verify(string(right+1:),SEP)>0) do while (verify(string(right+1:),IO_WHITESPACE)>0)
left = right + verify(string(right+1:),SEP) left = right + verify(string(right+1:),IO_WHITESPACE)
right = left + scan(string(left:),SEP) - 2 right = left + scan(string(left:),IO_WHITESPACE) - 2
if ( string(left:left) == '#' ) exit if ( string(left:left) == IO_COMMENT) exit
IO_stringPos = [IO_stringPos,left,right] IO_stringPos = [IO_stringPos,left,right]
IO_stringPos(1) = IO_stringPos(1)+1 IO_stringPos(1) = IO_stringPos(1)+1
endOfString: if (right < left) then endOfString: if (right < left) then
@ -677,7 +652,7 @@ end function verifyFloatValue
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief check correctness of IO functions !> @brief check correctness of some IO functions
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
subroutine unitTest subroutine unitTest
@ -704,6 +679,10 @@ subroutine unitTest
chunkPos = IO_stringPos(str) chunkPos = IO_stringPos(str)
if(3112019 /= IO_intValue(str,chunkPos,2)) call IO_error(0,ext_msg='IO_intValue') if(3112019 /= IO_intValue(str,chunkPos,2)) call IO_error(0,ext_msg='IO_intValue')
if(.not. IO_isBlank(' ')) call IO_error(0,ext_msg='IO_isBlank/1')
if(.not. IO_isBlank(' #isBlank')) call IO_error(0,ext_msg='IO_isBlank/2')
if( IO_isBlank(' i#s')) call IO_error(0,ext_msg='IO_isBlank/3')
end subroutine unitTest end subroutine unitTest
end module IO end module IO

View File

@ -20,7 +20,7 @@
#include "geometry_plastic_nonlocal.f90" #include "geometry_plastic_nonlocal.f90"
#include "discretization.f90" #include "discretization.f90"
#ifdef Marc4DAMASK #ifdef Marc4DAMASK
#include "mesh_marc.f90" #include "marc/discretization_marc.f90"
#endif #endif
#include "material.f90" #include "material.f90"
#include "lattice.f90" #include "lattice.f90"

View File

@ -132,7 +132,7 @@ contains
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
recursive function read_materialConfig(fileName,cnt) result(fileContent) recursive function read_materialConfig(fileName,cnt) result(fileContent)
character(len=*), intent(in) :: fileName character(len=*), intent(in) :: fileName !< name of the material configuration file
integer, intent(in), optional :: cnt !< recursion counter integer, intent(in), optional :: cnt !< recursion counter
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), dimension(:), allocatable :: includedContent character(len=pStringLen), dimension(:), allocatable :: includedContent

View File

@ -126,8 +126,8 @@ module constitutive
of of
end subroutine plastic_disloUCLA_LpAndItsTangent end subroutine plastic_disloUCLA_LpAndItsTangent
module subroutine plastic_nonlocal_LpAndItsTangent(Lp, dLp_dMp, & module subroutine plastic_nonlocal_LpAndItsTangent(Lp,dLp_dMp, &
Mp, Temperature, volume, ip, el) Mp,Temperature,instance,of,ip,el)
real(pReal), dimension(3,3), intent(out) :: & real(pReal), dimension(3,3), intent(out) :: &
Lp !< plastic velocity gradient Lp !< plastic velocity gradient
real(pReal), dimension(3,3,3,3), intent(out) :: & real(pReal), dimension(3,3,3,3), intent(out) :: &
@ -136,9 +136,10 @@ module constitutive
real(pReal), dimension(3,3), intent(in) :: & real(pReal), dimension(3,3), intent(in) :: &
Mp !< Mandel stress Mp !< Mandel stress
real(pReal), intent(in) :: & real(pReal), intent(in) :: &
Temperature, & Temperature
volume integer, intent(in) :: &
integer, intent(in) :: & instance, &
of, &
ip, & !< current integration point ip, & !< current integration point
el !< current element number el !< current element number
end subroutine plastic_nonlocal_LpAndItsTangent end subroutine plastic_nonlocal_LpAndItsTangent
@ -202,19 +203,21 @@ module constitutive
of of
end subroutine plastic_disloUCLA_dotState end subroutine plastic_disloUCLA_dotState
module subroutine plastic_nonlocal_dotState(Mp, F, Fp, Temperature, & module subroutine plastic_nonlocal_dotState(Mp, F, Fp, Temperature,timestep, &
timestep,ip,el) instance,of,ip,el)
integer, intent(in) :: &
ip, & !< current integration point
el !< current element number
real(pReal), intent(in) :: &
Temperature, & !< temperature
timestep !< substepped crystallite time increment
real(pReal), dimension(3,3), intent(in) ::& real(pReal), dimension(3,3), intent(in) ::&
Mp !< MandelStress Mp !< MandelStress
real(pReal), dimension(3,3,homogenization_maxNgrains,discretization_nIP,discretization_nElem), intent(in) :: & real(pReal), dimension(3,3,homogenization_maxNgrains,discretization_nIP,discretization_nElem), intent(in) :: &
F, & !< deformation gradient F, & !< deformation gradient
Fp !< plastic deformation gradient Fp !< plastic deformation gradient
real(pReal), intent(in) :: &
Temperature, & !< temperature
timestep !< substepped crystallite time increment
integer, intent(in) :: &
instance, &
of, &
ip, & !< current integration point
el !< current element number
end subroutine plastic_nonlocal_dotState end subroutine plastic_nonlocal_dotState
@ -232,13 +235,15 @@ module constitutive
of of
end subroutine plastic_disloUCLA_dependentState end subroutine plastic_disloUCLA_dependentState
module subroutine plastic_nonlocal_dependentState(F, Fp, ip, el) module subroutine plastic_nonlocal_dependentState(F, Fp, instance, of, ip, el)
integer, intent(in) :: &
ip, &
el
real(pReal), dimension(3,3), intent(in) :: & real(pReal), dimension(3,3), intent(in) :: &
F, & F, &
Fp Fp
integer, intent(in) :: &
instance, &
of, &
ip, &
el
end subroutine plastic_nonlocal_dependentState end subroutine plastic_nonlocal_dependentState
@ -250,12 +255,14 @@ module constitutive
of of
end subroutine plastic_kinehardening_deltaState end subroutine plastic_kinehardening_deltaState
module subroutine plastic_nonlocal_deltaState(Mp,ip,el) module subroutine plastic_nonlocal_deltaState(Mp,instance,of,ip,el)
integer, intent(in) :: &
ip, &
el
real(pReal), dimension(3,3), intent(in) :: & real(pReal), dimension(3,3), intent(in) :: &
Mp Mp
integer, intent(in) :: &
instance, &
of, &
ip, &
el
end subroutine plastic_nonlocal_deltaState end subroutine plastic_nonlocal_deltaState
@ -268,8 +275,9 @@ module constitutive
el !< element el !< element
end function plastic_dislotwin_homogenizedC end function plastic_dislotwin_homogenizedC
module subroutine plastic_nonlocal_updateCompatibility(orientation,i,e) module subroutine plastic_nonlocal_updateCompatibility(orientation,instance,i,e)
integer, intent(in) :: & integer, intent(in) :: &
instance, &
i, & i, &
e e
type(rotation), dimension(1,discretization_nIP,discretization_nElem), intent(in) :: & type(rotation), dimension(1,discretization_nIP,discretization_nElem), intent(in) :: &
@ -364,9 +372,7 @@ subroutine constitutive_init
write(6,'(/,a)') ' <<<+- constitutive init -+>>>'; flush(6) write(6,'(/,a)') ' <<<+- constitutive init -+>>>'; flush(6)
constitutive_plasticity_maxSizeDotState = 0
constitutive_source_maxSizeDotState = 0 constitutive_source_maxSizeDotState = 0
PhaseLoop2:do ph = 1,material_Nphase PhaseLoop2:do ph = 1,material_Nphase
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
! partition and inititalize state ! partition and inititalize state
@ -377,12 +383,11 @@ subroutine constitutive_init
sourceState(ph)%p(s)%state = sourceState(ph)%p(s)%partionedState0 sourceState(ph)%p(s)%state = sourceState(ph)%p(s)%partionedState0
end forall end forall
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
! determine max size of state and output ! determine max size of source state
constitutive_plasticity_maxSizeDotState = max(constitutive_plasticity_maxSizeDotState, & constitutive_source_maxSizeDotState = max(constitutive_source_maxSizeDotState, &
plasticState(ph)%sizeDotState) maxval(sourceState(ph)%p%sizeDotState))
constitutive_source_maxSizeDotState = max(constitutive_source_maxSizeDotState, &
maxval(sourceState(ph)%p(:)%sizeDotState))
enddo PhaseLoop2 enddo PhaseLoop2
constitutive_plasticity_maxSizeDotState = maxval(plasticState%sizeDotState)
end subroutine constitutive_init end subroutine constitutive_init
@ -426,20 +431,18 @@ subroutine constitutive_dependentState(F, Fp, ipc, ip, el)
tme, & !< thermal member position tme, & !< thermal member position
instance, of instance, of
ho = material_homogenizationAt(el) ho = material_homogenizationAt(el)
tme = thermalMapping(ho)%p(ip,el) tme = thermalMapping(ho)%p(ip,el)
of = material_phasememberAt(ipc,ip,el)
instance = phase_plasticityInstance(material_phaseAt(ipc,el))
plasticityType: select case (phase_plasticity(material_phaseAt(ipc,el))) plasticityType: select case (phase_plasticity(material_phaseAt(ipc,el)))
case (PLASTICITY_DISLOTWIN_ID) plasticityType case (PLASTICITY_DISLOTWIN_ID) plasticityType
of = material_phasememberAt(ipc,ip,el)
instance = phase_plasticityInstance(material_phaseAt(ipc,el))
call plastic_dislotwin_dependentState(temperature(ho)%p(tme),instance,of) call plastic_dislotwin_dependentState(temperature(ho)%p(tme),instance,of)
case (PLASTICITY_DISLOUCLA_ID) plasticityType case (PLASTICITY_DISLOUCLA_ID) plasticityType
of = material_phasememberAt(ipc,ip,el)
instance = phase_plasticityInstance(material_phaseAt(ipc,el))
call plastic_disloUCLA_dependentState(instance,of) call plastic_disloUCLA_dependentState(instance,of)
case (PLASTICITY_NONLOCAL_ID) plasticityType case (PLASTICITY_NONLOCAL_ID) plasticityType
call plastic_nonlocal_dependentState (F,Fp,ip,el) call plastic_nonlocal_dependentState (F,Fp,instance,of,ip,el)
end select plasticityType end select plasticityType
end subroutine constitutive_dependentState end subroutine constitutive_dependentState
@ -477,7 +480,9 @@ subroutine constitutive_LpAndItsTangents(Lp, dLp_dS, dLp_dFi, &
ho = material_homogenizationAt(el) ho = material_homogenizationAt(el)
tme = thermalMapping(ho)%p(ip,el) tme = thermalMapping(ho)%p(ip,el)
Mp = matmul(matmul(transpose(Fi),Fi),S) Mp = matmul(matmul(transpose(Fi),Fi),S)
of = material_phasememberAt(ipc,ip,el)
instance = phase_plasticityInstance(material_phaseAt(ipc,el))
plasticityType: select case (phase_plasticity(material_phaseAt(ipc,el))) plasticityType: select case (phase_plasticity(material_phaseAt(ipc,el)))
@ -486,33 +491,22 @@ subroutine constitutive_LpAndItsTangents(Lp, dLp_dS, dLp_dFi, &
dLp_dMp = 0.0_pReal dLp_dMp = 0.0_pReal
case (PLASTICITY_ISOTROPIC_ID) plasticityType case (PLASTICITY_ISOTROPIC_ID) plasticityType
of = material_phasememberAt(ipc,ip,el) call plastic_isotropic_LpAndItsTangent (Lp,dLp_dMp,Mp,instance,of)
instance = phase_plasticityInstance(material_phaseAt(ipc,el))
call plastic_isotropic_LpAndItsTangent (Lp,dLp_dMp,Mp,instance,of)
case (PLASTICITY_PHENOPOWERLAW_ID) plasticityType case (PLASTICITY_PHENOPOWERLAW_ID) plasticityType
of = material_phasememberAt(ipc,ip,el) call plastic_phenopowerlaw_LpAndItsTangent(Lp,dLp_dMp,Mp,instance,of)
instance = phase_plasticityInstance(material_phaseAt(ipc,el))
call plastic_phenopowerlaw_LpAndItsTangent (Lp,dLp_dMp,Mp,instance,of)
case (PLASTICITY_KINEHARDENING_ID) plasticityType case (PLASTICITY_KINEHARDENING_ID) plasticityType
of = material_phasememberAt(ipc,ip,el) call plastic_kinehardening_LpAndItsTangent(Lp,dLp_dMp,Mp,instance,of)
instance = phase_plasticityInstance(material_phaseAt(ipc,el))
call plastic_kinehardening_LpAndItsTangent (Lp,dLp_dMp, Mp,instance,of)
case (PLASTICITY_NONLOCAL_ID) plasticityType case (PLASTICITY_NONLOCAL_ID) plasticityType
call plastic_nonlocal_LpAndItsTangent (Lp,dLp_dMp,Mp, & call plastic_nonlocal_LpAndItsTangent (Lp,dLp_dMp,Mp, temperature(ho)%p(tme),instance,of,ip,el)
temperature(ho)%p(tme),geometry_plastic_nonlocal_IPvolume0(ip,el),ip,el)
case (PLASTICITY_DISLOTWIN_ID) plasticityType case (PLASTICITY_DISLOTWIN_ID) plasticityType
of = material_phasememberAt(ipc,ip,el) call plastic_dislotwin_LpAndItsTangent (Lp,dLp_dMp,Mp,temperature(ho)%p(tme),instance,of)
instance = phase_plasticityInstance(material_phaseAt(ipc,el))
call plastic_dislotwin_LpAndItsTangent (Lp,dLp_dMp,Mp,temperature(ho)%p(tme),instance,of)
case (PLASTICITY_DISLOUCLA_ID) plasticityType case (PLASTICITY_DISLOUCLA_ID) plasticityType
of = material_phasememberAt(ipc,ip,el) call plastic_disloucla_LpAndItsTangent (Lp,dLp_dMp,Mp,temperature(ho)%p(tme),instance,of)
instance = phase_plasticityInstance(material_phaseAt(ipc,el))
call plastic_disloucla_LpAndItsTangent (Lp,dLp_dMp,Mp,temperature(ho)%p(tme),instance,of)
end select plasticityType end select plasticityType
@ -724,7 +718,7 @@ subroutine constitutive_collectDotState(S, FArray, Fi, FpArray, subdt, ipc, ip,
real(pReal), intent(in) :: & real(pReal), intent(in) :: &
subdt !< timestep subdt !< timestep
real(pReal), intent(in), dimension(3,3,homogenization_maxNgrains,discretization_nIP,discretization_nElem) :: & real(pReal), intent(in), dimension(3,3,homogenization_maxNgrains,discretization_nIP,discretization_nElem) :: &
FArray, & !< elastic deformation gradient FArray, & !< elastic deformation gradient
FpArray !< plastic deformation gradient FpArray !< plastic deformation gradient
real(pReal), intent(in), dimension(3,3) :: & real(pReal), intent(in), dimension(3,3) :: &
Fi !< intermediate deformation gradient Fi !< intermediate deformation gradient
@ -740,39 +734,31 @@ subroutine constitutive_collectDotState(S, FArray, Fi, FpArray, subdt, ipc, ip,
ho = material_homogenizationAt(el) ho = material_homogenizationAt(el)
tme = thermalMapping(ho)%p(ip,el) tme = thermalMapping(ho)%p(ip,el)
of = material_phasememberAt(ipc,ip,el)
instance = phase_plasticityInstance(material_phaseAt(ipc,el))
Mp = matmul(matmul(transpose(Fi),Fi),S) Mp = matmul(matmul(transpose(Fi),Fi),S)
plasticityType: select case (phase_plasticity(material_phaseAt(ipc,el))) plasticityType: select case (phase_plasticity(material_phaseAt(ipc,el)))
case (PLASTICITY_ISOTROPIC_ID) plasticityType case (PLASTICITY_ISOTROPIC_ID) plasticityType
of = material_phasememberAt(ipc,ip,el)
instance = phase_plasticityInstance(material_phaseAt(ipc,el))
call plastic_isotropic_dotState (Mp,instance,of) call plastic_isotropic_dotState (Mp,instance,of)
case (PLASTICITY_PHENOPOWERLAW_ID) plasticityType case (PLASTICITY_PHENOPOWERLAW_ID) plasticityType
of = material_phasememberAt(ipc,ip,el)
instance = phase_plasticityInstance(material_phaseAt(ipc,el))
call plastic_phenopowerlaw_dotState(Mp,instance,of) call plastic_phenopowerlaw_dotState(Mp,instance,of)
case (PLASTICITY_KINEHARDENING_ID) plasticityType case (PLASTICITY_KINEHARDENING_ID) plasticityType
of = material_phasememberAt(ipc,ip,el)
instance = phase_plasticityInstance(material_phaseAt(ipc,el))
call plastic_kinehardening_dotState(Mp,instance,of) call plastic_kinehardening_dotState(Mp,instance,of)
case (PLASTICITY_DISLOTWIN_ID) plasticityType case (PLASTICITY_DISLOTWIN_ID) plasticityType
of = material_phasememberAt(ipc,ip,el)
instance = phase_plasticityInstance(material_phaseAt(ipc,el))
call plastic_dislotwin_dotState (Mp,temperature(ho)%p(tme),instance,of) call plastic_dislotwin_dotState (Mp,temperature(ho)%p(tme),instance,of)
case (PLASTICITY_DISLOUCLA_ID) plasticityType case (PLASTICITY_DISLOUCLA_ID) plasticityType
of = material_phasememberAt(ipc,ip,el)
instance = phase_plasticityInstance(material_phaseAt(ipc,el))
call plastic_disloucla_dotState (Mp,temperature(ho)%p(tme),instance,of) call plastic_disloucla_dotState (Mp,temperature(ho)%p(tme),instance,of)
case (PLASTICITY_NONLOCAL_ID) plasticityType case (PLASTICITY_NONLOCAL_ID) plasticityType
call plastic_nonlocal_dotState (Mp,FArray,FpArray,temperature(ho)%p(tme), & call plastic_nonlocal_dotState (Mp,FArray,FpArray,temperature(ho)%p(tme),subdt, &
subdt,ip,el) instance,of,ip,el)
end select plasticityType end select plasticityType
SourceLoop: do i = 1, phase_Nsources(material_phaseAt(ipc,el)) SourceLoop: do i = 1, phase_Nsources(material_phaseAt(ipc,el))
@ -783,13 +769,12 @@ subroutine constitutive_collectDotState(S, FArray, Fi, FpArray, subdt, ipc, ip,
call source_damage_anisoBrittle_dotState (S, ipc, ip, el) !< correct stress? call source_damage_anisoBrittle_dotState (S, ipc, ip, el) !< correct stress?
case (SOURCE_damage_isoDuctile_ID) sourceType case (SOURCE_damage_isoDuctile_ID) sourceType
call source_damage_isoDuctile_dotState ( ipc, ip, el) call source_damage_isoDuctile_dotState ( ipc, ip, el)
case (SOURCE_damage_anisoDuctile_ID) sourceType case (SOURCE_damage_anisoDuctile_ID) sourceType
call source_damage_anisoDuctile_dotState ( ipc, ip, el) call source_damage_anisoDuctile_dotState ( ipc, ip, el)
case (SOURCE_thermal_externalheat_ID) sourceType case (SOURCE_thermal_externalheat_ID) sourceType
of = material_phasememberAt(ipc,ip,el)
call source_thermal_externalheat_dotState(material_phaseAt(ipc,el),of) call source_thermal_externalheat_dotState(material_phaseAt(ipc,el),of)
end select sourceType end select sourceType
@ -820,16 +805,16 @@ subroutine constitutive_collectDeltaState(S, Fe, Fi, ipc, ip, el)
instance, of instance, of
Mp = matmul(matmul(transpose(Fi),Fi),S) Mp = matmul(matmul(transpose(Fi),Fi),S)
of = material_phasememberAt(ipc,ip,el)
instance = phase_plasticityInstance(material_phaseAt(ipc,el))
plasticityType: select case (phase_plasticity(material_phaseAt(ipc,el))) plasticityType: select case (phase_plasticity(material_phaseAt(ipc,el)))
case (PLASTICITY_KINEHARDENING_ID) plasticityType case (PLASTICITY_KINEHARDENING_ID) plasticityType
of = material_phasememberAt(ipc,ip,el)
instance = phase_plasticityInstance(material_phaseAt(ipc,el))
call plastic_kinehardening_deltaState(Mp,instance,of) call plastic_kinehardening_deltaState(Mp,instance,of)
case (PLASTICITY_NONLOCAL_ID) plasticityType case (PLASTICITY_NONLOCAL_ID) plasticityType
call plastic_nonlocal_deltaState(Mp,ip,el) call plastic_nonlocal_deltaState(Mp,instance,of,ip,el)
end select plasticityType end select plasticityType

View File

@ -12,16 +12,12 @@ submodule(constitutive) plastic_disloUCLA
type :: tParameters type :: tParameters
real(pReal) :: & real(pReal) :: &
aTol_rho, & D = 1.0_pReal, & !< grain size
D, & !< grain size mu = 1.0_pReal, & !< equivalent shear modulus
mu, & D_0 = 1.0_pReal, & !< prefactor for self-diffusion coefficient
D_0, & !< prefactor for self-diffusion coefficient Q_cl = 1.0_pReal !< activation energy for dislocation climb
Q_cl !< activation energy for dislocation climb
real(pReal), allocatable, dimension(:) :: & real(pReal), allocatable, dimension(:) :: &
rho_mob_0, & !< initial dislocation density
rho_dip_0, & !< initial dipole density
b_sl, & !< magnitude of burgers vector [m] b_sl, & !< magnitude of burgers vector [m]
nonSchmidCoeff, &
D_a, & D_a, &
i_sl, & !< Adj. parameter for distance between 2 forest dislocations i_sl, & !< Adj. parameter for distance between 2 forest dislocations
atomicVolume, & atomicVolume, &
@ -37,15 +33,13 @@ submodule(constitutive) plastic_disloUCLA
omega !< attempt frequency for kink pair nucleation omega !< attempt frequency for kink pair nucleation
real(pReal), allocatable, dimension(:,:) :: & real(pReal), allocatable, dimension(:,:) :: &
h_sl_sl, & !< slip resistance from slip activity h_sl_sl, & !< slip resistance from slip activity
forestProjectionEdge forestProjection
real(pReal), allocatable, dimension(:,:,:) :: & real(pReal), allocatable, dimension(:,:,:) :: &
Schmid, & P_sl, &
nonSchmid_pos, & nonSchmid_pos, &
nonSchmid_neg nonSchmid_neg
integer :: & integer :: &
sum_N_sl !< total number of active slip system sum_N_sl !< total number of active slip system
integer, allocatable, dimension(:) :: &
N_sl !< number of active slip systems for each family
character(len=pStringLen), allocatable, dimension(:) :: & character(len=pStringLen), allocatable, dimension(:) :: &
output output
logical :: & logical :: &
@ -88,11 +82,16 @@ module subroutine plastic_disloUCLA_init
NipcMyPhase, & NipcMyPhase, &
sizeState, sizeDotState, & sizeState, sizeDotState, &
startIndex, endIndex startIndex, endIndex
integer, dimension(:), allocatable :: &
N_sl
real(pReal),dimension(:), allocatable :: &
rho_mob_0, & !< initial dislocation density
rho_dip_0, & !< initial dipole density
a !< non-Schmid coefficients
character(len=pStringLen) :: & character(len=pStringLen) :: &
extmsg = '' extmsg = ''
write(6,'(/,a)') ' <<<+- plastic_'//PLASTICITY_DISLOUCLA_label//' init -+>>>'; flush(6) write(6,'(/,a)') ' <<<+- plastic_'//PLASTICITY_DISLOUCLA_LABEL//' init -+>>>'; flush(6)
write(6,'(/,a)') ' Cereceda et al., International Journal of Plasticity 78:242256, 2016' write(6,'(/,a)') ' Cereceda et al., International Journal of Plasticity 78:242256, 2016'
write(6,'(a)') ' https://dx.doi.org/10.1016/j.ijplas.2015.09.002' write(6,'(a)') ' https://dx.doi.org/10.1016/j.ijplas.2015.09.002'
@ -106,7 +105,6 @@ module subroutine plastic_disloUCLA_init
allocate(dotState(Ninstance)) allocate(dotState(Ninstance))
allocate(dependentState(Ninstance)) allocate(dependentState(Ninstance))
do p = 1, size(phase_plasticity) do p = 1, size(phase_plasticity)
if (phase_plasticity(p) /= PLASTICITY_DISLOUCLA_ID) cycle if (phase_plasticity(p) /= PLASTICITY_DISLOUCLA_ID) cycle
associate(prm => param(phase_plasticityInstance(p)), & associate(prm => param(phase_plasticityInstance(p)), &
@ -115,109 +113,96 @@ module subroutine plastic_disloUCLA_init
dst => dependentState(phase_plasticityInstance(p)), & dst => dependentState(phase_plasticityInstance(p)), &
config => config_phase(p)) config => config_phase(p))
!-------------------------------------------------------------------------------------------------- prm%output = config%getStrings('(output)',defaultVal=emptyStringArray)
! optional parameters that need to be defined
! This data is read in already in lattice
prm%mu = lattice_mu(p) prm%mu = lattice_mu(p)
prm%aTol_rho = config%getFloat('atol_rho')
! sanity checks
if (prm%aTol_rho <= 0.0_pReal) extmsg = trim(extmsg)//' atol_rho'
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
! slip related parameters ! slip related parameters
prm%N_sl = config%getInts('nslip',defaultVal=emptyIntArray) N_sl = config%getInts('nslip',defaultVal=emptyIntArray)
prm%sum_N_sl = sum(prm%N_sl) prm%sum_N_sl = sum(abs(N_sl))
slipActive: if (prm%sum_N_sl > 0) then slipActive: if (prm%sum_N_sl > 0) then
prm%Schmid = lattice_SchmidMatrix_slip(prm%N_sl,config%getString('lattice_structure'),& prm%P_sl = lattice_SchmidMatrix_slip(N_sl,config%getString('lattice_structure'),&
config%getFloat('c/a',defaultVal=0.0_pReal)) config%getFloat('c/a',defaultVal=0.0_pReal))
if(trim(config%getString('lattice_structure')) == 'bcc') then if(trim(config%getString('lattice_structure')) == 'bcc') then
prm%nonSchmidCoeff = config%getFloats('nonschmid_coefficients',& a = config%getFloats('nonschmid_coefficients',defaultVal = emptyRealArray)
defaultVal = emptyRealArray) prm%nonSchmid_pos = lattice_nonSchmidMatrix(N_sl,a,+1)
prm%nonSchmid_pos = lattice_nonSchmidMatrix(prm%N_sl,prm%nonSchmidCoeff,+1) prm%nonSchmid_neg = lattice_nonSchmidMatrix(N_sl,a,-1)
prm%nonSchmid_neg = lattice_nonSchmidMatrix(prm%N_sl,prm%nonSchmidCoeff,-1)
else else
allocate(prm%nonSchmidCoeff(0)) prm%nonSchmid_pos = prm%P_sl
prm%nonSchmid_pos = prm%Schmid prm%nonSchmid_neg = prm%P_sl
prm%nonSchmid_neg = prm%Schmid
endif endif
prm%h_sl_sl = lattice_interaction_SlipBySlip(prm%N_sl, & prm%h_sl_sl = lattice_interaction_SlipBySlip(N_sl,config%getFloats('interaction_slipslip'), &
config%getFloats('interaction_slipslip'), & config%getString('lattice_structure'))
config%getString('lattice_structure')) prm%forestProjection = lattice_forestProjection_edge(N_sl,config%getString('lattice_structure'),&
prm%forestProjectionEdge = lattice_forestProjection_edge(prm%N_sl,config%getString('lattice_structure'),& config%getFloat('c/a',defaultVal=0.0_pReal))
config%getFloat('c/a',defaultVal=0.0_pReal)) prm%forestProjection = transpose(prm%forestProjection)
prm%forestProjectionEdge = transpose(prm%forestProjectionEdge)
prm%rho_mob_0 = config%getFloats('rhoedge0', requiredSize=size(prm%N_sl)) rho_mob_0 = config%getFloats('rhoedge0', requiredSize=size(N_sl))
prm%rho_dip_0 = config%getFloats('rhoedgedip0', requiredSize=size(prm%N_sl)) rho_dip_0 = config%getFloats('rhoedgedip0', requiredSize=size(N_sl))
prm%v0 = config%getFloats('v0', requiredSize=size(prm%N_sl)) prm%v0 = config%getFloats('v0', requiredSize=size(N_sl))
prm%b_sl = config%getFloats('slipburgers', requiredSize=size(prm%N_sl)) prm%b_sl = config%getFloats('slipburgers', requiredSize=size(N_sl))
prm%delta_F = config%getFloats('qedge', requiredSize=size(prm%N_sl)) prm%delta_F = config%getFloats('qedge', requiredSize=size(N_sl))
prm%i_sl = config%getFloats('clambdaslip', requiredSize=size(prm%N_sl)) prm%i_sl = config%getFloats('clambdaslip', requiredSize=size(N_sl))
prm%tau_0 = config%getFloats('tau_peierls', requiredSize=size(prm%N_sl)) prm%tau_0 = config%getFloats('tau_peierls', requiredSize=size(N_sl))
prm%p = config%getFloats('p_slip', requiredSize=size(prm%N_sl), & prm%p = config%getFloats('p_slip', requiredSize=size(N_sl), &
defaultVal=[(1.0_pReal,i=1,size(prm%N_sl))]) defaultVal=[(1.0_pReal,i=1,size(N_sl))])
prm%q = config%getFloats('q_slip', requiredSize=size(prm%N_sl), & prm%q = config%getFloats('q_slip', requiredSize=size(N_sl), &
defaultVal=[(1.0_pReal,i=1,size(prm%N_sl))]) defaultVal=[(1.0_pReal,i=1,size(N_sl))])
prm%kink_height = config%getFloats('kink_height', requiredSize=size(prm%N_sl)) prm%kink_height = config%getFloats('kink_height', requiredSize=size(N_sl))
prm%w = config%getFloats('kink_width', requiredSize=size(prm%N_sl)) prm%w = config%getFloats('kink_width', requiredSize=size(N_sl))
prm%omega = config%getFloats('omega', requiredSize=size(prm%N_sl)) prm%omega = config%getFloats('omega', requiredSize=size(N_sl))
prm%B = config%getFloats('friction_coeff', requiredSize=size(prm%N_sl)) prm%B = config%getFloats('friction_coeff', requiredSize=size(N_sl))
prm%D = config%getFloat('grainsize') prm%D = config%getFloat('grainsize')
prm%D_0 = config%getFloat('d0') prm%D_0 = config%getFloat('d0')
prm%Q_cl = config%getFloat('qsd') prm%Q_cl = config%getFloat('qsd')
prm%atomicVolume = config%getFloat('catomicvolume') * prm%b_sl**3.0_pReal prm%atomicVolume = config%getFloat('catomicvolume') * prm%b_sl**3.0_pReal
prm%D_a = config%getFloat('cedgedipmindistance') * prm%b_sl prm%D_a = config%getFloat('cedgedipmindistance') * prm%b_sl
prm%dipoleformation = config%getFloat('dipoleformationfactor') > 0.0_pReal !should be on by default, ToDo: change to /key/-type key prm%dipoleformation = config%getFloat('dipoleformationfactor') > 0.0_pReal !should be on by default, ToDo: change to /key/-type key
! expand: family => system ! expand: family => system
prm%rho_mob_0 = math_expand(prm%rho_mob_0, prm%N_sl) rho_mob_0 = math_expand(rho_mob_0, N_sl)
prm%rho_dip_0 = math_expand(prm%rho_dip_0, prm%N_sl) rho_dip_0 = math_expand(rho_dip_0, N_sl)
prm%q = math_expand(prm%q, prm%N_sl) prm%q = math_expand(prm%q, N_sl)
prm%p = math_expand(prm%p, prm%N_sl) prm%p = math_expand(prm%p, N_sl)
prm%delta_F = math_expand(prm%delta_F, prm%N_sl) prm%delta_F = math_expand(prm%delta_F, N_sl)
prm%b_sl = math_expand(prm%b_sl, prm%N_sl) prm%b_sl = math_expand(prm%b_sl, N_sl)
prm%kink_height = math_expand(prm%kink_height, prm%N_sl) prm%kink_height = math_expand(prm%kink_height, N_sl)
prm%w = math_expand(prm%w, prm%N_sl) prm%w = math_expand(prm%w, N_sl)
prm%omega = math_expand(prm%omega, prm%N_sl) prm%omega = math_expand(prm%omega, N_sl)
prm%tau_0 = math_expand(prm%tau_0, prm%N_sl) prm%tau_0 = math_expand(prm%tau_0, N_sl)
prm%v0 = math_expand(prm%v0, prm%N_sl) prm%v0 = math_expand(prm%v0, N_sl)
prm%B = math_expand(prm%B, prm%N_sl) prm%B = math_expand(prm%B, N_sl)
prm%i_sl = math_expand(prm%i_sl, prm%N_sl) prm%i_sl = math_expand(prm%i_sl, N_sl)
prm%atomicVolume = math_expand(prm%atomicVolume, prm%N_sl) prm%atomicVolume = math_expand(prm%atomicVolume, N_sl)
prm%D_a = math_expand(prm%D_a, prm%N_sl) prm%D_a = math_expand(prm%D_a, N_sl)
! sanity checks ! sanity checks
if ( prm%D_0 <= 0.0_pReal) extmsg = trim(extmsg)//' D_0' if ( prm%D_0 <= 0.0_pReal) extmsg = trim(extmsg)//' D_0'
if ( prm%Q_cl <= 0.0_pReal) extmsg = trim(extmsg)//' Q_cl' if ( prm%Q_cl <= 0.0_pReal) extmsg = trim(extmsg)//' Q_cl'
if (any(prm%rho_mob_0 < 0.0_pReal)) extmsg = trim(extmsg)//' rhoedge0' if (any(rho_mob_0 < 0.0_pReal)) extmsg = trim(extmsg)//' rhoedge0'
if (any(prm%rho_dip_0 < 0.0_pReal)) extmsg = trim(extmsg)//' rhoedgedip0' if (any(rho_dip_0 < 0.0_pReal)) extmsg = trim(extmsg)//' rhoedgedip0'
if (any(prm%v0 < 0.0_pReal)) extmsg = trim(extmsg)//' v0' if (any(prm%v0 < 0.0_pReal)) extmsg = trim(extmsg)//' v0'
if (any(prm%b_sl <= 0.0_pReal)) extmsg = trim(extmsg)//' slipb_sl' if (any(prm%b_sl <= 0.0_pReal)) extmsg = trim(extmsg)//' b_sl'
if (any(prm%delta_F <= 0.0_pReal)) extmsg = trim(extmsg)//' qedge' if (any(prm%delta_F <= 0.0_pReal)) extmsg = trim(extmsg)//' qedge'
if (any(prm%tau_0 < 0.0_pReal)) extmsg = trim(extmsg)//' tau_0' if (any(prm%tau_0 < 0.0_pReal)) extmsg = trim(extmsg)//' tau_0'
if (any(prm%D_a <= 0.0_pReal)) extmsg = trim(extmsg)//' cedgedipmindistance or slipb_sl' if (any(prm%D_a <= 0.0_pReal)) extmsg = trim(extmsg)//' cedgedipmindistance or b_sl'
if (any(prm%atomicVolume <= 0.0_pReal)) extmsg = trim(extmsg)//' catomicvolume or slipb_sl' if (any(prm%atomicVolume <= 0.0_pReal)) extmsg = trim(extmsg)//' catomicvolume or b_sl'
else slipActive else slipActive
allocate(prm%rho_mob_0(0)) rho_mob_0= emptyRealArray; rho_dip_0 = emptyRealArray
allocate(prm%rho_dip_0(0)) allocate(prm%b_sl,prm%D_a,prm%i_sl,prm%atomicVolume,prm%tau_0, &
prm%delta_F,prm%v0,prm%p,prm%q,prm%B,prm%kink_height,prm%w,prm%omega, &
source = emptyRealArray)
allocate(prm%forestProjection(0,0))
allocate(prm%h_sl_sl (0,0))
endif slipActive endif slipActive
!--------------------------------------------------------------------------------------------------
! exit if any parameter is out of range
if (extmsg /= '') &
call IO_error(211,ext_msg=trim(extmsg)//'('//PLASTICITY_DISLOUCLA_label//')')
!--------------------------------------------------------------------------------------------------
! output pararameters
prm%output = config%getStrings('(output)',defaultVal=emptyStringArray)
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
! allocate state arrays ! allocate state arrays
NipcMyPhase = count(material_phaseAt == p) * discretization_nIP NipcMyPhase = count(material_phaseAt == p) * discretization_nIP
@ -227,26 +212,27 @@ module subroutine plastic_disloUCLA_init
call material_allocatePlasticState(p,NipcMyPhase,sizeState,sizeDotState,0) call material_allocatePlasticState(p,NipcMyPhase,sizeState,sizeDotState,0)
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
! locally defined state aliases and initialization of state0 and aTolState ! state aliases and initialization
startIndex = 1 startIndex = 1
endIndex = prm%sum_N_sl endIndex = prm%sum_N_sl
stt%rho_mob=>plasticState(p)%state(startIndex:endIndex,:) stt%rho_mob => plasticState(p)%state(startIndex:endIndex,:)
stt%rho_mob= spread(prm%rho_mob_0,2,NipcMyPhase) stt%rho_mob = spread(rho_mob_0,2,NipcMyPhase)
dot%rho_mob=>plasticState(p)%dotState(startIndex:endIndex,:) dot%rho_mob => plasticState(p)%dotState(startIndex:endIndex,:)
plasticState(p)%aTolState(startIndex:endIndex) = prm%aTol_rho plasticState(p)%atol(startIndex:endIndex) = config%getFloat('atol_rho',defaultVal=1.0_pReal)
if (any(plasticState(p)%atol(startIndex:endIndex) < 0.0_pReal)) extmsg = trim(extmsg)//' atol_rho'
startIndex = endIndex + 1 startIndex = endIndex + 1
endIndex = endIndex + prm%sum_N_sl endIndex = endIndex + prm%sum_N_sl
stt%rho_dip=>plasticState(p)%state(startIndex:endIndex,:) stt%rho_dip => plasticState(p)%state(startIndex:endIndex,:)
stt%rho_dip= spread(prm%rho_dip_0,2,NipcMyPhase) stt%rho_dip = spread(rho_dip_0,2,NipcMyPhase)
dot%rho_dip=>plasticState(p)%dotState(startIndex:endIndex,:) dot%rho_dip => plasticState(p)%dotState(startIndex:endIndex,:)
plasticState(p)%aTolState(startIndex:endIndex) = prm%aTol_rho plasticState(p)%atol(startIndex:endIndex) = config%getFloat('atol_rho',defaultVal=1.0_pReal)
startIndex = endIndex + 1 startIndex = endIndex + 1
endIndex = endIndex + prm%sum_N_sl endIndex = endIndex + prm%sum_N_sl
stt%gamma_sl=>plasticState(p)%state(startIndex:endIndex,:) stt%gamma_sl => plasticState(p)%state(startIndex:endIndex,:)
dot%gamma_sl=>plasticState(p)%dotState(startIndex:endIndex,:) dot%gamma_sl => plasticState(p)%dotState(startIndex:endIndex,:)
plasticState(p)%aTolState(startIndex:endIndex) = 1.0e6_pReal ! Don't use for convergence check plasticState(p)%atol(startIndex:endIndex) = 1.0e-2_pReal
! global alias ! global alias
plasticState(p)%slipRate => plasticState(p)%dotState(startIndex:endIndex,:) plasticState(p)%slipRate => plasticState(p)%dotState(startIndex:endIndex,:)
@ -257,6 +243,10 @@ module subroutine plastic_disloUCLA_init
end associate end associate
!--------------------------------------------------------------------------------------------------
! exit if any parameter is out of range
if (extmsg /= '') call IO_error(211,ext_msg=trim(extmsg)//'('//PLASTICITY_DISLOUCLA_LABEL//')')
enddo enddo
end subroutine plastic_disloUCLA_init end subroutine plastic_disloUCLA_init
@ -266,7 +256,7 @@ end subroutine plastic_disloUCLA_init
!> @brief Calculate plastic velocity gradient and its tangent. !> @brief Calculate plastic velocity gradient and its tangent.
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
pure module subroutine plastic_disloUCLA_LpAndItsTangent(Lp,dLp_dMp, & pure module subroutine plastic_disloUCLA_LpAndItsTangent(Lp,dLp_dMp, &
Mp,T,instance,of) Mp,T,instance,of)
real(pReal), dimension(3,3), intent(out) :: & real(pReal), dimension(3,3), intent(out) :: &
Lp !< plastic velocity gradient Lp !< plastic velocity gradient
real(pReal), dimension(3,3,3,3), intent(out) :: & real(pReal), dimension(3,3,3,3), intent(out) :: &
@ -293,11 +283,11 @@ pure module subroutine plastic_disloUCLA_LpAndItsTangent(Lp,dLp_dMp, &
call kinetics(Mp,T,instance,of,dot_gamma_pos,dot_gamma_neg,ddot_gamma_dtau_pos,ddot_gamma_dtau_neg) call kinetics(Mp,T,instance,of,dot_gamma_pos,dot_gamma_neg,ddot_gamma_dtau_pos,ddot_gamma_dtau_neg)
do i = 1, prm%sum_N_sl do i = 1, prm%sum_N_sl
Lp = Lp + (dot_gamma_pos(i)+dot_gamma_neg(i))*prm%Schmid(1:3,1:3,i) Lp = Lp + (dot_gamma_pos(i)+dot_gamma_neg(i))*prm%P_sl(1:3,1:3,i)
forall (k=1:3,l=1:3,m=1:3,n=1:3) & forall (k=1:3,l=1:3,m=1:3,n=1:3) &
dLp_dMp(k,l,m,n) = dLp_dMp(k,l,m,n) & dLp_dMp(k,l,m,n) = dLp_dMp(k,l,m,n) &
+ ddot_gamma_dtau_pos(i) * prm%Schmid(k,l,i) * prm%nonSchmid_pos(m,n,i) & + ddot_gamma_dtau_pos(i) * prm%P_sl(k,l,i) * prm%nonSchmid_pos(m,n,i) &
+ ddot_gamma_dtau_neg(i) * prm%Schmid(k,l,i) * prm%nonSchmid_neg(m,n,i) + ddot_gamma_dtau_neg(i) * prm%P_sl(k,l,i) * prm%nonSchmid_neg(m,n,i)
enddo enddo
end associate end associate
@ -311,9 +301,9 @@ end subroutine plastic_disloUCLA_LpAndItsTangent
module subroutine plastic_disloUCLA_dotState(Mp,T,instance,of) module subroutine plastic_disloUCLA_dotState(Mp,T,instance,of)
real(pReal), dimension(3,3), intent(in) :: & real(pReal), dimension(3,3), intent(in) :: &
Mp !< Mandel stress Mp !< Mandel stress
real(pReal), intent(in) :: & real(pReal), intent(in) :: &
T !< temperature T !< temperature
integer, intent(in) :: & integer, intent(in) :: &
instance, & instance, &
of of
@ -343,14 +333,14 @@ module subroutine plastic_disloUCLA_dotState(Mp,T,instance,of)
dot_rho_dip_climb = 0.0_pReal dot_rho_dip_climb = 0.0_pReal
else where else where
dip_distance = math_clip(3.0_pReal*prm%mu*prm%b_sl/(16.0_pReal*PI*abs(tau_pos)), & dip_distance = math_clip(3.0_pReal*prm%mu*prm%b_sl/(16.0_pReal*PI*abs(tau_pos)), &
prm%D_a, & ! lower limit prm%D_a, & ! lower limit
dst%Lambda_sl(:,of)) ! upper limit dst%Lambda_sl(:,of)) ! upper limit
dot_rho_dip_formation = merge(2.0_pReal*dip_distance* stt%rho_mob(:,of)*abs(dot%gamma_sl(:,of))/prm%b_sl, & ! ToDo: ignore region of spontaneous annihilation dot_rho_dip_formation = merge(2.0_pReal*dip_distance* stt%rho_mob(:,of)*abs(dot%gamma_sl(:,of))/prm%b_sl, & ! ToDo: ignore region of spontaneous annihilation
0.0_pReal, & 0.0_pReal, &
prm%dipoleformation) prm%dipoleformation)
v_cl = (3.0_pReal*prm%mu*VacancyDiffusion*prm%atomicVolume/(2.0_pReal*pi*kB*T)) & v_cl = (3.0_pReal*prm%mu*VacancyDiffusion*prm%atomicVolume/(2.0_pReal*pi*kB*T)) &
* (1.0_pReal/(dip_distance+prm%D_a)) * (1.0_pReal/(dip_distance+prm%D_a))
dot_rho_dip_climb = (4.0_pReal*v_cl*stt%rho_dip(:,of))/(dip_distance-prm%D_a) ! ToDo: Discuss with Franz: Stress dependency? dot_rho_dip_climb = (4.0_pReal*v_cl*stt%rho_dip(:,of))/(dip_distance-prm%D_a) ! ToDo: Discuss with Franz: Stress dependency?
end where end where
dot%rho_mob(:,of) = abs(dot%gamma_sl(:,of))/(prm%b_sl*dst%Lambda_sl(:,of)) & ! multiplication dot%rho_mob(:,of) = abs(dot%gamma_sl(:,of))/(prm%b_sl*dst%Lambda_sl(:,of)) & ! multiplication
@ -379,8 +369,7 @@ module subroutine plastic_disloUCLA_dependentState(instance,of)
associate(prm => param(instance), stt => state(instance),dst => dependentState(instance)) associate(prm => param(instance), stt => state(instance),dst => dependentState(instance))
dislocationSpacing = sqrt(matmul(prm%forestProjectionEdge, & dislocationSpacing = sqrt(matmul(prm%forestProjection,stt%rho_mob(:,of)+stt%rho_dip(:,of)))
stt%rho_mob(:,of)+stt%rho_dip(:,of)))
dst%threshold_stress(:,of) = prm%mu*prm%b_sl & dst%threshold_stress(:,of) = prm%mu*prm%b_sl &
* sqrt(matmul(prm%h_sl_sl,stt%rho_mob(:,of)+stt%rho_dip(:,of))) * sqrt(matmul(prm%h_sl_sl,stt%rho_mob(:,of)+stt%rho_dip(:,of)))
@ -411,7 +400,7 @@ module subroutine plastic_disloUCLA_results(instance,group)
if(prm%sum_N_sl>0) call results_writeDataset(group,stt%rho_dip,'rho_dip',& if(prm%sum_N_sl>0) call results_writeDataset(group,stt%rho_dip,'rho_dip',&
'dislocation dipole density''1/m²') 'dislocation dipole density''1/m²')
case('shear_rate_slip') ! should be gamma case('shear_rate_slip') ! should be gamma
if(prm%sum_N_sl>0) call results_writeDataset(group,stt%gamma_sl,'dot_gamma_sl',& ! this is not dot!! if(prm%sum_N_sl>0) call results_writeDataset(group,stt%gamma_sl,'dot_gamma_sl',& ! this is not dot!!
'plastic shear','1') 'plastic shear','1')
case('mfp_slip') !ToDo: should be Lambda case('mfp_slip') !ToDo: should be Lambda
if(prm%sum_N_sl>0) call results_writeDataset(group,dst%Lambda_sl,'Lambda_sl',& if(prm%sum_N_sl>0) call results_writeDataset(group,dst%Lambda_sl,'Lambda_sl',&
@ -464,8 +453,8 @@ pure subroutine kinetics(Mp,T,instance,of, &
associate(prm => param(instance), stt => state(instance), dst => dependentState(instance)) associate(prm => param(instance), stt => state(instance), dst => dependentState(instance))
do j = 1, prm%sum_N_sl do j = 1, prm%sum_N_sl
tau_pos(j) = math_mul33xx33(Mp,prm%nonSchmid_pos(1:3,1:3,j)) tau_pos(j) = math_tensordot(Mp,prm%nonSchmid_pos(1:3,1:3,j))
tau_neg(j) = math_mul33xx33(Mp,prm%nonSchmid_neg(1:3,1:3,j)) tau_neg(j) = math_tensordot(Mp,prm%nonSchmid_neg(1:3,1:3,j))
enddo enddo

View File

@ -14,36 +14,31 @@ submodule(constitutive) plastic_dislotwin
type :: tParameters type :: tParameters
real(pReal) :: & real(pReal) :: &
mu, & mu = 1.0_pReal, & !< equivalent shear modulus
nu, & nu = 1.0_pReal, & !< equivalent shear Poisson's ratio
D0, & !< prefactor for self-diffusion coefficient D0 = 1.0_pReal, & !< prefactor for self-diffusion coefficient
Qsd, & !< activation energy for dislocation climb Qsd = 1.0_pReal, & !< activation energy for dislocation climb
omega, & !< frequency factor for dislocation climb omega = 1.0_pReal, & !< frequency factor for dislocation climb
D, & !< grain size D = 1.0_pReal, & !< grain size
p_sb, & !< p-exponent in shear band velocity p_sb = 1.0_pReal, & !< p-exponent in shear band velocity
q_sb, & !< q-exponent in shear band velocity q_sb = 1.0_pReal, & !< q-exponent in shear band velocity
CEdgeDipMinDistance, & !< CEdgeDipMinDistance = 1.0_pReal, & !<
i_tw, & !< i_tw = 1.0_pReal, & !<
tau_0, & !< strength due to elements in solid solution tau_0 = 1.0_pReal, & !< strength due to elements in solid solution
L_tw, & !< Length of twin nuclei in Burgers vectors L_tw = 1.0_pReal, & !< Length of twin nuclei in Burgers vectors
L_tr, & !< Length of trans nuclei in Burgers vectors L_tr = 1.0_pReal, & !< Length of trans nuclei in Burgers vectors
xc_twin, & !< critical distance for formation of twin nucleus xc_twin = 1.0_pReal, & !< critical distance for formation of twin nucleus
xc_trans, & !< critical distance for formation of trans nucleus xc_trans = 1.0_pReal, & !< critical distance for formation of trans nucleus
V_cs, & !< cross slip volume V_cs = 1.0_pReal, & !< cross slip volume
sbResistance, & !< value for shearband resistance (might become an internal state variable at some point) sbResistance = 1.0_pReal, & !< value for shearband resistance
sbVelocity, & !< value for shearband velocity_0 sbVelocity = 1.0_pReal, & !< value for shearband velocity_0
sbQedge, & !< activation energy for shear bands E_sb = 1.0_pReal, & !< activation energy for shear bands
SFE_0K, & !< stacking fault energy at zero K SFE_0K = 1.0_pReal, & !< stacking fault energy at zero K
dSFE_dT, & !< temperature dependance of stacking fault energy dSFE_dT = 1.0_pReal, & !< temperature dependence of stacking fault energy
aTol_rho, & !< absolute tolerance for integration of dislocation density gamma_fcc_hex = 1.0_pReal, & !< Free energy difference between austensite and martensite
aTol_f_tw, & !< absolute tolerance for integration of twin volume fraction i_tr = 1.0_pReal, & !<
aTol_f_tr, & !< absolute tolerance for integration of trans volume fraction h = 1.0_pReal !< Stack height of hex nucleus
gamma_fcc_hex, & !< Free energy difference between austensite and martensite
i_tr, & !<
h !< Stack height of hex nucleus
real(pReal), allocatable, dimension(:) :: & real(pReal), allocatable, dimension(:) :: &
rho_mob_0, & !< initial unipolar dislocation density per slip system
rho_dip_0, & !< initial dipole dislocation density per slip system
b_sl, & !< absolute length of burgers vector [m] for each slip system b_sl, & !< absolute length of burgers vector [m] for each slip system
b_tw, & !< absolute length of burgers vector [m] for each twin system b_tw, & !< absolute length of burgers vector [m] for each twin system
b_tr, & !< absolute length of burgers vector [m] for each transformation system b_tr, & !< absolute length of burgers vector [m] for each transformation system
@ -53,7 +48,6 @@ submodule(constitutive) plastic_dislotwin
dot_N_0_tr, & !< trans nucleation rate [1/m³s] for each trans system dot_N_0_tr, & !< trans nucleation rate [1/m³s] for each trans system
t_tw, & !< twin thickness [m] for each twin system t_tw, & !< twin thickness [m] for each twin system
CLambdaSlip, & !< Adj. parameter for distance between 2 forest dislocations for each slip system CLambdaSlip, & !< Adj. parameter for distance between 2 forest dislocations for each slip system
atomicVolume, &
t_tr, & !< martensite lamellar thickness [m] for each trans system and instance t_tr, & !< martensite lamellar thickness [m] for each trans system and instance
p, & !< p-exponent in glide velocity p, & !< p-exponent in glide velocity
q, & !< q-exponent in glide velocity q, & !< q-exponent in glide velocity
@ -71,19 +65,15 @@ submodule(constitutive) plastic_dislotwin
forestProjection, & forestProjection, &
C66 C66
real(pReal), allocatable, dimension(:,:,:) :: & real(pReal), allocatable, dimension(:,:,:) :: &
P_tr, &
P_sl, & P_sl, &
P_tw, & P_tw, &
P_tr, &
C66_tw, & C66_tw, &
C66_tr C66_tr
integer :: & integer :: &
sum_N_sl, & !< total number of active slip system sum_N_sl, & !< total number of active slip system
sum_N_tw, & !< total number of active twin system sum_N_tw, & !< total number of active twin system
sum_N_tr !< total number of active transformation system sum_N_tr !< total number of active transformation system
integer, allocatable, dimension(:) :: &
N_sl, & !< number of active slip systems for each family
N_tw, & !< number of active twin systems for each family
N_tr !< number of active transformation systems for each family
integer, allocatable, dimension(:,:) :: & integer, allocatable, dimension(:,:) :: &
fcc_twinNucleationSlipPair ! ToDo: Better name? Is also use for trans fcc_twinNucleationSlipPair ! ToDo: Better name? Is also use for trans
character(len=pStringLen), allocatable, dimension(:) :: & character(len=pStringLen), allocatable, dimension(:) :: &
@ -140,11 +130,15 @@ module subroutine plastic_dislotwin_init
NipcMyPhase, & NipcMyPhase, &
sizeState, sizeDotState, & sizeState, sizeDotState, &
startIndex, endIndex startIndex, endIndex
integer, dimension(:), allocatable :: &
N_sl, N_tw, N_tr
real(pReal), allocatable, dimension(:) :: &
rho_mob_0, & !< initial unipolar dislocation density per slip system
rho_dip_0 !< initial dipole dislocation density per slip system
character(len=pStringLen) :: & character(len=pStringLen) :: &
extmsg = '' extmsg = ''
write(6,'(/,a)') ' <<<+- constitutive_'//PLASTICITY_DISLOTWIN_label//' init -+>>>'; flush(6) write(6,'(/,a)') ' <<<+- constitutive_'//PLASTICITY_DISLOTWIN_LABEL//' init -+>>>'; flush(6)
write(6,'(/,a)') ' Ma and Roters, Acta Materialia 52(12):36033612, 2004' write(6,'(/,a)') ' Ma and Roters, Acta Materialia 52(12):36033612, 2004'
write(6,'(a)') ' https://doi.org/10.1016/j.actamat.2004.04.012' write(6,'(a)') ' https://doi.org/10.1016/j.actamat.2004.04.012'
@ -173,83 +167,76 @@ module subroutine plastic_dislotwin_init
dst => dependentState(phase_plasticityInstance(p)), & dst => dependentState(phase_plasticityInstance(p)), &
config => config_phase(p)) config => config_phase(p))
prm%aTol_rho = config%getFloat('atol_rho', defaultVal=0.0_pReal) prm%output = config%getStrings('(output)', defaultVal=emptyStringArray)
prm%aTol_f_tw = config%getFloat('atol_twinfrac', defaultVal=0.0_pReal)
prm%aTol_f_tr = config%getFloat('atol_transfrac', defaultVal=0.0_pReal)
! This data is read in already in lattice ! This data is read in already in lattice
prm%mu = lattice_mu(p) prm%mu = lattice_mu(p)
prm%nu = lattice_nu(p) prm%nu = lattice_nu(p)
prm%C66 = lattice_C66(1:6,1:6,p) prm%C66 = lattice_C66(1:6,1:6,p)
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
! slip related parameters ! slip related parameters
prm%N_sl = config%getInts('nslip',defaultVal=emptyIntArray) N_sl = config%getInts('nslip',defaultVal=emptyIntArray)
prm%sum_N_sl = sum(prm%N_sl) prm%sum_N_sl = sum(abs(N_sl))
slipActive: if (prm%sum_N_sl > 0) then slipActive: if (prm%sum_N_sl > 0) then
prm%P_sl = lattice_SchmidMatrix_slip(prm%N_sl,config%getString('lattice_structure'),& prm%P_sl = lattice_SchmidMatrix_slip(N_sl,config%getString('lattice_structure'),&
config%getFloat('c/a',defaultVal=0.0_pReal)) config%getFloat('c/a',defaultVal=0.0_pReal))
prm%h_sl_sl = lattice_interaction_SlipBySlip(prm%N_sl, & prm%h_sl_sl = lattice_interaction_SlipBySlip(N_sl,config%getFloats('interaction_slipslip'), &
config%getFloats('interaction_slipslip'), &
config%getString('lattice_structure')) config%getString('lattice_structure'))
prm%forestProjection = lattice_forestProjection_edge(prm%N_sl,config%getString('lattice_structure'),& prm%forestProjection = lattice_forestProjection_edge(N_sl,config%getString('lattice_structure'),&
config%getFloat('c/a',defaultVal=0.0_pReal)) config%getFloat('c/a',defaultVal=0.0_pReal))
prm%forestProjection = transpose(prm%forestProjection) prm%forestProjection = transpose(prm%forestProjection)
prm%n0_sl = lattice_slip_normal(prm%N_sl,config%getString('lattice_structure'),& prm%n0_sl = lattice_slip_normal(N_sl,config%getString('lattice_structure'),&
config%getFloat('c/a',defaultVal=0.0_pReal)) config%getFloat('c/a',defaultVal=0.0_pReal))
prm%fccTwinTransNucleation = merge(.true., .false., lattice_structure(p) == lattice_FCC_ID) & prm%fccTwinTransNucleation = merge(.true., .false., lattice_structure(p) == lattice_FCC_ID) &
.and. (prm%N_sl(1) == 12) .and. (N_sl(1) == 12)
if(prm%fccTwinTransNucleation) & if(prm%fccTwinTransNucleation) prm%fcc_twinNucleationSlipPair = lattice_FCC_TWINNUCLEATIONSLIPPAIR
prm%fcc_twinNucleationSlipPair = lattice_FCC_TWINNUCLEATIONSLIPPAIR
prm%rho_mob_0 = config%getFloats('rhoedge0', requiredSize=size(prm%N_sl)) rho_mob_0 = config%getFloats('rhoedge0', requiredSize=size(N_sl))
prm%rho_dip_0 = config%getFloats('rhoedgedip0',requiredSize=size(prm%N_sl)) rho_dip_0 = config%getFloats('rhoedgedip0',requiredSize=size(N_sl))
prm%v0 = config%getFloats('v0', requiredSize=size(prm%N_sl)) prm%v0 = config%getFloats('v0', requiredSize=size(N_sl))
prm%b_sl = config%getFloats('slipburgers',requiredSize=size(prm%N_sl)) prm%b_sl = config%getFloats('slipburgers',requiredSize=size(N_sl))
prm%Delta_F = config%getFloats('qedge', requiredSize=size(prm%N_sl)) prm%Delta_F = config%getFloats('qedge', requiredSize=size(N_sl))
prm%CLambdaSlip = config%getFloats('clambdaslip',requiredSize=size(prm%N_sl)) prm%CLambdaSlip = config%getFloats('clambdaslip',requiredSize=size(N_sl))
prm%p = config%getFloats('p_slip', requiredSize=size(prm%N_sl)) prm%p = config%getFloats('p_slip', requiredSize=size(N_sl))
prm%q = config%getFloats('q_slip', requiredSize=size(prm%N_sl)) prm%q = config%getFloats('q_slip', requiredSize=size(N_sl))
prm%B = config%getFloats('b', requiredSize=size(prm%N_sl), & prm%B = config%getFloats('b', requiredSize=size(N_sl), &
defaultVal=[(0.0_pReal, i=1,size(prm%N_sl))]) defaultVal=[(0.0_pReal, i=1,size(N_sl))])
prm%tau_0 = config%getFloat('solidsolutionstrength') prm%tau_0 = config%getFloat('solidsolutionstrength')
prm%CEdgeDipMinDistance = config%getFloat('cedgedipmindistance') prm%CEdgeDipMinDistance = config%getFloat('cedgedipmindistance')
prm%D0 = config%getFloat('d0') prm%D0 = config%getFloat('d0')
prm%Qsd = config%getFloat('qsd') prm%Qsd = config%getFloat('qsd')
prm%atomicVolume = config%getFloat('catomicvolume') * prm%b_sl**3.0_pReal
prm%ExtendedDislocations = config%keyExists('/extend_dislocations/') prm%ExtendedDislocations = config%keyExists('/extend_dislocations/')
if (prm%ExtendedDislocations) then if (prm%ExtendedDislocations) then
prm%SFE_0K = config%getFloat('sfe_0k') prm%SFE_0K = config%getFloat('sfe_0k')
prm%dSFE_dT = config%getFloat('dsfe_dt') prm%dSFE_dT = config%getFloat('dsfe_dt')
endif endif
! multiplication factor according to crystal structure (nearest neighbors bcc vs fcc/hex) prm%dipoleformation = .not. config%keyExists('/nodipoleformation/')
!@details: Refer: Argon & Moffat, Acta Metallurgica, Vol. 29, pg 293 to 299, 1981
prm%omega = config%getFloat('omega', defaultVal = 1000.0_pReal) &
* merge(12.0_pReal, &
8.0_pReal, &
lattice_structure(p) == lattice_FCC_ID .or. lattice_structure(p) == lattice_HEX_ID)
! multiplication factor according to crystal structure (nearest neighbors bcc vs fcc/hex)
! details: Argon & Moffat, Acta Metallurgica, Vol. 29, pg 293 to 299, 1981
prm%omega = config%getFloat('omega', defaultVal = 1000.0_pReal) &
* merge(12.0_pReal,8.0_pReal,any(lattice_structure(p) == [lattice_FCC_ID,lattice_HEX_ID]))
! expand: family => system ! expand: family => system
prm%rho_mob_0 = math_expand(prm%rho_mob_0, prm%N_sl) rho_mob_0 = math_expand(rho_mob_0, N_sl)
prm%rho_dip_0 = math_expand(prm%rho_dip_0, prm%N_sl) rho_dip_0 = math_expand(rho_dip_0, N_sl)
prm%v0 = math_expand(prm%v0, prm%N_sl) prm%v0 = math_expand(prm%v0, N_sl)
prm%b_sl = math_expand(prm%b_sl, prm%N_sl) prm%b_sl = math_expand(prm%b_sl, N_sl)
prm%Delta_F = math_expand(prm%Delta_F, prm%N_sl) prm%Delta_F = math_expand(prm%Delta_F, N_sl)
prm%CLambdaSlip = math_expand(prm%CLambdaSlip, prm%N_sl) prm%CLambdaSlip = math_expand(prm%CLambdaSlip, N_sl)
prm%p = math_expand(prm%p, prm%N_sl) prm%p = math_expand(prm%p, N_sl)
prm%q = math_expand(prm%q, prm%N_sl) prm%q = math_expand(prm%q, N_sl)
prm%B = math_expand(prm%B, prm%N_sl) prm%B = math_expand(prm%B, N_sl)
prm%atomicVolume = math_expand(prm%atomicVolume,prm%N_sl)
! sanity checks ! sanity checks
if ( prm%D0 <= 0.0_pReal) extmsg = trim(extmsg)//' D0' if ( prm%D0 <= 0.0_pReal) extmsg = trim(extmsg)//' D0'
if ( prm%Qsd <= 0.0_pReal) extmsg = trim(extmsg)//' Qsd' if ( prm%Qsd <= 0.0_pReal) extmsg = trim(extmsg)//' Qsd'
if (any(prm%rho_mob_0 < 0.0_pReal)) extmsg = trim(extmsg)//' rho_mob_0' if (any(rho_mob_0 < 0.0_pReal)) extmsg = trim(extmsg)//' rho_mob_0'
if (any(prm%rho_dip_0 < 0.0_pReal)) extmsg = trim(extmsg)//' rho_dip_0' if (any(rho_dip_0 < 0.0_pReal)) extmsg = trim(extmsg)//' rho_dip_0'
if (any(prm%v0 < 0.0_pReal)) extmsg = trim(extmsg)//' v0' if (any(prm%v0 < 0.0_pReal)) extmsg = trim(extmsg)//' v0'
if (any(prm%b_sl <= 0.0_pReal)) extmsg = trim(extmsg)//' b_sl' if (any(prm%b_sl <= 0.0_pReal)) extmsg = trim(extmsg)//' b_sl'
if (any(prm%Delta_F <= 0.0_pReal)) extmsg = trim(extmsg)//' Delta_F' if (any(prm%Delta_F <= 0.0_pReal)) extmsg = trim(extmsg)//' Delta_F'
@ -257,158 +244,152 @@ module subroutine plastic_dislotwin_init
if (any(prm%B < 0.0_pReal)) extmsg = trim(extmsg)//' B' if (any(prm%B < 0.0_pReal)) extmsg = trim(extmsg)//' B'
if (any(prm%p<=0.0_pReal .or. prm%p>1.0_pReal)) extmsg = trim(extmsg)//' p' if (any(prm%p<=0.0_pReal .or. prm%p>1.0_pReal)) extmsg = trim(extmsg)//' p'
if (any(prm%q< 1.0_pReal .or. prm%q>2.0_pReal)) extmsg = trim(extmsg)//' q' if (any(prm%q< 1.0_pReal .or. prm%q>2.0_pReal)) extmsg = trim(extmsg)//' q'
else slipActive else slipActive
allocate(prm%b_sl(0)) rho_mob_0 = emptyRealArray; rho_dip_0 = emptyRealArray
allocate(prm%b_sl,prm%Delta_F,prm%v0,prm%CLambdaSlip,prm%p,prm%q,prm%B,source=emptyRealArray)
allocate(prm%forestProjection(0,0),prm%h_sl_sl(0,0))
endif slipActive endif slipActive
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
! twin related parameters ! twin related parameters
prm%N_tw = config%getInts('ntwin', defaultVal=emptyIntArray) N_tw = config%getInts('ntwin', defaultVal=emptyIntArray)
prm%sum_N_tw = sum(prm%N_tw) prm%sum_N_tw = sum(abs(N_tw))
if (prm%sum_N_tw > 0) then twinActive: if (prm%sum_N_tw > 0) then
prm%P_tw = lattice_SchmidMatrix_twin(prm%N_tw,config%getString('lattice_structure'),& prm%P_tw = lattice_SchmidMatrix_twin(N_tw,config%getString('lattice_structure'),&
config%getFloat('c/a',defaultVal=0.0_pReal)) config%getFloat('c/a',defaultVal=0.0_pReal))
prm%h_tw_tw = lattice_interaction_TwinByTwin(prm%N_tw,& prm%h_tw_tw = lattice_interaction_TwinByTwin(N_tw,&
config%getFloats('interaction_twintwin'), & config%getFloats('interaction_twintwin'), &
config%getString('lattice_structure')) config%getString('lattice_structure'))
prm%b_tw = config%getFloats('twinburgers', requiredSize=size(prm%N_tw)) prm%b_tw = config%getFloats('twinburgers', requiredSize=size(N_tw))
prm%t_tw = config%getFloats('twinsize', requiredSize=size(prm%N_tw)) prm%t_tw = config%getFloats('twinsize', requiredSize=size(N_tw))
prm%r = config%getFloats('r_twin', requiredSize=size(prm%N_tw)) prm%r = config%getFloats('r_twin', requiredSize=size(N_tw))
prm%xc_twin = config%getFloat('xc_twin') prm%xc_twin = config%getFloat('xc_twin')
prm%L_tw = config%getFloat('l0_twin') prm%L_tw = config%getFloat('l0_twin')
prm%i_tw = config%getFloat('cmfptwin') prm%i_tw = config%getFloat('cmfptwin')
prm%gamma_char= lattice_characteristicShear_Twin(prm%N_tw,config%getString('lattice_structure'),& prm%gamma_char= lattice_characteristicShear_Twin(N_tw,config%getString('lattice_structure'),&
config%getFloat('c/a',defaultVal=0.0_pReal)) config%getFloat('c/a',defaultVal=0.0_pReal))
prm%C66_tw = lattice_C66_twin(prm%N_tw,prm%C66,config%getString('lattice_structure'),& prm%C66_tw = lattice_C66_twin(N_tw,prm%C66,config%getString('lattice_structure'),&
config%getFloat('c/a',defaultVal=0.0_pReal)) config%getFloat('c/a',defaultVal=0.0_pReal))
if (.not. prm%fccTwinTransNucleation) then if (.not. prm%fccTwinTransNucleation) then
prm%dot_N_0_tw = config%getFloats('ndot0_twin') prm%dot_N_0_tw = config%getFloats('ndot0_twin')
prm%dot_N_0_tw = math_expand(prm%dot_N_0_tw,prm%N_tw) prm%dot_N_0_tw = math_expand(prm%dot_N_0_tw,N_tw)
endif endif
! expand: family => system ! expand: family => system
prm%b_tw = math_expand(prm%b_tw,prm%N_tw) prm%b_tw = math_expand(prm%b_tw,N_tw)
prm%t_tw = math_expand(prm%t_tw,prm%N_tw) prm%t_tw = math_expand(prm%t_tw,N_tw)
prm%r = math_expand(prm%r,prm%N_tw) prm%r = math_expand(prm%r,N_tw)
else ! sanity checks
allocate(prm%gamma_char(0)) if ( prm%xc_twin < 0.0_pReal) extmsg = trim(extmsg)//' xc_twin'
allocate(prm%t_tw (0)) if ( prm%L_tw < 0.0_pReal) extmsg = trim(extmsg)//' L_tw'
allocate(prm%b_tw (0)) if ( prm%i_tw < 0.0_pReal) extmsg = trim(extmsg)//' i_tw'
allocate(prm%r (0)) if (any(prm%b_tw < 0.0_pReal)) extmsg = trim(extmsg)//' b_tw'
allocate(prm%h_tw_tw (0,0)) if (any(prm%t_tw < 0.0_pReal)) extmsg = trim(extmsg)//' t_tw'
endif if (any(prm%r < 0.0_pReal)) extmsg = trim(extmsg)//' r'
if (.not. prm%fccTwinTransNucleation) then
if (any(prm%dot_N_0_tw < 0.0_pReal)) extmsg = trim(extmsg)//' dot_N_0_tw'
endif
else twinActive
allocate(prm%gamma_char,prm%b_tw,prm%dot_N_0_tw,prm%t_tw,prm%r,source=emptyRealArray)
allocate(prm%h_tw_tw(0,0))
endif twinActive
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
! transformation related parameters ! transformation related parameters
prm%N_tr = config%getInts('ntrans', defaultVal=emptyIntArray) N_tr = config%getInts('ntrans', defaultVal=emptyIntArray)
prm%sum_N_tr = sum(prm%N_tr) prm%sum_N_tr = sum(abs(N_tr))
if (prm%sum_N_tr > 0) then transActive: if (prm%sum_N_tr > 0) then
prm%b_tr = config%getFloats('transburgers') prm%b_tr = config%getFloats('transburgers')
prm%b_tr = math_expand(prm%b_tr,prm%N_tr) prm%b_tr = math_expand(prm%b_tr,N_tr)
prm%h = config%getFloat('transstackheight', defaultVal=0.0_pReal) ! ToDo: How to handle that??? prm%h = config%getFloat('transstackheight', defaultVal=0.0_pReal) ! ToDo: How to handle that???
prm%i_tr = config%getFloat('cmfptrans', defaultVal=0.0_pReal) ! ToDo: How to handle that??? prm%i_tr = config%getFloat('cmfptrans', defaultVal=0.0_pReal) ! ToDo: How to handle that???
prm%gamma_fcc_hex = config%getFloat('deltag') prm%gamma_fcc_hex = config%getFloat('deltag')
prm%xc_trans = config%getFloat('xc_trans', defaultVal=0.0_pReal) ! ToDo: How to handle that??? prm%xc_trans = config%getFloat('xc_trans', defaultVal=0.0_pReal) ! ToDo: How to handle that???
prm%L_tr = config%getFloat('l0_trans') prm%L_tr = config%getFloat('l0_trans')
prm%h_tr_tr = lattice_interaction_TransByTrans(prm%N_tr,& prm%h_tr_tr = lattice_interaction_TransByTrans(N_tr,config%getFloats('interaction_transtrans'), &
config%getFloats('interaction_transtrans'), & config%getString('lattice_structure'))
config%getString('lattice_structure'))
prm%C66_tr = lattice_C66_trans(prm%N_tr,prm%C66, & prm%C66_tr = lattice_C66_trans(N_tr,prm%C66,config%getString('trans_lattice_structure'), &
config%getString('trans_lattice_structure'), & 0.0_pReal, &
0.0_pReal, & config%getFloat('a_bcc', defaultVal=0.0_pReal), &
config%getFloat('a_bcc', defaultVal=0.0_pReal), & config%getFloat('a_fcc', defaultVal=0.0_pReal))
config%getFloat('a_fcc', defaultVal=0.0_pReal))
prm%P_tr = lattice_SchmidMatrix_trans(prm%N_tr, & prm%P_tr = lattice_SchmidMatrix_trans(N_tr,config%getString('trans_lattice_structure'), &
config%getString('trans_lattice_structure'), & 0.0_pReal, &
0.0_pReal, & config%getFloat('a_bcc', defaultVal=0.0_pReal), &
config%getFloat('a_bcc', defaultVal=0.0_pReal), & config%getFloat('a_fcc', defaultVal=0.0_pReal))
config%getFloat('a_fcc', defaultVal=0.0_pReal))
if (lattice_structure(p) /= lattice_FCC_ID) then if (lattice_structure(p) /= lattice_FCC_ID) then
prm%dot_N_0_tr = config%getFloats('ndot0_trans') prm%dot_N_0_tr = config%getFloats('ndot0_trans')
prm%dot_N_0_tr = math_expand(prm%dot_N_0_tr,prm%N_tr) prm%dot_N_0_tr = math_expand(prm%dot_N_0_tr,N_tr)
endif endif
prm%t_tr = config%getFloats('lamellarsize') prm%t_tr = config%getFloats('lamellarsize')
prm%t_tr = math_expand(prm%t_tr,prm%N_tr) prm%t_tr = math_expand(prm%t_tr,N_tr)
prm%s = config%getFloats('s_trans',defaultVal=[0.0_pReal]) prm%s = config%getFloats('s_trans',defaultVal=[0.0_pReal])
prm%s = math_expand(prm%s,prm%N_tr) prm%s = math_expand(prm%s,N_tr)
else
allocate(prm%t_tr (0)) ! sanity checks
allocate(prm%b_tr (0)) if ( prm%xc_trans < 0.0_pReal) extmsg = trim(extmsg)//' xc_trans'
allocate(prm%s (0)) if ( prm%L_tr < 0.0_pReal) extmsg = trim(extmsg)//' L_tr'
if ( prm%i_tr < 0.0_pReal) extmsg = trim(extmsg)//' i_tr'
if (any(prm%t_tr < 0.0_pReal)) extmsg = trim(extmsg)//' t_tr'
if (any(prm%s < 0.0_pReal)) extmsg = trim(extmsg)//' s'
if (lattice_structure(p) /= lattice_FCC_ID) then
if (any(prm%dot_N_0_tr < 0.0_pReal)) extmsg = trim(extmsg)//' dot_N_0_tr'
endif
else transActive
allocate(prm%s,prm%b_tr,prm%t_tr,prm%dot_N_0_tr,source=emptyRealArray)
allocate(prm%h_tr_tr(0,0)) allocate(prm%h_tr_tr(0,0))
endif endif transActive
if (sum(prm%N_tw) > 0 .or. prm%sum_N_tr > 0) then
prm%SFE_0K = config%getFloat('sfe_0k')
prm%dSFE_dT = config%getFloat('dsfe_dt')
prm%V_cs = config%getFloat('vcrossslip')
endif
if (prm%sum_N_sl > 0 .and. prm%sum_N_tw > 0) then
prm%h_sl_tw = lattice_interaction_SlipByTwin(prm%N_sl,prm%N_tw,&
config%getFloats('interaction_sliptwin'), &
config%getString('lattice_structure'))
if (prm%fccTwinTransNucleation .and. prm%sum_N_tw > 12) write(6,*) 'mist' ! ToDo: implement better test. The model will fail also if N_tw is [6,6]
endif
if (prm%sum_N_sl > 0 .and. prm%sum_N_tr > 0) then
prm%h_sl_tr = lattice_interaction_SlipByTrans(prm%N_sl,prm%N_tr,&
config%getFloats('interaction_sliptrans'), &
config%getString('lattice_structure'))
if (prm%fccTwinTransNucleation .and. prm%sum_N_tr > 12) write(6,*) 'mist' ! ToDo: implement better test. The model will fail also if N_tr is [6,6]
endif
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
! shearband related parameters ! shearband related parameters
prm%sbVelocity = config%getFloat('shearbandvelocity',defaultVal=0.0_pReal) prm%sbVelocity = config%getFloat('shearbandvelocity',defaultVal=0.0_pReal)
if (prm%sbVelocity > 0.0_pReal) then if (prm%sbVelocity > 0.0_pReal) then
prm%sbResistance = config%getFloat('shearbandresistance') prm%sbResistance = config%getFloat('shearbandresistance')
prm%sbQedge = config%getFloat('qedgepersbsystem') prm%E_sb = config%getFloat('qedgepersbsystem')
prm%p_sb = config%getFloat('p_shearband') prm%p_sb = config%getFloat('p_shearband')
prm%q_sb = config%getFloat('q_shearband') prm%q_sb = config%getFloat('q_shearband')
! sanity checks ! sanity checks
if (prm%sbResistance < 0.0_pReal) extmsg = trim(extmsg)//' shearbandresistance' if (prm%sbResistance < 0.0_pReal) extmsg = trim(extmsg)//' shearbandresistance'
if (prm%sbQedge < 0.0_pReal) extmsg = trim(extmsg)//' qedgepersbsystem' if (prm%E_sb < 0.0_pReal) extmsg = trim(extmsg)//' qedgepersbsystem'
if (prm%p_sb <= 0.0_pReal) extmsg = trim(extmsg)//' p_shearband' if (prm%p_sb <= 0.0_pReal) extmsg = trim(extmsg)//' p_shearband'
if (prm%q_sb <= 0.0_pReal) extmsg = trim(extmsg)//' q_shearband' if (prm%q_sb <= 0.0_pReal) extmsg = trim(extmsg)//' q_shearband'
endif endif
prm%D = config%getFloat('grainsize') !--------------------------------------------------------------------------------------------------
! parameters required for several mechanisms and their interactions
if(prm%sum_N_sl + prm%sum_N_tw + prm%sum_N_tw > 0) &
prm%D = config%getFloat('grainsize')
if (config%keyExists('dipoleformationfactor')) call IO_error(1,ext_msg='use /nodipoleformation/') twinOrSlipActive: if (prm%sum_N_tw + prm%sum_N_tr > 0) then
prm%dipoleformation = .not. config%keyExists('/nodipoleformation/') prm%SFE_0K = config%getFloat('sfe_0k')
prm%dSFE_dT = config%getFloat('dsfe_dt')
prm%V_cs = config%getFloat('vcrossslip')
endif twinOrSlipActive
slipAndTwinActive: if (prm%sum_N_sl * prm%sum_N_tw > 0) then
prm%h_sl_tw = lattice_interaction_SlipByTwin(N_sl,N_tw,&
config%getFloats('interaction_sliptwin'), &
config%getString('lattice_structure'))
if (prm%fccTwinTransNucleation .and. size(N_tw) /= 1) extmsg = trim(extmsg)//' interaction_sliptwin'
endif slipAndTwinActive
!if (Ndot0PerTwinFamily(f,p) < 0.0_pReal) & slipAndTransActive: if (prm%sum_N_sl * prm%sum_N_tr > 0) then
! call IO_error(211,el=p,ext_msg='dot_N_0_tw ('//PLASTICITY_DISLOTWIN_label//')') prm%h_sl_tr = lattice_interaction_SlipByTrans(N_sl,N_tr,&
config%getFloats('interaction_sliptrans'), &
if (any(prm%atomicVolume <= 0.0_pReal)) & config%getString('lattice_structure'))
call IO_error(211,el=p,ext_msg='cAtomicVolume ('//PLASTICITY_DISLOTWIN_label//')') if (prm%fccTwinTransNucleation .and. size(N_tr) /= 1) extmsg = trim(extmsg)//' interaction_sliptrans'
if (prm%sum_N_tw > 0) then endif slipAndTransActive
if (prm%aTol_rho <= 0.0_pReal) &
call IO_error(211,el=p,ext_msg='aTol_rho ('//PLASTICITY_DISLOTWIN_label//')')
if (prm%aTol_f_tw <= 0.0_pReal) &
call IO_error(211,el=p,ext_msg='aTol_f_tw ('//PLASTICITY_DISLOTWIN_label//')')
endif
if (prm%sum_N_tr > 0) then
if (prm%aTol_f_tr <= 0.0_pReal) &
call IO_error(211,el=p,ext_msg='aTol_f_tr ('//PLASTICITY_DISLOTWIN_label//')')
endif
prm%output = config%getStrings('(output)', defaultVal=emptyStringArray)
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
! allocate state arrays ! allocate state arrays
@ -421,26 +402,27 @@ module subroutine plastic_dislotwin_init
call material_allocatePlasticState(p,NipcMyPhase,sizeState,sizeDotState,0) call material_allocatePlasticState(p,NipcMyPhase,sizeState,sizeDotState,0)
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
! locally defined state aliases and initialization of state0 and aTolState ! locally defined state aliases and initialization of state0 and atol
startIndex = 1 startIndex = 1
endIndex = prm%sum_N_sl endIndex = prm%sum_N_sl
stt%rho_mob=>plasticState(p)%state(startIndex:endIndex,:) stt%rho_mob=>plasticState(p)%state(startIndex:endIndex,:)
stt%rho_mob= spread(prm%rho_mob_0,2,NipcMyPhase) stt%rho_mob= spread(rho_mob_0,2,NipcMyPhase)
dot%rho_mob=>plasticState(p)%dotState(startIndex:endIndex,:) dot%rho_mob=>plasticState(p)%dotState(startIndex:endIndex,:)
plasticState(p)%aTolState(startIndex:endIndex) = prm%aTol_rho plasticState(p)%atol(startIndex:endIndex) = config%getFloat('atol_rho',defaultVal=1.0_pReal)
if (any(plasticState(p)%atol(startIndex:endIndex) < 0.0_pReal)) extmsg = trim(extmsg)//' atol_rho'
startIndex = endIndex + 1 startIndex = endIndex + 1
endIndex = endIndex + prm%sum_N_sl endIndex = endIndex + prm%sum_N_sl
stt%rho_dip=>plasticState(p)%state(startIndex:endIndex,:) stt%rho_dip=>plasticState(p)%state(startIndex:endIndex,:)
stt%rho_dip= spread(prm%rho_dip_0,2,NipcMyPhase) stt%rho_dip= spread(rho_dip_0,2,NipcMyPhase)
dot%rho_dip=>plasticState(p)%dotState(startIndex:endIndex,:) dot%rho_dip=>plasticState(p)%dotState(startIndex:endIndex,:)
plasticState(p)%aTolState(startIndex:endIndex) = prm%aTol_rho plasticState(p)%atol(startIndex:endIndex) = config%getFloat('atol_rho',defaultVal=1.0_pReal)
startIndex = endIndex + 1 startIndex = endIndex + 1
endIndex = endIndex + prm%sum_N_sl endIndex = endIndex + prm%sum_N_sl
stt%gamma_sl=>plasticState(p)%state(startIndex:endIndex,:) stt%gamma_sl=>plasticState(p)%state(startIndex:endIndex,:)
dot%gamma_sl=>plasticState(p)%dotState(startIndex:endIndex,:) dot%gamma_sl=>plasticState(p)%dotState(startIndex:endIndex,:)
plasticState(p)%aTolState(startIndex:endIndex) = 1.0e6_pReal !ToDo: better make optional parameter plasticState(p)%atol(startIndex:endIndex) = 1.0e-2_pReal
! global alias ! global alias
plasticState(p)%slipRate => plasticState(p)%dotState(startIndex:endIndex,:) plasticState(p)%slipRate => plasticState(p)%dotState(startIndex:endIndex,:)
@ -448,13 +430,15 @@ module subroutine plastic_dislotwin_init
endIndex = endIndex + prm%sum_N_tw endIndex = endIndex + prm%sum_N_tw
stt%f_tw=>plasticState(p)%state(startIndex:endIndex,:) stt%f_tw=>plasticState(p)%state(startIndex:endIndex,:)
dot%f_tw=>plasticState(p)%dotState(startIndex:endIndex,:) dot%f_tw=>plasticState(p)%dotState(startIndex:endIndex,:)
plasticState(p)%aTolState(startIndex:endIndex) = prm%aTol_f_tw plasticState(p)%atol(startIndex:endIndex) = config%getFloat('f_twin',defaultVal=1.0e-7_pReal)
if (any(plasticState(p)%atol(startIndex:endIndex) < 0.0_pReal)) extmsg = trim(extmsg)//' f_twin'
startIndex = endIndex + 1 startIndex = endIndex + 1
endIndex = endIndex + prm%sum_N_tr endIndex = endIndex + prm%sum_N_tr
stt%f_tr=>plasticState(p)%state(startIndex:endIndex,:) stt%f_tr=>plasticState(p)%state(startIndex:endIndex,:)
dot%f_tr=>plasticState(p)%dotState(startIndex:endIndex,:) dot%f_tr=>plasticState(p)%dotState(startIndex:endIndex,:)
plasticState(p)%aTolState(startIndex:endIndex) = prm%aTol_f_tr plasticState(p)%atol(startIndex:endIndex) = config%getFloat('f_trans',defaultVal=1.0e-6_pReal)
if (any(plasticState(p)%atol(startIndex:endIndex) < 0.0_pReal)) extmsg = trim(extmsg)//' f_trans'
allocate(dst%Lambda_sl (prm%sum_N_sl,NipcMyPhase),source=0.0_pReal) allocate(dst%Lambda_sl (prm%sum_N_sl,NipcMyPhase),source=0.0_pReal)
allocate(dst%tau_pass (prm%sum_N_sl,NipcMyPhase),source=0.0_pReal) allocate(dst%tau_pass (prm%sum_N_sl,NipcMyPhase),source=0.0_pReal)
@ -469,11 +453,14 @@ module subroutine plastic_dislotwin_init
allocate(dst%tau_r_tr (prm%sum_N_tr,NipcMyPhase),source=0.0_pReal) allocate(dst%tau_r_tr (prm%sum_N_tr,NipcMyPhase),source=0.0_pReal)
allocate(dst%V_tr (prm%sum_N_tr,NipcMyPhase),source=0.0_pReal) allocate(dst%V_tr (prm%sum_N_tr,NipcMyPhase),source=0.0_pReal)
plasticState(p)%state0 = plasticState(p)%state ! ToDo: this could be done centrally
plasticState(p)%state0 = plasticState(p)%state ! ToDo: this could be done centrally
end associate end associate
!--------------------------------------------------------------------------------------------------
! exit if any parameter is out of range
if (extmsg /= '') call IO_error(211,ext_msg=trim(extmsg)//'('//PLASTICITY_DISLOTWIN_LABEL//')')
enddo enddo
end subroutine plastic_dislotwin_init end subroutine plastic_dislotwin_init
@ -544,7 +531,6 @@ module subroutine plastic_dislotwin_LpAndItsTangent(Lp,dLp_dMp,Mp,T,instance,of)
real(pReal):: dot_gamma_sb real(pReal):: dot_gamma_sb
real(pReal), dimension(3,3) :: eigVectors, P_sb real(pReal), dimension(3,3) :: eigVectors, P_sb
real(pReal), dimension(3) :: eigValues real(pReal), dimension(3) :: eigValues
logical :: error
real(pReal), dimension(3,6), parameter :: & real(pReal), dimension(3,6), parameter :: &
sb_sComposition = & sb_sComposition = &
reshape(real([& reshape(real([&
@ -588,13 +574,13 @@ module subroutine plastic_dislotwin_LpAndItsTangent(Lp,dLp_dMp,Mp,T,instance,of)
shearBandingContribution: if(dNeq0(prm%sbVelocity)) then shearBandingContribution: if(dNeq0(prm%sbVelocity)) then
BoltzmannRatio = prm%sbQedge/(kB*T) BoltzmannRatio = prm%E_sb/(kB*T)
call math_eigenValuesVectorsSym(Mp,eigValues,eigVectors,error) call math_eigh33(Mp,eigValues,eigVectors) ! is Mp symmetric by design?
do i = 1,6 do i = 1,6
P_sb = 0.5_pReal * math_outer(matmul(eigVectors,sb_sComposition(1:3,i)),& P_sb = 0.5_pReal * math_outer(matmul(eigVectors,sb_sComposition(1:3,i)),&
matmul(eigVectors,sb_mComposition(1:3,i))) matmul(eigVectors,sb_mComposition(1:3,i)))
tau = math_mul33xx33(Mp,P_sb) tau = math_tensordot(Mp,P_sb)
significantShearBandStress: if (abs(tau) > tol_math_check) then significantShearBandStress: if (abs(tau) > tol_math_check) then
StressRatio_p = (abs(tau)/prm%sbResistance)**prm%p_sb StressRatio_p = (abs(tau)/prm%sbResistance)**prm%p_sb
@ -650,7 +636,6 @@ module subroutine plastic_dislotwin_dotState(Mp,T,instance,of)
integer :: i integer :: i
real(pReal) :: & real(pReal) :: &
f_unrotated, & f_unrotated, &
VacancyDiffusion, &
rho_dip_distance, & rho_dip_distance, &
v_cl, & !< climb velocity v_cl, & !< climb velocity
Gamma, & !< stacking fault energy Gamma, & !< stacking fault energy
@ -673,7 +658,6 @@ module subroutine plastic_dislotwin_dotState(Mp,T,instance,of)
f_unrotated = 1.0_pReal & f_unrotated = 1.0_pReal &
- sum(stt%f_tw(1:prm%sum_N_tw,of)) & - sum(stt%f_tw(1:prm%sum_N_tw,of)) &
- sum(stt%f_tr(1:prm%sum_N_tr,of)) - sum(stt%f_tr(1:prm%sum_N_tr,of))
VacancyDiffusion = prm%D0*exp(-prm%Qsd/(kB*T))
call kinetics_slip(Mp,T,instance,of,dot_gamma_sl) call kinetics_slip(Mp,T,instance,of,dot_gamma_sl)
dot%gamma_sl(:,of) = abs(dot_gamma_sl) dot%gamma_sl(:,of) = abs(dot_gamma_sl)
@ -681,7 +665,7 @@ module subroutine plastic_dislotwin_dotState(Mp,T,instance,of)
rho_dip_distance_min = prm%CEdgeDipMinDistance*prm%b_sl rho_dip_distance_min = prm%CEdgeDipMinDistance*prm%b_sl
slipState: do i = 1, prm%sum_N_sl slipState: do i = 1, prm%sum_N_sl
tau = math_mul33xx33(Mp,prm%P_sl(1:3,1:3,i)) tau = math_tensordot(Mp,prm%P_sl(1:3,1:3,i))
significantSlipStress: if (dEq0(tau)) then significantSlipStress: if (dEq0(tau)) then
dot_rho_dip_formation(i) = 0.0_pReal dot_rho_dip_formation(i) = 0.0_pReal
@ -774,9 +758,9 @@ module subroutine plastic_dislotwin_dependentState(T,instance,of)
Gamma = prm%SFE_0K + prm%dSFE_dT * T Gamma = prm%SFE_0K + prm%dSFE_dT * T
!* rescaled volume fraction for topology !* rescaled volume fraction for topology
f_over_t_tw = stt%f_tw(1:prm%sum_N_tw,of)/prm%t_tw ! this is per system ... f_over_t_tw = stt%f_tw(1:prm%sum_N_tw,of)/prm%t_tw ! this is per system ...
f_over_t_tr = sumf_trans/prm%t_tr ! but this not f_over_t_tr = sumf_trans/prm%t_tr ! but this not
! ToDo ...Physically correct, but naming could be adjusted ! ToDo ...Physically correct, but naming could be adjusted
inv_lambda_sl_sl = sqrt(matmul(prm%forestProjection, & inv_lambda_sl_sl = sqrt(matmul(prm%forestProjection, &
stt%rho_mob(:,of)+stt%rho_dip(:,of)))/prm%CLambdaSlip stt%rho_mob(:,of)+stt%rho_dip(:,of)))/prm%CLambdaSlip
@ -791,7 +775,7 @@ module subroutine plastic_dislotwin_dependentState(T,instance,of)
inv_lambda_tr_tr = matmul(prm%h_tr_tr,f_over_t_tr)/(1.0_pReal-sumf_trans) inv_lambda_tr_tr = matmul(prm%h_tr_tr,f_over_t_tr)/(1.0_pReal-sumf_trans)
if ((prm%sum_N_tw > 0) .or. (prm%sum_N_tr > 0)) then ! ToDo: better logic needed here if ((prm%sum_N_tw > 0) .or. (prm%sum_N_tr > 0)) then ! ToDo: better logic needed here
dst%Lambda_sl(:,of) = prm%D & dst%Lambda_sl(:,of) = prm%D &
/ (1.0_pReal+prm%D*(inv_lambda_sl_sl + inv_lambda_sl_tw + inv_lambda_sl_tr)) / (1.0_pReal+prm%D*(inv_lambda_sl_sl + inv_lambda_sl_tw + inv_lambda_sl_tr))
else else
@ -818,10 +802,10 @@ module subroutine plastic_dislotwin_dependentState(T,instance,of)
dst%V_tr(:,of) = (PI/4.0_pReal)*prm%t_tr*dst%Lambda_tr(:,of)**2.0_pReal dst%V_tr(:,of) = (PI/4.0_pReal)*prm%t_tr*dst%Lambda_tr(:,of)**2.0_pReal
x0 = prm%mu*prm%b_tw**2.0_pReal/(Gamma*8.0_pReal*PI)*(2.0_pReal+prm%nu)/(1.0_pReal-prm%nu) ! ToDo: In the paper, this is the burgers vector for slip and is the same for twin and trans x0 = prm%mu*prm%b_tw**2.0_pReal/(Gamma*8.0_pReal*PI)*(2.0_pReal+prm%nu)/(1.0_pReal-prm%nu) ! ToDo: In the paper, this is the burgers vector for slip and is the same for twin and trans
dst%tau_r_tw(:,of) = prm%mu*prm%b_tw/(2.0_pReal*PI)*(1.0_pReal/(x0+prm%xc_twin)+cos(pi/3.0_pReal)/x0) dst%tau_r_tw(:,of) = prm%mu*prm%b_tw/(2.0_pReal*PI)*(1.0_pReal/(x0+prm%xc_twin)+cos(pi/3.0_pReal)/x0)
x0 = prm%mu*prm%b_tr**2.0_pReal/(Gamma*8.0_pReal*PI)*(2.0_pReal+prm%nu)/(1.0_pReal-prm%nu) ! ToDo: In the paper, this is the burgers vector for slip x0 = prm%mu*prm%b_tr**2.0_pReal/(Gamma*8.0_pReal*PI)*(2.0_pReal+prm%nu)/(1.0_pReal-prm%nu) ! ToDo: In the paper, this is the burgers vector for slip
dst%tau_r_tr(:,of) = prm%mu*prm%b_tr/(2.0_pReal*PI)*(1.0_pReal/(x0+prm%xc_trans)+cos(pi/3.0_pReal)/x0) dst%tau_r_tr(:,of) = prm%mu*prm%b_tr/(2.0_pReal*PI)*(1.0_pReal/(x0+prm%xc_trans)+cos(pi/3.0_pReal)/x0)
end associate end associate
@ -922,7 +906,7 @@ pure subroutine kinetics_slip(Mp,T,instance,of, &
associate(prm => param(instance), stt => state(instance), dst => dependentState(instance)) associate(prm => param(instance), stt => state(instance), dst => dependentState(instance))
do i = 1, prm%sum_N_sl do i = 1, prm%sum_N_sl
tau(i) = math_mul33xx33(Mp,prm%P_sl(1:3,1:3,i)) tau(i) = math_tensordot(Mp,prm%P_sl(1:3,1:3,i))
enddo enddo
tau_eff = abs(tau)-dst%tau_pass(:,of) tau_eff = abs(tau)-dst%tau_pass(:,of)
@ -993,7 +977,7 @@ pure subroutine kinetics_twin(Mp,T,dot_gamma_sl,instance,of,&
associate(prm => param(instance), stt => state(instance), dst => dependentState(instance)) associate(prm => param(instance), stt => state(instance), dst => dependentState(instance))
do i = 1, prm%sum_N_tw do i = 1, prm%sum_N_tw
tau(i) = math_mul33xx33(Mp,prm%P_tw(1:3,1:3,i)) tau(i) = math_tensordot(Mp,prm%P_tw(1:3,1:3,i))
isFCC: if (prm%fccTwinTransNucleation) then isFCC: if (prm%fccTwinTransNucleation) then
s1=prm%fcc_twinNucleationSlipPair(1,i) s1=prm%fcc_twinNucleationSlipPair(1,i)
s2=prm%fcc_twinNucleationSlipPair(2,i) s2=prm%fcc_twinNucleationSlipPair(2,i)
@ -1061,7 +1045,7 @@ pure subroutine kinetics_trans(Mp,T,dot_gamma_sl,instance,of,&
associate(prm => param(instance), stt => state(instance), dst => dependentState(instance)) associate(prm => param(instance), stt => state(instance), dst => dependentState(instance))
do i = 1, prm%sum_N_tr do i = 1, prm%sum_N_tr
tau(i) = math_mul33xx33(Mp,prm%P_tr(1:3,1:3,i)) tau(i) = math_tensordot(Mp,prm%P_tr(1:3,1:3,i))
isFCC: if (prm%fccTwinTransNucleation) then isFCC: if (prm%fccTwinTransNucleation) then
s1=prm%fcc_twinNucleationSlipPair(1,i) s1=prm%fcc_twinNucleationSlipPair(1,i)
s2=prm%fcc_twinNucleationSlipPair(2,i) s2=prm%fcc_twinNucleationSlipPair(2,i)

View File

@ -12,7 +12,6 @@ submodule(constitutive) plastic_isotropic
type :: tParameters type :: tParameters
real(pReal) :: & real(pReal) :: &
M, & !< Taylor factor M, & !< Taylor factor
xi_0, & !< initial critical stress
dot_gamma_0, & !< reference strain rate dot_gamma_0, & !< reference strain rate
n, & !< stress exponent n, & !< stress exponent
h0, & h0, &
@ -22,9 +21,7 @@ submodule(constitutive) plastic_isotropic
c_1, & c_1, &
c_4, & c_4, &
c_3, & c_3, &
c_2, & c_2
aTol_xi, &
aTol_gamma
integer :: & integer :: &
of_debug = 0 of_debug = 0
logical :: & logical :: &
@ -59,11 +56,12 @@ module subroutine plastic_isotropic_init
p, & p, &
NipcMyPhase, & NipcMyPhase, &
sizeState, sizeDotState sizeState, sizeDotState
real(pReal) :: &
xi_0 !< initial critical stress
character(len=pStringLen) :: & character(len=pStringLen) :: &
extmsg = '' extmsg = ''
write(6,'(/,a)') ' <<<+- plastic_'//PLASTICITY_ISOTROPIC_label//' init -+>>>'; flush(6) write(6,'(/,a)') ' <<<+- plastic_'//PLASTICITY_ISOTROPIC_LABEL//' init -+>>>'; flush(6)
write(6,'(/,a)') ' Maiti and Eisenlohr, Scripta Materialia 145:3740, 2018' write(6,'(/,a)') ' Maiti and Eisenlohr, Scripta Materialia 145:3740, 2018'
write(6,'(a)') ' https://doi.org/10.1016/j.scriptamat.2017.09.047' write(6,'(a)') ' https://doi.org/10.1016/j.scriptamat.2017.09.047'
@ -83,48 +81,35 @@ module subroutine plastic_isotropic_init
stt => state(phase_plasticityInstance(p)), & stt => state(phase_plasticityInstance(p)), &
config => config_phase(p)) config => config_phase(p))
prm%output = config%getStrings('(output)',defaultVal=emptyStringArray)
#ifdef DEBUG #ifdef DEBUG
if (p==material_phaseAt(debug_g,debug_e)) & if (p==material_phaseAt(debug_g,debug_e)) &
prm%of_debug = material_phasememberAt(debug_g,debug_i,debug_e) prm%of_debug = material_phasememberAt(debug_g,debug_i,debug_e)
#endif #endif
prm%xi_0 = config%getFloat('tau0') xi_0 = config%getFloat('tau0')
prm%xi_inf = config%getFloat('tausat') prm%xi_inf = config%getFloat('tausat')
prm%dot_gamma_0 = config%getFloat('gdot0') prm%dot_gamma_0 = config%getFloat('gdot0')
prm%n = config%getFloat('n') prm%n = config%getFloat('n')
prm%h0 = config%getFloat('h0') prm%h0 = config%getFloat('h0')
prm%M = config%getFloat('m') prm%M = config%getFloat('m')
prm%h_ln = config%getFloat('h0_slopelnrate', defaultVal=0.0_pReal) prm%h_ln = config%getFloat('h0_slopelnrate', defaultVal=0.0_pReal)
prm%c_1 = config%getFloat('tausat_sinhfita',defaultVal=0.0_pReal) prm%c_1 = config%getFloat('tausat_sinhfita',defaultVal=0.0_pReal)
prm%c_4 = config%getFloat('tausat_sinhfitb',defaultVal=0.0_pReal) prm%c_4 = config%getFloat('tausat_sinhfitb',defaultVal=0.0_pReal)
prm%c_3 = config%getFloat('tausat_sinhfitc',defaultVal=0.0_pReal) prm%c_3 = config%getFloat('tausat_sinhfitc',defaultVal=0.0_pReal)
prm%c_2 = config%getFloat('tausat_sinhfitd',defaultVal=0.0_pReal) prm%c_2 = config%getFloat('tausat_sinhfitd',defaultVal=0.0_pReal)
prm%a = config%getFloat('a') prm%a = config%getFloat('a')
prm%aTol_xi = config%getFloat('atol_flowstress',defaultVal=1.0_pReal)
prm%aTol_gamma = config%getFloat('atol_shear', defaultVal=1.0e-6_pReal)
prm%dilatation = config%keyExists('/dilatation/') prm%dilatation = config%keyExists('/dilatation/')
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
! sanity checks ! sanity checks
extmsg = '' if (xi_0 < 0.0_pReal) extmsg = trim(extmsg)//' xi_0'
if (prm%aTol_gamma <= 0.0_pReal) extmsg = trim(extmsg)//' aTol_gamma' if (prm%dot_gamma_0 <= 0.0_pReal) extmsg = trim(extmsg)//' dot_gamma_0'
if (prm%xi_0 < 0.0_pReal) extmsg = trim(extmsg)//' xi_0' if (prm%n <= 0.0_pReal) extmsg = trim(extmsg)//' n'
if (prm%dot_gamma_0 <= 0.0_pReal) extmsg = trim(extmsg)//' dot_gamma_0' if (prm%a <= 0.0_pReal) extmsg = trim(extmsg)//' a'
if (prm%n <= 0.0_pReal) extmsg = trim(extmsg)//' n' if (prm%M <= 0.0_pReal) extmsg = trim(extmsg)//' M'
if (prm%a <= 0.0_pReal) extmsg = trim(extmsg)//' a'
if (prm%M <= 0.0_pReal) extmsg = trim(extmsg)//' m'
if (prm%aTol_xi <= 0.0_pReal) extmsg = trim(extmsg)//' atol_xi'
if (prm%aTol_gamma <= 0.0_pReal) extmsg = trim(extmsg)//' atol_shear'
!--------------------------------------------------------------------------------------------------
! exit if any parameter is out of range
if (extmsg /= '') &
call IO_error(211,ext_msg=trim(extmsg)//'('//PLASTICITY_ISOTROPIC_label//')')
!--------------------------------------------------------------------------------------------------
! output pararameters
prm%output = config%getStrings('(output)',defaultVal=emptyStringArray)
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
! allocate state arrays ! allocate state arrays
@ -135,15 +120,17 @@ module subroutine plastic_isotropic_init
call material_allocatePlasticState(p,NipcMyPhase,sizeState,sizeDotState,0) call material_allocatePlasticState(p,NipcMyPhase,sizeState,sizeDotState,0)
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
! locally defined state aliases and initialization of state0 and aTolState ! state aliases and initialization
stt%xi => plasticState(p)%state (1,:) stt%xi => plasticState(p)%state (1,:)
stt%xi = prm%xi_0 stt%xi = xi_0
dot%xi => plasticState(p)%dotState(1,:) dot%xi => plasticState(p)%dotState(1,:)
plasticState(p)%aTolState(1) = prm%aTol_xi plasticState(p)%atol(1) = config%getFloat('atol_xi',defaultVal=1.0_pReal)
if (plasticState(p)%atol(1) < 0.0_pReal) extmsg = trim(extmsg)//' atol_xi'
stt%gamma => plasticState(p)%state (2,:) stt%gamma => plasticState(p)%state (2,:)
dot%gamma => plasticState(p)%dotState(2,:) dot%gamma => plasticState(p)%dotState(2,:)
plasticState(p)%aTolState(2) = prm%aTol_gamma plasticState(p)%atol(2) = config%getFloat('atol_gamma',defaultVal=1.0e-6_pReal)
if (plasticState(p)%atol(2) < 0.0_pReal) extmsg = trim(extmsg)//' atol_gamma'
! global alias ! global alias
plasticState(p)%slipRate => plasticState(p)%dotState(2:2,:) plasticState(p)%slipRate => plasticState(p)%dotState(2:2,:)
@ -151,6 +138,10 @@ module subroutine plastic_isotropic_init
end associate end associate
!--------------------------------------------------------------------------------------------------
! exit if any parameter is out of range
if (extmsg /= '') call IO_error(211,ext_msg=trim(extmsg)//'('//PLASTICITY_ISOTROPIC_LABEL//')')
enddo enddo
end subroutine plastic_isotropic_init end subroutine plastic_isotropic_init
@ -184,7 +175,7 @@ module subroutine plastic_isotropic_LpAndItsTangent(Lp,dLp_dMp,Mp,instance,of)
associate(prm => param(instance), stt => state(instance)) associate(prm => param(instance), stt => state(instance))
Mp_dev = math_deviatoric33(Mp) Mp_dev = math_deviatoric33(Mp)
squarenorm_Mp_dev = math_mul33xx33(Mp_dev,Mp_dev) squarenorm_Mp_dev = math_tensordot(Mp_dev,Mp_dev)
norm_Mp_dev = sqrt(squarenorm_Mp_dev) norm_Mp_dev = sqrt(squarenorm_Mp_dev)
if (norm_Mp_dev > 0.0_pReal) then if (norm_Mp_dev > 0.0_pReal) then
@ -222,14 +213,14 @@ end subroutine plastic_isotropic_LpAndItsTangent
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
module subroutine plastic_isotropic_LiAndItsTangent(Li,dLi_dMi,Mi,instance,of) module subroutine plastic_isotropic_LiAndItsTangent(Li,dLi_dMi,Mi,instance,of)
real(pReal), dimension(3,3), intent(out) :: & real(pReal), dimension(3,3), intent(out) :: &
Li !< inleastic velocity gradient Li !< inleastic velocity gradient
real(pReal), dimension(3,3,3,3), intent(out) :: & real(pReal), dimension(3,3,3,3), intent(out) :: &
dLi_dMi !< derivative of Li with respect to Mandel stress dLi_dMi !< derivative of Li with respect to Mandel stress
real(pReal), dimension(3,3), intent(in) :: & real(pReal), dimension(3,3), intent(in) :: &
Mi !< Mandel stress Mi !< Mandel stress
integer, intent(in) :: & integer, intent(in) :: &
instance, & instance, &
of of
@ -288,9 +279,9 @@ module subroutine plastic_isotropic_dotState(Mp,instance,of)
associate(prm => param(instance), stt => state(instance), dot => dotState(instance)) associate(prm => param(instance), stt => state(instance), dot => dotState(instance))
if (prm%dilatation) then if (prm%dilatation) then
norm_Mp = sqrt(math_mul33xx33(Mp,Mp)) norm_Mp = sqrt(math_tensordot(Mp,Mp))
else else
norm_Mp = sqrt(math_mul33xx33(math_deviatoric33(Mp),math_deviatoric33(Mp))) norm_Mp = sqrt(math_tensordot(math_deviatoric33(Mp),math_deviatoric33(Mp)))
endif endif
dot_gamma = prm%dot_gamma_0 * (sqrt(1.5_pReal) * norm_Mp /(prm%M*stt%xi(of))) **prm%n dot_gamma = prm%dot_gamma_0 * (sqrt(1.5_pReal) * norm_Mp /(prm%M*stt%xi(of))) **prm%n

View File

@ -9,30 +9,26 @@ submodule(constitutive) plastic_kinehardening
type :: tParameters type :: tParameters
real(pReal) :: & real(pReal) :: &
gdot0, & !< reference shear strain rate for slip gdot0 = 1.0_pReal, & !< reference shear strain rate for slip
n, & !< stress exponent for slip n = 1.0_pReal !< stress exponent for slip
aTolResistance, &
aTolShear
real(pReal), allocatable, dimension(:) :: & real(pReal), allocatable, dimension(:) :: &
crss0, & !< initial critical shear stress for slip
theta0, & !< initial hardening rate of forward stress for each slip theta0, & !< initial hardening rate of forward stress for each slip
theta1, & !< asymptotic hardening rate of forward stress for each slip theta1, & !< asymptotic hardening rate of forward stress for each slip
theta0_b, & !< initial hardening rate of back stress for each slip theta0_b, & !< initial hardening rate of back stress for each slip
theta1_b, & !< asymptotic hardening rate of back stress for each slip theta1_b, & !< asymptotic hardening rate of back stress for each slip
tau1, & tau1, &
tau1_b, & tau1_b
nonSchmidCoeff
real(pReal), allocatable, dimension(:,:) :: & real(pReal), allocatable, dimension(:,:) :: &
interaction_slipslip !< slip resistance from slip activity interaction_slipslip !< slip resistance from slip activity
real(pReal), allocatable, dimension(:,:,:) :: & real(pReal), allocatable, dimension(:,:,:) :: &
Schmid, & P, &
nonSchmid_pos, & nonSchmid_pos, &
nonSchmid_neg nonSchmid_neg
integer :: & integer :: &
totalNslip, & !< total number of active slip system sum_N_sl, & !< total number of active slip system
of_debug = 0 of_debug = 0
integer, allocatable, dimension(:) :: & logical :: &
Nslip !< number of active slip systems for each family nonSchmidActive = .false.
character(len=pStringLen), allocatable, dimension(:) :: & character(len=pStringLen), allocatable, dimension(:) :: &
output output
end type tParameters end type tParameters
@ -70,11 +66,15 @@ module subroutine plastic_kinehardening_init
NipcMyPhase, & NipcMyPhase, &
sizeState, sizeDeltaState, sizeDotState, & sizeState, sizeDeltaState, sizeDotState, &
startIndex, endIndex startIndex, endIndex
integer, dimension(:), allocatable :: &
N_sl
real(pReal), dimension(:), allocatable :: &
xi_0, & !< initial resistance against plastic flow
a !< non-Schmid coefficients
character(len=pStringLen) :: & character(len=pStringLen) :: &
extmsg = '' extmsg = ''
write(6,'(/,a)') ' <<<+- plastic_'//PLASTICITY_KINEHARDENING_label//' init -+>>>'; flush(6) write(6,'(/,a)') ' <<<+- plastic_'//PLASTICITY_KINEHARDENING_LABEL//' init -+>>>'; flush(6)
Ninstance = count(phase_plasticity == PLASTICITY_KINEHARDENING_ID) Ninstance = count(phase_plasticity == PLASTICITY_KINEHARDENING_ID)
if (iand(debug_level(debug_constitutive),debug_levelBasic) /= 0) & if (iand(debug_level(debug_constitutive),debug_levelBasic) /= 0) &
@ -93,130 +93,117 @@ module subroutine plastic_kinehardening_init
stt => state(phase_plasticityInstance(p)),& stt => state(phase_plasticityInstance(p)),&
config => config_phase(p)) config => config_phase(p))
prm%output = config%getStrings('(output)',defaultVal=emptyStringArray)
#ifdef DEBUG #ifdef DEBUG
if (p==material_phaseAt(debug_g,debug_e)) then if (p==material_phaseAt(debug_g,debug_e)) then
prm%of_debug = material_phasememberAt(debug_g,debug_i,debug_e) prm%of_debug = material_phasememberAt(debug_g,debug_i,debug_e)
endif endif
#endif #endif
!--------------------------------------------------------------------------------------------------
! optional parameters that need to be defined
prm%aTolResistance = config%getFloat('atol_resistance',defaultVal=1.0_pReal)
prm%aTolShear = config%getFloat('atol_shear', defaultVal=1.0e-6_pReal)
! sanity checks
if (prm%aTolResistance <= 0.0_pReal) extmsg = trim(extmsg)//' aTolresistance'
if (prm%aTolShear <= 0.0_pReal) extmsg = trim(extmsg)//' aTolShear'
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
! slip related parameters ! slip related parameters
prm%Nslip = config%getInts('nslip',defaultVal=emptyIntArray) N_sl = config%getInts('nslip',defaultVal=emptyIntArray)
prm%totalNslip = sum(prm%Nslip) prm%sum_N_sl = sum(abs(N_sl))
slipActive: if (prm%totalNslip > 0) then slipActive: if (prm%sum_N_sl > 0) then
prm%Schmid = lattice_SchmidMatrix_slip(prm%Nslip,config%getString('lattice_structure'),& prm%P = lattice_SchmidMatrix_slip(N_sl,config%getString('lattice_structure'),&
config%getFloat('c/a',defaultVal=0.0_pReal)) config%getFloat('c/a',defaultVal=0.0_pReal))
if(trim(config%getString('lattice_structure')) == 'bcc') then if(trim(config%getString('lattice_structure')) == 'bcc') then
prm%nonSchmidCoeff = config%getFloats('nonschmid_coefficients',& a = config%getFloats('nonschmid_coefficients',defaultVal = emptyRealArray)
defaultVal = emptyRealArray) if(size(a) > 0) prm%nonSchmidActive = .true.
prm%nonSchmid_pos = lattice_nonSchmidMatrix(prm%Nslip,prm%nonSchmidCoeff,+1) prm%nonSchmid_pos = lattice_nonSchmidMatrix(N_sl,a,+1)
prm%nonSchmid_neg = lattice_nonSchmidMatrix(prm%Nslip,prm%nonSchmidCoeff,-1) prm%nonSchmid_neg = lattice_nonSchmidMatrix(N_sl,a,-1)
else else
prm%nonSchmid_pos = prm%Schmid prm%nonSchmid_pos = prm%P
prm%nonSchmid_neg = prm%Schmid prm%nonSchmid_neg = prm%P
endif endif
prm%interaction_SlipSlip = lattice_interaction_SlipBySlip(prm%Nslip, & prm%interaction_SlipSlip = lattice_interaction_SlipBySlip(N_sl, &
config%getFloats('interaction_slipslip'), & config%getFloats('interaction_slipslip'), &
config%getString('lattice_structure')) config%getString('lattice_structure'))
prm%crss0 = config%getFloats('crss0', requiredSize=size(prm%Nslip)) xi_0 = config%getFloats('crss0', requiredSize=size(N_sl))
prm%tau1 = config%getFloats('tau1', requiredSize=size(prm%Nslip)) prm%tau1 = config%getFloats('tau1', requiredSize=size(N_sl))
prm%tau1_b = config%getFloats('tau1_b', requiredSize=size(prm%Nslip)) prm%tau1_b = config%getFloats('tau1_b', requiredSize=size(N_sl))
prm%theta0 = config%getFloats('theta0', requiredSize=size(prm%Nslip)) prm%theta0 = config%getFloats('theta0', requiredSize=size(N_sl))
prm%theta1 = config%getFloats('theta1', requiredSize=size(prm%Nslip)) prm%theta1 = config%getFloats('theta1', requiredSize=size(N_sl))
prm%theta0_b = config%getFloats('theta0_b', requiredSize=size(prm%Nslip)) prm%theta0_b = config%getFloats('theta0_b', requiredSize=size(N_sl))
prm%theta1_b = config%getFloats('theta1_b', requiredSize=size(prm%Nslip)) prm%theta1_b = config%getFloats('theta1_b', requiredSize=size(N_sl))
prm%gdot0 = config%getFloat('gdot0') prm%gdot0 = config%getFloat('gdot0')
prm%n = config%getFloat('n_slip') prm%n = config%getFloat('n_slip')
! expand: family => system ! expand: family => system
prm%crss0 = math_expand(prm%crss0, prm%Nslip) xi_0 = math_expand(xi_0, N_sl)
prm%tau1 = math_expand(prm%tau1, prm%Nslip) prm%tau1 = math_expand(prm%tau1, N_sl)
prm%tau1_b = math_expand(prm%tau1_b, prm%Nslip) prm%tau1_b = math_expand(prm%tau1_b, N_sl)
prm%theta0 = math_expand(prm%theta0, prm%Nslip) prm%theta0 = math_expand(prm%theta0, N_sl)
prm%theta1 = math_expand(prm%theta1, prm%Nslip) prm%theta1 = math_expand(prm%theta1, N_sl)
prm%theta0_b = math_expand(prm%theta0_b,prm%Nslip) prm%theta0_b = math_expand(prm%theta0_b,N_sl)
prm%theta1_b = math_expand(prm%theta1_b,prm%Nslip) prm%theta1_b = math_expand(prm%theta1_b,N_sl)
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
! sanity checks ! sanity checks
if ( prm%gdot0 <= 0.0_pReal) extmsg = trim(extmsg)//' gdot0' if ( prm%gdot0 <= 0.0_pReal) extmsg = trim(extmsg)//' gdot0'
if ( prm%n <= 0.0_pReal) extmsg = trim(extmsg)//' n_slip' if ( prm%n <= 0.0_pReal) extmsg = trim(extmsg)//' n_slip'
if (any(prm%crss0 <= 0.0_pReal)) extmsg = trim(extmsg)//' crss0' if (any(xi_0 <= 0.0_pReal)) extmsg = trim(extmsg)//' crss0'
if (any(prm%tau1 <= 0.0_pReal)) extmsg = trim(extmsg)//' tau1' if (any(prm%tau1 <= 0.0_pReal)) extmsg = trim(extmsg)//' tau1'
if (any(prm%tau1_b <= 0.0_pReal)) extmsg = trim(extmsg)//' tau1_b' if (any(prm%tau1_b <= 0.0_pReal)) extmsg = trim(extmsg)//' tau1_b'
!ToDo: Any sensible checks for theta? !ToDo: Any sensible checks for theta?
else slipActive
xi_0 = emptyRealArray
allocate(prm%tau1,prm%tau1_b,prm%theta0,prm%theta1,prm%theta0_b,prm%theta1_b,source=emptyRealArray)
allocate(prm%interaction_SlipSlip(0,0))
endif slipActive endif slipActive
!--------------------------------------------------------------------------------------------------
! exit if any parameter is out of range
if (extmsg /= '') &
call IO_error(211,ext_msg=trim(extmsg)//'('//PLASTICITY_KINEHARDENING_label//')')
!--------------------------------------------------------------------------------------------------
! output pararameters
prm%output = config%getStrings('(output)',defaultVal=emptyStringArray)
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
! allocate state arrays ! allocate state arrays
NipcMyPhase = count(material_phaseAt == p) * discretization_nIP NipcMyPhase = count(material_phaseAt == p) * discretization_nIP
sizeDotState = size(['crss ','crss_back', 'accshear ']) * prm%totalNslip sizeDotState = size(['crss ','crss_back', 'accshear ']) * prm%sum_N_sl
sizeDeltaState = size(['sense ', 'chi0 ', 'gamma0' ]) * prm%totalNslip sizeDeltaState = size(['sense ', 'chi0 ', 'gamma0' ]) * prm%sum_N_sl
sizeState = sizeDotState + sizeDeltaState sizeState = sizeDotState + sizeDeltaState
call material_allocatePlasticState(p,NipcMyPhase,sizeState,sizeDotState,sizeDeltaState) call material_allocatePlasticState(p,NipcMyPhase,sizeState,sizeDotState,sizeDeltaState)
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
! locally defined state aliases and initialization of state0 and aTolState ! state aliases and initialization
startIndex = 1 startIndex = 1
endIndex = prm%totalNslip endIndex = prm%sum_N_sl
stt%crss => plasticState(p)%state (startIndex:endIndex,:) stt%crss => plasticState(p)%state (startIndex:endIndex,:)
stt%crss = spread(prm%crss0, 2, NipcMyPhase) stt%crss = spread(xi_0, 2, NipcMyPhase)
dot%crss => plasticState(p)%dotState(startIndex:endIndex,:) dot%crss => plasticState(p)%dotState(startIndex:endIndex,:)
plasticState(p)%aTolState(startIndex:endIndex) = prm%aTolResistance plasticState(p)%atol(startIndex:endIndex) = config%getFloat('atol_xi',defaultVal=1.0_pReal)
if(any(plasticState(p)%atol(startIndex:endIndex) < 0.0_pReal)) extmsg = trim(extmsg)//' atol_xi'
startIndex = endIndex + 1 startIndex = endIndex + 1
endIndex = endIndex + prm%totalNslip endIndex = endIndex + prm%sum_N_sl
stt%crss_back => plasticState(p)%state (startIndex:endIndex,:) stt%crss_back => plasticState(p)%state (startIndex:endIndex,:)
dot%crss_back => plasticState(p)%dotState(startIndex:endIndex,:) dot%crss_back => plasticState(p)%dotState(startIndex:endIndex,:)
plasticState(p)%aTolState(startIndex:endIndex) = prm%aTolResistance plasticState(p)%atol(startIndex:endIndex) = config%getFloat('atol_xi',defaultVal=1.0_pReal)
startIndex = endIndex + 1 startIndex = endIndex + 1
endIndex = endIndex + prm%totalNslip endIndex = endIndex + prm%sum_N_sl
stt%accshear => plasticState(p)%state (startIndex:endIndex,:) stt%accshear => plasticState(p)%state (startIndex:endIndex,:)
dot%accshear => plasticState(p)%dotState(startIndex:endIndex,:) dot%accshear => plasticState(p)%dotState(startIndex:endIndex,:)
plasticState(p)%aTolState(startIndex:endIndex) = prm%aTolShear plasticState(p)%atol(startIndex:endIndex) = config%getFloat('atol_gamma',defaultVal=1.0e-6_pReal)
if(any(plasticState(p)%atol(startIndex:endIndex) < 0.0_pReal)) extmsg = trim(extmsg)//' atol_gamma'
! global alias ! global alias
plasticState(p)%slipRate => plasticState(p)%dotState(startIndex:endIndex,:) plasticState(p)%slipRate => plasticState(p)%dotState(startIndex:endIndex,:)
o = plasticState(p)%offsetDeltaState o = plasticState(p)%offsetDeltaState
startIndex = endIndex + 1 startIndex = endIndex + 1
endIndex = endIndex + prm%totalNslip endIndex = endIndex + prm%sum_N_sl
stt%sense => plasticState(p)%state (startIndex :endIndex ,:) stt%sense => plasticState(p)%state (startIndex :endIndex ,:)
dlt%sense => plasticState(p)%deltaState(startIndex-o:endIndex-o,:) dlt%sense => plasticState(p)%deltaState(startIndex-o:endIndex-o,:)
startIndex = endIndex + 1 startIndex = endIndex + 1
endIndex = endIndex + prm%totalNslip endIndex = endIndex + prm%sum_N_sl
stt%chi0 => plasticState(p)%state (startIndex :endIndex ,:) stt%chi0 => plasticState(p)%state (startIndex :endIndex ,:)
dlt%chi0 => plasticState(p)%deltaState(startIndex-o:endIndex-o,:) dlt%chi0 => plasticState(p)%deltaState(startIndex-o:endIndex-o,:)
startIndex = endIndex + 1 startIndex = endIndex + 1
endIndex = endIndex + prm%totalNslip endIndex = endIndex + prm%sum_N_sl
stt%gamma0 => plasticState(p)%state (startIndex :endIndex ,:) stt%gamma0 => plasticState(p)%state (startIndex :endIndex ,:)
dlt%gamma0 => plasticState(p)%deltaState(startIndex-o:endIndex-o,:) dlt%gamma0 => plasticState(p)%deltaState(startIndex-o:endIndex-o,:)
@ -224,8 +211,13 @@ module subroutine plastic_kinehardening_init
end associate end associate
!--------------------------------------------------------------------------------------------------
! exit if any parameter is out of range
if (extmsg /= '') call IO_error(211,ext_msg=trim(extmsg)//'('//PLASTICITY_KINEHARDENING_LABEL//')')
enddo enddo
end subroutine plastic_kinehardening_init end subroutine plastic_kinehardening_init
@ -247,7 +239,7 @@ pure module subroutine plastic_kinehardening_LpAndItsTangent(Lp,dLp_dMp,Mp,insta
integer :: & integer :: &
i,k,l,m,n i,k,l,m,n
real(pReal), dimension(param(instance)%totalNslip) :: & real(pReal), dimension(param(instance)%sum_N_sl) :: &
gdot_pos,gdot_neg, & gdot_pos,gdot_neg, &
dgdot_dtau_pos,dgdot_dtau_neg dgdot_dtau_pos,dgdot_dtau_neg
@ -258,12 +250,12 @@ pure module subroutine plastic_kinehardening_LpAndItsTangent(Lp,dLp_dMp,Mp,insta
call kinetics(Mp,instance,of,gdot_pos,gdot_neg,dgdot_dtau_pos,dgdot_dtau_neg) call kinetics(Mp,instance,of,gdot_pos,gdot_neg,dgdot_dtau_pos,dgdot_dtau_neg)
do i = 1, prm%totalNslip do i = 1, prm%sum_N_sl
Lp = Lp + (gdot_pos(i)+gdot_neg(i))*prm%Schmid(1:3,1:3,i) Lp = Lp + (gdot_pos(i)+gdot_neg(i))*prm%P(1:3,1:3,i)
forall (k=1:3,l=1:3,m=1:3,n=1:3) & forall (k=1:3,l=1:3,m=1:3,n=1:3) &
dLp_dMp(k,l,m,n) = dLp_dMp(k,l,m,n) & dLp_dMp(k,l,m,n) = dLp_dMp(k,l,m,n) &
+ dgdot_dtau_pos(i) * prm%Schmid(k,l,i) * prm%nonSchmid_pos(m,n,i) & + dgdot_dtau_pos(i) * prm%P(k,l,i) * prm%nonSchmid_pos(m,n,i) &
+ dgdot_dtau_neg(i) * prm%Schmid(k,l,i) * prm%nonSchmid_neg(m,n,i) + dgdot_dtau_neg(i) * prm%P(k,l,i) * prm%nonSchmid_neg(m,n,i)
enddo enddo
end associate end associate
@ -284,7 +276,7 @@ module subroutine plastic_kinehardening_dotState(Mp,instance,of)
real(pReal) :: & real(pReal) :: &
sumGamma sumGamma
real(pReal), dimension(param(instance)%totalNslip) :: & real(pReal), dimension(param(instance)%sum_N_sl) :: &
gdot_pos,gdot_neg gdot_pos,gdot_neg
@ -324,7 +316,7 @@ module subroutine plastic_kinehardening_deltaState(Mp,instance,of)
instance, & instance, &
of of
real(pReal), dimension(param(instance)%totalNslip) :: & real(pReal), dimension(param(instance)%sum_N_sl) :: &
gdot_pos,gdot_neg, & gdot_pos,gdot_neg, &
sense sense
@ -375,23 +367,23 @@ module subroutine plastic_kinehardening_results(instance,group)
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('resistance') case('resistance')
if(prm%totalNslip>0) call results_writeDataset(group,stt%crss,'xi_sl', & if(prm%sum_N_sl>0) call results_writeDataset(group,stt%crss,'xi_sl', &
'resistance against plastic slip','Pa') 'resistance against plastic slip','Pa')
case('backstress') ! ToDo: should be 'tau_back' case('backstress') ! ToDo: should be 'tau_back'
if(prm%totalNslip>0) call results_writeDataset(group,stt%crss_back,'tau_back', & if(prm%sum_N_sl>0) call results_writeDataset(group,stt%crss_back,'tau_back', &
'back stress against plastic slip','Pa') 'back stress against plastic slip','Pa')
case ('sense') case ('sense')
if(prm%totalNslip>0) call results_writeDataset(group,stt%sense,'sense_of_shear', & if(prm%sum_N_sl>0) call results_writeDataset(group,stt%sense,'sense_of_shear', &
'tbd','1') 'tbd','1')
case ('chi0') case ('chi0')
if(prm%totalNslip>0) call results_writeDataset(group,stt%chi0,'chi0', & if(prm%sum_N_sl>0) call results_writeDataset(group,stt%chi0,'chi0', &
'tbd','Pa') 'tbd','Pa')
case ('gamma0') case ('gamma0')
if(prm%totalNslip>0) call results_writeDataset(group,stt%gamma0,'gamma0', & if(prm%sum_N_sl>0) call results_writeDataset(group,stt%gamma0,'gamma0', &
'tbd','1') 'tbd','1')
case ('accumulatedshear') case ('accumulatedshear')
if(prm%totalNslip>0) call results_writeDataset(group,stt%accshear,'gamma_sl', & if(prm%sum_N_sl>0) call results_writeDataset(group,stt%accshear,'gamma_sl', &
'plastic shear','1') 'plastic shear','1')
end select end select
enddo outputsLoop enddo outputsLoop
end associate end associate
@ -415,31 +407,28 @@ pure subroutine kinetics(Mp,instance,of, &
instance, & instance, &
of of
real(pReal), intent(out), dimension(param(instance)%totalNslip) :: & real(pReal), intent(out), dimension(param(instance)%sum_N_sl) :: &
gdot_pos, & gdot_pos, &
gdot_neg gdot_neg
real(pReal), intent(out), optional, dimension(param(instance)%totalNslip) :: & real(pReal), intent(out), optional, dimension(param(instance)%sum_N_sl) :: &
dgdot_dtau_pos, & dgdot_dtau_pos, &
dgdot_dtau_neg dgdot_dtau_neg
real(pReal), dimension(param(instance)%totalNslip) :: & real(pReal), dimension(param(instance)%sum_N_sl) :: &
tau_pos, & tau_pos, &
tau_neg tau_neg
integer :: i integer :: i
logical :: nonSchmidActive
associate(prm => param(instance), stt => state(instance)) associate(prm => param(instance), stt => state(instance))
nonSchmidActive = size(prm%nonSchmidCoeff) > 0 do i = 1, prm%sum_N_sl
tau_pos(i) = math_tensordot(Mp,prm%nonSchmid_pos(1:3,1:3,i)) - stt%crss_back(i,of)
do i = 1, prm%totalNslip tau_neg(i) = merge(math_tensordot(Mp,prm%nonSchmid_neg(1:3,1:3,i)) - stt%crss_back(i,of), &
tau_pos(i) = math_mul33xx33(Mp,prm%nonSchmid_pos(1:3,1:3,i)) - stt%crss_back(i,of) 0.0_pReal, prm%nonSchmidActive)
tau_neg(i) = merge(math_mul33xx33(Mp,prm%nonSchmid_neg(1:3,1:3,i)) - stt%crss_back(i,of), &
0.0_pReal, nonSchmidActive)
enddo enddo
where(dNeq0(tau_pos)) where(dNeq0(tau_pos))
gdot_pos = prm%gdot0 * merge(0.5_pReal,1.0_pReal, nonSchmidActive) & ! 1/2 if non-Schmid active gdot_pos = prm%gdot0 * merge(0.5_pReal,1.0_pReal, prm%nonSchmidActive) & ! 1/2 if non-Schmid active
* sign(abs(tau_pos/stt%crss(:,of))**prm%n, tau_pos) * sign(abs(tau_pos/stt%crss(:,of))**prm%n, tau_pos)
else where else where
gdot_pos = 0.0_pReal gdot_pos = 0.0_pReal

View File

@ -19,7 +19,7 @@ module subroutine plastic_none_init
p, & p, &
NipcMyPhase NipcMyPhase
write(6,'(/,a)') ' <<<+- plastic_'//PLASTICITY_NONE_label//' init -+>>>'; flush(6) write(6,'(/,a)') ' <<<+- plastic_'//PLASTICITY_NONE_LABEL//' init -+>>>'; flush(6)
Ninstance = count(phase_plasticity == PLASTICITY_NONE_ID) Ninstance = count(phase_plasticity == PLASTICITY_NONE_ID)
if (iand(debug_level(debug_constitutive),debug_levelBasic) /= 0) & if (iand(debug_level(debug_constitutive),debug_levelBasic) /= 0) &

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More