Merge branch 'MiscImprovements' into development
This commit is contained in:
commit
d920efb8fe
|
@ -1,6 +1,3 @@
|
|||
*.pyc
|
||||
*.hdf5
|
||||
*.xdmf
|
||||
*.bak
|
||||
*~
|
||||
.DS_Store
|
||||
|
|
|
@ -77,9 +77,9 @@ variables:
|
|||
IntelMarc: "$IntelCompiler17_8"
|
||||
HDF5Marc: "HDF5/1.10.5/Intel-17.8"
|
||||
# ++++++++++++ Documentation ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
Doxygen1_8_15: "Documentation/Doxygen/1.8.15"
|
||||
Doxygen1_8_17: "Documentation/Doxygen/1.8.17"
|
||||
# ------------ Defaults ----------------------------------------------
|
||||
Doxygen: "$Doxygen1_8_15"
|
||||
Doxygen: "$Doxygen1_8_17"
|
||||
|
||||
|
||||
###################################################################################################
|
||||
|
@ -490,7 +490,7 @@ GridSolver:
|
|||
stage: createDocumentation
|
||||
script:
|
||||
- module load $IntelCompiler $MPICH_Intel $PETSc_MPICH_Intel $Doxygen
|
||||
- $DAMASKROOT/PRIVATE/documenting/runDoxygen.sh $DAMASKROOT spectral
|
||||
- $DAMASKROOT/PRIVATE/documenting/runDoxygen.sh $DAMASKROOT grid
|
||||
except:
|
||||
- master
|
||||
- release
|
||||
|
|
4
Makefile
4
Makefile
|
@ -8,13 +8,13 @@ all: grid mesh processing
|
|||
|
||||
.PHONY: grid
|
||||
grid: build/grid
|
||||
@(cd build/grid;make -j4 all install;)
|
||||
@(cd build/grid;make -j${DAMASK_NUM_THREADS} all install;)
|
||||
.PHONY: spectral
|
||||
spectral: grid
|
||||
|
||||
.PHONY: mesh
|
||||
mesh: build/mesh
|
||||
@(cd build/mesh; make -j4 all install;)
|
||||
@(cd build/mesh; make -j${DAMASK_NUM_THREADS} all install;)
|
||||
.PHONY: FEM
|
||||
FEM: mesh
|
||||
|
||||
|
|
2
PRIVATE
2
PRIVATE
|
@ -1 +1 @@
|
|||
Subproject commit d0d5b5a22be9778187b100214c782747793bb956
|
||||
Subproject commit 62bd5ede5260cd4e0e3d1c3930c474c1e045aeef
|
|
@ -1,9 +1,8 @@
|
|||
*.C_ref
|
||||
*.mesh
|
||||
*.outputConstitutive
|
||||
*.outputCrystallite
|
||||
*.outputHomogenization
|
||||
*.spectralOut
|
||||
*.hdf5
|
||||
*.xdmf
|
||||
*.sta
|
||||
*.vt*
|
||||
*.geom
|
||||
*.seeds
|
||||
postProc
|
||||
|
|
|
@ -3,23 +3,16 @@
|
|||
elasticity hooke
|
||||
plasticity dislotwin
|
||||
|
||||
#(output) edge_density
|
||||
#(output) dipole_density
|
||||
#(output) shearrate_slip
|
||||
#(output) accumulated_shear_slip
|
||||
#(output) mfp_slip
|
||||
#(output) resolved_stress_slip
|
||||
#(output) threshold_stress_slip
|
||||
#(output) twin_fraction
|
||||
#(output) shearrate_twin
|
||||
#(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
|
||||
(output) rho_mob
|
||||
(output) rho_dip
|
||||
(output) gamma_sl
|
||||
(output) lambda_sl
|
||||
(output) tau_pass
|
||||
(output) f_tw
|
||||
(output) lambda_tw
|
||||
(output) tau_hat_tw
|
||||
(output) f_tr
|
||||
|
||||
|
||||
### Material parameters ###
|
||||
lattice_structure fcc
|
||||
|
@ -45,7 +38,6 @@ D0 4.0e-5 # Vacancy diffusion prefactor [m**2/s]
|
|||
Qsd 4.5e-19 # Activation energy for climb [J]
|
||||
Catomicvolume 1.0 # Adj. parameter controlling the atomic volume [in b^3]
|
||||
Cedgedipmindistance 1.0 # Adj. parameter controlling the minimum dipole distance [in b]
|
||||
atol_rho 1.0
|
||||
interactionSlipSlip 0.122 0.122 0.625 0.07 0.137 0.122 # Interaction coefficients (Kubin et al. 2008)
|
||||
|
||||
### Shearband parameters ###
|
||||
|
@ -68,6 +60,5 @@ Cmfptwin 1.0 # Adj. parameter controlling twin mean free
|
|||
Cthresholdtwin 1.0 # Adj. parameter controlling twin threshold stress
|
||||
interactionSlipTwin 0.0 1.0 1.0 # Dislocation-Twin interaction coefficients
|
||||
interactionTwinTwin 0.0 1.0 # Twin-Twin interaction coefficients
|
||||
atol_twinFrac 1.0e-7
|
||||
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
|
||||
|
|
|
@ -18,4 +18,3 @@ n 20
|
|||
h0 75e6
|
||||
tausat 63e6
|
||||
a 2.25
|
||||
atol_resistance 1
|
||||
|
|
|
@ -22,4 +22,3 @@ h0 1e6
|
|||
n 5
|
||||
m 3
|
||||
a 2
|
||||
atol_resistance 1
|
||||
|
|
|
@ -66,6 +66,4 @@ cutoffRadius 1e-3 # cutoff radius for dislocation
|
|||
CFLfactor 2.0 # safety factor for CFL flux check (numerical parameter)
|
||||
significantRho 1e6 # minimum dislocation density considered relevant in m/m**3
|
||||
#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
|
||||
|
|
|
@ -27,7 +27,7 @@ Nslip 12 # number of slip systems per family
|
|||
c11 246.5e9
|
||||
c12 147.3e9
|
||||
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
|
||||
rhoSglEdgeNeg0 6e10 # Initial negative edge 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
|
||||
surfaceTransmissivity 1.0 # transmissivity of free surfaces for dislocation flux
|
||||
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
|
||||
significantN 1
|
||||
shortRangeStressCorrection 0
|
||||
|
|
|
@ -3,13 +3,10 @@ elasticity hooke
|
|||
plasticity phenopowerlaw
|
||||
|
||||
(output) resistance_slip
|
||||
(output) shearrate_slip
|
||||
(output) resolvedstress_slip
|
||||
(output) accumulated_shear_slip
|
||||
(output) accumulatedshear_slip
|
||||
|
||||
lattice_structure fcc
|
||||
Nslip 12 # per family
|
||||
Ntwin 0 # per family
|
||||
|
||||
c11 106.75e9
|
||||
c12 60.41e9
|
||||
|
@ -22,4 +19,3 @@ tausat_slip 63e6 # per family
|
|||
a_slip 2.25
|
||||
h0_slipslip 75e6
|
||||
interaction_slipslip 1 1 1.4 1.4 1.4 1.4
|
||||
atol_resistance 1
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
|
||||
|
||||
# parameters fitted by D. Ma to:
|
||||
# I. Kovács, G. Vörös
|
||||
# On the mathematical description of the tensile stress-strain curves of polycrystalline face centered cubic metals
|
||||
|
@ -7,20 +5,13 @@
|
|||
# DOI: 10.1016/S0749-6419(95)00043-7
|
||||
|
||||
[gold_phenopowerlaw]
|
||||
# slip only
|
||||
elasticity hooke
|
||||
plasticity phenopowerlaw
|
||||
|
||||
(output) resistance_slip
|
||||
(output) shearrate_slip
|
||||
(output) resolvedstress_slip
|
||||
(output) resistance_twin
|
||||
(output) shearrate_twin
|
||||
(output) resolvedstress_twin
|
||||
|
||||
lattice_structure fcc
|
||||
Nslip 12 # per family
|
||||
Ntwin 0 # per family
|
||||
|
||||
c11 191.0e9
|
||||
c12 162.0e9
|
||||
|
@ -31,9 +22,6 @@ n_slip 83.3
|
|||
tau0_slip 26.25e6 # per family
|
||||
tausat_slip 53.00e6 # per family
|
||||
a_slip 1.0
|
||||
gdot0_twin 0.001
|
||||
n_twin 20
|
||||
h0_slipslip 75e6
|
||||
interaction_slipslip 1 1 1.4 1.4 1.4 1.4
|
||||
atol_resistance 1
|
||||
|
||||
|
|
|
@ -7,11 +7,7 @@ plasticity phenopowerlaw
|
|||
elasticity hooke
|
||||
|
||||
(output) resistance_slip
|
||||
(output) shearrate_slip
|
||||
(output) resolvedstress_slip
|
||||
(output) resistance_twin
|
||||
(output) shearrate_twin
|
||||
(output) resolvedstress_twin
|
||||
|
||||
lattice_structure hex
|
||||
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
|
||||
####################################################
|
||||
atol_resistance 1
|
||||
atol_shear 1e-6
|
||||
atol_twinfrac 1e-6
|
||||
n_twin 20
|
||||
n_slip 20
|
||||
|
||||
|
|
|
@ -2,13 +2,6 @@
|
|||
plasticity phenopowerlaw
|
||||
elasticity hooke
|
||||
|
||||
# (output) resistance_slip
|
||||
# (output) shearrate_slip
|
||||
# (output) resolvedstress_slip
|
||||
# (output) resistance_twin
|
||||
# (output) shearrate_twin
|
||||
# (output) resolvedstress_twin
|
||||
|
||||
lattice_structure hex
|
||||
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
|
||||
gdot0_slip 0.001
|
||||
n_slip 20
|
||||
nslip 3 3 0 6 0 0
|
||||
tau0_slip 349.3e6 150e6 0 1107.9e6 0 0
|
||||
tausat_slip 568.6e6 1502.2e6 0 3420.1e6 0 0
|
||||
nslip 3 3 0 6
|
||||
tau0_slip 349.3e6 150e6 0 1107.9e6
|
||||
tausat_slip 568.6e6 1502.2e6 0 3420.1e6
|
||||
a_slip 2
|
||||
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_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_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
|
||||
|
|
|
@ -14,7 +14,6 @@ plasticity phenopowerlaw
|
|||
|
||||
lattice_structure fcc
|
||||
Nslip 12 # per family
|
||||
Ntwin 0 # per family
|
||||
|
||||
c11 106.75e9
|
||||
c12 60.41e9
|
||||
|
@ -25,22 +24,8 @@ n_slip 20
|
|||
tau0_slip 31e6 # per family
|
||||
tausat_slip 63e6 # per family
|
||||
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_twinslip 0
|
||||
h0_twintwin 0
|
||||
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) p
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
4 header
|
||||
3 header
|
||||
grid a 16 b 16 c 16
|
||||
microstructures 20
|
||||
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.187988 0.849313 0.953540 257.468172 53.250534 157.331503
|
||||
0.750488 0.349313 0.953540 216.994815 94.418518 251.147231
|
||||
|
|
|
@ -13,15 +13,6 @@ elasticity hooke
|
|||
plasticity phenopowerlaw
|
||||
|
||||
(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) F # deformation gradient tensor
|
||||
(output) Fe # elastic deformation gradient tensor
|
||||
|
@ -32,7 +23,6 @@ plasticity phenopowerlaw
|
|||
|
||||
lattice_structure fcc
|
||||
Nslip 12 # per family
|
||||
Ntwin 0 # per family
|
||||
|
||||
c11 106.75e9
|
||||
c12 60.41e9
|
||||
|
@ -45,7 +35,6 @@ tausat_slip 63e6 # per family
|
|||
a_slip 2.25
|
||||
h0_slipslip 75e6
|
||||
interaction_slipslip 1 1 1.4 1.4 1.4 1.4
|
||||
atol_resistance 1
|
||||
|
||||
#-------------------#
|
||||
<microstructure>
|
||||
|
|
|
@ -15,10 +15,6 @@ scriptID = ' '.join([scriptName,damask.version])
|
|||
# --------------------------------------------------------------------
|
||||
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='+',
|
||||
help='DADF5 files')
|
||||
parser.add_argument('-d','--dir', dest='dir',default='postProc',metavar='string',
|
||||
|
@ -33,38 +29,31 @@ options = parser.parse_args()
|
|||
if options.mat is None: options.mat=[]
|
||||
if options.con is None: options.con=[]
|
||||
|
||||
# --- loop over input files ------------------------------------------------------------------------
|
||||
|
||||
for filename in options.filenames:
|
||||
results = damask.DADF5(filename)
|
||||
results = damask.Result(filename)
|
||||
|
||||
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)
|
||||
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 = 5 # hack to keep test intact
|
||||
for i,inc in enumerate(results.iter_visible('increments')):
|
||||
print('Output step {}/{}'.format(i+1,len(results.increments)))
|
||||
|
||||
for inc in damask.util.show_progress(results.iterate('increments'),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.add('pos',coords.reshape(-1,3))
|
||||
|
||||
results.pick('materialpoints',False)
|
||||
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)))
|
||||
table.add(label,results.read_dataset(x,0,plain=True).reshape(results.grid.prod(),-1))
|
||||
|
||||
results.pick('constituents', False)
|
||||
results.pick('materialpoints',True)
|
||||
for label in options.mat:
|
||||
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)))
|
||||
table.add(label,results.read_dataset(x,0,plain=True).reshape(results.grid.prod(),-1))
|
||||
|
||||
dirname = os.path.abspath(os.path.join(os.path.dirname(filename),options.dir))
|
||||
if not os.path.isdir(dirname):
|
||||
|
|
|
@ -48,35 +48,31 @@ Phase_types = {'Primary': 0} #further additions to these can be done by looking
|
|||
# MAIN
|
||||
# --------------------------------------------------------------------
|
||||
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('--inc',nargs='+',help='Increment for which DREAM3D to be used, eg. 25',type=int)
|
||||
parser.add_argument('filenames', nargs='+',
|
||||
help='DADF5 files')
|
||||
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()
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# loop over input files
|
||||
for filename in options.filenames:
|
||||
f = damask.DADF5(filename) #DAMASK output file
|
||||
for increment in options.inc:
|
||||
f.set_by_increment(increment,increment)
|
||||
if len(f.visible['increments']) == 0:
|
||||
continue
|
||||
f = damask.Result(filename)
|
||||
N_digits = int(np.floor(np.log10(int(f.increments[-1][3:]))))+1
|
||||
|
||||
#-------output file creation-------------------------------------
|
||||
f.pick('increments',options.inc)
|
||||
for inc in damask.util.show_progress(f.iterate('increments'),len(f.selection['increments'])):
|
||||
dirname = os.path.abspath(os.path.join(os.path.dirname(filename),options.dir))
|
||||
try:
|
||||
os.mkdir(dirname)
|
||||
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['FileVersion'] = '7.0'
|
||||
#-----------------------------------------------------------------
|
||||
|
||||
|
||||
for g in ['DataContainerBundles','Pipeline']: # empty groups (needed)
|
||||
o.create_group(g)
|
||||
|
@ -84,10 +80,8 @@ for filename in options.filenames:
|
|||
data_container_label = 'DataContainers/ImageDataContainer'
|
||||
cell_data_label = data_container_label + '/CellData'
|
||||
|
||||
|
||||
# Phase information of DREAM.3D is constituent ID in DAMASK
|
||||
o[cell_data_label + '/Phases'] = f.get_constituent_ID().reshape(tuple(f.grid)+(1,))
|
||||
# Data quaternions
|
||||
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'],
|
||||
|
@ -103,12 +97,10 @@ for filename in options.filenames:
|
|||
o[cell_data_label + group].attrs['DataArrayVersion'] = np.array([2],np.int32)
|
||||
o[cell_data_label + group].attrs['Tuple Axis Dimensions'] = 'x={},y={},z={}'.format(*f.grid)
|
||||
|
||||
# phase attributes
|
||||
o[cell_data_label + '/Phases'].attrs['ComponentDimensions'] = np.array([1],np.uint64)
|
||||
o[cell_data_label + '/Phases'].attrs['ObjectType'] = 'DataArray<int32_t>'
|
||||
o[cell_data_label + '/Phases'].attrs['TupleDimensions'] = f.grid.astype(np.uint64)
|
||||
|
||||
# Quats attributes
|
||||
o[cell_data_label + '/Quats'].attrs['ComponentDimensions'] = np.array([4],np.uint64)
|
||||
o[cell_data_label + '/Quats'].attrs['ObjectType'] = 'DataArray<float>'
|
||||
o[cell_data_label + '/Quats'].attrs['TupleDimensions'] = f.grid.astype(np.uint64)
|
||||
|
@ -118,8 +110,8 @@ for filename in options.filenames:
|
|||
|
||||
# Data CrystalStructures
|
||||
o[ensemble_label + '/CrystalStructures'] = np.uint32(np.array([999,\
|
||||
Crystal_structures[f.get_crystal_structure()]])).reshape((2,1))
|
||||
o[ensemble_label + '/PhaseTypes'] = np.uint32(np.array([999,Phase_types['Primary']])).reshape((2,1)) # ToDo
|
||||
Crystal_structures[f.get_crystal_structure()]])).reshape(2,1)
|
||||
o[ensemble_label + '/PhaseTypes'] = np.uint32(np.array([999,Phase_types['Primary']])).reshape(2,1) # ToDo
|
||||
|
||||
# Attributes Ensemble Matrix
|
||||
o[ensemble_label].attrs['AttributeMatrixType'] = np.array([11],np.uint32)
|
||||
|
@ -133,8 +125,6 @@ for filename in options.filenames:
|
|||
o[ensemble_label+'/'+group].attrs['ObjectType'] = 'DataArray<uint32_t>'
|
||||
o[ensemble_label+'/'+group].attrs['TupleDimensions'] = np.array([2],np.uint64)
|
||||
|
||||
|
||||
# Create geometry info
|
||||
geom_label = data_container_label + '/_SIMPL_GEOMETRY'
|
||||
|
||||
o[geom_label + '/DIMENSIONS'] = np.int64(f.grid)
|
||||
|
|
|
@ -40,7 +40,7 @@ def volTetrahedron(coords):
|
|||
|
||||
# Get all the squares of all side lengths from the differences between
|
||||
# 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]
|
||||
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)
|
||||
shapeMismatch = shapeMismatch( size,table.get(options.defgrad).reshape(grid[2],grid[1],grid[0],3,3),nodes,centers)
|
||||
table.add('shapeMismatch(({}))'.format(options.defgrad),
|
||||
shapeMismatch.reshape((-1,1)),
|
||||
shapeMismatch.reshape(-1,1),
|
||||
scriptID+' '+' '.join(sys.argv[1:]))
|
||||
|
||||
if options.volume:
|
||||
volumeMismatch = volumeMismatch(size,table.get(options.defgrad).reshape(grid[2],grid[1],grid[0],3,3),nodes)
|
||||
table.add('volMismatch(({}))'.format(options.defgrad),
|
||||
volumeMismatch.reshape((-1,1)),
|
||||
volumeMismatch.reshape(-1,1),
|
||||
scriptID+' '+' '.join(sys.argv[1:]))
|
||||
|
||||
table.to_ASCII(sys.stdout if name is None else name)
|
||||
|
|
|
@ -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
|
||||
field = field.reshape(np.append(grid[::-1],shape))
|
||||
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:]))
|
||||
|
||||
table.to_ASCII(sys.stdout if name is None else name)
|
||||
|
|
|
@ -41,7 +41,7 @@ for name in filenames:
|
|||
table = damask.Table.from_ASCII(StringIO(''.join(sys.stdin.read())) if name is None else name)
|
||||
for tensor in options.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:]))
|
||||
if options.spherical:
|
||||
table.add('sph({})'.format(tensor),
|
||||
|
|
|
@ -54,20 +54,20 @@ for name in filenames:
|
|||
|
||||
F = table.get(options.f).reshape(np.append(grid[::-1],(3,3)))
|
||||
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,)})
|
||||
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:]))
|
||||
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:]))
|
||||
table.to_ASCII(sys.stdout if name is None else os.path.splitext(name)[0]+'_nodal.txt')
|
||||
else:
|
||||
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:]))
|
||||
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:]))
|
||||
table.to_ASCII(sys.stdout if name is None else name)
|
||||
|
|
|
@ -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
|
||||
field = field.reshape(np.append(grid[::-1],shape))
|
||||
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:]))
|
||||
|
||||
table.to_ASCII(sys.stdout if name is None else name)
|
||||
|
|
|
@ -68,7 +68,7 @@ for name in filenames:
|
|||
|
||||
for label in options.labels:
|
||||
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,
|
||||
mode = 'wrap' if options.periodic else 'nearest'),
|
||||
scriptID+' '+' '.join(sys.argv[1:]))
|
||||
|
|
|
@ -51,7 +51,7 @@ for name in filenames:
|
|||
shape = (1,) if np.prod(field.shape)//np.prod(grid) == 1 else (3,) # scalar or vector
|
||||
field = field.reshape(np.append(grid[::-1],shape))
|
||||
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:]))
|
||||
|
||||
table.to_ASCII(sys.stdout if name is None else name)
|
||||
|
|
|
@ -59,6 +59,6 @@ for name in filenames:
|
|||
idx = np.reshape(table.get(options.index).astype(int) + options.offset,(-1))-1
|
||||
|
||||
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)
|
||||
|
|
|
@ -203,13 +203,11 @@ for name in filenames:
|
|||
# ------------------------------------------ assemble header ---------------------------------------
|
||||
|
||||
table.info_append(scriptID + '\t' + ' '.join(sys.argv[1:]))
|
||||
table.labels_append(['{id}_'
|
||||
'S[{direction[0]:.1g}_{direction[1]:.1g}_{direction[2]:.1g}]'
|
||||
table.labels_append(['S[{direction[0]:.1g}_{direction[1]:.1g}_{direction[2]:.1g}]'
|
||||
'({normal[0]:.1g}_{normal[1]:.1g}_{normal[2]:.1g})'\
|
||||
.format( id = i+1,
|
||||
normal = theNormal,
|
||||
.format(normal = theNormal,
|
||||
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()
|
||||
|
||||
# ------------------------------------------ process data ------------------------------------------
|
||||
|
|
|
@ -50,11 +50,9 @@ for name in filenames:
|
|||
if options.rh: v[np.linalg.det(v) < 0.0,:,2] *= -1.0
|
||||
|
||||
for i,o in enumerate(['Min','Mid','Max']):
|
||||
table.add('eigval{}({})'.format(o,tensor),u[:,i],
|
||||
scriptID+' '+' '.join(sys.argv[1:]))
|
||||
table.add('eigval{}({})'.format(o,tensor),u[:,i], scriptID+' '+' '.join(sys.argv[1:]))
|
||||
|
||||
for i,o in enumerate(['Min','Mid','Max']):
|
||||
table.add('eigvec{}({})'.format(o,tensor),v[:,:,i],
|
||||
scriptID+' '+' '.join(sys.argv[1:]))
|
||||
table.add('eigvec{}({})'.format(o,tensor),v[:,:,i],scriptID+' '+' '.join(sys.argv[1:]))
|
||||
|
||||
table.to_ASCII(sys.stdout if name is None else name)
|
||||
|
|
|
@ -86,13 +86,13 @@ for name in filenames:
|
|||
table = damask.Table.from_ASCII(StringIO(''.join(sys.stdin.read())) if name is None else name)
|
||||
|
||||
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 theStrain in strains:
|
||||
(t,m) = parameters(theStretch,theStrain)
|
||||
label = '{}({}){}'.format(theStrain,theStretch,defgrad if defgrad != 'f' else '')
|
||||
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:]))
|
||||
|
||||
table.to_ASCII(sys.stdout if name is None else name)
|
||||
|
|
|
@ -91,7 +91,7 @@ for name in filenames:
|
|||
table = damask.Table(averagedDown,table.shapes,table.comments)
|
||||
|
||||
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))
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
import os
|
||||
import sys
|
||||
from io import StringIO
|
||||
from optparse import OptionParser
|
||||
|
||||
import numpy as np
|
||||
|
@ -71,60 +72,30 @@ parser.set_defaults(bins = (10,10),
|
|||
)
|
||||
|
||||
(options,filenames) = parser.parse_args()
|
||||
if filenames == []: filenames = [None]
|
||||
|
||||
minmax = np.array([np.array(options.xrange),
|
||||
np.array(options.yrange),
|
||||
np.array(options.zrange)])
|
||||
grid = np.zeros(options.bins,'f')
|
||||
result = np.zeros((options.bins[0],options.bins[1],3),'f')
|
||||
minmax = np.array([options.xrange,options.yrange,options.zrange])
|
||||
result = np.empty((options.bins[0],options.bins[1],3),'f')
|
||||
|
||||
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:
|
||||
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)
|
||||
|
||||
# ------------------------------------------ read header ------------------------------------------
|
||||
|
||||
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
|
||||
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])))
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
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,
|
||||
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:
|
||||
for x in range(options.bins[0]):
|
||||
sum = np.sum(grid[x,:])
|
||||
|
@ -153,24 +124,20 @@ for name in filenames:
|
|||
for y in range(options.bins[1]):
|
||||
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),
|
||||
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):
|
||||
if options.type[c].lower() == 'log': result[:,:,c] = np.exp(result[:,:,c])
|
||||
|
||||
if options.invert: result[:,:,2] = 1.0 - result[:,:,2]
|
||||
|
||||
# --- assemble header -------------------------------------------------------------------------------
|
||||
|
||||
table.info_clear()
|
||||
table.info_append(scriptID + '\t' + ' '.join(sys.argv[1:]))
|
||||
table.labels_clear()
|
||||
table.labels_append(['bin_%s'%options.data[0],'bin_%s'%options.data[1],'z'])
|
||||
table.head_write()
|
||||
|
||||
# --- output result ---------------------------------------------------------------------------------
|
||||
|
||||
table.data = result.reshape(options.bins[0]*options.bins[1],3)
|
||||
table.data_writeArray()
|
||||
|
||||
table.close()
|
||||
comments = scriptID + '\t' + ' '.join(sys.argv[1:])
|
||||
shapes = {'bin_%s'%options.data[0]:(1,),'bin_%s'%options.data[1]:(1,),'z':(1,)}
|
||||
table = damask.Table(result.reshape(options.bins[0]*options.bins[1],3),shapes,[comments])
|
||||
if 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))
|
||||
table.to_ASCII(outname)
|
||||
else:
|
||||
table.to_ASCII(sys.stdout)
|
||||
|
|
|
@ -60,12 +60,12 @@ for name in filenames:
|
|||
outSize = grid*packing
|
||||
|
||||
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)
|
||||
|
||||
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))
|
||||
|
||||
outname = os.path.join(os.path.dirname(name),prefix+os.path.basename(name))
|
||||
|
|
|
@ -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
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python2.7
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
@ -102,6 +102,7 @@ parser.set_defaults(label = None,
|
|||
)
|
||||
|
||||
(options,filenames) = parser.parse_args()
|
||||
if filenames == []: filenames = [None]
|
||||
|
||||
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)
|
||||
|
||||
# --- loop over input files -------------------------------------------------------------------------
|
||||
|
||||
if filenames == []: filenames = [None]
|
||||
|
||||
for name in filenames:
|
||||
try:
|
||||
table = damask.ASCIItable(name = name, labeled = options.label is not None, readonly = True)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python2.7
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
@ -95,6 +95,7 @@ parser.set_defaults(label = None,
|
|||
)
|
||||
|
||||
(options,filenames) = parser.parse_args()
|
||||
if filenames == []: filenames = [None]
|
||||
|
||||
options.size = np.array(options.size)
|
||||
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)
|
||||
|
||||
# --- loop over input files -------------------------------------------------------------------------
|
||||
|
||||
if filenames == []: filenames = [None]
|
||||
|
||||
for name in filenames:
|
||||
try:
|
||||
table = damask.ASCIItable(name = name, readonly = True,
|
||||
labeled = options.label is not None)
|
||||
table = damask.ASCIItable(name = name, labeled = options.label is not None, readonly = True)
|
||||
except IOError:
|
||||
continue
|
||||
table.report_name(scriptName,name)
|
||||
damask.util.report(scriptName,name)
|
||||
|
||||
# ------------------------------------------ read header ------------------------------------------
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python2.7
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
@ -72,18 +72,15 @@ parser.set_defaults(label = None,
|
|||
)
|
||||
|
||||
(options,filenames) = parser.parse_args()
|
||||
if filenames == []: filenames = [None]
|
||||
|
||||
if options.dimension == []: parser.error('dimension of data array missing')
|
||||
if options.pixelsize > 1: (options.pixelsizex,options.pixelsizey) = [options.pixelsize]*2
|
||||
|
||||
# --- loop over input files -------------------------------------------------------------------------
|
||||
|
||||
if filenames == []: filenames = [None]
|
||||
|
||||
for name in filenames:
|
||||
try:
|
||||
table = damask.ASCIItable(name = name, readonly = True,
|
||||
labeled = options.label is not None)
|
||||
table = damask.ASCIItable(name = name, labeled = options.label is not None, readonly = True)
|
||||
except IOError:
|
||||
continue
|
||||
damask.util.report(scriptName,name)
|
||||
|
|
|
@ -44,9 +44,7 @@ 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)
|
||||
for i,label in enumerate(options.label):
|
||||
table.rename(label,
|
||||
options.substitute[i],
|
||||
scriptID+' '+' '.join(sys.argv[1:]))
|
||||
for label,substitute in zip(options.label,options.substitute):
|
||||
table.rename(label,substitute,scriptID+' '+' '.join(sys.argv[1:]))
|
||||
|
||||
table.to_ASCII(sys.stdout if name is None else name)
|
||||
|
|
|
@ -2,10 +2,9 @@
|
|||
|
||||
import os
|
||||
import sys
|
||||
from io import StringIO
|
||||
from optparse import OptionParser
|
||||
|
||||
import numpy as np
|
||||
|
||||
import damask
|
||||
|
||||
|
||||
|
@ -40,65 +39,25 @@ parser.set_defaults(rotation = (1.,1.,1.,0),
|
|||
)
|
||||
|
||||
(options,filenames) = parser.parse_args()
|
||||
if filenames == []: filenames = [None]
|
||||
|
||||
if options.data is None:
|
||||
parser.error('no data column specified.')
|
||||
|
||||
r = damask.Rotation.fromAxisAngle(np.array(options.rotation),options.degrees,normalise=True)
|
||||
|
||||
# --- loop over input files -------------------------------------------------------------------------
|
||||
|
||||
if filenames == []: filenames = [None]
|
||||
r = damask.Rotation.fromAxisAngle(options.rotation,options.degrees,normalise=True)
|
||||
|
||||
for name in filenames:
|
||||
try:
|
||||
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 = []
|
||||
remarks = []
|
||||
active = {'vector':[],'tensor':[]}
|
||||
table.set(data,d,scriptID+' '+' '.join(sys.argv[1:]))
|
||||
|
||||
for i,dim in enumerate(table.label_dimension(options.data)):
|
||||
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
|
||||
table.to_ASCII(sys.stdout if name is None else name)
|
||||
|
|
|
@ -43,9 +43,7 @@ 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)
|
||||
for i,label in enumerate(options.labels):
|
||||
table.set(label,
|
||||
table.get(label)*float(options.factor[i]),
|
||||
scriptID+' '+' '.join(sys.argv[1:]))
|
||||
for label,factor in zip(options.labels,options.factor):
|
||||
table.set(label,table.get(label)*float(factor),scriptID+' '+' '.join(sys.argv[1:]))
|
||||
|
||||
table.to_ASCII(sys.stdout if name is None else name)
|
||||
|
|
|
@ -43,9 +43,7 @@ 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)
|
||||
for i,label in enumerate(options.labels):
|
||||
table.set(label,
|
||||
table.get(label)+float(options.offset[i]),
|
||||
scriptID+' '+' '.join(sys.argv[1:]))
|
||||
for label,offset in zip(options.labels,options.offset):
|
||||
table.set(label,table.get(label)+float(offset),scriptID+' '+' '.join(sys.argv[1:]))
|
||||
|
||||
table.to_ASCII(sys.stdout if name is None else name)
|
||||
|
|
|
@ -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)
|
|
@ -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()
|
|
@ -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()
|
|
@ -5,8 +5,6 @@ import sys
|
|||
from io import StringIO
|
||||
from optparse import OptionParser
|
||||
|
||||
import vtk
|
||||
|
||||
import damask
|
||||
|
||||
|
||||
|
@ -39,39 +37,9 @@ 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)
|
||||
|
||||
# ------------------------------------------ process data ---------------------------------------
|
||||
|
||||
Polydata = vtk.vtkPolyData()
|
||||
Points = vtk.vtkPoints()
|
||||
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 ---------------------------------------
|
||||
v = damask.VTK.from_polyData(table.get(options.pos))
|
||||
|
||||
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()))
|
||||
v.write(os.path.splitext(name)[0])
|
||||
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())
|
||||
sys.stdout.write(v.__repr__())
|
||||
|
|
|
@ -5,9 +5,6 @@ import sys
|
|||
from io import StringIO
|
||||
from optparse import OptionParser
|
||||
|
||||
import vtk
|
||||
import numpy as np
|
||||
|
||||
import damask
|
||||
|
||||
|
||||
|
@ -48,50 +45,14 @@ for name in filenames:
|
|||
|
||||
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':
|
||||
coords = [0.5 * np.array([3.0 * coords[i][0] - coords[i][0 + int(len(coords[i]) > 1)]] + \
|
||||
[coords[i][j-1] + coords[i][j] for j in range(1,len(coords[i]))] + \
|
||||
[3.0 * coords[i][-1] - coords[i][-1 - int(len(coords[i]) > 1)]]) for i in range(3)]
|
||||
grid, size, origin = damask.grid_filters.cell_coord0_gridSizeOrigin(table.get(options.pos))
|
||||
elif options.mode == 'point':
|
||||
grid, size, origin = damask.grid_filters.node_coord0_gridSizeOrigin(table.get(options.pos))
|
||||
|
||||
grid = np.array(list(map(len,coords)),'i')
|
||||
N = grid.prod() if options.mode == 'point' else (grid-1).prod()
|
||||
|
||||
# ------------------------------------------ process data ---------------------------------------
|
||||
|
||||
rGrid = vtk.vtkRectilinearGrid()
|
||||
coordArray = [vtk.vtkDoubleArray(),
|
||||
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 ---------------------------------------
|
||||
v = damask.VTK.from_rectilinearGrid(grid,size,origin)
|
||||
|
||||
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()))
|
||||
v.write('{}_{}({})'.format(os.path.splitext(name)[0],options.pos,options.mode))
|
||||
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())
|
||||
sys.stdout.write(v.__repr__())
|
||||
|
|
|
@ -22,8 +22,6 @@ Writes vtk file for visualization.
|
|||
""", version = scriptID)
|
||||
|
||||
(options, filenames) = parser.parse_args()
|
||||
|
||||
|
||||
if filenames == []: filenames = [None]
|
||||
|
||||
for name in filenames:
|
||||
|
@ -33,7 +31,7 @@ for name in filenames:
|
|||
|
||||
damask.util.croak(geom)
|
||||
|
||||
if name is None:
|
||||
sys.stdout.write(geom.to_vtk())
|
||||
else:
|
||||
if name:
|
||||
geom.to_vtk(os.path.splitext(name)[0])
|
||||
else:
|
||||
sys.stdout.write(geom.to_vtk())
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
import os
|
||||
import sys
|
||||
import multiprocessing
|
||||
from io import StringIO
|
||||
from functools import partial
|
||||
from optparse import OptionParser,OptionGroup
|
||||
|
||||
import numpy as np
|
||||
|
@ -15,73 +17,40 @@ scriptName = os.path.splitext(os.path.basename(__file__))[0]
|
|||
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 = \
|
||||
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)
|
||||
def Laguerre_tessellation(grid, seeds, grains, size, periodic, weights, cpus):
|
||||
|
||||
repeatweights = np.tile(weights,len(copies)).flatten(order='F') # Laguerre weights (1,2,3,1,2,3,...,1,2,3)
|
||||
for i,vec in enumerate(copies): # periodic copies of seed points ...
|
||||
try: seeds = np.append(seeds, coords+vec, axis=0) # ... (1+a,2+a,3+a,...,1+z,2+z,3+z)
|
||||
except NameError: seeds = coords+vec
|
||||
|
||||
if (repeatweights == 0.0).all(): # standard Voronoi (no weights, KD tree)
|
||||
myKDTree = spatial.cKDTree(seeds)
|
||||
devNull,closestSeeds = myKDTree.query(undeformed)
|
||||
if periodic:
|
||||
weights_p = np.tile(weights,27).flatten(order='F') # Laguerre weights (1,2,3,1,2,3,...,1,2,3)
|
||||
seeds_p = np.vstack((seeds -np.array([size[0],0.,0.]),seeds, seeds +np.array([size[0],0.,0.])))
|
||||
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]])))
|
||||
else:
|
||||
damask.util.croak('...using {} cpu{}'.format(options.cpus, 's' if options.cpus > 1 else ''))
|
||||
arguments = [[arg,seeds,repeatweights] for arg in list(undeformed)]
|
||||
weights_p = weights.flatten()
|
||||
seeds_p = seeds
|
||||
|
||||
if cpus > 1: # use multithreading
|
||||
if cpus > 1:
|
||||
default_args = partial(findClosestSeed,seeds_p,weights_p)
|
||||
pool = multiprocessing.Pool(processes = cpus) # initialize workers
|
||||
result = pool.map_async(findClosestSeed, arguments) # evaluate function in parallel
|
||||
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.zeros(len(arguments),dtype='i')
|
||||
for i,arg in enumerate(arguments):
|
||||
closestSeeds[i] = findClosestSeed(arg)
|
||||
closestSeeds= np.array([findClosestSeed(seeds_p,weights_p,point) for point in grid])
|
||||
|
||||
# closestSeed is modulo number of original seed points (i.e. excluding periodic copies)
|
||||
return grains[closestSeeds%coords.shape[0]]
|
||||
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',
|
||||
dest = 'size',
|
||||
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',
|
||||
'--origin',
|
||||
dest = 'origin',
|
||||
type = 'float', nargs = 3, metavar=' '.join(['float']*3),
|
||||
help = 'origin of grid')
|
||||
group.add_option('--nonnormalized',
|
||||
dest = 'normalized',
|
||||
action = 'store_false',
|
||||
help = 'seed coordinates are not normalized to a unit cube')
|
||||
help = 'origin of grid [0.0 0.0 0.0]')
|
||||
|
||||
parser.add_option_group(group)
|
||||
|
||||
|
@ -191,101 +156,60 @@ parser.set_defaults(pos = 'pos',
|
|||
cpus = 2,
|
||||
laguerre = False,
|
||||
periodic = True,
|
||||
normalized = True,
|
||||
config = True,
|
||||
)
|
||||
|
||||
(options,filenames) = parser.parse_args()
|
||||
|
||||
|
||||
if filenames == []: filenames = [None]
|
||||
|
||||
for name in filenames:
|
||||
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()
|
||||
info,extra_header = table.head_getGeom()
|
||||
|
||||
if options.grid is not None: info['grid'] = options.grid
|
||||
if options.size is not None: info['size'] = options.size
|
||||
if options.origin is not None: info['origin'] = options.origin
|
||||
|
||||
# ------------------------------------------ sanity checks ---------------------------------------
|
||||
|
||||
remarks = []
|
||||
errors = []
|
||||
labels = []
|
||||
|
||||
hasGrains = table.label_dimension(options.microstructure) == 1
|
||||
hasEulers = table.label_dimension(options.eulers) == 3
|
||||
hasWeights = table.label_dimension(options.weight) == 1 and options.laguerre
|
||||
|
||||
for i in range(3):
|
||||
if info['size'][i] <= 0.0: # any invalid size?
|
||||
info['size'][i] = float(info['grid'][i])/max(info['grid']) # normalize to grid
|
||||
remarks.append('rescaling size {} to {}...'.format(['x','y','z'][i],info['size'][i]))
|
||||
|
||||
if table.label_dimension(options.pos) != 3:
|
||||
errors.append('seed positions "{}" have dimension {}.'.format(options.pos,
|
||||
table.label_dimension(options.pos)))
|
||||
else:
|
||||
labels += [options.pos]
|
||||
|
||||
if not options.normalized: remarks.append('using real-space seed coordinates...')
|
||||
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)
|
||||
if errors != []:
|
||||
damask.util.croak(errors)
|
||||
table.close(dismiss=True)
|
||||
continue
|
||||
|
||||
# ------------------------------------------ read seeds ---------------------------------------
|
||||
|
||||
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))
|
||||
grains = table.get(options.microstructure) if options.microstructure in table.labels else np.arange(len(seeds))+1
|
||||
grainIDs = np.unique(grains).astype('i')
|
||||
NgrainIDs = len(grainIDs)
|
||||
|
||||
# --- tessellate microstructure ------------------------------------------------------------
|
||||
if options.eulers in table.labels:
|
||||
eulers = table.get(options.eulers)
|
||||
|
||||
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')
|
||||
coords = damask.grid_filters.cell_coord0(grid,size,-origin).reshape(-1,3,order='F')
|
||||
|
||||
damask.util.croak('tessellating...')
|
||||
indices = laguerreTessellation(grid, coords, weights, grains, options.periodic, options.cpus)
|
||||
if options.laguerre:
|
||||
indices = Laguerre_tessellation(coords,seeds,grains,size,options.periodic,
|
||||
table.get(options.weight),options.cpus)
|
||||
else:
|
||||
indices = Voronoi_tessellation (coords,seeds,grains,size,options.periodic)
|
||||
|
||||
config_header = []
|
||||
if options.config:
|
||||
|
||||
if hasEulers:
|
||||
if options.eulers in table.labels:
|
||||
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)]
|
||||
if options.axes: config_header += ['axes\t{} {} {}'.format(*options.axes)]
|
||||
|
||||
config_header += ['<microstructure>']
|
||||
for ID in grainIDs:
|
||||
|
@ -297,7 +221,7 @@ for name in filenames:
|
|||
|
||||
header = [scriptID + ' ' + ' '.join(sys.argv[1:])]\
|
||||
+ config_header
|
||||
geom = damask.Geom(indices.reshape(info['grid'],order='F'),info['size'],info['origin'],
|
||||
geom = damask.Geom(indices.reshape(grid),size,origin,
|
||||
homogenization=options.homogenization,comments=header)
|
||||
damask.util.croak(geom)
|
||||
|
||||
|
|
|
@ -30,17 +30,16 @@ for name in filenames:
|
|||
geom = damask.Geom.from_file(StringIO(''.join(sys.stdin.read())) if name is None else name)
|
||||
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 \
|
||||
+ [scriptID + ' ' + ' '.join(sys.argv[1:]),
|
||||
"grid\ta {}\tb {}\tc {}".format(*geom.grid),
|
||||
"size\tx {}\ty {}\tz {}".format(*geom.size),
|
||||
"origin\tx {}\ty {}\tz {}".format(*geom.origin),
|
||||
"homogenization\t{}".format(geom.homogenization)]
|
||||
'grid\ta {}\tb {}\tc {}'.format(*geom.grid),
|
||||
'size\tx {}\ty {}\tz {}'.format(*geom.size),
|
||||
'origin\tx {}\ty {}\tz {}'.format(*geom.origin),
|
||||
'homogenization\t{}'.format(geom.homogenization)]
|
||||
|
||||
table = damask.Table(coord0,{'pos':(3,)},comments)
|
||||
table.add('microstructure',geom.microstructure.reshape((-1,1),order='F'))
|
||||
|
||||
table.to_ASCII(sys.stdout if name is None else \
|
||||
os.path.splitext(name)[0]+'.txt')
|
||||
table.to_ASCII(sys.stdout if name is None else os.path.splitext(name)[0]+'.txt')
|
||||
|
|
|
@ -1,11 +1,17 @@
|
|||
#!/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
|
||||
import damask
|
||||
import os,sys,math,random
|
||||
|
||||
import numpy as np
|
||||
|
||||
import damask
|
||||
|
||||
|
||||
scriptName = os.path.splitext(os.path.basename(__file__))[0]
|
||||
scriptID = ' '.join([scriptName,damask.version])
|
||||
|
||||
|
@ -223,54 +229,29 @@ parser.set_defaults(randomSeed = None,
|
|||
)
|
||||
|
||||
(options,filenames) = parser.parse_args()
|
||||
|
||||
nSamples = options.number
|
||||
methods = [options.algorithm]
|
||||
|
||||
|
||||
# --- 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)
|
||||
|
||||
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)
|
||||
|
||||
# ------------------------------------------ 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 -----------------------------
|
||||
|
||||
ODF = {}
|
||||
limits = np.array([np.min(table.data[:,0:3],axis=0),
|
||||
np.max(table.data[:,0:3],axis=0)]) # min/max euler angles in degrees
|
||||
eulers = table.get('euler')
|
||||
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['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['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']:
|
||||
damask.util.croak('expecting %i values but got %i'%(ODF['nBins'],table.data.shape[0]))
|
||||
if eulers.shape[0] != ODF['nBins']:
|
||||
damask.util.croak('expecting %i values but got %i'%(ODF['nBins'],eulers.shape[0]))
|
||||
continue
|
||||
|
||||
# ----- build binnedODF array and normalize ------------------------------------------------------
|
||||
|
@ -278,9 +259,10 @@ for name in filenames:
|
|||
ODF['dV_V'] = [None]*ODF['nBins']
|
||||
ODF['nNonZero'] = 0
|
||||
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']):
|
||||
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])
|
||||
if ODF['dV_V'][b] > 0.0:
|
||||
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]))),
|
||||
])
|
||||
|
||||
# call methods
|
||||
Functions = {'IA': 'directInversion', 'STAT': 'TothVanHoutteSTAT', 'MC': 'MonteCarloBins'}
|
||||
method = Functions[options.algorithm]
|
||||
|
||||
Orientations, ReconstructedODF = (globals()[method])(ODF,nSamples)
|
||||
Orientations, ReconstructedODF = (globals()[method])(ODF,options.number)
|
||||
|
||||
# calculate accuracy of sample
|
||||
squaredDiff = {'orig':0.0,method:0.0}
|
||||
|
@ -319,7 +300,7 @@ for name in filenames:
|
|||
indivSum['orig'] += ODF['dV_V'][bin]
|
||||
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]),
|
||||
'rMSD of ODFs:\t %12.11f'%(squaredDiff[method]/indivSquaredSum['orig']),
|
||||
'nNonZero correlation slope:\t %12.11f'\
|
||||
|
@ -331,10 +312,10 @@ for name in filenames:
|
|||
(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']
|
||||
|
||||
formatwidth = 1+int(math.log10(nSamples))
|
||||
formatwidth = 1+int(math.log10(options.number))
|
||||
|
||||
materialConfig = [
|
||||
'#' + 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)),
|
||||
'(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]
|
||||
|
||||
materialConfig += ['[Grain%s]'%(str(ID+1).zfill(formatwidth)),
|
||||
|
@ -364,7 +345,5 @@ for name in filenames:
|
|||
|
||||
#--- 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')
|
||||
|
||||
table.close()
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -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__())
|
|
@ -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
|
|
@ -1,9 +1,15 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import threading,time,os,sys,random
|
||||
import numpy as np
|
||||
import threading
|
||||
import time
|
||||
import os
|
||||
import sys
|
||||
import random
|
||||
from optparse import OptionParser
|
||||
from io import StringIO
|
||||
|
||||
import numpy as np
|
||||
|
||||
import damask
|
||||
|
||||
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
|
||||
if bestSeedsUpdate > knownSeedsUpdate: # write best fit to virtual file
|
||||
knownSeedsUpdate = bestSeedsUpdate
|
||||
bestSeedsVFile.reset()
|
||||
bestSeedsVFile.seek(0)
|
||||
myBestSeedsVFile.close()
|
||||
myBestSeedsVFile = StringIO()
|
||||
i=0
|
||||
for line in bestSeedsVFile:
|
||||
myBestSeedsVFile.write(line)
|
||||
myBestSeedsVFile.writelines(bestSeedsVFile.readlines())
|
||||
s.release()
|
||||
|
||||
if randReset: # new direction because current one led to worse fit
|
||||
|
@ -67,46 +72,38 @@ class myThread (threading.Thread):
|
|||
for i in range(NmoveGrains):
|
||||
selectedMs.append(random.randrange(1,nMicrostructures))
|
||||
|
||||
direction.append(np.array(((random.random()-0.5)*delta[0],
|
||||
(random.random()-0.5)*delta[1],
|
||||
(random.random()-0.5)*delta[2])))
|
||||
direction.append((np.random.random()-0.5)*delta)
|
||||
|
||||
perturbedSeedsVFile.close() # reset virtual file
|
||||
perturbedSeedsVFile = StringIO()
|
||||
myBestSeedsVFile.reset()
|
||||
myBestSeedsVFile.seek(0)
|
||||
|
||||
perturbedSeedsTable = damask.ASCIItable(myBestSeedsVFile,perturbedSeedsVFile,labeled=True) # write best fit to perturbed seed file
|
||||
perturbedSeedsTable.head_read()
|
||||
perturbedSeedsTable.head_write()
|
||||
outputAlive=True
|
||||
ms = 1
|
||||
perturbedSeedsTable = damask.Table.from_ASCII(myBestSeedsVFile)
|
||||
coords = perturbedSeedsTable.get('pos')
|
||||
i = 0
|
||||
while outputAlive and perturbedSeedsTable.data_read(): # perturbe selected microstructure
|
||||
for ms,coord in enumerate(coords):
|
||||
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 <0.0,newCoords+1.0,newCoords)
|
||||
perturbedSeedsTable.data[0:3]=[format(f, '8.6f') for f in newCoords]
|
||||
coords[i]=newCoords
|
||||
direction[i]*=2.
|
||||
i+= 1
|
||||
ms+=1
|
||||
perturbedSeedsTable.data_write()
|
||||
#--- do tesselation with perturbed seed file ----------------------------------------------------------
|
||||
perturbedSeedsTable.set('pos',coords)
|
||||
perturbedSeedsTable.to_ASCII(perturbedSeedsVFile)
|
||||
|
||||
#--- do tesselation with perturbed seed file ------------------------------------------------------
|
||||
perturbedGeomVFile.close()
|
||||
perturbedGeomVFile = StringIO()
|
||||
perturbedSeedsVFile.reset()
|
||||
perturbedSeedsVFile.seek(0)
|
||||
perturbedGeomVFile.write(damask.util.execute('geom_fromVoronoiTessellation '+
|
||||
' -g '+' '.join(list(map(str, options.grid))),streamIn=perturbedSeedsVFile)[0])
|
||||
perturbedGeomVFile.reset()
|
||||
perturbedGeomVFile.seek(0)
|
||||
|
||||
#--- evaluate current seeds file ----------------------------------------------------------------------
|
||||
perturbedGeomTable = damask.ASCIItable(perturbedGeomVFile,None,labeled=False,readonly=True)
|
||||
perturbedGeomTable.head_read()
|
||||
for i in perturbedGeomTable.info:
|
||||
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
|
||||
#--- evaluate current seeds file ------------------------------------------------------------------
|
||||
perturbedGeom = damask.Geom.from_file(perturbedGeomVFile)
|
||||
myNmicrostructures = len(np.unique(perturbedGeom.microstructure))
|
||||
currentData=np.bincount(perturbedGeom.microstructure.ravel())[1:]/points
|
||||
currentError=[]
|
||||
currentHist=[]
|
||||
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(' best: '+np.array_str(currentHist[i]))
|
||||
currentSeedsName = baseFile+'_'+str(bestSeedsUpdate).replace('.','-') # name of new seed file (use time as unique identifier)
|
||||
perturbedSeedsVFile.reset()
|
||||
perturbedSeedsVFile.seek(0)
|
||||
bestSeedsVFile.close()
|
||||
bestSeedsVFile = StringIO()
|
||||
sys.stdout.flush()
|
||||
|
@ -154,11 +151,10 @@ class myThread (threading.Thread):
|
|||
break
|
||||
if i == min(nMicrostructures,myMatch+options.bins)-1: # same quality as before: take it to keep on moving
|
||||
bestSeedsUpdate = time.time()
|
||||
perturbedSeedsVFile.reset()
|
||||
perturbedSeedsVFile.seek(0)
|
||||
bestSeedsVFile.close()
|
||||
bestSeedsVFile = StringIO()
|
||||
for line in perturbedSeedsVFile:
|
||||
bestSeedsVFile.write(line)
|
||||
bestSeedsVFile.writelines(perturbedSeedsVFile.readlines())
|
||||
for j in range(nMicrostructures):
|
||||
target[j]['error'] = currentError[j]
|
||||
randReset = True
|
||||
|
@ -216,7 +212,7 @@ damask.util.report(scriptName,options.seedFile)
|
|||
if options.randomSeed is None:
|
||||
options.randomSeed = int(os.urandom(4).hex(),16)
|
||||
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]
|
||||
points = np.array(options.grid).prod().astype('float')
|
||||
|
||||
|
|
|
@ -54,17 +54,16 @@ for name in filenames:
|
|||
np.in1d(microstructure,options.blacklist,invert=True) if options.blacklist else \
|
||||
np.full(geom.grid.prod(),True,dtype=bool))
|
||||
|
||||
seeds = np.concatenate((damask.grid_filters.cell_coord0(geom.grid,geom.size).reshape((-1,3)),
|
||||
microstructure),
|
||||
axis=1)[mask]
|
||||
seeds = damask.grid_filters.cell_coord0(geom.grid,geom.size).reshape(-1,3)
|
||||
|
||||
comments = geom.comments \
|
||||
+ [scriptID + ' ' + ' '.join(sys.argv[1:]),
|
||||
"grid\ta {}\tb {}\tc {}".format(*geom.grid),
|
||||
"size\tx {}\ty {}\tz {}".format(*geom.size),
|
||||
"origin\tx {}\ty {}\tz {}".format(*geom.origin),
|
||||
"homogenization\t{}".format(geom.homogenization)]
|
||||
'grid\ta {}\tb {}\tc {}'.format(*geom.grid),
|
||||
'size\tx {}\ty {}\tz {}'.format(*geom.size),
|
||||
'origin\tx {}\ty {}\tz {}'.format(*geom.origin),
|
||||
'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 \
|
||||
os.path.splitext(name)[0]+'.seeds')
|
||||
|
|
|
@ -64,8 +64,8 @@ for name in filenames:
|
|||
|
||||
damask.util.croak('poking {} x {} x {} in box {} {} {}...'.format(Nx,Ny,Nz,*box))
|
||||
|
||||
seeds = np.zeros((Nx*Ny*Nz,4),'d')
|
||||
g = np.zeros(3,'i')
|
||||
seeds = np.zeros((Nx*Ny*Nz,4))
|
||||
g = np.zeros(3,dtype=np.int)
|
||||
|
||||
n = 0
|
||||
for i in range(Nx):
|
||||
|
@ -84,12 +84,13 @@ for name in filenames:
|
|||
|
||||
comments = geom.comments \
|
||||
+ [scriptID + ' ' + ' '.join(sys.argv[1:]),
|
||||
"poking\ta {}\tb {}\tc {}".format(Nx,Ny,Nz),
|
||||
"grid\ta {}\tb {}\tc {}".format(*geom.grid),
|
||||
"size\tx {}\ty {}\tz {}".format(*geom.size),
|
||||
"origin\tx {}\ty {}\tz {}".format(*geom.origin),
|
||||
"homogenization\t{}".format(geom.homogenization)]
|
||||
'poking\ta {}\tb {}\tc {}'.format(Nx,Ny,Nz),
|
||||
'grid\ta {}\tb {}\tc {}'.format(*geom.grid),
|
||||
'size\tx {}\ty {}\tz {}'.format(*geom.size),
|
||||
'origin\tx {}\ty {}\tz {}'.format(*geom.origin),
|
||||
'homogenization\t{}'.format(geom.homogenization)]
|
||||
|
||||
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 \
|
||||
os.path.splitext(name)[0]+'_poked_{}.seeds'.format(options.N))
|
||||
|
|
|
@ -1,36 +1,25 @@
|
|||
#!/usr/bin/env python3
|
||||
# -*- coding: UTF-8 no BOM -*-
|
||||
|
||||
import os,sys,math,random
|
||||
import numpy as np
|
||||
import damask
|
||||
import os
|
||||
import sys
|
||||
from optparse import OptionParser,OptionGroup
|
||||
|
||||
import numpy as np
|
||||
from scipy import spatial
|
||||
|
||||
import damask
|
||||
|
||||
|
||||
scriptName = os.path.splitext(os.path.basename(__file__))[0]
|
||||
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
|
||||
# --------------------------------------------------------------------
|
||||
|
||||
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.
|
||||
|
||||
""", version = scriptID)
|
||||
|
@ -39,11 +28,11 @@ parser.add_option('-N',
|
|||
dest = 'N',
|
||||
type = 'int', metavar = 'int',
|
||||
help = 'number of seed points [%default]')
|
||||
parser.add_option('-f',
|
||||
'--fraction',
|
||||
dest = 'fraction',
|
||||
parser.add_option('-s',
|
||||
'--size',
|
||||
dest = 'size',
|
||||
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',
|
||||
'--grid',
|
||||
dest = 'grid',
|
||||
|
@ -58,9 +47,6 @@ parser.add_option('-r',
|
|||
'--rnd',
|
||||
dest = 'randomSeed', type = 'int', metavar = 'int',
|
||||
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",
|
||||
"Parameters determining shape of weight distribution of seed points"
|
||||
|
@ -87,8 +73,7 @@ parser.add_option_group(group)
|
|||
group = OptionGroup(parser, "Selective Seeding",
|
||||
"More uniform distribution of seed points using Mitchell's Best Candidate Algorithm"
|
||||
)
|
||||
group.add_option( '-s',
|
||||
'--selective',
|
||||
group.add_option( '--selective',
|
||||
action = 'store_true',
|
||||
dest = 'selective',
|
||||
help = 'selective picking of seed points from random seed points')
|
||||
|
@ -104,7 +89,7 @@ parser.add_option_group(group)
|
|||
|
||||
parser.set_defaults(randomSeed = None,
|
||||
grid = (16,16,16),
|
||||
fraction = (1.0,1.0,1.0),
|
||||
size = (1.0,1.0,1.0),
|
||||
N = 20,
|
||||
weights = False,
|
||||
max = 0.0,
|
||||
|
@ -114,116 +99,67 @@ parser.set_defaults(randomSeed = None,
|
|||
selective = False,
|
||||
distance = 0.2,
|
||||
numCandidates = 10,
|
||||
format = None,
|
||||
)
|
||||
|
||||
(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]
|
||||
|
||||
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:
|
||||
try:
|
||||
table = damask.ASCIItable(outname = name)
|
||||
except IOError:
|
||||
continue
|
||||
damask.util.report(scriptName,name)
|
||||
|
||||
# --- sanity checks -------------------------------------------------------------------------
|
||||
|
||||
remarks = []
|
||||
errors = []
|
||||
if gridSize == 0:
|
||||
errors.append('zero grid dimension for {}.'.format(', '.join([['a','b','c'][x] for x in np.where(options.grid == 0)[0]])))
|
||||
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)
|
||||
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)))
|
||||
|
||||
# --- do work ------------------------------------------------------------------------------------
|
||||
eulers = np.random.rand(options.N,3) # create random Euler triplets
|
||||
eulers[:,0] *= 360.0 # phi_1 is uniformly distributed
|
||||
eulers[:,1] = np.degrees(np.arccos(2*eulers[:,1]-1.0)) # cos(Phi) is uniformly distributed
|
||||
eulers[:,2] *= 360.0 # phi_2 is uniformly distributed
|
||||
|
||||
grainEuler = np.random.rand(3,options.N) # create random Euler triplets
|
||||
grainEuler[0,:] *= 360.0 # phi_1 is uniformly distributed
|
||||
grainEuler[1,:] = np.degrees(np.arccos(2*grainEuler[1,:]-1)) # cos(Phi) is uniformly distributed
|
||||
grainEuler[2,:] *= 360.0 # phi_2 is uniformly distributed
|
||||
|
||||
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
|
||||
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.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)
|
||||
seeds = np.empty((options.N,3))
|
||||
seeds[0] = np.random.random(3) * size
|
||||
|
||||
i = 1
|
||||
progress = damask.util._ProgressBar(options.N,'',50)
|
||||
while i < options.N:
|
||||
candidates = np.random.random(options.numCandidates*3).reshape(options.numCandidates,3)
|
||||
distances = kdtree_search(seeds[:i],candidates)
|
||||
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
|
||||
if i%(options.N/100.) < 1: damask.util.croak('.',False)
|
||||
progress.update(i)
|
||||
|
||||
damask.util.croak('')
|
||||
seeds = seeds.T # prepare shape for stacking
|
||||
|
||||
comments = [scriptID + ' ' + ' '.join(sys.argv[1:]),
|
||||
'grid\ta {}\tb {}\tc {}'.format(*grid),
|
||||
'size\tx {}\ty {}\tz {}'.format(*size),
|
||||
'randomSeed\t{}'.format(options.randomSeed),
|
||||
]
|
||||
|
||||
table = damask.Table(np.hstack((seeds,eulers)),{'pos':(3,),'euler':(3,)},comments)
|
||||
table.add('microstructure',np.arange(options.microstructure,options.microstructure + options.N,dtype=int))
|
||||
|
||||
if options.weights:
|
||||
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:
|
||||
weights = []
|
||||
seeds = np.transpose(np.vstack(tuple([seeds,
|
||||
grainEuler,
|
||||
np.arange(options.microstructure,
|
||||
options.microstructure + options.N),
|
||||
] + weights
|
||||
)))
|
||||
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)
|
||||
table.add('weight',weights)
|
||||
|
||||
# ------------------------------------------ assemble header ---------------------------------------
|
||||
|
||||
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
|
||||
table.to_ASCII(sys.stdout if name is None else name)
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
*.pyc
|
||||
dist
|
||||
damask.egg-info
|
||||
|
|
|
@ -36,7 +36,7 @@ sc = np.pi**(1./6.)/6.**(1./6.)
|
|||
beta = np.pi**(5./6.)/6.**(1./6.)/2.
|
||||
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.
|
||||
|
||||
|
@ -59,7 +59,7 @@ def CubeToBall(cube):
|
|||
ball = np.zeros(3)
|
||||
else:
|
||||
# get pyramide and scale by grid parameter ratio
|
||||
p = get_order(cube)
|
||||
p = _get_order(cube)
|
||||
XYZ = cube[p] * sc
|
||||
|
||||
# intercept all the points along the z-axis
|
||||
|
@ -87,7 +87,7 @@ def CubeToBall(cube):
|
|||
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.
|
||||
|
||||
|
@ -109,7 +109,7 @@ def BallToCube(ball):
|
|||
if np.allclose(ball,0.0,rtol=0.0,atol=1.0e-300):
|
||||
cube = np.zeros(3)
|
||||
else:
|
||||
p = get_order(ball)
|
||||
p = _get_order(ball)
|
||||
xyz3 = ball[p]
|
||||
|
||||
# inverse M_3
|
||||
|
@ -137,7 +137,7 @@ def BallToCube(ball):
|
|||
return cube
|
||||
|
||||
|
||||
def get_order(xyz):
|
||||
def _get_order(xyz):
|
||||
"""
|
||||
Get order of the coordinates.
|
||||
|
|
@ -1,37 +1,25 @@
|
|||
"""Main aggregator."""
|
||||
import os
|
||||
import re
|
||||
import os as _os
|
||||
import re as _re
|
||||
|
||||
name = 'damask'
|
||||
with open(os.path.join(os.path.dirname(__file__),'VERSION')) as f:
|
||||
version = re.sub(r'^v','',f.readline().strip())
|
||||
with open(_os.path.join(_os.path.dirname(__file__),'VERSION')) as _f:
|
||||
version = _re.sub(r'^v','',_f.readline().strip())
|
||||
|
||||
# classes
|
||||
from .environment import Environment # noqa
|
||||
from .table import Table # noqa
|
||||
from .ktv import VTK # noqa
|
||||
from .colormaps import Colormap, Color # noqa
|
||||
from .rotation import Rotation # noqa
|
||||
from .lattice import Symmetry, Lattice# noqa
|
||||
from .orientation import Orientation # noqa
|
||||
from .result import Result # noqa
|
||||
from .geom import Geom # noqa
|
||||
from .solver import Solver # noqa
|
||||
|
||||
# compatibility hack
|
||||
from .result import Result as DADF5 # noqa
|
||||
from ._environment import Environment # noqa
|
||||
from ._table import Table # noqa
|
||||
from ._vtk import VTK # noqa
|
||||
from ._colormaps import Colormap, Color # noqa
|
||||
from ._rotation import Rotation # noqa
|
||||
from ._lattice import Symmetry, Lattice# noqa
|
||||
from ._orientation import Orientation # noqa
|
||||
from ._result import Result # noqa
|
||||
from ._geom import Geom # noqa
|
||||
from . import solver # noqa
|
||||
|
||||
# deprecated
|
||||
from .asciitable import ASCIItable # noqa
|
||||
from .util import extendableOption # noqa
|
||||
from ._asciitable import ASCIItable # noqa
|
||||
from ._test import Test # noqa
|
||||
from .config import Material # noqa
|
||||
from .test import Test # noqa
|
||||
|
||||
# functions in modules
|
||||
from . import mechanics # noqa
|
||||
from . import grid_filters # noqa
|
||||
|
||||
# clean temporary variables
|
||||
del os
|
||||
del re
|
||||
del f
|
||||
from .util import extendableOption # noqa
|
||||
|
|
|
@ -14,9 +14,7 @@ class ASCIItable():
|
|||
|
||||
# ------------------------------------------------------------------
|
||||
def __init__(self,
|
||||
name = None,
|
||||
outname = None,
|
||||
buffered = False, # is ignored, only exists for compatibility reasons
|
||||
name,
|
||||
labeled = True, # assume table has labels
|
||||
readonly = False, # no reading from file
|
||||
):
|
||||
|
@ -27,8 +25,9 @@ class ASCIItable():
|
|||
'dataStart': 0,
|
||||
}
|
||||
|
||||
self.__IO__['inPlace'] = not outname and name and not readonly
|
||||
if self.__IO__['inPlace']: outname = name + self.tmpext # transparently create tmp file
|
||||
self.__IO__['inPlace'] = name and not readonly
|
||||
outname = name + self.tmpext if self.__IO__['inPlace'] else None # transparently create tmp file
|
||||
|
||||
try:
|
||||
self.__IO__['in'] = (open( name,'r') if os.access( name, os.R_OK) else None) if name else sys.stdin
|
||||
except TypeError:
|
||||
|
@ -166,42 +165,6 @@ class ASCIItable():
|
|||
|
||||
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,
|
||||
what,
|
||||
|
@ -424,29 +387,26 @@ class ASCIItable():
|
|||
return labels_missing
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
def data_write(self,
|
||||
delimiter = '\t'):
|
||||
def data_write(self):
|
||||
"""Write current data array and report alive output back."""
|
||||
if len(self.data) == 0: return True
|
||||
|
||||
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:
|
||||
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,
|
||||
fmt = None,
|
||||
delimiter = '\t'):
|
||||
def data_writeArray(self):
|
||||
"""Write whole numpy array data."""
|
||||
for row in self.data:
|
||||
try:
|
||||
output = [fmt % value for value in row] if fmt else list(map(repr,row))
|
||||
output = list(map(repr,row))
|
||||
except Exception:
|
||||
output = [fmt % row] if fmt else [repr(row)]
|
||||
output = [repr(row)]
|
||||
|
||||
try:
|
||||
self.__IO__['out'].write(delimiter.join(output) + '\n')
|
||||
self.__IO__['out'].write('\t'.join(output) + '\n')
|
||||
except Exception:
|
||||
pass
|
||||
|
|
@ -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
|
|
@ -1,16 +1,17 @@
|
|||
import os
|
||||
import tkinter
|
||||
|
||||
class Environment():
|
||||
class Environment:
|
||||
|
||||
def __init__(self):
|
||||
"""Read and provide values of DAMASK configuration."""
|
||||
self.options = self._get_options()
|
||||
try:
|
||||
import tkinter
|
||||
tk = tkinter.Tk()
|
||||
self.screen_width = tk.winfo_screenwidth()
|
||||
self.screen_height = tk.winfo_screenheight()
|
||||
except Exception:
|
||||
tk.destroy()
|
||||
except tkinter.TclError:
|
||||
self.screen_width = 1024
|
||||
self.screen_height = 768
|
||||
|
|
@ -8,7 +8,7 @@ from . import VTK
|
|||
from . import util
|
||||
|
||||
|
||||
class Geom():
|
||||
class Geom:
|
||||
"""Geometry definition for grid solvers."""
|
||||
|
||||
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)),
|
||||
])
|
||||
|
||||
|
||||
def update(self,microstructure=None,size=None,origin=None,rescale=False):
|
||||
"""
|
||||
Updates microstructure and size.
|
||||
|
@ -109,6 +110,7 @@ class Geom():
|
|||
|
||||
return util.return_message(message)
|
||||
|
||||
|
||||
def set_comments(self,comments):
|
||||
"""
|
||||
Replaces all existing comments.
|
||||
|
@ -122,6 +124,7 @@ class Geom():
|
|||
self.comments = []
|
||||
self.add_comments(comments)
|
||||
|
||||
|
||||
def add_comments(self,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)]
|
||||
|
||||
|
||||
def set_microstructure(self,microstructure):
|
||||
"""
|
||||
Replaces the existing microstructure representation.
|
||||
|
@ -152,6 +156,7 @@ class Geom():
|
|||
else:
|
||||
self.microstructure = np.copy(microstructure)
|
||||
|
||||
|
||||
def set_size(self,size):
|
||||
"""
|
||||
Replaces the existing size information.
|
||||
|
@ -171,6 +176,7 @@ class Geom():
|
|||
else:
|
||||
self.size = np.array(size)
|
||||
|
||||
|
||||
def set_origin(self,origin):
|
||||
"""
|
||||
Replaces the existing origin information.
|
||||
|
@ -187,6 +193,7 @@ class Geom():
|
|||
else:
|
||||
self.origin = np.array(origin)
|
||||
|
||||
|
||||
def set_homogenization(self,homogenization):
|
||||
"""
|
||||
Replaces the existing homogenization index.
|
||||
|
@ -203,34 +210,47 @@ class Geom():
|
|||
else:
|
||||
self.homogenization = homogenization
|
||||
|
||||
|
||||
@property
|
||||
def grid(self):
|
||||
return self.get_grid()
|
||||
|
||||
|
||||
@property
|
||||
def N_microstructure(self):
|
||||
return len(np.unique(self.microstructure))
|
||||
|
||||
|
||||
def get_microstructure(self):
|
||||
"""Return the microstructure representation."""
|
||||
return np.copy(self.microstructure)
|
||||
|
||||
|
||||
def get_size(self):
|
||||
"""Return the physical size in meter."""
|
||||
return np.copy(self.size)
|
||||
|
||||
|
||||
def get_origin(self):
|
||||
"""Return the origin in meter."""
|
||||
return np.copy(self.origin)
|
||||
|
||||
|
||||
def get_grid(self):
|
||||
"""Return the grid discretization."""
|
||||
return np.array(self.microstructure.shape)
|
||||
|
||||
|
||||
def get_homogenization(self):
|
||||
"""Return the homogenization index."""
|
||||
return self.homogenization
|
||||
|
||||
|
||||
def get_comments(self):
|
||||
"""Return the comments."""
|
||||
return self.comments[:]
|
||||
|
||||
|
||||
def get_header(self):
|
||||
"""Return the full header (grid, size, origin, homogenization, comments)."""
|
||||
header = ['{} header'.format(len(self.comments)+4)] + self.comments
|
||||
|
@ -240,6 +260,7 @@ class Geom():
|
|||
header.append('homogenization {}'.format(self.get_homogenization()))
|
||||
return header
|
||||
|
||||
|
||||
@staticmethod
|
||||
def from_file(fname):
|
||||
"""
|
||||
|
@ -425,8 +446,8 @@ class Geom():
|
|||
if 'x' in directions:
|
||||
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)
|
||||
#self.add_comments('tbd')
|
||||
|
||||
|
||||
def scale(self,grid):
|
||||
|
@ -439,6 +460,7 @@ class Geom():
|
|||
new grid dimension
|
||||
|
||||
"""
|
||||
#self.add_comments('geom.py:scale v{}'.format(version)
|
||||
return self.update(
|
||||
ndimage.interpolation.zoom(
|
||||
self.microstructure,
|
||||
|
@ -449,7 +471,6 @@ class Geom():
|
|||
prefilter=False
|
||||
)
|
||||
)
|
||||
#self.add_comments('tbd')
|
||||
|
||||
|
||||
def clean(self,stencil=3):
|
||||
|
@ -466,13 +487,13 @@ class Geom():
|
|||
unique, inverse = np.unique(arr, return_inverse=True)
|
||||
return unique[np.argmax(np.bincount(inverse))]
|
||||
|
||||
#self.add_comments('geom.py:clean v{}'.format(version)
|
||||
return self.update(ndimage.filters.generic_filter(
|
||||
self.microstructure,
|
||||
mostFrequent,
|
||||
size=(stencil,)*3
|
||||
).astype(self.microstructure.dtype)
|
||||
)
|
||||
#self.add_comments('tbd')
|
||||
|
||||
|
||||
def renumber(self):
|
||||
|
@ -481,5 +502,5 @@ class Geom():
|
|||
for i, oldID in enumerate(np.unique(self.microstructure)):
|
||||
renumbered = np.where(self.microstructure == oldID, i+1, renumbered)
|
||||
|
||||
#self.add_comments('geom.py:renumber v{}'.format(version)
|
||||
return self.update(renumbered)
|
||||
#self.add_comments('tbd')
|
|
@ -1,10 +1,8 @@
|
|||
import numpy as np
|
||||
|
||||
from .rotation import Rotation
|
||||
from . import Rotation
|
||||
|
||||
P = -1
|
||||
|
||||
# ******************************************************************************************
|
||||
class Symmetry:
|
||||
"""
|
||||
Symmetry operations for lattice systems.
|
|
@ -1,7 +1,7 @@
|
|||
import numpy as np
|
||||
|
||||
from .lattice import Lattice
|
||||
from .rotation import Rotation
|
||||
from . import Lattice
|
||||
from . import Rotation
|
||||
|
||||
class Orientation:
|
||||
"""
|
|
@ -22,7 +22,7 @@ class Result:
|
|||
"""
|
||||
Read and write to DADF5 files.
|
||||
|
||||
DADF5 (DAKMASK HDF5) files contain DAMASK results.
|
||||
DADF5 (DAMASK HDF5) files contain DAMASK results.
|
||||
"""
|
||||
|
||||
def __init__(self,fname):
|
||||
|
@ -85,7 +85,14 @@ class Result:
|
|||
|
||||
def __repr__(self):
|
||||
"""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):
|
||||
|
@ -171,13 +178,13 @@ class Result:
|
|||
|
||||
"""
|
||||
datasets = self.selection[what]
|
||||
last_datasets = datasets.copy()
|
||||
last_selection = datasets.copy()
|
||||
for dataset in datasets:
|
||||
if last_datasets != self.selection[what]:
|
||||
if last_selection != self.selection[what]:
|
||||
self._manage_selection('set',what,datasets)
|
||||
raise Exception
|
||||
self._manage_selection('set',what,dataset)
|
||||
last_datasets = self.selection[what]
|
||||
last_selection = self.selection[what]
|
||||
yield dataset
|
||||
self._manage_selection('set',what,datasets)
|
||||
|
||||
|
@ -664,7 +671,7 @@ class Result:
|
|||
'meta' : {
|
||||
'Unit': 'RGB (8bit)',
|
||||
'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)
|
||||
}
|
||||
}
|
||||
|
@ -1014,13 +1021,13 @@ class Result:
|
|||
pool.join()
|
||||
|
||||
|
||||
def to_vtk(self,labels,mode='cell'):
|
||||
def to_vtk(self,labels=[],mode='cell'):
|
||||
"""
|
||||
Export to vtk cell/point data.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
labels : str or list of
|
||||
labels : str or list of, optional
|
||||
Labels of the datasets to be exported.
|
||||
mode : str, either 'cell' or 'point'
|
||||
Export in cell format or point format.
|
||||
|
@ -1039,7 +1046,7 @@ class Result:
|
|||
elif mode.lower()=='point':
|
||||
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']))):
|
||||
|
||||
|
@ -1093,9 +1100,6 @@ class Result:
|
|||
|
||||
###################################################################################################
|
||||
# BEGIN DEPRECATED
|
||||
iter_visible = iterate
|
||||
iter_selection = iterate
|
||||
|
||||
|
||||
def _time_to_inc(self,start,end):
|
||||
selected = []
|
||||
|
@ -1118,21 +1122,3 @@ class Result:
|
|||
|
||||
"""
|
||||
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)])
|
|
@ -1,6 +1,6 @@
|
|||
import numpy as np
|
||||
|
||||
from . import Lambert
|
||||
from ._Lambert import ball_to_cube, cube_to_ball
|
||||
|
||||
P = -1
|
||||
|
||||
|
@ -304,7 +304,7 @@ class Rotation:
|
|||
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:
|
||||
om = np.linalg.inv(om.T/np.pi) # transform reciprocal basis set
|
||||
orthonormal = False # contains stretch
|
||||
|
@ -338,7 +338,7 @@ class Rotation:
|
|||
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]))
|
||||
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))
|
||||
|
||||
|
@ -492,7 +492,7 @@ class Rotation:
|
|||
|
||||
@staticmethod
|
||||
def qu2ro(qu):
|
||||
"""Quaternion to Rodriques-Frank vector."""
|
||||
"""Quaternion to Rodrigues-Frank vector."""
|
||||
if iszero(qu[0]):
|
||||
ro = [qu[1], qu[2], qu[3], np.inf]
|
||||
else:
|
||||
|
@ -567,7 +567,7 @@ class Rotation:
|
|||
|
||||
@staticmethod
|
||||
def om2ro(om):
|
||||
"""Rotation matrix to Rodriques-Frank vector."""
|
||||
"""Rotation matrix to Rodrigues-Frank vector."""
|
||||
return Rotation.eu2ro(Rotation.om2eu(om))
|
||||
|
||||
@staticmethod
|
||||
|
@ -628,7 +628,7 @@ class Rotation:
|
|||
|
||||
@staticmethod
|
||||
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
|
||||
if ro[3] >= np.pi: # Differs from original implementation. check convention 5
|
||||
ro[3] = np.inf
|
||||
|
@ -682,7 +682,7 @@ class Rotation:
|
|||
|
||||
@staticmethod
|
||||
def ax2ro(ax):
|
||||
"""Axis angle pair to Rodriques-Frank vector."""
|
||||
"""Axis angle pair to Rodrigues-Frank vector."""
|
||||
if iszero(ax[3]):
|
||||
ro = [ 0.0, 0.0, P, 0.0 ]
|
||||
else:
|
||||
|
@ -708,7 +708,7 @@ class Rotation:
|
|||
#---------- Rodrigues-Frank vector ----------
|
||||
@staticmethod
|
||||
def ro2qu(ro):
|
||||
"""Rodriques-Frank vector to quaternion."""
|
||||
"""Rodrigues-Frank vector to quaternion."""
|
||||
return Rotation.ax2qu(Rotation.ro2ax(ro))
|
||||
|
||||
@staticmethod
|
||||
|
@ -718,12 +718,12 @@ class Rotation:
|
|||
|
||||
@staticmethod
|
||||
def ro2eu(ro):
|
||||
"""Rodriques-Frank vector to Bunge-Euler angles."""
|
||||
"""Rodrigues-Frank vector to Bunge-Euler angles."""
|
||||
return Rotation.om2eu(Rotation.ro2om(ro))
|
||||
|
||||
@staticmethod
|
||||
def ro2ax(ro):
|
||||
"""Rodriques-Frank vector to axis angle pair."""
|
||||
"""Rodrigues-Frank vector to axis angle pair."""
|
||||
ta = ro[3]
|
||||
|
||||
if iszero(ta):
|
||||
|
@ -738,7 +738,7 @@ class Rotation:
|
|||
|
||||
@staticmethod
|
||||
def ro2ho(ro):
|
||||
"""Rodriques-Frank vector to homochoric vector."""
|
||||
"""Rodrigues-Frank vector to homochoric vector."""
|
||||
if iszero(np.sum(ro[0:3]**2.0)):
|
||||
ho = [ 0.0, 0.0, 0.0 ]
|
||||
else:
|
||||
|
@ -748,7 +748,7 @@ class Rotation:
|
|||
|
||||
@staticmethod
|
||||
def ro2cu(ro):
|
||||
"""Rodriques-Frank vector to cubochoric vector."""
|
||||
"""Rodrigues-Frank vector to cubochoric vector."""
|
||||
return Rotation.ho2cu(Rotation.ro2ho(ro))
|
||||
|
||||
|
||||
|
@ -796,13 +796,13 @@ class Rotation:
|
|||
|
||||
@staticmethod
|
||||
def ho2ro(ho):
|
||||
"""Axis angle pair to Rodriques-Frank vector."""
|
||||
"""Axis angle pair to Rodrigues-Frank vector."""
|
||||
return Rotation.ax2ro(Rotation.ho2ax(ho))
|
||||
|
||||
@staticmethod
|
||||
def ho2cu(ho):
|
||||
"""Homochoric vector to cubochoric vector."""
|
||||
return Lambert.BallToCube(ho)
|
||||
return ball_to_cube(ho)
|
||||
|
||||
|
||||
#---------- Cubochoric ----------
|
||||
|
@ -828,10 +828,10 @@ class Rotation:
|
|||
|
||||
@staticmethod
|
||||
def cu2ro(cu):
|
||||
"""Cubochoric vector to Rodriques-Frank vector."""
|
||||
"""Cubochoric vector to Rodrigues-Frank vector."""
|
||||
return Rotation.ho2ro(Rotation.cu2ho(cu))
|
||||
|
||||
@staticmethod
|
||||
def cu2ho(cu):
|
||||
"""Cubochoric vector to homochoric vector."""
|
||||
return Lambert.CubeToBall(cu)
|
||||
return cube_to_ball(cu)
|
|
@ -5,7 +5,7 @@ import numpy as np
|
|||
|
||||
from . import version
|
||||
|
||||
class Table():
|
||||
class Table:
|
||||
"""Store spreadsheet-like data."""
|
||||
|
||||
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.data = pd.DataFrame(data=data)
|
||||
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."""
|
||||
labels = []
|
||||
for label,shape in self.shapes.items():
|
||||
|
@ -37,7 +37,7 @@ class Table():
|
|||
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."""
|
||||
labels = []
|
||||
for label,shape in self.shapes.items():
|
||||
|
@ -45,11 +45,10 @@ class Table():
|
|||
self.data.columns = labels
|
||||
|
||||
|
||||
def __add_comment(self,label,shape,info):
|
||||
def _add_comment(self,label,shape,info):
|
||||
if info is not None:
|
||||
self.comments.append('{}{}: {}'.format(label,
|
||||
' '+str(shape) if np.prod(shape,dtype=int) > 1 else '',
|
||||
info))
|
||||
c = '{}{}: {}'.format(label,' '+str(shape) if np.prod(shape,dtype=int) > 1 else '',info)
|
||||
self.comments.append(c)
|
||||
|
||||
|
||||
@staticmethod
|
||||
|
@ -57,7 +56,8 @@ class Table():
|
|||
"""
|
||||
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'.
|
||||
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):
|
||||
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:
|
||||
data = self.data[label].to_numpy().reshape((-1,)+self.shapes[label])
|
||||
|
||||
|
@ -188,7 +188,7 @@ class Table():
|
|||
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):
|
||||
idx,key = label.split('_',1)
|
||||
|
@ -212,7 +212,7 @@ class Table():
|
|||
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,)
|
||||
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.comments.append('{} => {}{}'.format(label_old,
|
||||
label_new,
|
||||
'' if info is None else ': {}'.format(info),
|
||||
))
|
||||
|
||||
c = '{} => {}{}'.format(label_old,label_new,'' if info is None else ': {}'.format(info))
|
||||
self.comments.append(c)
|
||||
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.
|
||||
|
||||
"""
|
||||
self.__label_flat()
|
||||
self._label_flat()
|
||||
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)))
|
||||
|
||||
|
||||
|
@ -287,7 +283,7 @@ class Table():
|
|||
Parameters
|
||||
----------
|
||||
other : Table
|
||||
Table to append
|
||||
Table to append.
|
||||
|
||||
"""
|
||||
if self.shapes != other.shapes or not self.data.columns.equals(other.data.columns):
|
||||
|
@ -305,7 +301,7 @@ class Table():
|
|||
Parameters
|
||||
----------
|
||||
other : Table
|
||||
Table to join
|
||||
Table to join.
|
||||
|
||||
"""
|
||||
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]
|
||||
|
||||
|
||||
def to_ASCII(self,fname,new=False):
|
||||
def to_ASCII(self,fname,new_style=False):
|
||||
"""
|
||||
Store as plain text file.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
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()
|
||||
|
@ -338,7 +336,7 @@ class Table():
|
|||
labels += ['{}:{}_{}'.format('x'.join([str(d) for d in self.shapes[l]]),i+1,l) \
|
||||
for i in range(np.prod(self.shapes[l]))]
|
||||
|
||||
if new:
|
||||
if new_style:
|
||||
header = ['# {}'.format(comment) for comment in self.comments]
|
||||
else:
|
||||
header = ['{} header'.format(len(self.comments)+1)] \
|
|
@ -1,11 +1,16 @@
|
|||
import os,sys,shutil
|
||||
import logging,logging.config
|
||||
import damask
|
||||
import numpy as np
|
||||
import os
|
||||
import sys
|
||||
import shutil
|
||||
import logging
|
||||
import logging.config
|
||||
from collections.abc import Iterable
|
||||
from optparse import OptionParser
|
||||
|
||||
class Test():
|
||||
import numpy as np
|
||||
|
||||
import damask
|
||||
|
||||
class Test:
|
||||
"""
|
||||
General class for testing.
|
||||
|
||||
|
@ -282,12 +287,10 @@ class Test():
|
|||
|
||||
import numpy as np
|
||||
logging.info('\n '.join(['comparing',File1,File2]))
|
||||
table1 = damask.ASCIItable(name=File1,readonly=True)
|
||||
table1.head_read()
|
||||
len1=len(table1.info)+2
|
||||
table2 = damask.ASCIItable(name=File2,readonly=True)
|
||||
table2.head_read()
|
||||
len2=len(table2.info)+2
|
||||
table = damask.Table.from_ASCII(File1)
|
||||
len1=len(table.comments)+2
|
||||
table = damask.Table.from_ASCII(File2)
|
||||
len2=len(table.comments)+2
|
||||
|
||||
refArray = np.nan_to_num(np.genfromtxt(File1,missing_values='n/a',skip_header = len1,autostrip=True))
|
||||
curArray = np.nan_to_num(np.genfromtxt(File2,missing_values='n/a',skip_header = len2,autostrip=True))
|
||||
|
@ -445,15 +448,15 @@ class Test():
|
|||
if not (isinstance(files, Iterable) and not isinstance(files, str)): # check whether list of files is requested
|
||||
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:
|
||||
table.head_read()
|
||||
table._label_flat()
|
||||
|
||||
columns += [columns[0]]*(len(files)-len(columns)) # extend to same length as files
|
||||
columns = columns[:len(files)] # truncate to same length as files
|
||||
|
||||
for i,column in enumerate(columns):
|
||||
if column is None: columns[i] = 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')
|
||||
for i in range(len(columns)):
|
||||
|
@ -467,9 +470,8 @@ class Test():
|
|||
|
||||
data = []
|
||||
for table,labels in zip(tables,columns):
|
||||
table.data_readArray(labels)
|
||||
data.append(table.data)
|
||||
table.close()
|
||||
table._label_condensed()
|
||||
data.append(np.hstack(list(table.get(label) for label in labels)))
|
||||
|
||||
|
||||
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...
|
||||
|
||||
tables = [damask.ASCIItable(name = filename,readonly = True) for filename in files]
|
||||
for table in tables:
|
||||
table.head_read()
|
||||
tables = [damask.Table.from_ASCII(filename) for filename in files]
|
||||
|
||||
columns += [columns[0]]*(len(files)-len(columns)) # extend to same length as files
|
||||
columns = columns[:len(files)] # truncate to same length as files
|
||||
|
||||
for i,column in enumerate(columns):
|
||||
if column is None: columns[i] = 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')
|
||||
for i in range(len(columns)):
|
||||
|
@ -515,22 +515,20 @@ class Test():
|
|||
)
|
||||
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
|
||||
data = [] # list of feature table extracted from each file (ASCII table)
|
||||
|
||||
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]))
|
||||
return False
|
||||
table.data_readArray(labels) # read data, ...
|
||||
data.append(table.data) # ... store, ...
|
||||
table.close() # ... close
|
||||
data.append(np.hstack(list(table.get(label) for label in labels)).astype(np.float)) # store
|
||||
|
||||
for j,label in enumerate(labels): # iterate over object labels
|
||||
maximum[j] = np.maximum(
|
||||
maximum[j],
|
||||
np.amax(np.linalg.norm(table.data[:,table.label_indexrange(label)],
|
||||
np.amax(np.linalg.norm(table.get(label),
|
||||
axis=1))
|
||||
) # find maximum Euclidean norm across rows
|
||||
|
||||
|
@ -552,8 +550,6 @@ class Test():
|
|||
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('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
|
||||
for i in range(1,len(data)):
|
|
@ -4,6 +4,7 @@ import pandas as pd
|
|||
import numpy as np
|
||||
import 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 Environment
|
||||
|
@ -30,6 +31,7 @@ class VTK:
|
|||
"""
|
||||
self.geom = geom
|
||||
|
||||
|
||||
@staticmethod
|
||||
def from_rectilinearGrid(grid,size,origin=np.zeros(3)):
|
||||
"""
|
||||
|
@ -47,16 +49,11 @@ class VTK:
|
|||
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.SetDimensions(*(grid+1))
|
||||
geom.SetXCoordinates(coordArray[0])
|
||||
geom.SetYCoordinates(coordArray[1])
|
||||
geom.SetZCoordinates(coordArray[2])
|
||||
geom.SetXCoordinates(np_to_vtk(np.linspace(origin[0],origin[0]+size[0],grid[0]+1),deep=True))
|
||||
geom.SetYCoordinates(np_to_vtk(np.linspace(origin[1],origin[1]+size[1],grid[1]+1),deep=True))
|
||||
geom.SetZCoordinates(np_to_vtk(np.linspace(origin[2],origin[2]+size[2],grid[2]+1),deep=True))
|
||||
|
||||
return VTK(geom)
|
||||
|
||||
|
@ -84,7 +81,7 @@ class VTK:
|
|||
cells.SetNumberOfCells(connectivity.shape[0])
|
||||
T = np.concatenate((np.ones((connectivity.shape[0],1),dtype=np.int64)*connectivity.shape[1],
|
||||
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.SetPoints(vtk_nodes)
|
||||
|
@ -123,9 +120,9 @@ class VTK:
|
|||
Parameters
|
||||
----------
|
||||
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
|
||||
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.
|
||||
|
||||
"""
|
||||
|
@ -134,11 +131,13 @@ class VTK:
|
|||
reader = vtk.vtkGenericDataObjectReader()
|
||||
reader.SetFileName(fname)
|
||||
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()
|
||||
elif 'unstructuredgrid' in dataset_type.lower():
|
||||
elif dataset_type.lower().endswith('unstructuredgrid'):
|
||||
geom = reader.GetUnstructuredGridOutput()
|
||||
elif 'polydata' in dataset_type.lower():
|
||||
elif dataset_type.lower().endswith('polydata'):
|
||||
geom = reader.GetPolyDataOutput()
|
||||
else:
|
||||
raise TypeError('Unknown dataset type for vtk file {}'.format(dataset_type))
|
||||
|
@ -159,7 +158,6 @@ class VTK:
|
|||
return VTK(geom)
|
||||
|
||||
|
||||
# ToDo: If extension is given, check for consistency.
|
||||
def write(self,fname):
|
||||
"""
|
||||
Write to file.
|
||||
|
@ -177,8 +175,11 @@ class VTK:
|
|||
elif(isinstance(self.geom,vtk.vtkPolyData)):
|
||||
writer = vtk.vtkXMLPolyDataWriter()
|
||||
|
||||
writer.SetFileName('{}.{}'.format(os.path.splitext(fname)[0],
|
||||
writer.GetDefaultFileExtension()))
|
||||
default_ext = 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.SetDataModeToBinary()
|
||||
writer.SetInputData(self.geom)
|
||||
|
@ -195,15 +196,19 @@ class VTK:
|
|||
|
||||
if isinstance(data,np.ndarray):
|
||||
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)
|
||||
if data.shape[0] == N_cells:
|
||||
self.geom.GetCellData().AddArray(d)
|
||||
elif data.shape[0] == N_points:
|
||||
self.geom.GetPointData().AddArray(d)
|
||||
elif isinstance(data,pd.DataFrame):
|
||||
pass
|
||||
raise NotImplementedError('pd.DataFrame')
|
||||
elif isinstance(data,Table):
|
||||
pass
|
||||
raise NotImplementedError('damask.Table')
|
||||
else:
|
||||
raise TypeError
|
||||
|
||||
|
||||
def __repr__(self):
|
|
@ -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
|
|
@ -1,5 +1,3 @@
|
|||
# -*- coding: UTF-8 no BOM -*-
|
||||
|
||||
"""Aggregator for configuration file handling"""
|
||||
"""Aggregator for configuration file handling."""
|
||||
|
||||
from .material import Material # noqa
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
# -*- coding: UTF-8 no BOM -*-
|
||||
|
||||
import re
|
||||
import os
|
||||
|
||||
|
||||
class Section():
|
||||
def __init__(self,data = {'__order__':[]},part = ''):
|
||||
"""New material.config section."""
|
||||
classes = {
|
||||
'homogenization':Homogenization,
|
||||
'microstructure':Microstructure,
|
||||
|
@ -35,26 +34,31 @@ class Section():
|
|||
|
||||
class Homogenization(Section):
|
||||
def __init__(self,data = {'__order__':[]}):
|
||||
"""New material.config <homogenization> section."""
|
||||
Section.__init__(self,data)
|
||||
|
||||
|
||||
class Crystallite(Section):
|
||||
def __init__(self,data = {'__order__':[]}):
|
||||
"""New material.config <crystallite> section."""
|
||||
Section.__init__(self,data)
|
||||
|
||||
|
||||
class Phase(Section):
|
||||
def __init__(self,data = {'__order__':[]}):
|
||||
"""New material.config <Phase> section."""
|
||||
Section.__init__(self,data)
|
||||
|
||||
|
||||
class Microstructure(Section):
|
||||
def __init__(self,data = {'__order__':[]}):
|
||||
"""New material.config <microstructure> section."""
|
||||
Section.__init__(self,data)
|
||||
|
||||
|
||||
class Texture(Section):
|
||||
def __init__(self,data = {'__order__':[]}):
|
||||
"""New material.config <texture> section."""
|
||||
Section.__init__(self,data)
|
||||
|
||||
def add_component(self,theType,properties):
|
||||
|
@ -79,10 +83,10 @@ class Texture(Section):
|
|||
|
||||
|
||||
class Material():
|
||||
"""Reads, manipulates and writes material.config files"""
|
||||
"""Read, manipulate, and write material.config files."""
|
||||
|
||||
def __init__(self,verbose=True):
|
||||
"""Generates ordered list of parts"""
|
||||
"""Generates ordered list of parts."""
|
||||
self.parts = [
|
||||
'homogenization',
|
||||
'crystallite',
|
||||
|
@ -100,7 +104,7 @@ class Material():
|
|||
self.verbose = verbose
|
||||
|
||||
def __repr__(self):
|
||||
"""Returns current data structure in material.config format"""
|
||||
"""Returns current data structure in material.config format."""
|
||||
me = []
|
||||
for part in self.parts:
|
||||
if self.verbose: print('processing <{}>'.format(part))
|
||||
|
@ -158,9 +162,9 @@ class Material():
|
|||
|
||||
|
||||
def read(self,filename=None):
|
||||
"""Reads material.config file"""
|
||||
"""Read material.config file."""
|
||||
def recursiveRead(filename):
|
||||
"""Takes care of include statements like '{}'"""
|
||||
"""Takes care of include statements like '{}'."""
|
||||
result = []
|
||||
re_include = re.compile(r'^{(.+)}$')
|
||||
with open(filename) as f: lines = f.readlines()
|
||||
|
@ -176,7 +180,7 @@ class Material():
|
|||
self.parse(part=p, content=c)
|
||||
|
||||
def write(self,filename='material.config', overwrite=False):
|
||||
"""Writes to material.config"""
|
||||
"""Write to material.config."""
|
||||
i = 0
|
||||
outname = filename
|
||||
while os.path.exists(outname) and not overwrite:
|
||||
|
@ -189,7 +193,7 @@ class Material():
|
|||
return outname
|
||||
|
||||
def add_section(self, part=None, section=None, initialData=None, merge=False):
|
||||
"""adding/updating"""
|
||||
"""Add Update."""
|
||||
part = part.lower()
|
||||
section = section.lower()
|
||||
if part not in self.parts: raise Exception('invalid part {}'.format(part))
|
||||
|
|
|
@ -98,17 +98,12 @@ def cell_coord0(grid,size,origin=np.zeros(3)):
|
|||
size : numpy.ndarray
|
||||
physical size of the periodic field.
|
||||
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
|
||||
end = origin - size/grid*.5 + size
|
||||
x, y, z = np.meshgrid(np.linspace(start[2],end[2],grid[2]),
|
||||
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)
|
||||
end = origin + size - size/grid*.5
|
||||
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
|
||||
|
||||
|
||||
def cell_displacement_fluct(size,F):
|
||||
|
@ -180,7 +175,7 @@ def cell_coord(size,F,origin=np.zeros(3)):
|
|||
F : numpy.ndarray
|
||||
deformation gradient field.
|
||||
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)
|
||||
|
@ -251,15 +246,12 @@ def node_coord0(grid,size,origin=np.zeros(3)):
|
|||
size : numpy.ndarray
|
||||
physical size of the periodic field.
|
||||
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]),
|
||||
np.linspace(origin[1],size[1]+origin[1],1+grid[1]),
|
||||
np.linspace(origin[0],size[0]+origin[0],1+grid[0]),
|
||||
indexing = 'ij')
|
||||
|
||||
return np.concatenate((z[:,:,:,None],y[:,:,:,None],x[:,:,:,None]),axis = 3)
|
||||
return np.mgrid[origin[0]:size[0]+origin[0]:(grid[0]+1)*1j,
|
||||
origin[1]:size[1]+origin[1]:(grid[1]+1)*1j,
|
||||
origin[2]:size[2]+origin[2]:(grid[2]+1)*1j].T
|
||||
|
||||
|
||||
def node_displacement_fluct(size,F):
|
||||
|
@ -319,7 +311,7 @@ def node_coord(size,F,origin=np.zeros(3)):
|
|||
F : numpy.ndarray
|
||||
deformation gradient field.
|
||||
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)
|
||||
|
@ -399,5 +391,5 @@ def regrid(size,F,new_grid):
|
|||
c[np.where(c[:,:,:,d]<0)] += 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()
|
||||
|
|
|
@ -8,10 +8,10 @@ def Cauchy(P,F):
|
|||
|
||||
Parameters
|
||||
----------
|
||||
F : numpy.array of shape (:,3,3) or (3,3)
|
||||
F : numpy.ndarray of shape (:,3,3) or (3,3)
|
||||
Deformation gradient.
|
||||
P : numpy.array of shape (:,3,3) or (3,3)
|
||||
1. Piola-Kirchhoff stress.
|
||||
P : numpy.ndarray of shape (:,3,3) or (3,3)
|
||||
First Piola-Kirchhoff stress.
|
||||
|
||||
"""
|
||||
if np.shape(F) == np.shape(P) == (3,3):
|
||||
|
@ -27,7 +27,7 @@ def deviatoric_part(T):
|
|||
|
||||
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.
|
||||
|
||||
"""
|
||||
|
@ -44,7 +44,7 @@ def eigenvalues(T_sym):
|
|||
|
||||
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.
|
||||
|
||||
"""
|
||||
|
@ -59,7 +59,7 @@ def eigenvectors(T_sym,RHS=False):
|
|||
|
||||
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.
|
||||
RHS: bool, optional
|
||||
Enforce right-handed coordinate system. Default is False.
|
||||
|
@ -81,11 +81,11 @@ def left_stretch(T):
|
|||
|
||||
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.
|
||||
|
||||
"""
|
||||
return __polar_decomposition(T,'V')[0]
|
||||
return _polar_decomposition(T,'V')[0]
|
||||
|
||||
|
||||
def maximum_shear(T_sym):
|
||||
|
@ -94,7 +94,7 @@ def maximum_shear(T_sym):
|
|||
|
||||
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.
|
||||
|
||||
"""
|
||||
|
@ -109,11 +109,11 @@ def Mises_strain(epsilon):
|
|||
|
||||
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.
|
||||
|
||||
"""
|
||||
return __Mises(epsilon,2.0/3.0)
|
||||
return _Mises(epsilon,2.0/3.0)
|
||||
|
||||
|
||||
def Mises_stress(sigma):
|
||||
|
@ -122,11 +122,11 @@ def Mises_stress(sigma):
|
|||
|
||||
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.
|
||||
|
||||
"""
|
||||
return __Mises(sigma,3.0/2.0)
|
||||
return _Mises(sigma,3.0/2.0)
|
||||
|
||||
|
||||
def PK2(P,F):
|
||||
|
@ -135,9 +135,9 @@ def PK2(P,F):
|
|||
|
||||
Parameters
|
||||
----------
|
||||
P : numpy.array of shape (:,3,3) or (3,3)
|
||||
1. Piola-Kirchhoff stress.
|
||||
F : numpy.array of shape (:,3,3) or (3,3)
|
||||
P : numpy.ndarray of shape (:,3,3) or (3,3)
|
||||
First Piola-Kirchhoff stress.
|
||||
F : numpy.ndarray of shape (:,3,3) or (3,3)
|
||||
Deformation gradient.
|
||||
|
||||
"""
|
||||
|
@ -154,11 +154,11 @@ def right_stretch(T):
|
|||
|
||||
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.
|
||||
|
||||
"""
|
||||
return __polar_decomposition(T,'U')[0]
|
||||
return _polar_decomposition(T,'U')[0]
|
||||
|
||||
|
||||
def rotational_part(T):
|
||||
|
@ -167,11 +167,11 @@ def rotational_part(T):
|
|||
|
||||
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.
|
||||
|
||||
"""
|
||||
return __polar_decomposition(T,'R')[0]
|
||||
return _polar_decomposition(T,'R')[0]
|
||||
|
||||
|
||||
def spherical_part(T,tensor=False):
|
||||
|
@ -180,7 +180,7 @@ def spherical_part(T,tensor=False):
|
|||
|
||||
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 : bool, optional
|
||||
Map spherical part onto identity tensor. Default is false
|
||||
|
@ -206,7 +206,7 @@ def strain_tensor(F,t,m):
|
|||
|
||||
Parameters
|
||||
----------
|
||||
F : numpy.array of shape (:,3,3) or (3,3)
|
||||
F : numpy.ndarray of shape (:,3,3) or (3,3)
|
||||
Deformation gradient.
|
||||
t : {‘V’, ‘U’}
|
||||
Type of the polar decomposition, ‘V’ for left stretch tensor and ‘U’ for right stretch tensor.
|
||||
|
@ -214,7 +214,7 @@ def strain_tensor(F,t,m):
|
|||
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':
|
||||
B = np.matmul(F_,transpose(F_))
|
||||
w,n = np.linalg.eigh(B)
|
||||
|
@ -231,7 +231,7 @@ def strain_tensor(F,t,m):
|
|||
else:
|
||||
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
|
||||
|
||||
|
||||
|
@ -241,7 +241,7 @@ def symmetric(T):
|
|||
|
||||
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.
|
||||
|
||||
"""
|
||||
|
@ -254,7 +254,7 @@ def transpose(T):
|
|||
|
||||
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.
|
||||
|
||||
"""
|
||||
|
@ -262,13 +262,13 @@ def transpose(T):
|
|||
np.transpose(T,(0,2,1))
|
||||
|
||||
|
||||
def __polar_decomposition(T,requested):
|
||||
def _polar_decomposition(T,requested):
|
||||
"""
|
||||
Singular value decomposition.
|
||||
|
||||
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.
|
||||
requested : iterable of str
|
||||
Requested outputs: ‘R’ for the rotation tensor,
|
||||
|
@ -290,13 +290,13 @@ def __polar_decomposition(T,requested):
|
|||
return tuple(output)
|
||||
|
||||
|
||||
def __Mises(T_sym,s):
|
||||
def _Mises(T_sym,s):
|
||||
"""
|
||||
Base equation for Mises equivalent of a stres or strain tensor.
|
||||
|
||||
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.
|
||||
s : float
|
||||
Scaling factor (2/3 for strain, 3/2 for stress).
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
"""Tools to control the various solvers."""
|
||||
|
||||
from .solver import Solver # noqa
|
||||
from .marc import Marc # noqa
|
||||
from ._marc import Marc # noqa
|
||||
|
|
|
@ -3,13 +3,12 @@ import subprocess
|
|||
import shlex
|
||||
import string
|
||||
|
||||
from .solver import Solver
|
||||
import damask
|
||||
from .._environment import Environment
|
||||
|
||||
class Marc(Solver):
|
||||
class Marc:
|
||||
"""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.
|
||||
|
||||
|
@ -29,7 +28,7 @@ class Marc(Solver):
|
|||
#--------------------------
|
||||
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)
|
||||
|
||||
return path_lib if os.path.exists(path_lib) else ''
|
||||
|
@ -38,7 +37,7 @@ class Marc(Solver):
|
|||
#--------------------------
|
||||
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)
|
||||
|
||||
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'))
|
||||
if not os.path.isfile(user):
|
|
@ -1,6 +0,0 @@
|
|||
class Solver():
|
||||
"""
|
||||
General class for solver specific functionality.
|
||||
|
||||
Sub-classed by the individual solvers.
|
||||
"""
|
|
@ -66,12 +66,12 @@ def croak(what, newline = True):
|
|||
Parameters
|
||||
----------
|
||||
what : str or iterable
|
||||
Content to be displayed
|
||||
Content to be displayed.
|
||||
newline : bool, optional
|
||||
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.flush()
|
||||
|
||||
|
@ -122,8 +122,8 @@ def execute(cmd,
|
|||
Input (via pipe) for executed process.
|
||||
wd : str, optional
|
||||
Working directory of process. Defaults to ./ .
|
||||
env :
|
||||
Environment
|
||||
env : dict, optional
|
||||
Environment for execution.
|
||||
|
||||
"""
|
||||
initialPath = os.getcwd()
|
||||
|
@ -258,7 +258,7 @@ def scale_to_coprime(v):
|
|||
return m//reduce(np.gcd,m)
|
||||
|
||||
|
||||
class return_message():
|
||||
class return_message:
|
||||
"""Object with formatted return message."""
|
||||
|
||||
def __init__(self,message):
|
||||
|
|
|
@ -18,7 +18,7 @@ def default():
|
|||
x=np.concatenate((np.ones(40,dtype=int),
|
||||
np.arange(2,42),
|
||||
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])
|
||||
|
||||
@pytest.fixture
|
||||
|
|
|
@ -27,7 +27,7 @@ class TestResult:
|
|||
def test_time_increments(self,default):
|
||||
shape = default.read_dataset(default.get_dataset_location('F'),0).shape
|
||||
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
|
||||
|
||||
|
||||
|
@ -61,7 +61,7 @@ class TestResult:
|
|||
default.add_determinant('P')
|
||||
loc = {'P': default.get_dataset_location('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)
|
||||
assert np.allclose(in_memory,in_file)
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@ class TestTable:
|
|||
|
||||
def test_write_read_new_style(self,default,tmpdir):
|
||||
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:
|
||||
new = Table.from_ASCII(f)
|
||||
assert all(default.data==new.data) and default.shapes == new.shapes
|
||||
|
@ -173,4 +173,4 @@ class TestTable:
|
|||
['test data'])
|
||||
t.add('s',np.array(['b','a']))
|
||||
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))
|
||||
|
|
|
@ -31,7 +31,7 @@ class TestGridFilters:
|
|||
size = np.random.random(3)
|
||||
origin = np.random.random(3)
|
||||
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)
|
||||
|
||||
def test_displacement_fluct_equivalence(self):
|
||||
|
|
|
@ -1,4 +1 @@
|
|||
Makefile
|
||||
cmake_install.cmake
|
||||
quit__genmod.f90
|
||||
*.marc
|
||||
|
|
|
@ -9,13 +9,11 @@ file(GLOB damask-sources *.f90 *.c)
|
|||
# probably we should have a subfolder for MSC.Marc
|
||||
list(FILTER damask-sources EXCLUDE REGEX ".*CPFEM.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")
|
||||
|
||||
|
||||
if (PROJECT_NAME STREQUAL "damask-grid")
|
||||
|
||||
list(FILTER damask-sources EXCLUDE REGEX ".*mesh_FEM.*.f90")
|
||||
file(GLOB grid-sources grid/*.f90)
|
||||
|
||||
if(NOT CMAKE_BUILD_TYPE STREQUAL "SYNTAXONLY")
|
||||
|
@ -30,7 +28,6 @@ if (PROJECT_NAME STREQUAL "damask-grid")
|
|||
|
||||
elseif (PROJECT_NAME STREQUAL "damask-mesh")
|
||||
|
||||
list(FILTER damask-sources EXCLUDE REGEX ".*mesh_grid.*.f90")
|
||||
file(GLOB mesh-sources mesh/*.f90)
|
||||
|
||||
add_executable(DAMASK_FEM ${damask-sources} ${mesh-sources})
|
||||
|
|
|
@ -10,7 +10,7 @@ module CPFEM
|
|||
use FEsolving
|
||||
use math
|
||||
use rotations
|
||||
use mesh
|
||||
use discretization_marc
|
||||
use material
|
||||
use config
|
||||
use crystallite
|
||||
|
@ -85,7 +85,7 @@ subroutine CPFEM_initAll(el,ip)
|
|||
call rotations_init
|
||||
call HDF5_utilities_init
|
||||
call results_init
|
||||
call mesh_init(ip, el)
|
||||
call discretization_marc_init(ip, el)
|
||||
call lattice_init
|
||||
call material_init
|
||||
call constitutive_init
|
||||
|
@ -139,8 +139,8 @@ subroutine CPFEM_general(mode, parallelExecution, ffn, ffn1, temperature_inp, dt
|
|||
|
||||
real(pReal) J_inverse, & ! inverse of Jacobian
|
||||
rnd
|
||||
real(pReal), dimension (3,3) :: Kirchhoff, & ! Piola-Kirchhoff stress in Matrix notation
|
||||
cauchyStress33 ! stress vector in Matrix notation
|
||||
real(pReal), dimension (3,3) :: Kirchhoff, & ! Piola-Kirchhoff stress
|
||||
cauchyStress33 ! stress vector
|
||||
real(pReal), dimension (3,3,3,3) :: H_sym, &
|
||||
H, &
|
||||
jacobian3333 ! jacobian in Matrix notation
|
||||
|
@ -180,7 +180,6 @@ subroutine CPFEM_general(mode, parallelExecution, ffn, ffn1, temperature_inp, dt
|
|||
|
||||
!*** 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 (.not. parallelExecution) then
|
||||
chosenThermal1: select case (thermal_type(material_homogenizationAt(elCP)))
|
||||
case (THERMAL_conduction_ID) chosenThermal1
|
||||
|
@ -203,12 +202,10 @@ subroutine CPFEM_general(mode, parallelExecution, ffn, ffn1, temperature_inp, dt
|
|||
materialpoint_F0(1:3,1:3,ip,elCP) = ffn
|
||||
materialpoint_F(1:3,1:3,ip,elCP) = ffn1
|
||||
CPFEM_calc_done = .false.
|
||||
endif ! collection
|
||||
|
||||
endif
|
||||
|
||||
|
||||
!*** calculation of stress and jacobian
|
||||
|
||||
if (iand(mode, CPFEM_CALCRESULTS) /= 0_pInt) then
|
||||
|
||||
!*** deformation gradient outdated or any actual deformation gradient differs more than relevantStrain from the stored one
|
||||
|
@ -230,25 +227,22 @@ subroutine CPFEM_general(mode, parallelExecution, ffn, ffn1, temperature_inp, dt
|
|||
CPFEM_dcsde(1:6,1:6,ip,elCP) = ODD_JACOBIAN * math_identity2nd(6)
|
||||
|
||||
!*** 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) ! calculate stress and its tangent
|
||||
call materialpoint_stressAndItsTangent(updateJaco, dt)
|
||||
|
||||
!* parallel computation and calulation not yet done
|
||||
|
||||
elseif (.not. CPFEM_calc_done) then
|
||||
if (iand(debug_level(debug_CPFEM), debug_levelExtensive) /= 0_pInt) &
|
||||
write(6,'(a,i8,a,i8)') '<< CPFEM >> calculation for elements ',FEsolving_execElem(1),&
|
||||
' to ',FEsolving_execElem(2)
|
||||
call materialpoint_stressAndItsTangent(updateJaco, dt) ! calculate stress and its tangent (parallel execution inside)
|
||||
call materialpoint_stressAndItsTangent(updateJaco, dt)
|
||||
CPFEM_calc_done = .true.
|
||||
endif
|
||||
|
||||
|
@ -262,7 +256,6 @@ subroutine CPFEM_general(mode, parallelExecution, ffn, ffn1, temperature_inp, dt
|
|||
|
||||
else terminalIllness
|
||||
|
||||
|
||||
! 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))
|
||||
|
|
|
@ -21,11 +21,11 @@ module CPFEM2
|
|||
use homogenization
|
||||
use constitutive
|
||||
use crystallite
|
||||
#ifdef FEM
|
||||
use FEM_Zoo
|
||||
use mesh
|
||||
#else
|
||||
use mesh_grid
|
||||
#if defined(FEM)
|
||||
use FEM_quadrature
|
||||
use discretization_mesh
|
||||
#elif defined(Grid)
|
||||
use discretization_grid
|
||||
#endif
|
||||
|
||||
implicit none
|
||||
|
@ -43,7 +43,7 @@ subroutine CPFEM_initAll
|
|||
call prec_init
|
||||
call IO_init
|
||||
#ifdef FEM
|
||||
call FEM_Zoo_init
|
||||
call FEM_quadrature_init
|
||||
#endif
|
||||
call numerics_init
|
||||
call debug_init
|
||||
|
@ -53,7 +53,11 @@ subroutine CPFEM_initAll
|
|||
call lattice_init
|
||||
call HDF5_utilities_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 constitutive_init
|
||||
call crystallite_init
|
||||
|
|
|
@ -178,7 +178,7 @@ subroutine hypela2(d,g,e,de,s,t,dt,ngens,m,nn,kcus,matus,ndi,nshear,disp, &
|
|||
use numerics
|
||||
use FEsolving
|
||||
use debug
|
||||
use mesh
|
||||
use discretization_marc
|
||||
use CPFEM
|
||||
|
||||
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)
|
||||
! Beware of changes in newer Marc versions
|
||||
|
||||
#include QUOTE(PASTE(./MarcInclude/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/concom,Marc4DAMASK)) ! concom is needed for inc, lovl
|
||||
#include QUOTE(PASTE(./marc/include/creeps,Marc4DAMASK)) ! creeps is needed for timinc (time increment)
|
||||
|
||||
logical :: cutBack
|
||||
real(pReal), dimension(6) :: stress
|
||||
|
@ -378,7 +378,7 @@ end subroutine hypela2
|
|||
subroutine flux(f,ts,n,time)
|
||||
use prec
|
||||
use thermal_conduction
|
||||
use mesh
|
||||
use discretization_marc
|
||||
|
||||
implicit none
|
||||
real(pReal), dimension(6), intent(in) :: &
|
||||
|
@ -408,7 +408,7 @@ subroutine uedinc(inc,incsub)
|
|||
implicit none
|
||||
integer, intent(in) :: inc, incsub
|
||||
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
|
||||
call CPFEM_results(inc,cptim)
|
||||
|
|
|
@ -525,10 +525,10 @@ end subroutine HDF5_setLink
|
|||
!--------------------------------------------------------------------------------------------------
|
||||
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
|
||||
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(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)
|
||||
|
||||
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
|
||||
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(HSIZE_T), dimension(size(shape(dataset))) :: &
|
||||
|
@ -605,10 +605,10 @@ end subroutine HDF5_read_real2
|
|||
!--------------------------------------------------------------------------------------------------
|
||||
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
|
||||
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(HSIZE_T), dimension(size(shape(dataset))) :: &
|
||||
|
@ -645,10 +645,10 @@ end subroutine HDF5_read_real3
|
|||
!--------------------------------------------------------------------------------------------------
|
||||
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
|
||||
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(HSIZE_T), dimension(size(shape(dataset))) :: &
|
||||
|
@ -685,10 +685,10 @@ end subroutine HDF5_read_real4
|
|||
!--------------------------------------------------------------------------------------------------
|
||||
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
|
||||
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(HSIZE_T), dimension(size(shape(dataset))) :: &
|
||||
|
@ -725,10 +725,10 @@ end subroutine HDF5_read_real5
|
|||
!--------------------------------------------------------------------------------------------------
|
||||
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
|
||||
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(HSIZE_T), dimension(size(shape(dataset))) :: &
|
||||
|
@ -765,10 +765,10 @@ end subroutine HDF5_read_real6
|
|||
!--------------------------------------------------------------------------------------------------
|
||||
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
|
||||
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(HSIZE_T), dimension(size(shape(dataset))) :: &
|
||||
|
@ -806,10 +806,11 @@ end subroutine HDF5_read_real7
|
|||
!--------------------------------------------------------------------------------------------------
|
||||
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
|
||||
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(HSIZE_T), dimension(size(shape(dataset))) :: &
|
||||
|
@ -846,10 +847,10 @@ end subroutine HDF5_read_int1
|
|||
!--------------------------------------------------------------------------------------------------
|
||||
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
|
||||
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(HSIZE_T), dimension(size(shape(dataset))) :: &
|
||||
|
@ -886,10 +887,10 @@ end subroutine HDF5_read_int2
|
|||
!--------------------------------------------------------------------------------------------------
|
||||
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
|
||||
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(HSIZE_T), dimension(size(shape(dataset))) :: &
|
||||
|
@ -926,10 +927,10 @@ end subroutine HDF5_read_int3
|
|||
!--------------------------------------------------------------------------------------------------
|
||||
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
|
||||
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(HSIZE_T), dimension(size(shape(dataset))) :: &
|
||||
|
@ -966,10 +967,10 @@ end subroutine HDF5_read_int4
|
|||
!--------------------------------------------------------------------------------------------------
|
||||
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
|
||||
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(HSIZE_T), dimension(size(shape(dataset))) :: &
|
||||
|
@ -1006,10 +1007,10 @@ end subroutine HDF5_read_int5
|
|||
!--------------------------------------------------------------------------------------------------
|
||||
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
|
||||
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(HSIZE_T), dimension(size(shape(dataset))) :: &
|
||||
|
@ -1046,10 +1047,10 @@ end subroutine HDF5_read_int6
|
|||
!--------------------------------------------------------------------------------------------------
|
||||
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
|
||||
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(HSIZE_T), dimension(size(shape(dataset))) :: &
|
||||
|
@ -1087,10 +1088,10 @@ end subroutine HDF5_read_int7
|
|||
!--------------------------------------------------------------------------------------------------
|
||||
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
|
||||
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
|
||||
|
@ -1128,10 +1129,10 @@ end subroutine HDF5_write_real1
|
|||
!--------------------------------------------------------------------------------------------------
|
||||
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
|
||||
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
|
||||
|
@ -1169,10 +1170,10 @@ end subroutine HDF5_write_real2
|
|||
!--------------------------------------------------------------------------------------------------
|
||||
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
|
||||
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
|
||||
|
@ -1210,10 +1211,10 @@ end subroutine HDF5_write_real3
|
|||
!--------------------------------------------------------------------------------------------------
|
||||
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
|
||||
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
|
||||
|
@ -1252,10 +1253,10 @@ end subroutine HDF5_write_real4
|
|||
!--------------------------------------------------------------------------------------------------
|
||||
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
|
||||
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
|
||||
|
@ -1293,10 +1294,10 @@ end subroutine HDF5_write_real5
|
|||
!--------------------------------------------------------------------------------------------------
|
||||
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
|
||||
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
|
||||
|
@ -1334,10 +1335,10 @@ end subroutine HDF5_write_real6
|
|||
!--------------------------------------------------------------------------------------------------
|
||||
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
|
||||
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
|
||||
|
@ -1376,10 +1377,10 @@ end subroutine HDF5_write_real7
|
|||
!--------------------------------------------------------------------------------------------------
|
||||
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
|
||||
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
|
||||
|
@ -1417,10 +1418,10 @@ end subroutine HDF5_write_int1
|
|||
!--------------------------------------------------------------------------------------------------
|
||||
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
|
||||
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
|
||||
|
@ -1458,10 +1459,10 @@ end subroutine HDF5_write_int2
|
|||
!--------------------------------------------------------------------------------------------------
|
||||
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
|
||||
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
|
||||
|
@ -1499,10 +1500,10 @@ end subroutine HDF5_write_int3
|
|||
!--------------------------------------------------------------------------------------------------
|
||||
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
|
||||
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
|
||||
|
@ -1540,10 +1541,10 @@ end subroutine HDF5_write_int4
|
|||
!--------------------------------------------------------------------------------------------------
|
||||
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
|
||||
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
|
||||
|
@ -1581,10 +1582,10 @@ end subroutine HDF5_write_int5
|
|||
!--------------------------------------------------------------------------------------------------
|
||||
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
|
||||
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
|
||||
|
@ -1622,10 +1623,10 @@ end subroutine HDF5_write_int6
|
|||
!--------------------------------------------------------------------------------------------------
|
||||
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
|
||||
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
|
||||
|
@ -1666,7 +1667,7 @@ end subroutine HDF5_write_int7
|
|||
!--------------------------------------------------------------------------------------------------
|
||||
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
|
||||
character(len=*), intent(in) :: datasetName !< name of the dataset in the file
|
||||
logical, intent(in), optional :: parallel
|
||||
|
|
69
src/IO.f90
69
src/IO.f90
|
@ -7,14 +7,15 @@
|
|||
!--------------------------------------------------------------------------------------------------
|
||||
module IO
|
||||
use prec
|
||||
use DAMASK_interface
|
||||
|
||||
implicit none
|
||||
private
|
||||
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 :: &
|
||||
IO_EOL = new_line(' ') !< end of line str
|
||||
IO_EOL = new_line('DAMASK'), & !< end of line character
|
||||
IO_COMMENT = '#'
|
||||
character(len=*), parameter, private :: &
|
||||
IO_DIVIDER = '───────────────────'//&
|
||||
'───────────────────'//&
|
||||
|
@ -23,7 +24,7 @@ module IO
|
|||
public :: &
|
||||
IO_init, &
|
||||
IO_read_ASCII, &
|
||||
IO_open_jobFile_binary, &
|
||||
IO_open_binary, &
|
||||
IO_isBlank, &
|
||||
IO_getTag, &
|
||||
IO_stringPos, &
|
||||
|
@ -43,6 +44,7 @@ contains
|
|||
subroutine IO_init
|
||||
|
||||
write(6,'(/,a)') ' <<<+- IO init -+>>>'; flush(6)
|
||||
|
||||
call unitTest
|
||||
|
||||
end subroutine IO_init
|
||||
|
@ -114,24 +116,6 @@ function IO_read_ASCII(fileName) result(fileContent)
|
|||
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.
|
||||
!> @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=*), parameter :: blankChar = achar(32)//achar(9)//achar(10)//achar(13) ! whitespaces
|
||||
character(len=*), parameter :: comment = achar(35) ! comment id '#'
|
||||
integer :: posNonBlank
|
||||
|
||||
integer :: posNonBlank, posComment
|
||||
|
||||
posNonBlank = verify(string,blankChar)
|
||||
posComment = scan(string,comment)
|
||||
IO_isBlank = posNonBlank == 0 .or. posNonBlank == posComment
|
||||
posNonBlank = verify(string,IO_WHITESPACE)
|
||||
IO_isBlank = posNonBlank == 0 .or. posNonBlank == scan(string,IO_COMMENT)
|
||||
|
||||
end function IO_isBlank
|
||||
|
||||
|
@ -194,18 +174,14 @@ pure function IO_getTag(string,openChar,closeChar)
|
|||
closeChar !< indicates end of tag
|
||||
character(len=:), allocatable :: IO_getTag
|
||||
|
||||
character(len=*), parameter :: SEP=achar(32)//achar(9)//achar(10)//achar(13) ! whitespaces
|
||||
integer :: left,right
|
||||
|
||||
if (openChar /= closeChar) then
|
||||
left = scan(string,openChar)
|
||||
right = scan(string,closeChar)
|
||||
else
|
||||
left = scan(string,openChar)
|
||||
right = left + merge(scan(string(left+1:),openChar),0,len(string) > left)
|
||||
endif
|
||||
right = merge(scan(string,closeChar), &
|
||||
left + merge(scan(string(left+1:),openChar),0,len(string) > left), &
|
||||
openChar /= closeChar)
|
||||
|
||||
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)
|
||||
else foundTag
|
||||
IO_getTag = ''
|
||||
|
@ -215,8 +191,8 @@ end function IO_getTag
|
|||
|
||||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
!> @brief locates all space-separated chunks in given string and returns array containing number
|
||||
!! them and the left/right position to be used by IO_xxxVal
|
||||
!> @brief locates all whitespace-separated chunks in given string and returns array containing
|
||||
!! 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
|
||||
!! 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
|
||||
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
|
||||
|
||||
allocate(IO_stringPos(1), source=0)
|
||||
right = 0
|
||||
|
||||
do while (verify(string(right+1:),SEP)>0)
|
||||
left = right + verify(string(right+1:),SEP)
|
||||
right = left + scan(string(left:),SEP) - 2
|
||||
if ( string(left:left) == '#' ) exit
|
||||
do while (verify(string(right+1:),IO_WHITESPACE)>0)
|
||||
left = right + verify(string(right+1:),IO_WHITESPACE)
|
||||
right = left + scan(string(left:),IO_WHITESPACE) - 2
|
||||
if ( string(left:left) == IO_COMMENT) exit
|
||||
IO_stringPos = [IO_stringPos,left,right]
|
||||
IO_stringPos(1) = IO_stringPos(1)+1
|
||||
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
|
||||
|
||||
|
@ -704,6 +679,10 @@ subroutine unitTest
|
|||
chunkPos = IO_stringPos(str)
|
||||
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 module IO
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
#include "geometry_plastic_nonlocal.f90"
|
||||
#include "discretization.f90"
|
||||
#ifdef Marc4DAMASK
|
||||
#include "mesh_marc.f90"
|
||||
#include "marc/discretization_marc.f90"
|
||||
#endif
|
||||
#include "material.f90"
|
||||
#include "lattice.f90"
|
||||
|
|
|
@ -132,7 +132,7 @@ contains
|
|||
!--------------------------------------------------------------------------------------------------
|
||||
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
|
||||
character(len=pStringLen), dimension(:), allocatable :: fileContent !< file content, separated per lines
|
||||
character(len=pStringLen), dimension(:), allocatable :: includedContent
|
||||
|
|
|
@ -127,7 +127,7 @@ module constitutive
|
|||
end subroutine plastic_disloUCLA_LpAndItsTangent
|
||||
|
||||
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) :: &
|
||||
Lp !< plastic velocity gradient
|
||||
real(pReal), dimension(3,3,3,3), intent(out) :: &
|
||||
|
@ -136,9 +136,10 @@ module constitutive
|
|||
real(pReal), dimension(3,3), intent(in) :: &
|
||||
Mp !< Mandel stress
|
||||
real(pReal), intent(in) :: &
|
||||
Temperature, &
|
||||
volume
|
||||
Temperature
|
||||
integer, intent(in) :: &
|
||||
instance, &
|
||||
of, &
|
||||
ip, & !< current integration point
|
||||
el !< current element number
|
||||
end subroutine plastic_nonlocal_LpAndItsTangent
|
||||
|
@ -202,19 +203,21 @@ module constitutive
|
|||
of
|
||||
end subroutine plastic_disloUCLA_dotState
|
||||
|
||||
module subroutine plastic_nonlocal_dotState(Mp, F, Fp, Temperature, &
|
||||
timestep,ip,el)
|
||||
integer, intent(in) :: &
|
||||
ip, & !< current integration point
|
||||
el !< current element number
|
||||
real(pReal), intent(in) :: &
|
||||
Temperature, & !< temperature
|
||||
timestep !< substepped crystallite time increment
|
||||
module subroutine plastic_nonlocal_dotState(Mp, F, Fp, Temperature,timestep, &
|
||||
instance,of,ip,el)
|
||||
real(pReal), dimension(3,3), intent(in) ::&
|
||||
Mp !< MandelStress
|
||||
real(pReal), dimension(3,3,homogenization_maxNgrains,discretization_nIP,discretization_nElem), intent(in) :: &
|
||||
F, & !< 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
|
||||
|
||||
|
||||
|
@ -232,13 +235,15 @@ module constitutive
|
|||
of
|
||||
end subroutine plastic_disloUCLA_dependentState
|
||||
|
||||
module subroutine plastic_nonlocal_dependentState(F, Fp, ip, el)
|
||||
integer, intent(in) :: &
|
||||
ip, &
|
||||
el
|
||||
module subroutine plastic_nonlocal_dependentState(F, Fp, instance, of, ip, el)
|
||||
real(pReal), dimension(3,3), intent(in) :: &
|
||||
F, &
|
||||
Fp
|
||||
integer, intent(in) :: &
|
||||
instance, &
|
||||
of, &
|
||||
ip, &
|
||||
el
|
||||
end subroutine plastic_nonlocal_dependentState
|
||||
|
||||
|
||||
|
@ -250,12 +255,14 @@ module constitutive
|
|||
of
|
||||
end subroutine plastic_kinehardening_deltaState
|
||||
|
||||
module subroutine plastic_nonlocal_deltaState(Mp,ip,el)
|
||||
integer, intent(in) :: &
|
||||
ip, &
|
||||
el
|
||||
module subroutine plastic_nonlocal_deltaState(Mp,instance,of,ip,el)
|
||||
real(pReal), dimension(3,3), intent(in) :: &
|
||||
Mp
|
||||
integer, intent(in) :: &
|
||||
instance, &
|
||||
of, &
|
||||
ip, &
|
||||
el
|
||||
end subroutine plastic_nonlocal_deltaState
|
||||
|
||||
|
||||
|
@ -268,8 +275,9 @@ module constitutive
|
|||
el !< element
|
||||
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) :: &
|
||||
instance, &
|
||||
i, &
|
||||
e
|
||||
type(rotation), dimension(1,discretization_nIP,discretization_nElem), intent(in) :: &
|
||||
|
@ -364,9 +372,7 @@ subroutine constitutive_init
|
|||
|
||||
write(6,'(/,a)') ' <<<+- constitutive init -+>>>'; flush(6)
|
||||
|
||||
constitutive_plasticity_maxSizeDotState = 0
|
||||
constitutive_source_maxSizeDotState = 0
|
||||
|
||||
PhaseLoop2:do ph = 1,material_Nphase
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! partition and inititalize state
|
||||
|
@ -377,12 +383,11 @@ subroutine constitutive_init
|
|||
sourceState(ph)%p(s)%state = sourceState(ph)%p(s)%partionedState0
|
||||
end forall
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! determine max size of state and output
|
||||
constitutive_plasticity_maxSizeDotState = max(constitutive_plasticity_maxSizeDotState, &
|
||||
plasticState(ph)%sizeDotState)
|
||||
! determine max size of source state
|
||||
constitutive_source_maxSizeDotState = max(constitutive_source_maxSizeDotState, &
|
||||
maxval(sourceState(ph)%p(:)%sizeDotState))
|
||||
maxval(sourceState(ph)%p%sizeDotState))
|
||||
enddo PhaseLoop2
|
||||
constitutive_plasticity_maxSizeDotState = maxval(plasticState%sizeDotState)
|
||||
|
||||
end subroutine constitutive_init
|
||||
|
||||
|
@ -428,18 +433,16 @@ subroutine constitutive_dependentState(F, Fp, ipc, ip, el)
|
|||
|
||||
ho = material_homogenizationAt(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)))
|
||||
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)
|
||||
case (PLASTICITY_DISLOUCLA_ID) plasticityType
|
||||
of = material_phasememberAt(ipc,ip,el)
|
||||
instance = phase_plasticityInstance(material_phaseAt(ipc,el))
|
||||
call plastic_disloUCLA_dependentState(instance,of)
|
||||
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 subroutine constitutive_dependentState
|
||||
|
@ -478,6 +481,8 @@ subroutine constitutive_LpAndItsTangents(Lp, dLp_dS, dLp_dFi, &
|
|||
tme = thermalMapping(ho)%p(ip,el)
|
||||
|
||||
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)))
|
||||
|
||||
|
@ -486,32 +491,21 @@ subroutine constitutive_LpAndItsTangents(Lp, dLp_dS, dLp_dFi, &
|
|||
dLp_dMp = 0.0_pReal
|
||||
|
||||
case (PLASTICITY_ISOTROPIC_ID) plasticityType
|
||||
of = material_phasememberAt(ipc,ip,el)
|
||||
instance = phase_plasticityInstance(material_phaseAt(ipc,el))
|
||||
call plastic_isotropic_LpAndItsTangent (Lp,dLp_dMp,Mp,instance,of)
|
||||
|
||||
case (PLASTICITY_PHENOPOWERLAW_ID) plasticityType
|
||||
of = material_phasememberAt(ipc,ip,el)
|
||||
instance = phase_plasticityInstance(material_phaseAt(ipc,el))
|
||||
call plastic_phenopowerlaw_LpAndItsTangent(Lp,dLp_dMp,Mp,instance,of)
|
||||
|
||||
case (PLASTICITY_KINEHARDENING_ID) plasticityType
|
||||
of = material_phasememberAt(ipc,ip,el)
|
||||
instance = phase_plasticityInstance(material_phaseAt(ipc,el))
|
||||
call plastic_kinehardening_LpAndItsTangent(Lp,dLp_dMp,Mp,instance,of)
|
||||
|
||||
case (PLASTICITY_NONLOCAL_ID) plasticityType
|
||||
call plastic_nonlocal_LpAndItsTangent (Lp,dLp_dMp,Mp, &
|
||||
temperature(ho)%p(tme),geometry_plastic_nonlocal_IPvolume0(ip,el),ip,el)
|
||||
call plastic_nonlocal_LpAndItsTangent (Lp,dLp_dMp,Mp, temperature(ho)%p(tme),instance,of,ip,el)
|
||||
|
||||
case (PLASTICITY_DISLOTWIN_ID) plasticityType
|
||||
of = material_phasememberAt(ipc,ip,el)
|
||||
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
|
||||
of = material_phasememberAt(ipc,ip,el)
|
||||
instance = phase_plasticityInstance(material_phaseAt(ipc,el))
|
||||
call plastic_disloucla_LpAndItsTangent (Lp,dLp_dMp,Mp,temperature(ho)%p(tme),instance,of)
|
||||
|
||||
end select plasticityType
|
||||
|
@ -740,39 +734,31 @@ subroutine constitutive_collectDotState(S, FArray, Fi, FpArray, subdt, ipc, ip,
|
|||
|
||||
ho = material_homogenizationAt(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)
|
||||
|
||||
plasticityType: select case (phase_plasticity(material_phaseAt(ipc,el)))
|
||||
|
||||
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)
|
||||
|
||||
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)
|
||||
|
||||
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)
|
||||
|
||||
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)
|
||||
|
||||
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)
|
||||
|
||||
case (PLASTICITY_NONLOCAL_ID) plasticityType
|
||||
call plastic_nonlocal_dotState (Mp,FArray,FpArray,temperature(ho)%p(tme), &
|
||||
subdt,ip,el)
|
||||
call plastic_nonlocal_dotState (Mp,FArray,FpArray,temperature(ho)%p(tme),subdt, &
|
||||
instance,of,ip,el)
|
||||
end select plasticityType
|
||||
|
||||
SourceLoop: do i = 1, phase_Nsources(material_phaseAt(ipc,el))
|
||||
|
@ -789,7 +775,6 @@ subroutine constitutive_collectDotState(S, FArray, Fi, FpArray, subdt, ipc, ip,
|
|||
call source_damage_anisoDuctile_dotState ( ipc, ip, el)
|
||||
|
||||
case (SOURCE_thermal_externalheat_ID) sourceType
|
||||
of = material_phasememberAt(ipc,ip,el)
|
||||
call source_thermal_externalheat_dotState(material_phaseAt(ipc,el),of)
|
||||
|
||||
end select sourceType
|
||||
|
@ -820,16 +805,16 @@ subroutine constitutive_collectDeltaState(S, Fe, Fi, ipc, ip, el)
|
|||
instance, of
|
||||
|
||||
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)))
|
||||
|
||||
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)
|
||||
|
||||
case (PLASTICITY_NONLOCAL_ID) plasticityType
|
||||
call plastic_nonlocal_deltaState(Mp,ip,el)
|
||||
call plastic_nonlocal_deltaState(Mp,instance,of,ip,el)
|
||||
|
||||
end select plasticityType
|
||||
|
||||
|
|
|
@ -12,16 +12,12 @@ submodule(constitutive) plastic_disloUCLA
|
|||
|
||||
type :: tParameters
|
||||
real(pReal) :: &
|
||||
aTol_rho, &
|
||||
D, & !< grain size
|
||||
mu, &
|
||||
D_0, & !< prefactor for self-diffusion coefficient
|
||||
Q_cl !< activation energy for dislocation climb
|
||||
D = 1.0_pReal, & !< grain size
|
||||
mu = 1.0_pReal, & !< equivalent shear modulus
|
||||
D_0 = 1.0_pReal, & !< prefactor for self-diffusion coefficient
|
||||
Q_cl = 1.0_pReal !< activation energy for dislocation climb
|
||||
real(pReal), allocatable, dimension(:) :: &
|
||||
rho_mob_0, & !< initial dislocation density
|
||||
rho_dip_0, & !< initial dipole density
|
||||
b_sl, & !< magnitude of burgers vector [m]
|
||||
nonSchmidCoeff, &
|
||||
D_a, &
|
||||
i_sl, & !< Adj. parameter for distance between 2 forest dislocations
|
||||
atomicVolume, &
|
||||
|
@ -37,15 +33,13 @@ submodule(constitutive) plastic_disloUCLA
|
|||
omega !< attempt frequency for kink pair nucleation
|
||||
real(pReal), allocatable, dimension(:,:) :: &
|
||||
h_sl_sl, & !< slip resistance from slip activity
|
||||
forestProjectionEdge
|
||||
forestProjection
|
||||
real(pReal), allocatable, dimension(:,:,:) :: &
|
||||
Schmid, &
|
||||
P_sl, &
|
||||
nonSchmid_pos, &
|
||||
nonSchmid_neg
|
||||
integer :: &
|
||||
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(:) :: &
|
||||
output
|
||||
logical :: &
|
||||
|
@ -88,11 +82,16 @@ module subroutine plastic_disloUCLA_init
|
|||
NipcMyPhase, &
|
||||
sizeState, sizeDotState, &
|
||||
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) :: &
|
||||
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:242–256, 2016'
|
||||
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(dependentState(Ninstance))
|
||||
|
||||
|
||||
do p = 1, size(phase_plasticity)
|
||||
if (phase_plasticity(p) /= PLASTICITY_DISLOUCLA_ID) cycle
|
||||
associate(prm => param(phase_plasticityInstance(p)), &
|
||||
|
@ -115,57 +113,50 @@ module subroutine plastic_disloUCLA_init
|
|||
dst => dependentState(phase_plasticityInstance(p)), &
|
||||
config => config_phase(p))
|
||||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! optional parameters that need to be defined
|
||||
prm%output = config%getStrings('(output)',defaultVal=emptyStringArray)
|
||||
|
||||
! This data is read in already in lattice
|
||||
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
|
||||
prm%N_sl = config%getInts('nslip',defaultVal=emptyIntArray)
|
||||
prm%sum_N_sl = sum(prm%N_sl)
|
||||
N_sl = config%getInts('nslip',defaultVal=emptyIntArray)
|
||||
prm%sum_N_sl = sum(abs(N_sl))
|
||||
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))
|
||||
|
||||
if(trim(config%getString('lattice_structure')) == 'bcc') then
|
||||
prm%nonSchmidCoeff = config%getFloats('nonschmid_coefficients',&
|
||||
defaultVal = emptyRealArray)
|
||||
prm%nonSchmid_pos = lattice_nonSchmidMatrix(prm%N_sl,prm%nonSchmidCoeff,+1)
|
||||
prm%nonSchmid_neg = lattice_nonSchmidMatrix(prm%N_sl,prm%nonSchmidCoeff,-1)
|
||||
a = config%getFloats('nonschmid_coefficients',defaultVal = emptyRealArray)
|
||||
prm%nonSchmid_pos = lattice_nonSchmidMatrix(N_sl,a,+1)
|
||||
prm%nonSchmid_neg = lattice_nonSchmidMatrix(N_sl,a,-1)
|
||||
else
|
||||
allocate(prm%nonSchmidCoeff(0))
|
||||
prm%nonSchmid_pos = prm%Schmid
|
||||
prm%nonSchmid_neg = prm%Schmid
|
||||
prm%nonSchmid_pos = prm%P_sl
|
||||
prm%nonSchmid_neg = prm%P_sl
|
||||
endif
|
||||
|
||||
prm%h_sl_sl = lattice_interaction_SlipBySlip(prm%N_sl, &
|
||||
config%getFloats('interaction_slipslip'), &
|
||||
prm%h_sl_sl = lattice_interaction_SlipBySlip(N_sl,config%getFloats('interaction_slipslip'), &
|
||||
config%getString('lattice_structure'))
|
||||
prm%forestProjectionEdge = 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))
|
||||
prm%forestProjectionEdge = transpose(prm%forestProjectionEdge)
|
||||
prm%forestProjection = transpose(prm%forestProjection)
|
||||
|
||||
prm%rho_mob_0 = config%getFloats('rhoedge0', requiredSize=size(prm%N_sl))
|
||||
prm%rho_dip_0 = config%getFloats('rhoedgedip0', requiredSize=size(prm%N_sl))
|
||||
prm%v0 = config%getFloats('v0', requiredSize=size(prm%N_sl))
|
||||
prm%b_sl = config%getFloats('slipburgers', requiredSize=size(prm%N_sl))
|
||||
prm%delta_F = config%getFloats('qedge', requiredSize=size(prm%N_sl))
|
||||
rho_mob_0 = config%getFloats('rhoedge0', requiredSize=size(N_sl))
|
||||
rho_dip_0 = config%getFloats('rhoedgedip0', requiredSize=size(N_sl))
|
||||
prm%v0 = config%getFloats('v0', requiredSize=size(N_sl))
|
||||
prm%b_sl = config%getFloats('slipburgers', requiredSize=size(N_sl))
|
||||
prm%delta_F = config%getFloats('qedge', requiredSize=size(N_sl))
|
||||
|
||||
prm%i_sl = config%getFloats('clambdaslip', requiredSize=size(prm%N_sl))
|
||||
prm%tau_0 = config%getFloats('tau_peierls', requiredSize=size(prm%N_sl))
|
||||
prm%p = config%getFloats('p_slip', requiredSize=size(prm%N_sl), &
|
||||
defaultVal=[(1.0_pReal,i=1,size(prm%N_sl))])
|
||||
prm%q = config%getFloats('q_slip', requiredSize=size(prm%N_sl), &
|
||||
defaultVal=[(1.0_pReal,i=1,size(prm%N_sl))])
|
||||
prm%kink_height = config%getFloats('kink_height', requiredSize=size(prm%N_sl))
|
||||
prm%w = config%getFloats('kink_width', requiredSize=size(prm%N_sl))
|
||||
prm%omega = config%getFloats('omega', requiredSize=size(prm%N_sl))
|
||||
prm%B = config%getFloats('friction_coeff', requiredSize=size(prm%N_sl))
|
||||
prm%i_sl = config%getFloats('clambdaslip', requiredSize=size(N_sl))
|
||||
prm%tau_0 = config%getFloats('tau_peierls', requiredSize=size(N_sl))
|
||||
prm%p = config%getFloats('p_slip', requiredSize=size(N_sl), &
|
||||
defaultVal=[(1.0_pReal,i=1,size(N_sl))])
|
||||
prm%q = config%getFloats('q_slip', requiredSize=size(N_sl), &
|
||||
defaultVal=[(1.0_pReal,i=1,size(N_sl))])
|
||||
prm%kink_height = config%getFloats('kink_height', requiredSize=size(N_sl))
|
||||
prm%w = config%getFloats('kink_width', requiredSize=size(N_sl))
|
||||
prm%omega = config%getFloats('omega', requiredSize=size(N_sl))
|
||||
prm%B = config%getFloats('friction_coeff', requiredSize=size(N_sl))
|
||||
|
||||
prm%D = config%getFloat('grainsize')
|
||||
prm%D_0 = config%getFloat('d0')
|
||||
|
@ -175,49 +166,43 @@ module subroutine plastic_disloUCLA_init
|
|||
prm%dipoleformation = config%getFloat('dipoleformationfactor') > 0.0_pReal !should be on by default, ToDo: change to /key/-type key
|
||||
|
||||
! expand: family => system
|
||||
prm%rho_mob_0 = math_expand(prm%rho_mob_0, prm%N_sl)
|
||||
prm%rho_dip_0 = math_expand(prm%rho_dip_0, prm%N_sl)
|
||||
prm%q = math_expand(prm%q, prm%N_sl)
|
||||
prm%p = math_expand(prm%p, prm%N_sl)
|
||||
prm%delta_F = math_expand(prm%delta_F, prm%N_sl)
|
||||
prm%b_sl = math_expand(prm%b_sl, prm%N_sl)
|
||||
prm%kink_height = math_expand(prm%kink_height, prm%N_sl)
|
||||
prm%w = math_expand(prm%w, prm%N_sl)
|
||||
prm%omega = math_expand(prm%omega, prm%N_sl)
|
||||
prm%tau_0 = math_expand(prm%tau_0, prm%N_sl)
|
||||
prm%v0 = math_expand(prm%v0, prm%N_sl)
|
||||
prm%B = math_expand(prm%B, prm%N_sl)
|
||||
prm%i_sl = math_expand(prm%i_sl, prm%N_sl)
|
||||
prm%atomicVolume = math_expand(prm%atomicVolume, prm%N_sl)
|
||||
prm%D_a = math_expand(prm%D_a, prm%N_sl)
|
||||
|
||||
rho_mob_0 = math_expand(rho_mob_0, N_sl)
|
||||
rho_dip_0 = math_expand(rho_dip_0, N_sl)
|
||||
prm%q = math_expand(prm%q, N_sl)
|
||||
prm%p = math_expand(prm%p, N_sl)
|
||||
prm%delta_F = math_expand(prm%delta_F, N_sl)
|
||||
prm%b_sl = math_expand(prm%b_sl, N_sl)
|
||||
prm%kink_height = math_expand(prm%kink_height, N_sl)
|
||||
prm%w = math_expand(prm%w, N_sl)
|
||||
prm%omega = math_expand(prm%omega, N_sl)
|
||||
prm%tau_0 = math_expand(prm%tau_0, N_sl)
|
||||
prm%v0 = math_expand(prm%v0, N_sl)
|
||||
prm%B = math_expand(prm%B, N_sl)
|
||||
prm%i_sl = math_expand(prm%i_sl, N_sl)
|
||||
prm%atomicVolume = math_expand(prm%atomicVolume, N_sl)
|
||||
prm%D_a = math_expand(prm%D_a, N_sl)
|
||||
|
||||
! sanity checks
|
||||
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 (any(prm%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_mob_0 < 0.0_pReal)) extmsg = trim(extmsg)//' rhoedge0'
|
||||
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%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%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%atomicVolume <= 0.0_pReal)) extmsg = trim(extmsg)//' catomicvolume 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 b_sl'
|
||||
|
||||
else slipActive
|
||||
allocate(prm%rho_mob_0(0))
|
||||
allocate(prm%rho_dip_0(0))
|
||||
rho_mob_0= emptyRealArray; rho_dip_0 = emptyRealArray
|
||||
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
|
||||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! 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
|
||||
NipcMyPhase = count(material_phaseAt == p) * discretization_nIP
|
||||
|
@ -227,26 +212,27 @@ module subroutine plastic_disloUCLA_init
|
|||
call material_allocatePlasticState(p,NipcMyPhase,sizeState,sizeDotState,0)
|
||||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! locally defined state aliases and initialization of state0 and aTolState
|
||||
! state aliases and initialization
|
||||
startIndex = 1
|
||||
endIndex = prm%sum_N_sl
|
||||
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,:)
|
||||
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
|
||||
endIndex = endIndex + prm%sum_N_sl
|
||||
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,:)
|
||||
plasticState(p)%aTolState(startIndex:endIndex) = prm%aTol_rho
|
||||
plasticState(p)%atol(startIndex:endIndex) = config%getFloat('atol_rho',defaultVal=1.0_pReal)
|
||||
|
||||
startIndex = endIndex + 1
|
||||
endIndex = endIndex + prm%sum_N_sl
|
||||
stt%gamma_sl => plasticState(p)%state(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
|
||||
plasticState(p)%slipRate => plasticState(p)%dotState(startIndex:endIndex,:)
|
||||
|
||||
|
@ -257,6 +243,10 @@ module subroutine plastic_disloUCLA_init
|
|||
|
||||
end associate
|
||||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! exit if any parameter is out of range
|
||||
if (extmsg /= '') call IO_error(211,ext_msg=trim(extmsg)//'('//PLASTICITY_DISLOUCLA_LABEL//')')
|
||||
|
||||
enddo
|
||||
|
||||
end subroutine plastic_disloUCLA_init
|
||||
|
@ -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)
|
||||
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) &
|
||||
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_neg(i) * prm%Schmid(k,l,i) * prm%nonSchmid_neg(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%P_sl(k,l,i) * prm%nonSchmid_neg(m,n,i)
|
||||
enddo
|
||||
|
||||
end associate
|
||||
|
@ -379,8 +369,7 @@ module subroutine plastic_disloUCLA_dependentState(instance,of)
|
|||
|
||||
associate(prm => param(instance), stt => state(instance),dst => dependentState(instance))
|
||||
|
||||
dislocationSpacing = sqrt(matmul(prm%forestProjectionEdge, &
|
||||
stt%rho_mob(:,of)+stt%rho_dip(:,of)))
|
||||
dislocationSpacing = sqrt(matmul(prm%forestProjection,stt%rho_mob(:,of)+stt%rho_dip(:,of)))
|
||||
dst%threshold_stress(:,of) = prm%mu*prm%b_sl &
|
||||
* sqrt(matmul(prm%h_sl_sl,stt%rho_mob(:,of)+stt%rho_dip(:,of)))
|
||||
|
||||
|
@ -464,8 +453,8 @@ pure subroutine kinetics(Mp,T,instance,of, &
|
|||
associate(prm => param(instance), stt => state(instance), dst => dependentState(instance))
|
||||
|
||||
do j = 1, prm%sum_N_sl
|
||||
tau_pos(j) = math_mul33xx33(Mp,prm%nonSchmid_pos(1:3,1:3,j))
|
||||
tau_neg(j) = math_mul33xx33(Mp,prm%nonSchmid_neg(1:3,1:3,j))
|
||||
tau_pos(j) = math_tensordot(Mp,prm%nonSchmid_pos(1:3,1:3,j))
|
||||
tau_neg(j) = math_tensordot(Mp,prm%nonSchmid_neg(1:3,1:3,j))
|
||||
enddo
|
||||
|
||||
|
||||
|
|
|
@ -14,36 +14,31 @@ submodule(constitutive) plastic_dislotwin
|
|||
|
||||
type :: tParameters
|
||||
real(pReal) :: &
|
||||
mu, &
|
||||
nu, &
|
||||
D0, & !< prefactor for self-diffusion coefficient
|
||||
Qsd, & !< activation energy for dislocation climb
|
||||
omega, & !< frequency factor for dislocation climb
|
||||
D, & !< grain size
|
||||
p_sb, & !< p-exponent in shear band velocity
|
||||
q_sb, & !< q-exponent in shear band velocity
|
||||
CEdgeDipMinDistance, & !<
|
||||
i_tw, & !<
|
||||
tau_0, & !< strength due to elements in solid solution
|
||||
L_tw, & !< Length of twin nuclei in Burgers vectors
|
||||
L_tr, & !< Length of trans nuclei in Burgers vectors
|
||||
xc_twin, & !< critical distance for formation of twin nucleus
|
||||
xc_trans, & !< critical distance for formation of trans nucleus
|
||||
V_cs, & !< cross slip volume
|
||||
sbResistance, & !< value for shearband resistance (might become an internal state variable at some point)
|
||||
sbVelocity, & !< value for shearband velocity_0
|
||||
sbQedge, & !< activation energy for shear bands
|
||||
SFE_0K, & !< stacking fault energy at zero K
|
||||
dSFE_dT, & !< temperature dependance of stacking fault energy
|
||||
aTol_rho, & !< absolute tolerance for integration of dislocation density
|
||||
aTol_f_tw, & !< absolute tolerance for integration of twin volume fraction
|
||||
aTol_f_tr, & !< absolute tolerance for integration of trans volume fraction
|
||||
gamma_fcc_hex, & !< Free energy difference between austensite and martensite
|
||||
i_tr, & !<
|
||||
h !< Stack height of hex nucleus
|
||||
mu = 1.0_pReal, & !< equivalent shear modulus
|
||||
nu = 1.0_pReal, & !< equivalent shear Poisson's ratio
|
||||
D0 = 1.0_pReal, & !< prefactor for self-diffusion coefficient
|
||||
Qsd = 1.0_pReal, & !< activation energy for dislocation climb
|
||||
omega = 1.0_pReal, & !< frequency factor for dislocation climb
|
||||
D = 1.0_pReal, & !< grain size
|
||||
p_sb = 1.0_pReal, & !< p-exponent in shear band velocity
|
||||
q_sb = 1.0_pReal, & !< q-exponent in shear band velocity
|
||||
CEdgeDipMinDistance = 1.0_pReal, & !<
|
||||
i_tw = 1.0_pReal, & !<
|
||||
tau_0 = 1.0_pReal, & !< strength due to elements in solid solution
|
||||
L_tw = 1.0_pReal, & !< Length of twin nuclei in Burgers vectors
|
||||
L_tr = 1.0_pReal, & !< Length of trans nuclei in Burgers vectors
|
||||
xc_twin = 1.0_pReal, & !< critical distance for formation of twin nucleus
|
||||
xc_trans = 1.0_pReal, & !< critical distance for formation of trans nucleus
|
||||
V_cs = 1.0_pReal, & !< cross slip volume
|
||||
sbResistance = 1.0_pReal, & !< value for shearband resistance
|
||||
sbVelocity = 1.0_pReal, & !< value for shearband velocity_0
|
||||
E_sb = 1.0_pReal, & !< activation energy for shear bands
|
||||
SFE_0K = 1.0_pReal, & !< stacking fault energy at zero K
|
||||
dSFE_dT = 1.0_pReal, & !< temperature dependence of stacking fault energy
|
||||
gamma_fcc_hex = 1.0_pReal, & !< Free energy difference between austensite and martensite
|
||||
i_tr = 1.0_pReal, & !<
|
||||
h = 1.0_pReal !< Stack height of hex nucleus
|
||||
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_tw, & !< absolute length of burgers vector [m] for each twin 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
|
||||
t_tw, & !< twin thickness [m] for each twin 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
|
||||
p, & !< p-exponent in glide velocity
|
||||
q, & !< q-exponent in glide velocity
|
||||
|
@ -71,19 +65,15 @@ submodule(constitutive) plastic_dislotwin
|
|||
forestProjection, &
|
||||
C66
|
||||
real(pReal), allocatable, dimension(:,:,:) :: &
|
||||
P_tr, &
|
||||
P_sl, &
|
||||
P_tw, &
|
||||
P_tr, &
|
||||
C66_tw, &
|
||||
C66_tr
|
||||
integer :: &
|
||||
sum_N_sl, & !< total number of active slip system
|
||||
sum_N_tw, & !< total number of active twin 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(:,:) :: &
|
||||
fcc_twinNucleationSlipPair ! ToDo: Better name? Is also use for trans
|
||||
character(len=pStringLen), allocatable, dimension(:) :: &
|
||||
|
@ -140,11 +130,15 @@ module subroutine plastic_dislotwin_init
|
|||
NipcMyPhase, &
|
||||
sizeState, sizeDotState, &
|
||||
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) :: &
|
||||
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):3603–3612, 2004'
|
||||
write(6,'(a)') ' https://doi.org/10.1016/j.actamat.2004.04.012'
|
||||
|
@ -173,9 +167,7 @@ module subroutine plastic_dislotwin_init
|
|||
dst => dependentState(phase_plasticityInstance(p)), &
|
||||
config => config_phase(p))
|
||||
|
||||
prm%aTol_rho = config%getFloat('atol_rho', defaultVal=0.0_pReal)
|
||||
prm%aTol_f_tw = config%getFloat('atol_twinfrac', defaultVal=0.0_pReal)
|
||||
prm%aTol_f_tr = config%getFloat('atol_transfrac', defaultVal=0.0_pReal)
|
||||
prm%output = config%getStrings('(output)', defaultVal=emptyStringArray)
|
||||
|
||||
! This data is read in already in lattice
|
||||
prm%mu = lattice_mu(p)
|
||||
|
@ -184,72 +176,67 @@ module subroutine plastic_dislotwin_init
|
|||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! slip related parameters
|
||||
prm%N_sl = config%getInts('nslip',defaultVal=emptyIntArray)
|
||||
prm%sum_N_sl = sum(prm%N_sl)
|
||||
N_sl = config%getInts('nslip',defaultVal=emptyIntArray)
|
||||
prm%sum_N_sl = sum(abs(N_sl))
|
||||
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))
|
||||
prm%h_sl_sl = lattice_interaction_SlipBySlip(prm%N_sl, &
|
||||
config%getFloats('interaction_slipslip'), &
|
||||
prm%h_sl_sl = lattice_interaction_SlipBySlip(N_sl,config%getFloats('interaction_slipslip'), &
|
||||
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))
|
||||
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))
|
||||
prm%fccTwinTransNucleation = merge(.true., .false., lattice_structure(p) == lattice_FCC_ID) &
|
||||
.and. (prm%N_sl(1) == 12)
|
||||
if(prm%fccTwinTransNucleation) &
|
||||
prm%fcc_twinNucleationSlipPair = lattice_FCC_TWINNUCLEATIONSLIPPAIR
|
||||
.and. (N_sl(1) == 12)
|
||||
if(prm%fccTwinTransNucleation) prm%fcc_twinNucleationSlipPair = lattice_FCC_TWINNUCLEATIONSLIPPAIR
|
||||
|
||||
prm%rho_mob_0 = config%getFloats('rhoedge0', requiredSize=size(prm%N_sl))
|
||||
prm%rho_dip_0 = config%getFloats('rhoedgedip0',requiredSize=size(prm%N_sl))
|
||||
prm%v0 = config%getFloats('v0', requiredSize=size(prm%N_sl))
|
||||
prm%b_sl = config%getFloats('slipburgers',requiredSize=size(prm%N_sl))
|
||||
prm%Delta_F = config%getFloats('qedge', requiredSize=size(prm%N_sl))
|
||||
prm%CLambdaSlip = config%getFloats('clambdaslip',requiredSize=size(prm%N_sl))
|
||||
prm%p = config%getFloats('p_slip', requiredSize=size(prm%N_sl))
|
||||
prm%q = config%getFloats('q_slip', requiredSize=size(prm%N_sl))
|
||||
prm%B = config%getFloats('b', requiredSize=size(prm%N_sl), &
|
||||
defaultVal=[(0.0_pReal, i=1,size(prm%N_sl))])
|
||||
rho_mob_0 = config%getFloats('rhoedge0', requiredSize=size(N_sl))
|
||||
rho_dip_0 = config%getFloats('rhoedgedip0',requiredSize=size(N_sl))
|
||||
prm%v0 = config%getFloats('v0', requiredSize=size(N_sl))
|
||||
prm%b_sl = config%getFloats('slipburgers',requiredSize=size(N_sl))
|
||||
prm%Delta_F = config%getFloats('qedge', requiredSize=size(N_sl))
|
||||
prm%CLambdaSlip = config%getFloats('clambdaslip',requiredSize=size(N_sl))
|
||||
prm%p = config%getFloats('p_slip', requiredSize=size(N_sl))
|
||||
prm%q = config%getFloats('q_slip', requiredSize=size(N_sl))
|
||||
prm%B = config%getFloats('b', requiredSize=size(N_sl), &
|
||||
defaultVal=[(0.0_pReal, i=1,size(N_sl))])
|
||||
|
||||
prm%tau_0 = config%getFloat('solidsolutionstrength')
|
||||
prm%CEdgeDipMinDistance = config%getFloat('cedgedipmindistance')
|
||||
prm%D0 = config%getFloat('d0')
|
||||
prm%Qsd = config%getFloat('qsd')
|
||||
prm%atomicVolume = config%getFloat('catomicvolume') * prm%b_sl**3.0_pReal
|
||||
prm%ExtendedDislocations = config%keyExists('/extend_dislocations/')
|
||||
if (prm%ExtendedDislocations) then
|
||||
prm%SFE_0K = config%getFloat('sfe_0k')
|
||||
prm%dSFE_dT = config%getFloat('dsfe_dt')
|
||||
endif
|
||||
|
||||
! multiplication factor according to crystal structure (nearest neighbors bcc vs fcc/hex)
|
||||
!@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)
|
||||
prm%dipoleformation = .not. config%keyExists('/nodipoleformation/')
|
||||
|
||||
! 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
|
||||
prm%rho_mob_0 = math_expand(prm%rho_mob_0, prm%N_sl)
|
||||
prm%rho_dip_0 = math_expand(prm%rho_dip_0, prm%N_sl)
|
||||
prm%v0 = math_expand(prm%v0, prm%N_sl)
|
||||
prm%b_sl = math_expand(prm%b_sl, prm%N_sl)
|
||||
prm%Delta_F = math_expand(prm%Delta_F, prm%N_sl)
|
||||
prm%CLambdaSlip = math_expand(prm%CLambdaSlip, prm%N_sl)
|
||||
prm%p = math_expand(prm%p, prm%N_sl)
|
||||
prm%q = math_expand(prm%q, prm%N_sl)
|
||||
prm%B = math_expand(prm%B, prm%N_sl)
|
||||
prm%atomicVolume = math_expand(prm%atomicVolume,prm%N_sl)
|
||||
rho_mob_0 = math_expand(rho_mob_0, N_sl)
|
||||
rho_dip_0 = math_expand(rho_dip_0, N_sl)
|
||||
prm%v0 = math_expand(prm%v0, N_sl)
|
||||
prm%b_sl = math_expand(prm%b_sl, N_sl)
|
||||
prm%Delta_F = math_expand(prm%Delta_F, N_sl)
|
||||
prm%CLambdaSlip = math_expand(prm%CLambdaSlip, N_sl)
|
||||
prm%p = math_expand(prm%p, N_sl)
|
||||
prm%q = math_expand(prm%q, N_sl)
|
||||
prm%B = math_expand(prm%B, N_sl)
|
||||
|
||||
! sanity checks
|
||||
if ( prm%D0 <= 0.0_pReal) extmsg = trim(extmsg)//' D0'
|
||||
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(prm%rho_dip_0 < 0.0_pReal)) extmsg = trim(extmsg)//' rho_dip_0'
|
||||
if (any(rho_mob_0 < 0.0_pReal)) extmsg = trim(extmsg)//' rho_mob_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%b_sl <= 0.0_pReal)) extmsg = trim(extmsg)//' b_sl'
|
||||
if (any(prm%Delta_F <= 0.0_pReal)) extmsg = trim(extmsg)//' Delta_F'
|
||||
|
@ -257,61 +244,69 @@ module subroutine plastic_dislotwin_init
|
|||
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%q< 1.0_pReal .or. prm%q>2.0_pReal)) extmsg = trim(extmsg)//' q'
|
||||
|
||||
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
|
||||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! twin related parameters
|
||||
prm%N_tw = config%getInts('ntwin', defaultVal=emptyIntArray)
|
||||
prm%sum_N_tw = sum(prm%N_tw)
|
||||
if (prm%sum_N_tw > 0) then
|
||||
prm%P_tw = lattice_SchmidMatrix_twin(prm%N_tw,config%getString('lattice_structure'),&
|
||||
N_tw = config%getInts('ntwin', defaultVal=emptyIntArray)
|
||||
prm%sum_N_tw = sum(abs(N_tw))
|
||||
twinActive: if (prm%sum_N_tw > 0) then
|
||||
prm%P_tw = lattice_SchmidMatrix_twin(N_tw,config%getString('lattice_structure'),&
|
||||
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%getString('lattice_structure'))
|
||||
|
||||
prm%b_tw = config%getFloats('twinburgers', requiredSize=size(prm%N_tw))
|
||||
prm%t_tw = config%getFloats('twinsize', requiredSize=size(prm%N_tw))
|
||||
prm%r = config%getFloats('r_twin', requiredSize=size(prm%N_tw))
|
||||
prm%b_tw = config%getFloats('twinburgers', requiredSize=size(N_tw))
|
||||
prm%t_tw = config%getFloats('twinsize', requiredSize=size(N_tw))
|
||||
prm%r = config%getFloats('r_twin', requiredSize=size(N_tw))
|
||||
|
||||
prm%xc_twin = config%getFloat('xc_twin')
|
||||
prm%L_tw = config%getFloat('l0_twin')
|
||||
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))
|
||||
|
||||
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))
|
||||
|
||||
if (.not. prm%fccTwinTransNucleation) then
|
||||
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
|
||||
|
||||
! expand: family => system
|
||||
prm%b_tw = math_expand(prm%b_tw,prm%N_tw)
|
||||
prm%t_tw = math_expand(prm%t_tw,prm%N_tw)
|
||||
prm%r = math_expand(prm%r,prm%N_tw)
|
||||
prm%b_tw = math_expand(prm%b_tw,N_tw)
|
||||
prm%t_tw = math_expand(prm%t_tw,N_tw)
|
||||
prm%r = math_expand(prm%r,N_tw)
|
||||
|
||||
else
|
||||
allocate(prm%gamma_char(0))
|
||||
allocate(prm%t_tw (0))
|
||||
allocate(prm%b_tw (0))
|
||||
allocate(prm%r (0))
|
||||
allocate(prm%h_tw_tw (0,0))
|
||||
! sanity checks
|
||||
if ( prm%xc_twin < 0.0_pReal) extmsg = trim(extmsg)//' xc_twin'
|
||||
if ( prm%L_tw < 0.0_pReal) extmsg = trim(extmsg)//' L_tw'
|
||||
if ( prm%i_tw < 0.0_pReal) extmsg = trim(extmsg)//' i_tw'
|
||||
if (any(prm%b_tw < 0.0_pReal)) extmsg = trim(extmsg)//' b_tw'
|
||||
if (any(prm%t_tw < 0.0_pReal)) extmsg = trim(extmsg)//' t_tw'
|
||||
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
|
||||
prm%N_tr = config%getInts('ntrans', defaultVal=emptyIntArray)
|
||||
prm%sum_N_tr = sum(prm%N_tr)
|
||||
if (prm%sum_N_tr > 0) then
|
||||
N_tr = config%getInts('ntrans', defaultVal=emptyIntArray)
|
||||
prm%sum_N_tr = sum(abs(N_tr))
|
||||
transActive: if (prm%sum_N_tr > 0) then
|
||||
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%i_tr = config%getFloat('cmfptrans', defaultVal=0.0_pReal) ! ToDo: How to handle that???
|
||||
|
@ -319,96 +314,82 @@ module subroutine plastic_dislotwin_init
|
|||
prm%xc_trans = config%getFloat('xc_trans', defaultVal=0.0_pReal) ! ToDo: How to handle that???
|
||||
prm%L_tr = config%getFloat('l0_trans')
|
||||
|
||||
prm%h_tr_tr = lattice_interaction_TransByTrans(prm%N_tr,&
|
||||
config%getFloats('interaction_transtrans'), &
|
||||
prm%h_tr_tr = lattice_interaction_TransByTrans(N_tr,config%getFloats('interaction_transtrans'), &
|
||||
config%getString('lattice_structure'))
|
||||
|
||||
prm%C66_tr = lattice_C66_trans(prm%N_tr,prm%C66, &
|
||||
config%getString('trans_lattice_structure'), &
|
||||
prm%C66_tr = lattice_C66_trans(N_tr,prm%C66,config%getString('trans_lattice_structure'), &
|
||||
0.0_pReal, &
|
||||
config%getFloat('a_bcc', defaultVal=0.0_pReal), &
|
||||
config%getFloat('a_fcc', defaultVal=0.0_pReal))
|
||||
|
||||
prm%P_tr = lattice_SchmidMatrix_trans(prm%N_tr, &
|
||||
config%getString('trans_lattice_structure'), &
|
||||
prm%P_tr = lattice_SchmidMatrix_trans(N_tr,config%getString('trans_lattice_structure'), &
|
||||
0.0_pReal, &
|
||||
config%getFloat('a_bcc', defaultVal=0.0_pReal), &
|
||||
config%getFloat('a_fcc', defaultVal=0.0_pReal))
|
||||
|
||||
if (lattice_structure(p) /= lattice_FCC_ID) then
|
||||
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
|
||||
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 = math_expand(prm%s,prm%N_tr)
|
||||
else
|
||||
allocate(prm%t_tr (0))
|
||||
allocate(prm%b_tr (0))
|
||||
allocate(prm%s (0))
|
||||
prm%s = math_expand(prm%s,N_tr)
|
||||
|
||||
! sanity checks
|
||||
if ( prm%xc_trans < 0.0_pReal) extmsg = trim(extmsg)//' xc_trans'
|
||||
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))
|
||||
endif
|
||||
|
||||
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
|
||||
endif transActive
|
||||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! shearband related parameters
|
||||
prm%sbVelocity = config%getFloat('shearbandvelocity',defaultVal=0.0_pReal)
|
||||
if (prm%sbVelocity > 0.0_pReal) then
|
||||
prm%sbResistance = config%getFloat('shearbandresistance')
|
||||
prm%sbQedge = config%getFloat('qedgepersbsystem')
|
||||
prm%E_sb = config%getFloat('qedgepersbsystem')
|
||||
prm%p_sb = config%getFloat('p_shearband')
|
||||
prm%q_sb = config%getFloat('q_shearband')
|
||||
|
||||
! sanity checks
|
||||
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%q_sb <= 0.0_pReal) extmsg = trim(extmsg)//' q_shearband'
|
||||
endif
|
||||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! 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/')
|
||||
prm%dipoleformation = .not. config%keyExists('/nodipoleformation/')
|
||||
twinOrSlipActive: if (prm%sum_N_tw + 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 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) &
|
||||
! call IO_error(211,el=p,ext_msg='dot_N_0_tw ('//PLASTICITY_DISLOTWIN_label//')')
|
||||
|
||||
if (any(prm%atomicVolume <= 0.0_pReal)) &
|
||||
call IO_error(211,el=p,ext_msg='cAtomicVolume ('//PLASTICITY_DISLOTWIN_label//')')
|
||||
if (prm%sum_N_tw > 0) then
|
||||
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)
|
||||
slipAndTransActive: if (prm%sum_N_sl * prm%sum_N_tr > 0) then
|
||||
prm%h_sl_tr = lattice_interaction_SlipByTrans(N_sl,N_tr,&
|
||||
config%getFloats('interaction_sliptrans'), &
|
||||
config%getString('lattice_structure'))
|
||||
if (prm%fccTwinTransNucleation .and. size(N_tr) /= 1) extmsg = trim(extmsg)//' interaction_sliptrans'
|
||||
endif slipAndTransActive
|
||||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! allocate state arrays
|
||||
|
@ -421,26 +402,27 @@ module subroutine plastic_dislotwin_init
|
|||
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
|
||||
endIndex = prm%sum_N_sl
|
||||
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,:)
|
||||
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
|
||||
endIndex = endIndex + prm%sum_N_sl
|
||||
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,:)
|
||||
plasticState(p)%aTolState(startIndex:endIndex) = prm%aTol_rho
|
||||
plasticState(p)%atol(startIndex:endIndex) = config%getFloat('atol_rho',defaultVal=1.0_pReal)
|
||||
|
||||
startIndex = endIndex + 1
|
||||
endIndex = endIndex + prm%sum_N_sl
|
||||
stt%gamma_sl=>plasticState(p)%state(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
|
||||
plasticState(p)%slipRate => plasticState(p)%dotState(startIndex:endIndex,:)
|
||||
|
||||
|
@ -448,13 +430,15 @@ module subroutine plastic_dislotwin_init
|
|||
endIndex = endIndex + prm%sum_N_tw
|
||||
stt%f_tw=>plasticState(p)%state(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
|
||||
endIndex = endIndex + prm%sum_N_tr
|
||||
stt%f_tr=>plasticState(p)%state(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%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%V_tr (prm%sum_N_tr,NipcMyPhase),source=0.0_pReal)
|
||||
|
||||
|
||||
plasticState(p)%state0 = plasticState(p)%state ! ToDo: this could be done centrally
|
||||
|
||||
end associate
|
||||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! exit if any parameter is out of range
|
||||
if (extmsg /= '') call IO_error(211,ext_msg=trim(extmsg)//'('//PLASTICITY_DISLOTWIN_LABEL//')')
|
||||
|
||||
enddo
|
||||
|
||||
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), dimension(3,3) :: eigVectors, P_sb
|
||||
real(pReal), dimension(3) :: eigValues
|
||||
logical :: error
|
||||
real(pReal), dimension(3,6), parameter :: &
|
||||
sb_sComposition = &
|
||||
reshape(real([&
|
||||
|
@ -588,13 +574,13 @@ module subroutine plastic_dislotwin_LpAndItsTangent(Lp,dLp_dMp,Mp,T,instance,of)
|
|||
|
||||
shearBandingContribution: if(dNeq0(prm%sbVelocity)) then
|
||||
|
||||
BoltzmannRatio = prm%sbQedge/(kB*T)
|
||||
call math_eigenValuesVectorsSym(Mp,eigValues,eigVectors,error)
|
||||
BoltzmannRatio = prm%E_sb/(kB*T)
|
||||
call math_eigh33(Mp,eigValues,eigVectors) ! is Mp symmetric by design?
|
||||
|
||||
do i = 1,6
|
||||
P_sb = 0.5_pReal * math_outer(matmul(eigVectors,sb_sComposition(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
|
||||
StressRatio_p = (abs(tau)/prm%sbResistance)**prm%p_sb
|
||||
|
@ -650,7 +636,6 @@ module subroutine plastic_dislotwin_dotState(Mp,T,instance,of)
|
|||
integer :: i
|
||||
real(pReal) :: &
|
||||
f_unrotated, &
|
||||
VacancyDiffusion, &
|
||||
rho_dip_distance, &
|
||||
v_cl, & !< climb velocity
|
||||
Gamma, & !< stacking fault energy
|
||||
|
@ -673,7 +658,6 @@ module subroutine plastic_dislotwin_dotState(Mp,T,instance,of)
|
|||
f_unrotated = 1.0_pReal &
|
||||
- sum(stt%f_tw(1:prm%sum_N_tw,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)
|
||||
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
|
||||
|
||||
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
|
||||
dot_rho_dip_formation(i) = 0.0_pReal
|
||||
|
@ -922,7 +906,7 @@ pure subroutine kinetics_slip(Mp,T,instance,of, &
|
|||
associate(prm => param(instance), stt => state(instance), dst => dependentState(instance))
|
||||
|
||||
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
|
||||
|
||||
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))
|
||||
|
||||
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
|
||||
s1=prm%fcc_twinNucleationSlipPair(1,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))
|
||||
|
||||
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
|
||||
s1=prm%fcc_twinNucleationSlipPair(1,i)
|
||||
s2=prm%fcc_twinNucleationSlipPair(2,i)
|
||||
|
|
|
@ -12,7 +12,6 @@ submodule(constitutive) plastic_isotropic
|
|||
type :: tParameters
|
||||
real(pReal) :: &
|
||||
M, & !< Taylor factor
|
||||
xi_0, & !< initial critical stress
|
||||
dot_gamma_0, & !< reference strain rate
|
||||
n, & !< stress exponent
|
||||
h0, &
|
||||
|
@ -22,9 +21,7 @@ submodule(constitutive) plastic_isotropic
|
|||
c_1, &
|
||||
c_4, &
|
||||
c_3, &
|
||||
c_2, &
|
||||
aTol_xi, &
|
||||
aTol_gamma
|
||||
c_2
|
||||
integer :: &
|
||||
of_debug = 0
|
||||
logical :: &
|
||||
|
@ -59,11 +56,12 @@ module subroutine plastic_isotropic_init
|
|||
p, &
|
||||
NipcMyPhase, &
|
||||
sizeState, sizeDotState
|
||||
|
||||
real(pReal) :: &
|
||||
xi_0 !< initial critical stress
|
||||
character(len=pStringLen) :: &
|
||||
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:37–40, 2018'
|
||||
write(6,'(a)') ' https://doi.org/10.1016/j.scriptamat.2017.09.047'
|
||||
|
@ -83,12 +81,14 @@ module subroutine plastic_isotropic_init
|
|||
stt => state(phase_plasticityInstance(p)), &
|
||||
config => config_phase(p))
|
||||
|
||||
prm%output = config%getStrings('(output)',defaultVal=emptyStringArray)
|
||||
|
||||
#ifdef DEBUG
|
||||
if (p==material_phaseAt(debug_g,debug_e)) &
|
||||
prm%of_debug = material_phasememberAt(debug_g,debug_i,debug_e)
|
||||
#endif
|
||||
|
||||
prm%xi_0 = config%getFloat('tau0')
|
||||
xi_0 = config%getFloat('tau0')
|
||||
prm%xi_inf = config%getFloat('tausat')
|
||||
prm%dot_gamma_0 = config%getFloat('gdot0')
|
||||
prm%n = config%getFloat('n')
|
||||
|
@ -100,31 +100,16 @@ module subroutine plastic_isotropic_init
|
|||
prm%c_3 = config%getFloat('tausat_sinhfitc',defaultVal=0.0_pReal)
|
||||
prm%c_2 = config%getFloat('tausat_sinhfitd',defaultVal=0.0_pReal)
|
||||
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/')
|
||||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! sanity checks
|
||||
extmsg = ''
|
||||
if (prm%aTol_gamma <= 0.0_pReal) extmsg = trim(extmsg)//' aTol_gamma'
|
||||
if (prm%xi_0 < 0.0_pReal) extmsg = trim(extmsg)//' xi_0'
|
||||
if (xi_0 < 0.0_pReal) extmsg = trim(extmsg)//' xi_0'
|
||||
if (prm%dot_gamma_0 <= 0.0_pReal) extmsg = trim(extmsg)//' dot_gamma_0'
|
||||
if (prm%n <= 0.0_pReal) extmsg = trim(extmsg)//' n'
|
||||
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)
|
||||
if (prm%M <= 0.0_pReal) extmsg = trim(extmsg)//' M'
|
||||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! allocate state arrays
|
||||
|
@ -135,15 +120,17 @@ module subroutine plastic_isotropic_init
|
|||
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 = prm%xi_0
|
||||
stt%xi = xi_0
|
||||
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,:)
|
||||
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
|
||||
plasticState(p)%slipRate => plasticState(p)%dotState(2:2,:)
|
||||
|
||||
|
@ -151,6 +138,10 @@ module subroutine plastic_isotropic_init
|
|||
|
||||
end associate
|
||||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! exit if any parameter is out of range
|
||||
if (extmsg /= '') call IO_error(211,ext_msg=trim(extmsg)//'('//PLASTICITY_ISOTROPIC_LABEL//')')
|
||||
|
||||
enddo
|
||||
|
||||
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))
|
||||
|
||||
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)
|
||||
|
||||
if (norm_Mp_dev > 0.0_pReal) then
|
||||
|
@ -288,9 +279,9 @@ module subroutine plastic_isotropic_dotState(Mp,instance,of)
|
|||
associate(prm => param(instance), stt => state(instance), dot => dotState(instance))
|
||||
|
||||
if (prm%dilatation) then
|
||||
norm_Mp = sqrt(math_mul33xx33(Mp,Mp))
|
||||
norm_Mp = sqrt(math_tensordot(Mp,Mp))
|
||||
else
|
||||
norm_Mp = sqrt(math_mul33xx33(math_deviatoric33(Mp),math_deviatoric33(Mp)))
|
||||
norm_Mp = sqrt(math_tensordot(math_deviatoric33(Mp),math_deviatoric33(Mp)))
|
||||
endif
|
||||
|
||||
dot_gamma = prm%dot_gamma_0 * (sqrt(1.5_pReal) * norm_Mp /(prm%M*stt%xi(of))) **prm%n
|
||||
|
|
|
@ -9,30 +9,26 @@ submodule(constitutive) plastic_kinehardening
|
|||
|
||||
type :: tParameters
|
||||
real(pReal) :: &
|
||||
gdot0, & !< reference shear strain rate for slip
|
||||
n, & !< stress exponent for slip
|
||||
aTolResistance, &
|
||||
aTolShear
|
||||
gdot0 = 1.0_pReal, & !< reference shear strain rate for slip
|
||||
n = 1.0_pReal !< stress exponent for slip
|
||||
real(pReal), allocatable, dimension(:) :: &
|
||||
crss0, & !< initial critical shear stress for slip
|
||||
theta0, & !< initial 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
|
||||
theta1_b, & !< asymptotic hardening rate of back stress for each slip
|
||||
tau1, &
|
||||
tau1_b, &
|
||||
nonSchmidCoeff
|
||||
tau1_b
|
||||
real(pReal), allocatable, dimension(:,:) :: &
|
||||
interaction_slipslip !< slip resistance from slip activity
|
||||
real(pReal), allocatable, dimension(:,:,:) :: &
|
||||
Schmid, &
|
||||
P, &
|
||||
nonSchmid_pos, &
|
||||
nonSchmid_neg
|
||||
integer :: &
|
||||
totalNslip, & !< total number of active slip system
|
||||
sum_N_sl, & !< total number of active slip system
|
||||
of_debug = 0
|
||||
integer, allocatable, dimension(:) :: &
|
||||
Nslip !< number of active slip systems for each family
|
||||
logical :: &
|
||||
nonSchmidActive = .false.
|
||||
character(len=pStringLen), allocatable, dimension(:) :: &
|
||||
output
|
||||
end type tParameters
|
||||
|
@ -70,11 +66,15 @@ module subroutine plastic_kinehardening_init
|
|||
NipcMyPhase, &
|
||||
sizeState, sizeDeltaState, sizeDotState, &
|
||||
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) :: &
|
||||
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)
|
||||
if (iand(debug_level(debug_constitutive),debug_levelBasic) /= 0) &
|
||||
|
@ -93,130 +93,117 @@ module subroutine plastic_kinehardening_init
|
|||
stt => state(phase_plasticityInstance(p)),&
|
||||
config => config_phase(p))
|
||||
|
||||
prm%output = config%getStrings('(output)',defaultVal=emptyStringArray)
|
||||
|
||||
#ifdef DEBUG
|
||||
if (p==material_phaseAt(debug_g,debug_e)) then
|
||||
prm%of_debug = material_phasememberAt(debug_g,debug_i,debug_e)
|
||||
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
|
||||
prm%Nslip = config%getInts('nslip',defaultVal=emptyIntArray)
|
||||
prm%totalNslip = sum(prm%Nslip)
|
||||
slipActive: if (prm%totalNslip > 0) then
|
||||
prm%Schmid = lattice_SchmidMatrix_slip(prm%Nslip,config%getString('lattice_structure'),&
|
||||
N_sl = config%getInts('nslip',defaultVal=emptyIntArray)
|
||||
prm%sum_N_sl = sum(abs(N_sl))
|
||||
slipActive: if (prm%sum_N_sl > 0) then
|
||||
prm%P = lattice_SchmidMatrix_slip(N_sl,config%getString('lattice_structure'),&
|
||||
config%getFloat('c/a',defaultVal=0.0_pReal))
|
||||
|
||||
if(trim(config%getString('lattice_structure')) == 'bcc') then
|
||||
prm%nonSchmidCoeff = config%getFloats('nonschmid_coefficients',&
|
||||
defaultVal = emptyRealArray)
|
||||
prm%nonSchmid_pos = lattice_nonSchmidMatrix(prm%Nslip,prm%nonSchmidCoeff,+1)
|
||||
prm%nonSchmid_neg = lattice_nonSchmidMatrix(prm%Nslip,prm%nonSchmidCoeff,-1)
|
||||
a = config%getFloats('nonschmid_coefficients',defaultVal = emptyRealArray)
|
||||
if(size(a) > 0) prm%nonSchmidActive = .true.
|
||||
prm%nonSchmid_pos = lattice_nonSchmidMatrix(N_sl,a,+1)
|
||||
prm%nonSchmid_neg = lattice_nonSchmidMatrix(N_sl,a,-1)
|
||||
else
|
||||
prm%nonSchmid_pos = prm%Schmid
|
||||
prm%nonSchmid_neg = prm%Schmid
|
||||
prm%nonSchmid_pos = prm%P
|
||||
prm%nonSchmid_neg = prm%P
|
||||
endif
|
||||
prm%interaction_SlipSlip = lattice_interaction_SlipBySlip(prm%Nslip, &
|
||||
prm%interaction_SlipSlip = lattice_interaction_SlipBySlip(N_sl, &
|
||||
config%getFloats('interaction_slipslip'), &
|
||||
config%getString('lattice_structure'))
|
||||
|
||||
prm%crss0 = config%getFloats('crss0', requiredSize=size(prm%Nslip))
|
||||
prm%tau1 = config%getFloats('tau1', requiredSize=size(prm%Nslip))
|
||||
prm%tau1_b = config%getFloats('tau1_b', requiredSize=size(prm%Nslip))
|
||||
prm%theta0 = config%getFloats('theta0', requiredSize=size(prm%Nslip))
|
||||
prm%theta1 = config%getFloats('theta1', requiredSize=size(prm%Nslip))
|
||||
prm%theta0_b = config%getFloats('theta0_b', requiredSize=size(prm%Nslip))
|
||||
prm%theta1_b = config%getFloats('theta1_b', requiredSize=size(prm%Nslip))
|
||||
xi_0 = config%getFloats('crss0', requiredSize=size(N_sl))
|
||||
prm%tau1 = config%getFloats('tau1', requiredSize=size(N_sl))
|
||||
prm%tau1_b = config%getFloats('tau1_b', requiredSize=size(N_sl))
|
||||
prm%theta0 = config%getFloats('theta0', requiredSize=size(N_sl))
|
||||
prm%theta1 = config%getFloats('theta1', requiredSize=size(N_sl))
|
||||
prm%theta0_b = config%getFloats('theta0_b', requiredSize=size(N_sl))
|
||||
prm%theta1_b = config%getFloats('theta1_b', requiredSize=size(N_sl))
|
||||
|
||||
prm%gdot0 = config%getFloat('gdot0')
|
||||
prm%n = config%getFloat('n_slip')
|
||||
|
||||
! expand: family => system
|
||||
prm%crss0 = math_expand(prm%crss0, prm%Nslip)
|
||||
prm%tau1 = math_expand(prm%tau1, prm%Nslip)
|
||||
prm%tau1_b = math_expand(prm%tau1_b, prm%Nslip)
|
||||
prm%theta0 = math_expand(prm%theta0, prm%Nslip)
|
||||
prm%theta1 = math_expand(prm%theta1, prm%Nslip)
|
||||
prm%theta0_b = math_expand(prm%theta0_b,prm%Nslip)
|
||||
prm%theta1_b = math_expand(prm%theta1_b,prm%Nslip)
|
||||
|
||||
|
||||
xi_0 = math_expand(xi_0, N_sl)
|
||||
prm%tau1 = math_expand(prm%tau1, N_sl)
|
||||
prm%tau1_b = math_expand(prm%tau1_b, N_sl)
|
||||
prm%theta0 = math_expand(prm%theta0, N_sl)
|
||||
prm%theta1 = math_expand(prm%theta1, N_sl)
|
||||
prm%theta0_b = math_expand(prm%theta0_b,N_sl)
|
||||
prm%theta1_b = math_expand(prm%theta1_b,N_sl)
|
||||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! sanity checks
|
||||
if ( prm%gdot0 <= 0.0_pReal) extmsg = trim(extmsg)//' gdot0'
|
||||
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_b <= 0.0_pReal)) extmsg = trim(extmsg)//' tau1_b'
|
||||
|
||||
!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
|
||||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! 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
|
||||
NipcMyPhase = count(material_phaseAt == p) * discretization_nIP
|
||||
sizeDotState = size(['crss ','crss_back', 'accshear ']) * prm%totalNslip
|
||||
sizeDeltaState = size(['sense ', 'chi0 ', 'gamma0' ]) * prm%totalNslip
|
||||
sizeDotState = size(['crss ','crss_back', 'accshear ']) * prm%sum_N_sl
|
||||
sizeDeltaState = size(['sense ', 'chi0 ', 'gamma0' ]) * prm%sum_N_sl
|
||||
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
|
||||
endIndex = prm%totalNslip
|
||||
endIndex = prm%sum_N_sl
|
||||
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,:)
|
||||
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
|
||||
endIndex = endIndex + prm%totalNslip
|
||||
endIndex = endIndex + prm%sum_N_sl
|
||||
stt%crss_back => plasticState(p)%state (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
|
||||
endIndex = endIndex + prm%totalNslip
|
||||
endIndex = endIndex + prm%sum_N_sl
|
||||
stt%accshear => plasticState(p)%state (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
|
||||
plasticState(p)%slipRate => plasticState(p)%dotState(startIndex:endIndex,:)
|
||||
|
||||
o = plasticState(p)%offsetDeltaState
|
||||
startIndex = endIndex + 1
|
||||
endIndex = endIndex + prm%totalNslip
|
||||
endIndex = endIndex + prm%sum_N_sl
|
||||
stt%sense => plasticState(p)%state (startIndex :endIndex ,:)
|
||||
dlt%sense => plasticState(p)%deltaState(startIndex-o:endIndex-o,:)
|
||||
|
||||
startIndex = endIndex + 1
|
||||
endIndex = endIndex + prm%totalNslip
|
||||
endIndex = endIndex + prm%sum_N_sl
|
||||
stt%chi0 => plasticState(p)%state (startIndex :endIndex ,:)
|
||||
dlt%chi0 => plasticState(p)%deltaState(startIndex-o:endIndex-o,:)
|
||||
|
||||
startIndex = endIndex + 1
|
||||
endIndex = endIndex + prm%totalNslip
|
||||
endIndex = endIndex + prm%sum_N_sl
|
||||
stt%gamma0 => plasticState(p)%state (startIndex :endIndex ,:)
|
||||
dlt%gamma0 => plasticState(p)%deltaState(startIndex-o:endIndex-o,:)
|
||||
|
||||
|
@ -224,8 +211,13 @@ module subroutine plastic_kinehardening_init
|
|||
|
||||
end associate
|
||||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! exit if any parameter is out of range
|
||||
if (extmsg /= '') call IO_error(211,ext_msg=trim(extmsg)//'('//PLASTICITY_KINEHARDENING_LABEL//')')
|
||||
|
||||
enddo
|
||||
|
||||
|
||||
end subroutine plastic_kinehardening_init
|
||||
|
||||
|
||||
|
@ -247,7 +239,7 @@ pure module subroutine plastic_kinehardening_LpAndItsTangent(Lp,dLp_dMp,Mp,insta
|
|||
|
||||
integer :: &
|
||||
i,k,l,m,n
|
||||
real(pReal), dimension(param(instance)%totalNslip) :: &
|
||||
real(pReal), dimension(param(instance)%sum_N_sl) :: &
|
||||
gdot_pos,gdot_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)
|
||||
|
||||
do i = 1, prm%totalNslip
|
||||
Lp = Lp + (gdot_pos(i)+gdot_neg(i))*prm%Schmid(1:3,1:3,i)
|
||||
do i = 1, prm%sum_N_sl
|
||||
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) &
|
||||
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_neg(i) * prm%Schmid(k,l,i) * prm%nonSchmid_neg(m,n,i)
|
||||
+ dgdot_dtau_pos(i) * prm%P(k,l,i) * prm%nonSchmid_pos(m,n,i) &
|
||||
+ dgdot_dtau_neg(i) * prm%P(k,l,i) * prm%nonSchmid_neg(m,n,i)
|
||||
enddo
|
||||
|
||||
end associate
|
||||
|
@ -284,7 +276,7 @@ module subroutine plastic_kinehardening_dotState(Mp,instance,of)
|
|||
|
||||
real(pReal) :: &
|
||||
sumGamma
|
||||
real(pReal), dimension(param(instance)%totalNslip) :: &
|
||||
real(pReal), dimension(param(instance)%sum_N_sl) :: &
|
||||
gdot_pos,gdot_neg
|
||||
|
||||
|
||||
|
@ -324,7 +316,7 @@ module subroutine plastic_kinehardening_deltaState(Mp,instance,of)
|
|||
instance, &
|
||||
of
|
||||
|
||||
real(pReal), dimension(param(instance)%totalNslip) :: &
|
||||
real(pReal), dimension(param(instance)%sum_N_sl) :: &
|
||||
gdot_pos,gdot_neg, &
|
||||
sense
|
||||
|
||||
|
@ -375,22 +367,22 @@ module subroutine plastic_kinehardening_results(instance,group)
|
|||
outputsLoop: do o = 1,size(prm%output)
|
||||
select case(trim(prm%output(o)))
|
||||
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')
|
||||
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')
|
||||
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')
|
||||
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')
|
||||
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')
|
||||
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')
|
||||
end select
|
||||
enddo outputsLoop
|
||||
|
@ -415,31 +407,28 @@ pure subroutine kinetics(Mp,instance,of, &
|
|||
instance, &
|
||||
of
|
||||
|
||||
real(pReal), intent(out), dimension(param(instance)%totalNslip) :: &
|
||||
real(pReal), intent(out), dimension(param(instance)%sum_N_sl) :: &
|
||||
gdot_pos, &
|
||||
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_neg
|
||||
|
||||
real(pReal), dimension(param(instance)%totalNslip) :: &
|
||||
real(pReal), dimension(param(instance)%sum_N_sl) :: &
|
||||
tau_pos, &
|
||||
tau_neg
|
||||
integer :: i
|
||||
logical :: nonSchmidActive
|
||||
|
||||
associate(prm => param(instance), stt => state(instance))
|
||||
|
||||
nonSchmidActive = size(prm%nonSchmidCoeff) > 0
|
||||
|
||||
do i = 1, prm%totalNslip
|
||||
tau_pos(i) = math_mul33xx33(Mp,prm%nonSchmid_pos(1:3,1:3,i)) - stt%crss_back(i,of)
|
||||
tau_neg(i) = merge(math_mul33xx33(Mp,prm%nonSchmid_neg(1:3,1:3,i)) - stt%crss_back(i,of), &
|
||||
0.0_pReal, nonSchmidActive)
|
||||
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)
|
||||
tau_neg(i) = merge(math_tensordot(Mp,prm%nonSchmid_neg(1:3,1:3,i)) - stt%crss_back(i,of), &
|
||||
0.0_pReal, prm%nonSchmidActive)
|
||||
enddo
|
||||
|
||||
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)
|
||||
else where
|
||||
gdot_pos = 0.0_pReal
|
||||
|
|
|
@ -19,7 +19,7 @@ module subroutine plastic_none_init
|
|||
p, &
|
||||
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)
|
||||
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
Loading…
Reference in New Issue