Merge branch 'development' into YAML-improvements
This commit is contained in:
commit
2bd4e79a37
|
@ -239,6 +239,16 @@ Compile_Intel_Prepare:
|
|||
- release
|
||||
|
||||
###################################################################################################
|
||||
Pytest_grid:
|
||||
stage: grid
|
||||
script:
|
||||
- module load $IntelCompiler $MPICH_Intel $PETSc_MPICH_Intel
|
||||
- cd pytest
|
||||
- pytest
|
||||
except:
|
||||
- master
|
||||
- release
|
||||
|
||||
Thermal:
|
||||
stage: grid
|
||||
script: Thermal/test.py
|
||||
|
@ -253,27 +263,6 @@ grid_parsingArguments:
|
|||
- master
|
||||
- release
|
||||
|
||||
StateIntegration_compareVariants:
|
||||
stage: grid
|
||||
script: StateIntegration_compareVariants/test.py
|
||||
except:
|
||||
- master
|
||||
- release
|
||||
|
||||
nonlocal_densityConservation:
|
||||
stage: grid
|
||||
script: nonlocal_densityConservation/test.py
|
||||
except:
|
||||
- master
|
||||
- release
|
||||
|
||||
RGC_DetectChanges:
|
||||
stage: grid
|
||||
script: RGC_DetectChanges/test.py
|
||||
except:
|
||||
- master
|
||||
- release
|
||||
|
||||
Nonlocal_Damage_DetectChanges:
|
||||
stage: grid
|
||||
script: Nonlocal_Damage_DetectChanges/test.py
|
||||
|
@ -302,15 +291,6 @@ grid_all_loadCaseRotation:
|
|||
- master
|
||||
- release
|
||||
|
||||
grid_mech_MPI:
|
||||
stage: grid
|
||||
script:
|
||||
- module load $IntelCompiler $MPICH_Intel $PETSc_MPICH_Intel
|
||||
- grid_mech_MPI/test.py
|
||||
except:
|
||||
- master
|
||||
- release
|
||||
|
||||
grid_all_restartMPI:
|
||||
stage: grid
|
||||
script:
|
||||
|
@ -327,13 +307,6 @@ Plasticity_DetectChanges:
|
|||
- master
|
||||
- release
|
||||
|
||||
Homogenization:
|
||||
stage: grid
|
||||
script: Homogenization/test.py
|
||||
except:
|
||||
- master
|
||||
- release
|
||||
|
||||
Phenopowerlaw_singleSlip:
|
||||
stage: grid
|
||||
script: Phenopowerlaw_singleSlip/test.py
|
||||
|
@ -341,15 +314,6 @@ Phenopowerlaw_singleSlip:
|
|||
- master
|
||||
- release
|
||||
|
||||
Pytest_grid:
|
||||
stage: grid
|
||||
script:
|
||||
- cd pytest
|
||||
- pytest
|
||||
except:
|
||||
- master
|
||||
- release
|
||||
|
||||
###################################################################################################
|
||||
Marc_compileIfort:
|
||||
stage: compileMarc
|
||||
|
|
8
Makefile
8
Makefile
|
@ -9,18 +9,10 @@ all: grid mesh processing
|
|||
.PHONY: grid
|
||||
grid: build/grid
|
||||
@(cd build/grid;make -j${DAMASK_NUM_THREADS} all install;)
|
||||
@rm -f ${DAMASK_ROOT}/bin/DAMASK_spectral > /dev/null || true
|
||||
@ln -s ${DAMASK_ROOT}/bin/DAMASK_grid ${DAMASK_ROOT}/bin/DAMASK_spectral || true
|
||||
.PHONY: spectral
|
||||
spectral: grid
|
||||
|
||||
.PHONY: mesh
|
||||
mesh: build/mesh
|
||||
@(cd build/mesh; make -j${DAMASK_NUM_THREADS} all install;)
|
||||
@rm -f ${DAMASK_ROOT}/bin/DAMASK_FEM > /dev/null || true
|
||||
@ln -s ${DAMASK_ROOT}/bin/DAMASK_mesh ${DAMASK_ROOT}/bin/DAMASK_FEM || true
|
||||
.PHONY: FEM
|
||||
FEM: mesh
|
||||
|
||||
.PHONY: build/grid
|
||||
build/grid:
|
||||
|
|
2
PRIVATE
2
PRIVATE
|
@ -1 +1 @@
|
|||
Subproject commit 3444f5334c1c6c05b781e0e25bbcb658d9ce7c5d
|
||||
Subproject commit 64e62f805b5ad784e3397ee5f735aaeb3cc134c2
|
|
@ -78,12 +78,9 @@ crystallite:
|
|||
iJacoLpresiduum: 1 # frequency of Jacobian update of residuum in Lp
|
||||
|
||||
commercialFEM:
|
||||
ijacostiffness: 1 # frequency of stiffness update
|
||||
unitlength: 1 # physical length of one computational length unit
|
||||
|
||||
generic:
|
||||
charLength: 1.0 # characteristic length scale for gradient problems.
|
||||
random_seed: 0 # fixed seeding for pseudo-random number generator, Default 0: use random seed.
|
||||
residualStiffness: 1.0e-6 # non-zero residual damage.
|
||||
|
||||
|
||||
|
|
|
@ -1,115 +1,110 @@
|
|||
---
|
||||
homogenization:
|
||||
SX:
|
||||
mech: {type:
|
||||
none}
|
||||
microstructure:
|
||||
- constituents:
|
||||
- fraction: 1.0
|
||||
orientation: [1.0, 0.0, 0.0, 0.0]
|
||||
phase: Aluminum
|
||||
homogenization: SX
|
||||
- constituents:
|
||||
- fraction: 1.0
|
||||
orientation: [0.7936696712125002, -0.28765777461664166,
|
||||
-0.3436487135089419, 0.4113964260949434]
|
||||
phase: Aluminum
|
||||
homogenization: SX
|
||||
- constituents:
|
||||
- fraction: 1.0
|
||||
orientation: [0.3986143167493579, -0.7014883552495493, 0.2154871765709027, 0.5500781677772945]
|
||||
phase: Aluminum
|
||||
homogenization: SX
|
||||
- constituents:
|
||||
- fraction: 1.0
|
||||
orientation: [0.28645844315788244,
|
||||
mech: {type: none}
|
||||
|
||||
material:
|
||||
- constituents:
|
||||
- fraction: 1.0
|
||||
O: [1.0, 0.0, 0.0, 0.0]
|
||||
phase: Aluminum
|
||||
homogenization: SX
|
||||
- constituents:
|
||||
- fraction: 1.0
|
||||
O: [0.7936696712125002, -0.28765777461664166, -0.3436487135089419, 0.4113964260949434]
|
||||
phase: Aluminum
|
||||
homogenization: SX
|
||||
- constituents:
|
||||
- fraction: 1.0
|
||||
O: [0.3986143167493579, -0.7014883552495493, 0.2154871765709027, 0.5500781677772945]
|
||||
phase: Aluminum
|
||||
homogenization: SX
|
||||
- constituents:
|
||||
- fraction: 1.0
|
||||
O: [0.28645844315788244, -0.022571491243423537, -0.467933059311115, -0.8357456192708106]
|
||||
phase: Aluminum
|
||||
homogenization: SX
|
||||
- constituents:
|
||||
- fraction: 1.0
|
||||
O: [0.33012772942625784, -0.6781865350268957, 0.6494525351030648, 0.09638521992649676]
|
||||
phase: Aluminum
|
||||
homogenization: SX
|
||||
- constituents:
|
||||
- fraction: 1.0
|
||||
O: [0.43596817439583935, -0.5982537129781701, 0.046599032277502436, 0.6707106499919265]
|
||||
phase: Aluminum
|
||||
homogenization: SX
|
||||
- constituents:
|
||||
- fraction: 1.0
|
||||
O: [0.169734823419553, -0.699615227367322, -0.6059581215838098, -0.33844257746495854]
|
||||
phase: Aluminum
|
||||
homogenization: SX
|
||||
- constituents:
|
||||
- fraction: 1.0
|
||||
O: [0.9698864809294915, 0.1729052643205874, -0.15948307917616958, 0.06315956884687175]
|
||||
phase: Aluminum
|
||||
homogenization: SX
|
||||
- constituents:
|
||||
- fraction: 1.0
|
||||
O: [0.46205660912967883, 0.3105054068891252, -0.617849551030653, 0.555294529545738]
|
||||
phase: Aluminum
|
||||
homogenization: SX
|
||||
- constituents:
|
||||
- fraction: 1.0
|
||||
O: [0.4512443497461787, -0.7636045534540555, -0.04739348426715133, -0.45939142396805815]
|
||||
phase: Aluminum
|
||||
homogenization: SX
|
||||
- constituents:
|
||||
- fraction: 1.0
|
||||
O: [0.2161856212656443, -0.6581450184826598, -0.5498086209601588, 0.4667112513346289]
|
||||
phase: Aluminum
|
||||
homogenization: SX
|
||||
- constituents:
|
||||
- fraction: 1.0
|
||||
O: [0.8753220715350803, -0.4561599367657419, -0.13298279533852678, -0.08969369719975541]
|
||||
phase: Aluminum
|
||||
homogenization: SX
|
||||
- constituents:
|
||||
- fraction: 1.0
|
||||
O: [0.11908260752431069, 0.18266024809834172, -0.7144822594012615, -0.664807992845101]
|
||||
phase: Aluminum
|
||||
homogenization: SX
|
||||
- constituents:
|
||||
- fraction: 1.0
|
||||
O: [0.751104669484278, 0.5585633382623958, -0.34579336397009175, 0.06538900566860861]
|
||||
phase: Aluminum
|
||||
homogenization: SX
|
||||
- constituents:
|
||||
- fraction: 1.0
|
||||
O: [0.08740438971703973, 0.8991264096610437, -0.4156704205935976, 0.10559485570696363]
|
||||
phase: Aluminum
|
||||
homogenization: SX
|
||||
- constituents:
|
||||
- fraction: 1.0
|
||||
O: [0.5584325870096193, 0.6016408353068798, -0.14280340445801173, 0.5529814994483859]
|
||||
phase: Aluminum
|
||||
homogenization: SX
|
||||
- constituents:
|
||||
- fraction: 1.0
|
||||
O: [0.4052725440888093, 0.25253073423599154, 0.5693263597910454, -0.669215876471182]
|
||||
phase: Aluminum
|
||||
homogenization: SX
|
||||
- constituents:
|
||||
- fraction: 1.0
|
||||
O: [0.7570164606888676, 0.15265448024694664, -0.5998021466848317, 0.20942796551297105]
|
||||
phase: Aluminum
|
||||
homogenization: SX
|
||||
- constituents:
|
||||
- fraction: 1.0
|
||||
O: [0.6987659297138081, -0.132172211261028, -0.19693254724422338, 0.6748883269678543]
|
||||
phase: Aluminum
|
||||
homogenization: SX
|
||||
- constituents:
|
||||
- fraction: 1.0
|
||||
O: [0.7729330445886478, 0.21682179052722322, -0.5207379472917645, 0.2905078484066341]
|
||||
phase: Aluminum
|
||||
homogenization: SX
|
||||
|
||||
|
||||
-0.022571491243423537,
|
||||
-0.467933059311115, -0.8357456192708106]
|
||||
phase: Aluminum
|
||||
homogenization: SX
|
||||
- constituents:
|
||||
- fraction: 1.0
|
||||
orientation: [0.33012772942625784, -0.6781865350268957, 0.6494525351030648, 0.09638521992649676]
|
||||
phase: Aluminum
|
||||
homogenization: SX
|
||||
- constituents:
|
||||
- fraction: 1.0
|
||||
orientation: [0.43596817439583935, -0.5982537129781701, 0.046599032277502436, 0.6707106499919265]
|
||||
phase: Aluminum
|
||||
homogenization: SX
|
||||
- constituents:
|
||||
- fraction: 1.0
|
||||
orientation: [0.169734823419553, -0.699615227367322, -0.6059581215838098, -0.33844257746495854]
|
||||
phase: Aluminum
|
||||
homogenization: SX
|
||||
- constituents:
|
||||
- fraction: 1.0
|
||||
orientation: [0.9698864809294915, 0.1729052643205874, -0.15948307917616958, 0.06315956884687175]
|
||||
phase: Aluminum
|
||||
homogenization: SX
|
||||
- constituents:
|
||||
- fraction: 1.0
|
||||
orientation: [0.46205660912967883, 0.3105054068891252, -0.617849551030653, 0.555294529545738]
|
||||
phase: Aluminum
|
||||
homogenization: SX
|
||||
- constituents:
|
||||
- fraction: 1.0
|
||||
orientation: [0.4512443497461787, -0.7636045534540555, -0.04739348426715133, -0.45939142396805815]
|
||||
phase: Aluminum
|
||||
homogenization: SX
|
||||
- constituents:
|
||||
- fraction: 1.0
|
||||
orientation: [0.2161856212656443, -0.6581450184826598, -0.5498086209601588, 0.4667112513346289]
|
||||
phase: Aluminum
|
||||
homogenization: SX
|
||||
- constituents:
|
||||
- fraction: 1.0
|
||||
orientation: [0.8753220715350803, -0.4561599367657419, -0.13298279533852678, -0.08969369719975541]
|
||||
phase: Aluminum
|
||||
homogenization: SX
|
||||
- constituents:
|
||||
- fraction: 1.0
|
||||
orientation: [0.11908260752431069, 0.18266024809834172, -0.7144822594012615, -0.664807992845101]
|
||||
phase: Aluminum
|
||||
homogenization: SX
|
||||
- constituents:
|
||||
- fraction: 1.0
|
||||
orientation: [0.751104669484278, 0.5585633382623958, -0.34579336397009175, 0.06538900566860861]
|
||||
phase: Aluminum
|
||||
homogenization: SX
|
||||
- constituents:
|
||||
- fraction: 1.0
|
||||
orientation: [0.08740438971703973, 0.8991264096610437, -0.4156704205935976, 0.10559485570696363]
|
||||
phase: Aluminum
|
||||
homogenization: SX
|
||||
- constituents:
|
||||
- fraction: 1.0
|
||||
orientation: [0.5584325870096193, 0.6016408353068798, -0.14280340445801173, 0.5529814994483859]
|
||||
phase: Aluminum
|
||||
homogenization: SX
|
||||
- constituents:
|
||||
- fraction: 1.0
|
||||
orientation: [0.4052725440888093, 0.25253073423599154, 0.5693263597910454, -0.669215876471182]
|
||||
phase: Aluminum
|
||||
homogenization: SX
|
||||
- constituents:
|
||||
- fraction: 1.0
|
||||
orientation: [0.7570164606888676, 0.15265448024694664, -0.5998021466848317, 0.20942796551297105]
|
||||
phase: Aluminum
|
||||
homogenization: SX
|
||||
- constituents:
|
||||
- fraction: 1.0
|
||||
orientation: [0.6987659297138081, -0.132172211261028, -0.19693254724422338, 0.6748883269678543]
|
||||
phase: Aluminum
|
||||
homogenization: SX
|
||||
- constituents:
|
||||
- fraction: 1.0
|
||||
orientation: [0.7729330445886478, 0.21682179052722322, -0.5207379472917645, 0.2905078484066341]
|
||||
phase: Aluminum
|
||||
homogenization: SX
|
||||
phase:
|
||||
Aluminum:
|
||||
elasticity: {C_11: 106.75e9, C_12: 60.41e9, C_44: 28.34e9, type: hooke}
|
||||
|
@ -125,7 +120,6 @@ phase:
|
|||
h_sl_sl: [1, 1, 1.4, 1.4, 1.4, 1.4]
|
||||
n_sl: 20
|
||||
output: [xi_sl]
|
||||
type: phenopowerlaw
|
||||
xi_0_sl: [31e6]
|
||||
xi_inf_sl: [63e6]
|
||||
type: phenopowerlaw
|
||||
|
||||
|
|
|
@ -1,161 +0,0 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import os
|
||||
import sys
|
||||
from optparse import OptionParser
|
||||
import re
|
||||
import fnmatch
|
||||
import math # noqa
|
||||
|
||||
import numpy as np
|
||||
|
||||
import damask
|
||||
|
||||
|
||||
scriptName = os.path.splitext(os.path.basename(__file__))[0]
|
||||
scriptID = ' '.join([scriptName,damask.version])
|
||||
|
||||
def sortingList(labels,whitelistitems):
|
||||
|
||||
indices = []
|
||||
names = []
|
||||
|
||||
for label in labels:
|
||||
if re.match(r'^\d+_',label):
|
||||
indices.append(int(label.split('_',1)[0]))
|
||||
names.append(label.split('_',1)[1])
|
||||
else:
|
||||
indices.append(0)
|
||||
names.append(label)
|
||||
|
||||
return [indices,names,whitelistitems]
|
||||
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# MAIN
|
||||
# --------------------------------------------------------------------
|
||||
|
||||
parser = OptionParser(option_class=damask.extendableOption, usage='%prog options [ASCIItable(s)]', description = """
|
||||
Filter rows according to condition and columns by either white or black listing.
|
||||
|
||||
Examples:
|
||||
Every odd row if x coordinate is positive -- " #ip.x# >= 0.0 and #_row_#%2 == 1 ).
|
||||
All rows where label 'foo' equals 'bar' -- " #s#foo# == 'bar' "
|
||||
|
||||
""", version = scriptID)
|
||||
|
||||
parser.add_option('-w','--white',
|
||||
dest = 'whitelist',
|
||||
action = 'extend', metavar = '<string LIST>',
|
||||
help = 'whitelist of column labels (a,b,c,...)')
|
||||
parser.add_option('-b','--black',
|
||||
dest = 'blacklist',
|
||||
action = 'extend', metavar='<string LIST>',
|
||||
help = 'blacklist of column labels (a,b,c,...)')
|
||||
parser.add_option('-c','--condition',
|
||||
dest = 'condition', metavar='string',
|
||||
help = 'condition to filter rows')
|
||||
|
||||
parser.set_defaults(condition = None,
|
||||
)
|
||||
|
||||
(options,filenames) = parser.parse_args()
|
||||
|
||||
# --- loop over input files -------------------------------------------------------------------------
|
||||
|
||||
if filenames == []: filenames = [None]
|
||||
|
||||
for name in filenames:
|
||||
try:
|
||||
table = damask.ASCIItable(name = name)
|
||||
except IOError:
|
||||
continue
|
||||
damask.util.report(scriptName,name)
|
||||
|
||||
# ------------------------------------------ assemble info ---------------------------------------
|
||||
|
||||
table.head_read()
|
||||
|
||||
# ------------------------------------------ process data ---------------------------------------
|
||||
|
||||
specials = { \
|
||||
'_row_': 0,
|
||||
}
|
||||
labels = []
|
||||
positions = []
|
||||
|
||||
for position,label in enumerate(table.labels(raw = True)):
|
||||
if (options.whitelist is None or any([ position in table.label_indexrange(needle) \
|
||||
or fnmatch.fnmatch(label,needle) for needle in options.whitelist])) \
|
||||
and (options.blacklist is None or not any([ position in table.label_indexrange(needle) \
|
||||
or fnmatch.fnmatch(label,needle) for needle in options.blacklist])): # a label to keep?
|
||||
labels.append(label) # remember name...
|
||||
positions.append(position) # ...and position
|
||||
|
||||
if len(labels) > 0 and options.whitelist is not None and options.blacklist is None: # check whether reordering is possible
|
||||
whitelistitem = np.zeros(len(labels),dtype=int)
|
||||
for i,label in enumerate(labels): # check each selected label
|
||||
match = [ positions[i] in table.label_indexrange(needle) \
|
||||
or fnmatch.fnmatch(label,needle) for needle in options.whitelist] # which whitelist items do match it
|
||||
whitelistitem[i] = match.index(True) if np.sum(match) == 1 else -1 # unique match to a whitelist item --> store which
|
||||
|
||||
order = range(len(labels)) if np.any(whitelistitem < 0) \
|
||||
else np.lexsort(sortingList(labels,whitelistitem)) # reorder if unique, i.e. no "-1" in whitelistitem
|
||||
else:
|
||||
order = range(len(labels)) # maintain original order of labels
|
||||
|
||||
# --------------------------------------- evaluate condition ---------------------------------------
|
||||
if options.condition is not None:
|
||||
condition = options.condition # copy per file, since might be altered inline
|
||||
breaker = False
|
||||
|
||||
for position,(all,marker,column) in enumerate(set(re.findall(r'#(([s]#)?(.+?))#',condition))): # find three groups
|
||||
idx = table.label_index(column)
|
||||
dim = table.label_dimension(column)
|
||||
if idx < 0 and column not in specials:
|
||||
damask.util.croak('column "{}" not found.'.format(column))
|
||||
breaker = True
|
||||
else:
|
||||
if column in specials:
|
||||
replacement = 'specials["{}"]'.format(column)
|
||||
elif dim == 1: # scalar input
|
||||
replacement = '{}(table.data[{}])'.format({ '':'float',
|
||||
's#':'str'}[marker],idx) # take float or string value of data column
|
||||
elif dim > 1: # multidimensional input (vector, tensor, etc.)
|
||||
replacement = 'np.array(table.data[{}:{}],dtype=float)'.format(idx,idx+dim) # use (flat) array representation
|
||||
|
||||
condition = condition.replace('#'+all+'#',replacement)
|
||||
|
||||
if breaker: continue # found mistake in condition evaluation --> next file
|
||||
|
||||
# ------------------------------------------ assemble header ---------------------------------------
|
||||
|
||||
table.info_append(scriptID + '\t' + ' '.join(sys.argv[1:]))
|
||||
table.labels_clear()
|
||||
table.labels_append(np.array(labels)[order]) # update with new label set
|
||||
table.head_write()
|
||||
|
||||
# ------------------------------------------ process and output data ------------------------------------------
|
||||
|
||||
positions = np.array(positions)[order]
|
||||
|
||||
atOnce = options.condition is None
|
||||
if atOnce: # read full array and filter columns
|
||||
try:
|
||||
table.data_readArray(positions+1) # read desired columns (indexed 1,...)
|
||||
table.data_writeArray() # directly write out
|
||||
except Exception:
|
||||
table.data_rewind()
|
||||
atOnce = False # data contains items that prevent array chunking
|
||||
|
||||
if not atOnce: # read data line by line
|
||||
outputAlive = True
|
||||
while outputAlive and table.data_read(): # read next data line of ASCII table
|
||||
specials['_row_'] += 1 # count row
|
||||
if options.condition is None or eval(condition): # valid row ?
|
||||
table.data = [table.data[position] for position in positions] # retain filtered columns
|
||||
outputAlive = table.data_write() # output processed line
|
||||
|
||||
# ------------------------------------------ finalize output -----------------------------------------
|
||||
|
||||
table.close() # close input ASCII table (works for stdin)
|
|
@ -52,16 +52,11 @@ parser.add_option('-q', '--quaternion',
|
|||
type = 'string',
|
||||
metavar='string',
|
||||
help = 'name of the dataset containing pointwise/average orientation as quaternion [%default]')
|
||||
parser.add_option('--homogenization',
|
||||
dest = 'homogenization',
|
||||
type = 'int', metavar = 'int',
|
||||
help = 'homogenization index to be used [%default]')
|
||||
|
||||
parser.set_defaults(pointwise = 'CellData',
|
||||
quaternion = 'Quats',
|
||||
phase = 'Phases',
|
||||
microstructure = 'FeatureIds',
|
||||
homogenization = 1,
|
||||
)
|
||||
|
||||
(options, filenames) = parser.parse_args()
|
||||
|
@ -150,8 +145,7 @@ for name in filenames:
|
|||
|
||||
header = [scriptID + ' ' + ' '.join(sys.argv[1:])]\
|
||||
+ config_header
|
||||
geom = damask.Geom(microstructure,size,origin,
|
||||
homogenization=options.homogenization,comments=header)
|
||||
geom = damask.Geom(microstructure,size,origin,comments=header)
|
||||
damask.util.croak(geom)
|
||||
|
||||
geom.save_ASCII(os.path.splitext(name)[0]+'.geom',compress=False)
|
||||
|
|
|
@ -4,8 +4,6 @@ import os
|
|||
import sys
|
||||
from optparse import OptionParser
|
||||
|
||||
import numpy as np
|
||||
|
||||
import damask
|
||||
|
||||
|
||||
|
@ -13,14 +11,7 @@ scriptName = os.path.splitext(os.path.basename(__file__))[0]
|
|||
scriptID = ' '.join([scriptName,damask.version])
|
||||
|
||||
|
||||
minimal_surfaces = ['primitive','gyroid','diamond']
|
||||
|
||||
surface = {
|
||||
'primitive': lambda x,y,z: np.cos(x)+np.cos(y)+np.cos(z),
|
||||
'gyroid': lambda x,y,z: np.sin(x)*np.cos(y)+np.sin(y)*np.cos(z)+np.cos(x)*np.sin(z),
|
||||
'diamond': lambda x,y,z: np.cos(x-y)*np.cos(z)+np.sin(x+y)*np.sin(z),
|
||||
}
|
||||
|
||||
minimal_surfaces = list(damask.Geom._minimal_surface.keys())
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# MAIN
|
||||
|
@ -52,10 +43,6 @@ parser.add_option('-p', '--periods',
|
|||
dest = 'periods',
|
||||
type = 'int', metavar = 'int',
|
||||
help = 'number of repetitions of unit cell [%default]')
|
||||
parser.add_option('--homogenization',
|
||||
dest = 'homogenization',
|
||||
type = 'int', metavar = 'int',
|
||||
help = 'homogenization index to be used [%default]')
|
||||
parser.add_option('--m',
|
||||
dest = 'microstructure',
|
||||
type = 'int', nargs = 2, metavar = 'int int',
|
||||
|
@ -66,7 +53,6 @@ parser.set_defaults(type = minimal_surfaces[0],
|
|||
periods = 1,
|
||||
grid = (16,16,16),
|
||||
size = (1.0,1.0,1.0),
|
||||
homogenization = 1,
|
||||
microstructure = (1,2),
|
||||
)
|
||||
|
||||
|
@ -76,17 +62,8 @@ parser.set_defaults(type = minimal_surfaces[0],
|
|||
name = None if filename == [] else filename[0]
|
||||
damask.util.report(scriptName,name)
|
||||
|
||||
x,y,z = np.meshgrid(options.periods*2.0*np.pi*(np.arange(options.grid[0])+0.5)/options.grid[0],
|
||||
options.periods*2.0*np.pi*(np.arange(options.grid[1])+0.5)/options.grid[1],
|
||||
options.periods*2.0*np.pi*(np.arange(options.grid[2])+0.5)/options.grid[2],
|
||||
indexing='xy',sparse=True)
|
||||
|
||||
microstructure = np.where(options.threshold < surface[options.type](x,y,z),
|
||||
options.microstructure[1],options.microstructure[0])
|
||||
|
||||
geom=damask.Geom(microstructure,options.size,
|
||||
homogenization=options.homogenization,
|
||||
comments=[scriptID + ' ' + ' '.join(sys.argv[1:])])
|
||||
geom=damask.Geom.from_minimal_surface(options.grid,options.size,options.type,options.threshold,
|
||||
options.periods,options.microstructure)
|
||||
damask.util.croak(geom)
|
||||
|
||||
geom.save_ASCII(sys.stdout if name is None else name,compress=False)
|
||||
|
|
|
@ -57,10 +57,6 @@ parser.add_option('-w', '--omega',
|
|||
dest='omega',
|
||||
type='float', metavar = 'float',
|
||||
help='rotation angle around normal of osteon [%default]')
|
||||
parser.add_option( '--homogenization',
|
||||
dest='homogenization',
|
||||
type='int', metavar = 'int',
|
||||
help='homogenization index to be used [%default]')
|
||||
|
||||
parser.set_defaults(canal = 25e-6,
|
||||
osteon = 100e-6,
|
||||
|
@ -70,7 +66,7 @@ parser.set_defaults(canal = 25e-6,
|
|||
amplitude = 60,
|
||||
size = (300e-6,300e-6),
|
||||
grid = (512,512),
|
||||
homogenization = 1)
|
||||
)
|
||||
|
||||
(options,filename) = parser.parse_args()
|
||||
|
||||
|
@ -139,7 +135,7 @@ header = [scriptID + ' ' + ' '.join(sys.argv[1:])]\
|
|||
+ config_header
|
||||
geom = damask.Geom(microstructure.reshape(grid),
|
||||
size,-size/2,
|
||||
homogenization=options.homogenization,comments=header)
|
||||
comments=header)
|
||||
damask.util.croak(geom)
|
||||
|
||||
geom.save_ASCII(sys.stdout if name is None else name,compress=False)
|
||||
|
|
|
@ -44,14 +44,9 @@ parser.add_option('--axes',
|
|||
dest = 'axes',
|
||||
type = 'string', nargs = 3, metavar = ' '.join(['string']*3),
|
||||
help = 'orientation coordinate frame in terms of position coordinate frame [+x +y +z]')
|
||||
parser.add_option('--homogenization',
|
||||
dest = 'homogenization',
|
||||
type = 'int', metavar = 'int',
|
||||
help = 'homogenization index to be used [%default]')
|
||||
|
||||
|
||||
parser.set_defaults(homogenization = 1,
|
||||
pos = 'pos',
|
||||
parser.set_defaults(pos = 'pos',
|
||||
)
|
||||
|
||||
(options,filenames) = parser.parse_args()
|
||||
|
@ -102,7 +97,7 @@ for name in filenames:
|
|||
header = [scriptID + ' ' + ' '.join(sys.argv[1:])]\
|
||||
+ config_header
|
||||
geom = damask.Geom(microstructure,size,origin,
|
||||
homogenization=options.homogenization,comments=header)
|
||||
comments=header)
|
||||
damask.util.croak(geom)
|
||||
|
||||
geom.save_ASCII(sys.stdout if name is None else os.path.splitext(name)[0]+'.geom',compress=False)
|
||||
|
|
|
@ -1,231 +0,0 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import os
|
||||
import sys
|
||||
import multiprocessing
|
||||
from io import StringIO
|
||||
from functools import partial
|
||||
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])
|
||||
|
||||
|
||||
def findClosestSeed(seeds, weights, point):
|
||||
return np.argmin(np.sum((np.broadcast_to(point,(len(seeds),3))-seeds)**2,axis=1) - weights)
|
||||
|
||||
|
||||
def Laguerre_tessellation(grid, size, seeds, weights, origin = np.zeros(3), periodic = True, cpus = 2):
|
||||
|
||||
if periodic:
|
||||
weights_p = np.tile(weights.squeeze(),27) # 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]])))
|
||||
coords = damask.grid_filters.cell_coord0(grid*3,size*3,-origin-size).reshape(-1,3)
|
||||
else:
|
||||
weights_p = weights.squeeze()
|
||||
seeds_p = seeds
|
||||
coords = damask.grid_filters.cell_coord0(grid,size,-origin).reshape(-1,3)
|
||||
|
||||
if cpus > 1:
|
||||
pool = multiprocessing.Pool(processes = cpus)
|
||||
result = pool.map_async(partial(findClosestSeed,seeds_p,weights_p), [coord for coord in coords])
|
||||
pool.close()
|
||||
pool.join()
|
||||
closest_seed = np.array(result.get()).reshape(-1,3)
|
||||
else:
|
||||
closest_seed= np.array([findClosestSeed(seeds_p,weights_p,coord) for coord in coords])
|
||||
|
||||
if periodic:
|
||||
closest_seed = closest_seed.reshape(grid*3)
|
||||
return closest_seed[grid[0]:grid[0]*2,grid[1]:grid[1]*2,grid[2]:grid[2]*2]%seeds.shape[0]
|
||||
else:
|
||||
return closest_seed
|
||||
|
||||
|
||||
def Voronoi_tessellation(grid, size, seeds, origin = np.zeros(3), periodic = True):
|
||||
|
||||
coords = damask.grid_filters.cell_coord0(grid,size,-origin).reshape(-1,3)
|
||||
KDTree = spatial.cKDTree(seeds,boxsize=size) if periodic else spatial.cKDTree(seeds)
|
||||
devNull,closest_seed = KDTree.query(coords)
|
||||
|
||||
return closest_seed
|
||||
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# MAIN
|
||||
# --------------------------------------------------------------------
|
||||
|
||||
parser = OptionParser(option_class=damask.extendableOption, usage='%prog option(s) [seedfile(s)]', description = """
|
||||
Generate geometry description and material configuration by tessellation of given seeds file.
|
||||
|
||||
""", version = scriptID)
|
||||
|
||||
|
||||
group = OptionGroup(parser, "Tessellation","")
|
||||
|
||||
group.add_option('-l',
|
||||
'--laguerre',
|
||||
dest = 'laguerre',
|
||||
action = 'store_true',
|
||||
help = 'use Laguerre (weighted Voronoi) tessellation')
|
||||
group.add_option('--cpus',
|
||||
dest = 'cpus',
|
||||
type = 'int', metavar = 'int',
|
||||
help = 'number of parallel processes to use for Laguerre tessellation [%default]')
|
||||
group.add_option('--nonperiodic',
|
||||
dest = 'periodic',
|
||||
action = 'store_false',
|
||||
help = 'nonperiodic tessellation')
|
||||
|
||||
parser.add_option_group(group)
|
||||
|
||||
group = OptionGroup(parser, "Geometry","")
|
||||
|
||||
group.add_option('-g',
|
||||
'--grid',
|
||||
dest = 'grid',
|
||||
type = 'int', nargs = 3, metavar = ' '.join(['int']*3),
|
||||
help = 'a,b,c grid of hexahedral box')
|
||||
group.add_option('-s',
|
||||
'--size',
|
||||
dest = 'size',
|
||||
type = 'float', nargs = 3, metavar=' '.join(['float']*3),
|
||||
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 [0.0 0.0 0.0]')
|
||||
|
||||
parser.add_option_group(group)
|
||||
|
||||
group = OptionGroup(parser, "Seeds","")
|
||||
|
||||
group.add_option('-p',
|
||||
'--pos', '--seedposition',
|
||||
dest = 'pos',
|
||||
type = 'string', metavar = 'string',
|
||||
help = 'label of coordinates [%default]')
|
||||
group.add_option('-w',
|
||||
'--weight',
|
||||
dest = 'weight',
|
||||
type = 'string', metavar = 'string',
|
||||
help = 'label of weights [%default]')
|
||||
group.add_option('-m',
|
||||
'--microstructure',
|
||||
dest = 'microstructure',
|
||||
type = 'string', metavar = 'string',
|
||||
help = 'label of microstructures [%default]')
|
||||
group.add_option('-e',
|
||||
'--eulers',
|
||||
dest = 'eulers',
|
||||
type = 'string', metavar = 'string',
|
||||
help = 'label of Euler angles [%default]')
|
||||
group.add_option('--axes',
|
||||
dest = 'axes',
|
||||
type = 'string', nargs = 3, metavar = ' '.join(['string']*3),
|
||||
help = 'orientation coordinate frame in terms of position coordinate frame')
|
||||
|
||||
parser.add_option_group(group)
|
||||
|
||||
group = OptionGroup(parser, "Configuration","")
|
||||
|
||||
group.add_option('--without-config',
|
||||
dest = 'config',
|
||||
action = 'store_false',
|
||||
help = 'omit material configuration header')
|
||||
group.add_option('--homogenization',
|
||||
dest = 'homogenization',
|
||||
type = 'int', metavar = 'int',
|
||||
help = 'homogenization index to be used [%default]')
|
||||
group.add_option('--phase',
|
||||
dest = 'phase',
|
||||
type = 'int', metavar = 'int',
|
||||
help = 'phase index to be used [%default]')
|
||||
|
||||
parser.add_option_group(group)
|
||||
|
||||
parser.set_defaults(pos = 'pos',
|
||||
weight = 'weight',
|
||||
microstructure = 'microstructure',
|
||||
eulers = 'euler',
|
||||
homogenization = 1,
|
||||
phase = 1,
|
||||
cpus = 2,
|
||||
laguerre = False,
|
||||
periodic = True,
|
||||
config = True,
|
||||
)
|
||||
|
||||
(options,filenames) = parser.parse_args()
|
||||
if filenames == []: filenames = [None]
|
||||
|
||||
for name in filenames:
|
||||
damask.util.report(scriptName,name)
|
||||
|
||||
table = damask.Table.load(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)
|
||||
|
||||
seeds = table.get(options.pos)
|
||||
|
||||
grains = table.get(options.microstructure) if options.microstructure in table.labels else np.arange(len(seeds))+1
|
||||
grainIDs = np.unique(grains).astype('i')
|
||||
|
||||
if options.eulers in table.labels:
|
||||
eulers = table.get(options.eulers)
|
||||
|
||||
if options.laguerre:
|
||||
indices = grains[Laguerre_tessellation(grid,size,seeds,table.get(options.weight),origin,
|
||||
options.periodic,options.cpus)]
|
||||
else:
|
||||
indices = grains[Voronoi_tessellation (grid,size,seeds,origin,options.periodic)]
|
||||
|
||||
config_header = []
|
||||
if options.config:
|
||||
|
||||
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: config_header += ['axes\t{} {} {}'.format(*options.axes)]
|
||||
|
||||
config_header += ['<microstructure>']
|
||||
for ID in grainIDs:
|
||||
config_header += ['[Grain{}]'.format(ID),
|
||||
'(constituent)\tphase {}\ttexture {}\tfraction 1.0'.format(options.phase,ID)
|
||||
]
|
||||
|
||||
config_header += ['<!skip>']
|
||||
|
||||
header = [scriptID + ' ' + ' '.join(sys.argv[1:])]\
|
||||
+ config_header
|
||||
geom = damask.Geom(indices.reshape(grid),size,origin,
|
||||
homogenization=options.homogenization,comments=header)
|
||||
damask.util.croak(geom)
|
||||
|
||||
geom.save_ASCII(sys.stdout if name is None else os.path.splitext(name)[0]+'.geom',compress=False)
|
|
@ -41,7 +41,7 @@ parser.add_option('-N', '--iterations',
|
|||
help = 'curvature flow iterations [%default]')
|
||||
parser.add_option('-i', '--immutable',
|
||||
action = 'extend', dest = 'immutable', metavar = '<int LIST>',
|
||||
help = 'list of immutable microstructure indices')
|
||||
help = 'list of immutable material indices')
|
||||
parser.add_option('--ndimage',
|
||||
dest = 'ndimage', action='store_true',
|
||||
help = 'use ndimage.gaussian_filter in lieu of explicit FFT')
|
||||
|
@ -64,15 +64,15 @@ for name in filenames:
|
|||
|
||||
geom = damask.Geom.load_ASCII(StringIO(''.join(sys.stdin.read())) if name is None else name)
|
||||
|
||||
grid_original = geom.get_grid()
|
||||
grid_original = geom.grid
|
||||
damask.util.croak(geom)
|
||||
microstructure = np.tile(geom.microstructure,np.where(grid_original == 1, 2,1)) # make one copy along dimensions with grid == 1
|
||||
grid = np.array(microstructure.shape)
|
||||
material = np.tile(geom.material,np.where(grid_original == 1, 2,1)) # make one copy along dimensions with grid == 1
|
||||
grid = np.array(material.shape)
|
||||
|
||||
# --- initialize support data ---------------------------------------------------------------------
|
||||
|
||||
# store a copy the initial microstructure to find locations of immutable indices
|
||||
microstructure_original = np.copy(microstructure)
|
||||
# store a copy of the initial material indices to find locations of immutable indices
|
||||
material_original = np.copy(material)
|
||||
|
||||
if not options.ndimage:
|
||||
X,Y,Z = np.mgrid[0:grid[0],0:grid[1],0:grid[2]]
|
||||
|
@ -88,14 +88,14 @@ for name in filenames:
|
|||
|
||||
for smoothIter in range(options.N):
|
||||
|
||||
interfaceEnergy = np.zeros(microstructure.shape,dtype=np.float32)
|
||||
interfaceEnergy = np.zeros(material.shape,dtype=np.float32)
|
||||
for i in (-1,0,1):
|
||||
for j in (-1,0,1):
|
||||
for k in (-1,0,1):
|
||||
# assign interfacial energy to all voxels that have a differing neighbor (in Moore neighborhood)
|
||||
interfaceEnergy = np.maximum(interfaceEnergy,
|
||||
getInterfaceEnergy(microstructure,np.roll(np.roll(np.roll(
|
||||
microstructure,i,axis=0), j,axis=1), k,axis=2)))
|
||||
getInterfaceEnergy(material,np.roll(np.roll(np.roll(
|
||||
material,i,axis=0), j,axis=1), k,axis=2)))
|
||||
|
||||
# periodically extend interfacial energy array by half a grid size in positive and negative directions
|
||||
periodic_interfaceEnergy = np.tile(interfaceEnergy,(3,3,3))[grid[0]//2:-grid[0]//2,
|
||||
|
@ -143,33 +143,35 @@ for name in filenames:
|
|||
return_distances = False,
|
||||
return_indices = True) # want index of closest bulk grain
|
||||
|
||||
periodic_microstructure = np.tile(microstructure,(3,3,3))[grid[0]//2:-grid[0]//2,
|
||||
periodic_material = np.tile(material,(3,3,3))[grid[0]//2:-grid[0]//2,
|
||||
grid[1]//2:-grid[1]//2,
|
||||
grid[2]//2:-grid[2]//2] # periodically extend the microstructure
|
||||
grid[2]//2:-grid[2]//2] # periodically extend the geometry
|
||||
|
||||
microstructure = periodic_microstructure[index[0],
|
||||
material = periodic_material[index[0],
|
||||
index[1],
|
||||
index[2]].reshape(2*grid)[grid[0]//2:-grid[0]//2,
|
||||
grid[1]//2:-grid[1]//2,
|
||||
grid[2]//2:-grid[2]//2] # extent grains into interface region
|
||||
|
||||
# replace immutable microstructures with closest mutable ones
|
||||
index = ndimage.morphology.distance_transform_edt(np.in1d(microstructure,options.immutable).reshape(grid),
|
||||
# replace immutable materials with closest mutable ones
|
||||
index = ndimage.morphology.distance_transform_edt(np.in1d(material,options.immutable).reshape(grid),
|
||||
return_distances = False,
|
||||
return_indices = True)
|
||||
microstructure = microstructure[index[0],
|
||||
material = material[index[0],
|
||||
index[1],
|
||||
index[2]]
|
||||
|
||||
immutable = np.zeros(microstructure.shape, dtype=np.bool)
|
||||
# find locations where immutable microstructures have been in original structure
|
||||
immutable = np.zeros(material.shape, dtype=np.bool)
|
||||
# find locations where immutable materials have been in original structure
|
||||
for micro in options.immutable:
|
||||
immutable += microstructure_original == micro
|
||||
immutable += material_original == micro
|
||||
|
||||
# undo any changes involving immutable microstructures
|
||||
microstructure = np.where(immutable, microstructure_original,microstructure)
|
||||
# undo any changes involving immutable materials
|
||||
material = np.where(immutable, material_original,material)
|
||||
|
||||
geom = geom.duplicate(microstructure[0:grid_original[0],0:grid_original[1],0:grid_original[2]])
|
||||
geom.add_comments(scriptID + ' ' + ' '.join(sys.argv[1:]))
|
||||
|
||||
geom.save_ASCII(sys.stdout if name is None else name,compress=False)
|
||||
damask.Geom(material = material[0:grid_original[0],0:grid_original[1],0:grid_original[2]],
|
||||
size = geom.size,
|
||||
origin = geom.origin,
|
||||
comments = geom.comments + [scriptID + ' ' + ' '.join(sys.argv[1:])],
|
||||
)\
|
||||
.save_ASCII(sys.stdout if name is None else name,compress=False)
|
||||
|
|
|
@ -1,349 +0,0 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import os
|
||||
import sys
|
||||
import math
|
||||
import random
|
||||
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])
|
||||
|
||||
|
||||
# --- helper functions ---
|
||||
def integerFactorization(i):
|
||||
|
||||
j = int(math.floor(math.sqrt(float(i))))
|
||||
while j>1 and int(i)%j != 0:
|
||||
j -= 1
|
||||
return j
|
||||
|
||||
def binAsBins(bin,intervals):
|
||||
"""Explode compound bin into 3D bins list."""
|
||||
bins = [0]*3
|
||||
bins[0] = (bin//(intervals[1] * intervals[2])) % intervals[0]
|
||||
bins[1] = (bin//intervals[2]) % intervals[1]
|
||||
bins[2] = bin % intervals[2]
|
||||
return bins
|
||||
|
||||
def binsAsBin(bins,intervals):
|
||||
"""Implode 3D bins into compound bin."""
|
||||
return (bins[0]*intervals[1] + bins[1])*intervals[2] + bins[2]
|
||||
|
||||
def EulersAsBins(Eulers,intervals,deltas,center):
|
||||
"""Return list of Eulers translated into 3D bins list."""
|
||||
return [int((euler+(0.5-center)*delta)//delta)%interval \
|
||||
for euler,delta,interval in zip(Eulers,deltas,intervals) \
|
||||
]
|
||||
|
||||
def binAsEulers(bin,intervals,deltas,center):
|
||||
"""Compound bin number translated into list of Eulers."""
|
||||
Eulers = [0.0]*3
|
||||
Eulers[2] = (bin%intervals[2] + center)*deltas[2]
|
||||
Eulers[1] = (bin//intervals[2]%intervals[1] + center)*deltas[1]
|
||||
Eulers[0] = (bin//(intervals[2]*intervals[1]) + center)*deltas[0]
|
||||
return Eulers
|
||||
|
||||
def directInvRepetitions(probability,scale):
|
||||
"""Calculate number of samples drawn by direct inversion."""
|
||||
nDirectInv = 0
|
||||
for bin in range(len(probability)): # loop over bins
|
||||
nDirectInv += int(round(probability[bin]*scale)) # calc repetition
|
||||
return nDirectInv
|
||||
|
||||
|
||||
# ---------------------- sampling methods -----------------------------------------------------------------------
|
||||
|
||||
# ----- efficient algorithm ---------
|
||||
def directInversion (ODF,nSamples):
|
||||
"""ODF contains 'dV_V' (normalized to 1), 'center', 'intervals', 'limits' (in radians)."""
|
||||
nOptSamples = max(ODF['nNonZero'],nSamples) # random subsampling if too little samples requested
|
||||
|
||||
nInvSamples = 0
|
||||
repetition = [None]*ODF['nBins']
|
||||
|
||||
scaleLower = 0.0
|
||||
nInvSamplesLower = 0
|
||||
scaleUpper = float(nOptSamples)
|
||||
incFactor = 1.0
|
||||
nIter = 0
|
||||
nInvSamplesUpper = directInvRepetitions(ODF['dV_V'],scaleUpper)
|
||||
while (\
|
||||
(scaleUpper-scaleLower > scaleUpper*1e-15 or nInvSamplesUpper < nOptSamples) and \
|
||||
nInvSamplesUpper != nOptSamples \
|
||||
): # closer match required?
|
||||
if nInvSamplesUpper < nOptSamples:
|
||||
scaleLower,scaleUpper = scaleUpper,scaleUpper+incFactor*(scaleUpper-scaleLower)/2.0
|
||||
incFactor *= 2.0
|
||||
nInvSamplesLower,nInvSamplesUpper = nInvSamplesUpper,directInvRepetitions(ODF['dV_V'],scaleUpper)
|
||||
else:
|
||||
scaleUpper = (scaleLower+scaleUpper)/2.0
|
||||
incFactor = 1.0
|
||||
nInvSamplesUpper = directInvRepetitions(ODF['dV_V'],scaleUpper)
|
||||
nIter += 1
|
||||
damask.util.croak('%i:(%12.11f,%12.11f) %i <= %i <= %i'%(nIter,scaleLower,scaleUpper,
|
||||
nInvSamplesLower,nOptSamples,nInvSamplesUpper))
|
||||
nInvSamples = nInvSamplesUpper
|
||||
scale = scaleUpper
|
||||
damask.util.croak('created set of %i samples (%12.11f) with scaling %12.11f delivering %i'%(nInvSamples,
|
||||
float(nInvSamples)/nOptSamples-1.0,
|
||||
scale,nSamples))
|
||||
repetition = [None]*ODF['nBins'] # preallocate and clear
|
||||
|
||||
for bin in range(ODF['nBins']): # loop over bins
|
||||
repetition[bin] = int(round(ODF['dV_V'][bin]*scale)) # calc repetition
|
||||
|
||||
# build set
|
||||
set = [None]*nInvSamples
|
||||
i = 0
|
||||
for bin in range(ODF['nBins']):
|
||||
set[i:i+repetition[bin]] = [bin]*repetition[bin] # fill set with bin, i.e. orientation
|
||||
i += repetition[bin] # advance set counter
|
||||
|
||||
orientations = np.zeros((nSamples,3),'f')
|
||||
reconstructedODF = np.zeros(ODF['nBins'],'f')
|
||||
unitInc = 1.0/nSamples
|
||||
for j in range(nSamples):
|
||||
if (j == nInvSamples-1): ex = j
|
||||
else: ex = int(round(random.uniform(j+0.5,nInvSamples-0.5)))
|
||||
bin = set[ex]
|
||||
Eulers = binAsEulers(bin,ODF['interval'],ODF['delta'],ODF['center'])
|
||||
orientations[j] = np.degrees(Eulers)
|
||||
reconstructedODF[bin] += unitInc
|
||||
set[ex] = set[j] # exchange orientations
|
||||
|
||||
return orientations, reconstructedODF
|
||||
|
||||
|
||||
# ----- trial and error algorithms ---------
|
||||
|
||||
def MonteCarloEulers (ODF,nSamples):
|
||||
"""ODF contains 'dV_V' (normalized to 1), 'center', 'intervals', 'limits' (in radians)."""
|
||||
countMC = 0
|
||||
maxdV_V = max(ODF['dV_V'])
|
||||
orientations = np.zeros((nSamples,3),'f')
|
||||
reconstructedODF = np.zeros(ODF['nBins'],'f')
|
||||
unitInc = 1.0/nSamples
|
||||
|
||||
for j in range(nSamples):
|
||||
MC = maxdV_V*2.0
|
||||
bin = 0
|
||||
while MC > ODF['dV_V'][bin]:
|
||||
countMC += 1
|
||||
MC = maxdV_V*random.random()
|
||||
Eulers = [limit*random.random() for limit in ODF['limit']]
|
||||
bins = EulersAsBins(Eulers,ODF['interval'],ODF['delta'],ODF['center'])
|
||||
bin = binsAsBin(bins,ODF['interval'])
|
||||
orientations[j] = np.degrees(Eulers)
|
||||
reconstructedODF[bin] += unitInc
|
||||
|
||||
return orientations, reconstructedODF, countMC
|
||||
|
||||
|
||||
def MonteCarloBins (ODF,nSamples):
|
||||
"""ODF contains 'dV_V' (normalized to 1), 'center', 'intervals', 'limits' (in radians)."""
|
||||
countMC = 0
|
||||
maxdV_V = max(ODF['dV_V'])
|
||||
orientations = np.zeros((nSamples,3),'f')
|
||||
reconstructedODF = np.zeros(ODF['nBins'],'f')
|
||||
unitInc = 1.0/nSamples
|
||||
|
||||
for j in range(nSamples):
|
||||
MC = maxdV_V*2.0
|
||||
bin = 0
|
||||
while MC > ODF['dV_V'][bin]:
|
||||
countMC += 1
|
||||
MC = maxdV_V*random.random()
|
||||
bin = int(ODF['nBins'] * random.random())
|
||||
Eulers = binAsEulers(bin,ODF['interval'],ODF['delta'],ODF['center'])
|
||||
orientations[j] = np.degrees(Eulers)
|
||||
reconstructedODF[bin] += unitInc
|
||||
|
||||
return orientations, reconstructedODF
|
||||
|
||||
|
||||
def TothVanHoutteSTAT (ODF,nSamples):
|
||||
"""ODF contains 'dV_V' (normalized to 1), 'center', 'intervals', 'limits' (in radians)."""
|
||||
orientations = np.zeros((nSamples,3),'f')
|
||||
reconstructedODF = np.zeros(ODF['nBins'],'f')
|
||||
unitInc = 1.0/nSamples
|
||||
|
||||
selectors = [random.random() for i in range(nSamples)]
|
||||
selectors.sort()
|
||||
indexSelector = 0
|
||||
|
||||
cumdV_V = 0.0
|
||||
countSamples = 0
|
||||
|
||||
for bin in range(ODF['nBins']) :
|
||||
cumdV_V += ODF['dV_V'][bin]
|
||||
while indexSelector < nSamples and selectors[indexSelector] < cumdV_V:
|
||||
Eulers = binAsEulers(bin,ODF['interval'],ODF['delta'],ODF['center'])
|
||||
orientations[countSamples] = np.degrees(Eulers)
|
||||
reconstructedODF[bin] += unitInc
|
||||
countSamples += 1
|
||||
indexSelector += 1
|
||||
|
||||
damask.util.croak('created set of %i when asked to deliver %i'%(countSamples,nSamples))
|
||||
|
||||
return orientations, reconstructedODF
|
||||
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# MAIN
|
||||
# --------------------------------------------------------------------
|
||||
parser = OptionParser(option_class=damask.extendableOption, usage='%prog options [file[s]]', description ="""
|
||||
Transform linear binned ODF data into given number of orientations.
|
||||
IA: integral approximation, STAT: Van Houtte, MC: Monte Carlo
|
||||
|
||||
""", version = scriptID)
|
||||
|
||||
algorithms = ['IA', 'STAT','MC']
|
||||
parser.add_option('-n', '--nsamples',
|
||||
dest = 'number',
|
||||
type = 'int', metavar = 'int',
|
||||
help = 'number of orientations to be generated [%default]')
|
||||
parser.add_option('-a','--algorithm',
|
||||
dest = 'algorithm',
|
||||
choices = algorithms, metavar = 'string',
|
||||
help = 'sampling algorithm {%s} [IA]'%(', '.join(algorithms)))
|
||||
parser.add_option('-p','--phase',
|
||||
dest = 'phase',
|
||||
type = 'int', metavar = 'int',
|
||||
help = 'phase index to be used [%default]')
|
||||
parser.add_option('-r', '--rnd',
|
||||
dest = 'randomSeed',
|
||||
type = 'int', metavar = 'int', \
|
||||
help = 'seed of random number generator [%default]')
|
||||
parser.set_defaults(randomSeed = None,
|
||||
number = 500,
|
||||
algorithm = 'IA',
|
||||
phase = 1,
|
||||
ang = True,
|
||||
)
|
||||
|
||||
(options,filenames) = parser.parse_args()
|
||||
if filenames == []: filenames = [None]
|
||||
|
||||
for name in filenames:
|
||||
damask.util.report(scriptName,name)
|
||||
|
||||
table = damask.Table.load(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)
|
||||
|
||||
# --------------- figure out limits (left/right), delta, and interval -----------------------------
|
||||
ODF = {}
|
||||
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(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 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 ------------------------------------------------------
|
||||
sumdV_V = 0.0
|
||||
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,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]
|
||||
ODF['nNonZero'] += 1
|
||||
|
||||
for b in range(ODF['nBins']):
|
||||
ODF['dV_V'][b] /= sumdV_V # normalize dV/V
|
||||
|
||||
damask.util.croak(['non-zero fraction: %12.11f (%i/%i)'%(float(ODF['nNonZero'])/ODF['nBins'],
|
||||
ODF['nNonZero'],
|
||||
ODF['nBins']),
|
||||
'Volume integral of ODF: %12.11f\n'%sumdV_V,
|
||||
'Reference Integral: %12.11f\n'%(ODF['limit'][0]*ODF['limit'][2]*(1-math.cos(ODF['limit'][1]))),
|
||||
])
|
||||
|
||||
Functions = {'IA': 'directInversion', 'STAT': 'TothVanHoutteSTAT', 'MC': 'MonteCarloBins'}
|
||||
method = Functions[options.algorithm]
|
||||
|
||||
Orientations, ReconstructedODF = (globals()[method])(ODF,options.number)
|
||||
|
||||
# calculate accuracy of sample
|
||||
squaredDiff = {'orig':0.0,method:0.0}
|
||||
squaredRelDiff = {'orig':0.0,method:0.0}
|
||||
mutualProd = {'orig':0.0,method:0.0}
|
||||
indivSum = {'orig':0.0,method:0.0}
|
||||
indivSquaredSum = {'orig':0.0,method:0.0}
|
||||
|
||||
for bin in range(ODF['nBins']):
|
||||
squaredDiff[method] += (ODF['dV_V'][bin] - ReconstructedODF[bin])**2
|
||||
if ODF['dV_V'][bin] > 0.0:
|
||||
squaredRelDiff[method] += (ODF['dV_V'][bin] - ReconstructedODF[bin])**2/ODF['dV_V'][bin]**2
|
||||
mutualProd[method] += ODF['dV_V'][bin]*ReconstructedODF[bin]
|
||||
indivSum[method] += ReconstructedODF[bin]
|
||||
indivSquaredSum[method] += ReconstructedODF[bin]**2
|
||||
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(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'\
|
||||
%((ODF['nNonZero']*mutualProd[method]-indivSum['orig']*indivSum[method])/\
|
||||
(ODF['nNonZero']*indivSquaredSum['orig']-indivSum['orig']**2)),
|
||||
'nNonZero correlation confidence:\t %12.11f'\
|
||||
%((mutualProd[method]-indivSum['orig']*indivSum[method]/ODF['nNonZero'])/\
|
||||
(ODF['nNonZero']*math.sqrt((indivSquaredSum['orig']/ODF['nNonZero']-(indivSum['orig']/ODF['nNonZero'])**2)*\
|
||||
(indivSquaredSum[method]/ODF['nNonZero']-(indivSum[method]/ODF['nNonZero'])**2)))),
|
||||
])
|
||||
|
||||
if method == 'IA' and options.number < ODF['nNonZero']:
|
||||
strOpt = '(%i)'%ODF['nNonZero']
|
||||
|
||||
formatwidth = 1+int(math.log10(options.number))
|
||||
|
||||
materialConfig = [
|
||||
'#' + scriptID + ' ' + ' '.join(sys.argv[1:]),
|
||||
'# random seed %i'%randomSeed,
|
||||
'#-------------------#',
|
||||
'<microstructure>',
|
||||
'#-------------------#',
|
||||
]
|
||||
|
||||
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)),
|
||||
]
|
||||
|
||||
materialConfig += [
|
||||
'#-------------------#',
|
||||
'<texture>',
|
||||
'#-------------------#',
|
||||
]
|
||||
|
||||
for ID in range(options.number):
|
||||
eulers = Orientations[ID]
|
||||
|
||||
materialConfig += ['[Grain%s]'%(str(ID+1).zfill(formatwidth)),
|
||||
'(gauss) phi1 {} Phi {} phi2 {} scatter 0.0 fraction 1.0'.format(*eulers),
|
||||
]
|
||||
|
||||
#--- output finalization --------------------------------------------------------------------------
|
||||
|
||||
with (open(os.path.splitext(name)[0]+'_'+method+'_'+str(options.number)+'_material.config','w')) as outfile:
|
||||
outfile.write('\n'.join(materialConfig)+'\n')
|
|
@ -100,7 +100,7 @@ def mesh(r,d):
|
|||
|
||||
|
||||
#-------------------------------------------------------------------------------------------------
|
||||
def material():
|
||||
def materials():
|
||||
return [\
|
||||
"*new_mater standard",
|
||||
"*mater_option general:state:solid",
|
||||
|
@ -130,10 +130,10 @@ def geometry():
|
|||
|
||||
|
||||
#-------------------------------------------------------------------------------------------------
|
||||
def initial_conditions(microstructures):
|
||||
def initial_conditions(material):
|
||||
elements = []
|
||||
element = 0
|
||||
for id in microstructures:
|
||||
for id in material:
|
||||
element += 1
|
||||
if len(elements) < id:
|
||||
for i in range(id-len(elements)):
|
||||
|
@ -153,7 +153,7 @@ def initial_conditions(microstructures):
|
|||
for grain,elementList in enumerate(elements):
|
||||
cmds.append([\
|
||||
"*new_icond",
|
||||
"*icond_name microstructure_%i"%(grain+1),
|
||||
"*icond_name material_%i"%(grain+1),
|
||||
"*icond_type state_variable",
|
||||
"*icond_param_value state_var_id 2",
|
||||
"*icond_dof_value var %i"%(grain+1),
|
||||
|
@ -197,14 +197,14 @@ for name in filenames:
|
|||
damask.util.report(scriptName,name)
|
||||
|
||||
geom = damask.Geom.load_ASCII(StringIO(''.join(sys.stdin.read())) if name is None else name)
|
||||
microstructure = geom.get_microstructure().flatten(order='F')
|
||||
material = geom.material.flatten(order='F')
|
||||
|
||||
cmds = [\
|
||||
init(),
|
||||
mesh(geom.grid,geom.size),
|
||||
material(),
|
||||
materials(),
|
||||
geometry(),
|
||||
initial_conditions(microstructure),
|
||||
initial_conditions(material),
|
||||
'*identify_sets',
|
||||
'*show_model',
|
||||
'*redraw',
|
||||
|
|
|
@ -30,7 +30,7 @@ class myThread (threading.Thread):
|
|||
def run(self):
|
||||
global bestSeedsUpdate
|
||||
global bestSeedsVFile
|
||||
global nMicrostructures
|
||||
global nMaterials
|
||||
global delta
|
||||
global points
|
||||
global target
|
||||
|
@ -48,7 +48,6 @@ class myThread (threading.Thread):
|
|||
|
||||
myBestSeedsVFile = StringIO() # store local copy of best seeds file
|
||||
perturbedSeedsVFile = StringIO() # perturbed best seeds file
|
||||
perturbedGeomVFile = StringIO() # tessellated geom file
|
||||
|
||||
#--- still not matching desired bin class ----------------------------------------------------------
|
||||
while bestMatch < options.threshold:
|
||||
|
@ -70,7 +69,7 @@ class myThread (threading.Thread):
|
|||
selectedMs = []
|
||||
direction = []
|
||||
for i in range(NmoveGrains):
|
||||
selectedMs.append(random.randrange(1,nMicrostructures))
|
||||
selectedMs.append(random.randrange(1,nMaterials))
|
||||
|
||||
direction.append((np.random.random()-0.5)*delta)
|
||||
|
||||
|
@ -92,20 +91,15 @@ class myThread (threading.Thread):
|
|||
perturbedSeedsTable.set('pos',coords).save(perturbedSeedsVFile,legacy=True)
|
||||
|
||||
#--- do tesselation with perturbed seed file ------------------------------------------------------
|
||||
perturbedGeomVFile.close()
|
||||
perturbedGeomVFile = StringIO()
|
||||
perturbedSeedsVFile.seek(0)
|
||||
perturbedGeomVFile.write(damask.util.execute('geom_fromVoronoiTessellation '+
|
||||
' -g '+' '.join(list(map(str, options.grid))),streamIn=perturbedSeedsVFile)[0])
|
||||
perturbedGeomVFile.seek(0)
|
||||
perturbedGeom = damask.Geom.from_Voronoi_tessellation(options.grid,np.ones(3),coords)
|
||||
|
||||
|
||||
#--- evaluate current seeds file ------------------------------------------------------------------
|
||||
perturbedGeom = damask.Geom.load_ASCII(perturbedGeomVFile)
|
||||
myNmicrostructures = len(np.unique(perturbedGeom.microstructure))
|
||||
currentData=np.bincount(perturbedGeom.microstructure.ravel())[1:]/points
|
||||
myNmaterials = len(np.unique(perturbedGeom.material))
|
||||
currentData = np.bincount(perturbedGeom.material.ravel())[1:]/points
|
||||
currentError=[]
|
||||
currentHist=[]
|
||||
for i in range(nMicrostructures): # calculate the deviation in all bins per histogram
|
||||
for i in range(nMaterials): # calculate the deviation in all bins per histogram
|
||||
currentHist.append(np.histogram(currentData,bins=target[i]['bins'])[0])
|
||||
currentError.append(np.sqrt(np.square(np.array(target[i]['histogram']-currentHist[i])).sum()))
|
||||
|
||||
|
@ -117,12 +111,12 @@ class myThread (threading.Thread):
|
|||
bestMatch = match
|
||||
#--- count bin classes with no mismatch ----------------------------------------------------------------------
|
||||
myMatch=0
|
||||
for i in range(nMicrostructures):
|
||||
for i in range(nMaterials):
|
||||
if currentError[i] > 0.0: break
|
||||
myMatch = i+1
|
||||
|
||||
if myNmicrostructures == nMicrostructures:
|
||||
for i in range(min(nMicrostructures,myMatch+options.bins)):
|
||||
if myNmaterials == nMaterials:
|
||||
for i in range(min(nMaterials,myMatch+options.bins)):
|
||||
if currentError[i] > target[i]['error']: # worse fitting, next try
|
||||
randReset = True
|
||||
break
|
||||
|
@ -141,25 +135,25 @@ class myThread (threading.Thread):
|
|||
for line in perturbedSeedsVFile:
|
||||
currentSeedsFile.write(line)
|
||||
bestSeedsVFile.write(line)
|
||||
for j in range(nMicrostructures): # save new errors for all bins
|
||||
for j in range(nMaterials): # save new errors for all bins
|
||||
target[j]['error'] = currentError[j]
|
||||
if myMatch > match: # one or more new bins have no deviation
|
||||
damask.util.croak( 'Stage {:d} cleared'.format(myMatch))
|
||||
match=myMatch
|
||||
sys.stdout.flush()
|
||||
break
|
||||
if i == min(nMicrostructures,myMatch+options.bins)-1: # same quality as before: take it to keep on moving
|
||||
if i == min(nMaterials,myMatch+options.bins)-1: # same quality as before: take it to keep on moving
|
||||
bestSeedsUpdate = time.time()
|
||||
perturbedSeedsVFile.seek(0)
|
||||
bestSeedsVFile.close()
|
||||
bestSeedsVFile = StringIO()
|
||||
bestSeedsVFile.writelines(perturbedSeedsVFile.readlines())
|
||||
for j in range(nMicrostructures):
|
||||
for j in range(nMaterials):
|
||||
target[j]['error'] = currentError[j]
|
||||
randReset = True
|
||||
else: #--- not all grains are tessellated
|
||||
damask.util.croak('Thread {:d}: Microstructure mismatch ({:d} microstructures mapped)'\
|
||||
.format(self.threadID,myNmicrostructures))
|
||||
damask.util.croak('Thread {:d}: Material mismatch ({:d} material indices mapped)'\
|
||||
.format(self.threadID,myNmaterials))
|
||||
randReset = True
|
||||
|
||||
|
||||
|
@ -217,38 +211,31 @@ points = np.array(options.grid).prod().astype('float')
|
|||
|
||||
# ----------- calculate target distribution and bin edges
|
||||
targetGeom = damask.Geom.load_ASCII(os.path.splitext(os.path.basename(options.target))[0]+'.geom')
|
||||
nMicrostructures = len(np.unique(targetGeom.microstructure))
|
||||
targetVolFrac = np.bincount(targetGeom.microstructure.flatten())/targetGeom.grid.prod().astype(np.float)
|
||||
nMaterials = len(np.unique(targetGeom.material))
|
||||
targetVolFrac = np.bincount(targetGeom.material.flatten())/targetGeom.grid.prod().astype(np.float)
|
||||
target = []
|
||||
for i in range(1,nMicrostructures+1):
|
||||
for i in range(1,nMaterials+1):
|
||||
targetHist,targetBins = np.histogram(targetVolFrac,bins=i) #bin boundaries
|
||||
target.append({'histogram':targetHist,'bins':targetBins})
|
||||
|
||||
# ----------- create initial seed file or open existing one
|
||||
bestSeedsVFile = StringIO()
|
||||
if os.path.isfile(os.path.splitext(options.seedFile)[0]+'.seeds'):
|
||||
with open(os.path.splitext(options.seedFile)[0]+'.seeds') as initialSeedFile:
|
||||
for line in initialSeedFile: bestSeedsVFile.write(line)
|
||||
initial_seeds = damask.Table.load(os.path.splitext(options.seedFile)[0]+'.seeds').get('pos')
|
||||
else:
|
||||
bestSeedsVFile.write(damask.util.execute('seeds_fromRandom'+\
|
||||
' -g '+' '.join(list(map(str, options.grid)))+\
|
||||
' -r {:d}'.format(options.randomSeed)+\
|
||||
' -N '+str(nMicrostructures))[0])
|
||||
initial_seeds = damask.seeds.from_random(np.ones(3),nMaterials,options.grid,options.randomSeed)
|
||||
|
||||
bestSeedsUpdate = time.time()
|
||||
|
||||
# ----------- tessellate initial seed file to get and evaluate geom file
|
||||
bestSeedsVFile.seek(0)
|
||||
initialGeomVFile = StringIO()
|
||||
initialGeomVFile.write(damask.util.execute('geom_fromVoronoiTessellation '+
|
||||
' -g '+' '.join(list(map(str, options.grid))),bestSeedsVFile)[0])
|
||||
initialGeomVFile.seek(0)
|
||||
initialGeom = damask.Geom.load_ASCII(initialGeomVFile)
|
||||
initialGeom = damask.Geom.from_Voronoi_tessellation(options.grid,np.ones(3),initial_seeds)
|
||||
|
||||
if len(np.unique(targetGeom.microstructure)) != nMicrostructures:
|
||||
damask.util.croak('error. Microstructure count mismatch')
|
||||
if len(np.unique(targetGeom.material)) != nMaterials:
|
||||
damask.util.croak('error. Material count mismatch')
|
||||
|
||||
initialData = np.bincount(initialGeom.microstructure.flatten())/points
|
||||
for i in range(nMicrostructures):
|
||||
initialData = np.bincount(initialGeom.material.flatten())/points
|
||||
for i in range(nMaterials):
|
||||
initialHist = np.histogram(initialData,bins=target[i]['bins'])[0]
|
||||
target[i]['error']=np.sqrt(np.square(np.array(target[i]['histogram']-initialHist)).sum())
|
||||
|
||||
|
@ -257,19 +244,18 @@ if target[0]['error'] > 0.0:
|
|||
target[0]['error'] *=((target[0]['bins'][0]-np.min(initialData))**2.0+
|
||||
(target[0]['bins'][1]-np.max(initialData))**2.0)**0.5
|
||||
match=0
|
||||
for i in range(nMicrostructures):
|
||||
for i in range(nMaterials):
|
||||
if target[i]['error'] > 0.0: break
|
||||
match = i+1
|
||||
|
||||
|
||||
if options.maxseeds < 1:
|
||||
maxSeeds = len(np.unique(initialGeom.microstructure))
|
||||
maxSeeds = len(np.unique(initialGeom.material))
|
||||
else:
|
||||
maxSeeds = options.maxseeds
|
||||
|
||||
if match >0: damask.util.croak('Stage {:d} cleared'.format(match))
|
||||
sys.stdout.flush()
|
||||
initialGeomVFile.close()
|
||||
|
||||
# start mulithreaded monte carlo simulation
|
||||
threads = []
|
||||
|
|
|
@ -1,68 +0,0 @@
|
|||
#!/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 [file[s]]', description = """
|
||||
Create seed file taking microstructure indices from given geom file.
|
||||
Indices can be black-listed or white-listed.
|
||||
|
||||
""", version = scriptID)
|
||||
|
||||
parser.add_option('-w',
|
||||
'--white',
|
||||
action = 'extend', metavar = '<int LIST>',
|
||||
dest = 'whitelist',
|
||||
help = 'whitelist of grain IDs')
|
||||
parser.add_option('-b',
|
||||
'--black',
|
||||
action = 'extend', metavar = '<int LIST>',
|
||||
dest = 'blacklist',
|
||||
help = 'blacklist of grain IDs')
|
||||
|
||||
parser.set_defaults(whitelist = [],
|
||||
blacklist = [],
|
||||
)
|
||||
|
||||
(options,filenames) = parser.parse_args()
|
||||
if filenames == []: filenames = [None]
|
||||
|
||||
options.whitelist = [int(i) for i in options.whitelist]
|
||||
options.blacklist = [int(i) for i in options.blacklist]
|
||||
|
||||
for name in filenames:
|
||||
damask.util.report(scriptName,name)
|
||||
|
||||
geom = damask.Geom.load_ASCII(StringIO(''.join(sys.stdin.read())) if name is None else name)
|
||||
microstructure = geom.get_microstructure().reshape((-1,1),order='F')
|
||||
|
||||
mask = np.logical_and(np.in1d(microstructure,options.whitelist,invert=False) if options.whitelist else \
|
||||
np.full(geom.grid.prod(),True,dtype=bool),
|
||||
np.in1d(microstructure,options.blacklist,invert=True) if options.blacklist else \
|
||||
np.full(geom.grid.prod(),True,dtype=bool))
|
||||
|
||||
seeds = damask.grid_filters.cell_coord0(geom.grid,geom.size).reshape(-1,3,order='F')
|
||||
|
||||
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)]
|
||||
|
||||
damask.Table(seeds[mask],{'pos':(3,)},comments)\
|
||||
.add('microstructure',microstructure[mask].astype(int))\
|
||||
.save(sys.stdout if name is None else os.path.splitext(name)[0]+'.seeds',legacy=True)
|
|
@ -76,7 +76,7 @@ for name in filenames:
|
|||
g[2] = k + offset[2]
|
||||
g %= geom.grid
|
||||
seeds[n,0:3] = (g+0.5)/geom.grid # normalize coordinates to box
|
||||
seeds[n, 3] = geom.microstructure[g[0],g[1],g[2]]
|
||||
seeds[n, 3] = geom.material[g[0],g[1],g[2]]
|
||||
if options.x: g[0] += 1
|
||||
if options.y: g[1] += 1
|
||||
n += 1
|
||||
|
@ -88,9 +88,9 @@ for name in filenames:
|
|||
'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 = damask.Table(seeds,{'pos':(3,),'material':(1,)},comments)
|
||||
table.set('material',table.get('material').astype(np.int))\
|
||||
.save(sys.stdout if name is None else \
|
||||
os.path.splitext(name)[0]+f'_poked_{options.N}.seeds',legacy=True)
|
||||
|
|
|
@ -1,165 +0,0 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
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])
|
||||
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# MAIN
|
||||
# --------------------------------------------------------------------
|
||||
|
||||
parser = OptionParser(option_class=damask.extendableOption, usage='%prog options', description = """
|
||||
Distribute given number of points randomly within rectangular cuboid.
|
||||
Reports positions with random crystal orientations in seeds file format to STDOUT.
|
||||
|
||||
""", version = scriptID)
|
||||
|
||||
parser.add_option('-N',
|
||||
dest = 'N',
|
||||
type = 'int', metavar = 'int',
|
||||
help = 'number of seed points [%default]')
|
||||
parser.add_option('-s',
|
||||
'--size',
|
||||
dest = 'size',
|
||||
type = 'float', nargs = 3, metavar = 'float float float',
|
||||
help='size x,y,z of unit cube to fill %default')
|
||||
parser.add_option('-g',
|
||||
'--grid',
|
||||
dest = 'grid',
|
||||
type = 'int', nargs = 3, metavar = 'int int int',
|
||||
help='min a,b,c grid of hexahedral box %default')
|
||||
parser.add_option('-m',
|
||||
'--microstructure',
|
||||
dest = 'microstructure',
|
||||
type = 'int', metavar = 'int',
|
||||
help = 'first microstructure index [%default]')
|
||||
parser.add_option('-r',
|
||||
'--rnd',
|
||||
dest = 'randomSeed', type = 'int', metavar = 'int',
|
||||
help = 'seed of random number generator [%default]')
|
||||
|
||||
group = OptionGroup(parser, "Laguerre Tessellation",
|
||||
"Parameters determining shape of weight distribution of seed points"
|
||||
)
|
||||
group.add_option( '-w',
|
||||
'--weights',
|
||||
action = 'store_true',
|
||||
dest = 'weights',
|
||||
help = 'assign random weights to seed points for Laguerre tessellation [%default]')
|
||||
group.add_option( '--max',
|
||||
dest = 'max',
|
||||
type = 'float', metavar = 'float',
|
||||
help = 'max of uniform distribution for weights [%default]')
|
||||
group.add_option( '--mean',
|
||||
dest = 'mean',
|
||||
type = 'float', metavar = 'float',
|
||||
help = 'mean of normal distribution for weights [%default]')
|
||||
group.add_option( '--sigma',
|
||||
dest = 'sigma',
|
||||
type = 'float', metavar = 'float',
|
||||
help='standard deviation of normal distribution for weights [%default]')
|
||||
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( '--selective',
|
||||
action = 'store_true',
|
||||
dest = 'selective',
|
||||
help = 'selective picking of seed points from random seed points')
|
||||
group.add_option( '--distance',
|
||||
dest = 'distance',
|
||||
type = 'float', metavar = 'float',
|
||||
help = 'minimum distance to next neighbor [%default]')
|
||||
group.add_option( '--numCandidates',
|
||||
dest = 'numCandidates',
|
||||
type = 'int', metavar = 'int',
|
||||
help = 'size of point group to select best distance from [%default]')
|
||||
parser.add_option_group(group)
|
||||
|
||||
parser.set_defaults(randomSeed = None,
|
||||
grid = (16,16,16),
|
||||
size = (1.0,1.0,1.0),
|
||||
N = 20,
|
||||
weights = False,
|
||||
max = 0.0,
|
||||
mean = 0.2,
|
||||
sigma = 0.05,
|
||||
microstructure = 1,
|
||||
selective = False,
|
||||
distance = 0.2,
|
||||
numCandidates = 10,
|
||||
)
|
||||
|
||||
(options,filenames) = parser.parse_args()
|
||||
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:
|
||||
damask.util.report(scriptName,name)
|
||||
|
||||
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)))
|
||||
|
||||
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
|
||||
|
||||
|
||||
if not options.selective:
|
||||
coords = damask.grid_filters.cell_coord0(grid,size).reshape(-1,3,order='F')
|
||||
seeds = coords[np.random.choice(np.prod(grid), options.N, replace=False)] \
|
||||
+ np.broadcast_to(size/grid,(options.N,3))*(np.random.rand(options.N,3)*.5-.25) # wobble without leaving grid
|
||||
else:
|
||||
seeds = np.empty((options.N,3))
|
||||
seeds[0] = np.random.random(3) * size
|
||||
|
||||
i = 1
|
||||
progress = damask.util._ProgressBar(options.N,'',50)
|
||||
while i < options.N:
|
||||
candidates = np.random.rand(options.numCandidates,3)*np.broadcast_to(size,(options.numCandidates,3))
|
||||
tree = spatial.cKDTree(seeds[:i])
|
||||
distances, dev_null = tree.query(candidates)
|
||||
best = distances.argmax()
|
||||
if distances[best] > options.distance: # require minimum separation
|
||||
seeds[i] = candidates[best] # maximum separation to existing point cloud
|
||||
i += 1
|
||||
progress.update(i)
|
||||
|
||||
|
||||
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)\
|
||||
.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)
|
||||
table = table.add('weight',weights)
|
||||
|
||||
table.save(sys.stdout if name is None else name,legacy=True)
|
|
@ -20,6 +20,12 @@ from ._result import Result # noqa
|
|||
from ._geom import Geom # noqa
|
||||
from ._material import Material # noqa
|
||||
from . import solver # noqa
|
||||
from . import util # noqa
|
||||
from . import seeds # noqa
|
||||
from . import grid_filters # noqa
|
||||
from . import mechanics # noqa
|
||||
|
||||
|
||||
|
||||
# deprecated
|
||||
Environment = _
|
||||
|
|
|
@ -147,11 +147,11 @@ class Colormap(mpl.colors.ListedColormap):
|
|||
|
||||
References
|
||||
----------
|
||||
.. [1] DAMASK colormap theory
|
||||
[1] DAMASK colormap theory
|
||||
https://www.kennethmoreland.com/color-maps/ColorMapsExpanded.pdf
|
||||
.. [2] DAMASK colormaps first use
|
||||
[2] DAMASK colormaps first use
|
||||
https://doi.org/10.1016/j.ijplas.2012.09.012
|
||||
.. [3] Matplotlib colormaps overview
|
||||
[3] Matplotlib colormaps overview
|
||||
https://matplotlib.org/tutorials/colors/colormaps.html
|
||||
|
||||
"""
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,6 +1,8 @@
|
|||
import numpy as np
|
||||
|
||||
from . import mechanics
|
||||
from . import util
|
||||
from . import grid_filters
|
||||
|
||||
_P = -1
|
||||
|
||||
|
@ -212,7 +214,7 @@ class Rotation:
|
|||
Returns
|
||||
-------
|
||||
q : numpy.ndarray of shape (...,4)
|
||||
Unit quaternion in positive real hemisphere: (q_0, q_1, q_2, q_3), |q|=1, q_0 ≥ 0.
|
||||
Unit quaternion in positive real hemisphere: (q_0, q_1, q_2, q_3), ǀqǀ=1, q_0 ≥ 0.
|
||||
|
||||
"""
|
||||
return self.quaternion.copy()
|
||||
|
@ -255,7 +257,7 @@ class Rotation:
|
|||
-------
|
||||
axis_angle : numpy.ndarray of shape (...,4) unless pair == True:
|
||||
tuple containing numpy.ndarray of shapes (...,3) and (...)
|
||||
Axis angle pair: (n_1, n_2, n_3, ω), |n| = 1 and ω ∈ [0,π]
|
||||
Axis angle pair: (n_1, n_2, n_3, ω), ǀnǀ = 1 and ω ∈ [0,π]
|
||||
unless degrees = True: ω ∈ [0,180].
|
||||
|
||||
"""
|
||||
|
@ -290,7 +292,7 @@ class Rotation:
|
|||
-------
|
||||
rho : numpy.ndarray of shape (...,4) unless vector == True:
|
||||
numpy.ndarray of shape (...,3)
|
||||
Rodrigues-Frank vector: [n_1, n_2, n_3, tan(ω/2)], |n| = 1 and ω ∈ [0,π].
|
||||
Rodrigues-Frank vector: [n_1, n_2, n_3, tan(ω/2)], ǀnǀ = 1 and ω ∈ [0,π].
|
||||
|
||||
"""
|
||||
ro = Rotation._qu2ro(self.quaternion)
|
||||
|
@ -307,7 +309,7 @@ class Rotation:
|
|||
Returns
|
||||
-------
|
||||
h : numpy.ndarray of shape (...,3)
|
||||
Homochoric vector: (h_1, h_2, h_3), |h| < 1/2*π^(2/3).
|
||||
Homochoric vector: (h_1, h_2, h_3), ǀhǀ < 1/2*π^(2/3).
|
||||
|
||||
"""
|
||||
return Rotation._qu2ho(self.quaternion)
|
||||
|
@ -353,7 +355,7 @@ class Rotation:
|
|||
----------
|
||||
q : numpy.ndarray of shape (...,4)
|
||||
Unit quaternion in positive real hemisphere: (q_0, q_1, q_2, q_3),
|
||||
|q|=1, q_0 ≥ 0.
|
||||
ǀqǀ=1, q_0 ≥ 0.
|
||||
accept_homomorph : boolean, optional
|
||||
Allow homomorphic variants, i.e. q_0 < 0 (negative real hemisphere).
|
||||
Defaults to False.
|
||||
|
@ -416,12 +418,12 @@ class Rotation:
|
|||
Parameters
|
||||
----------
|
||||
axis_angle : numpy.ndarray of shape (...,4)
|
||||
Axis angle pair: [n_1, n_2, n_3, ω], |n| = 1 and ω ∈ [0,π]
|
||||
Axis angle pair: [n_1, n_2, n_3, ω], ǀnǀ = 1 and ω ∈ [0,π]
|
||||
unless degrees = True: ω ∈ [0,180].
|
||||
degrees : boolean, optional
|
||||
Angle ω is given in degrees. Defaults to False.
|
||||
normalize: boolean, optional
|
||||
Allow |n| ≠ 1. Defaults to False.
|
||||
Allow ǀnǀ ≠ 1. Defaults to False.
|
||||
P : int ∈ {-1,1}, optional
|
||||
Convention used. Defaults to -1.
|
||||
|
||||
|
@ -503,9 +505,9 @@ class Rotation:
|
|||
----------
|
||||
rho : numpy.ndarray of shape (...,4)
|
||||
Rodrigues-Frank vector (angle separated from axis).
|
||||
(n_1, n_2, n_3, tan(ω/2)), |n| = 1 and ω ∈ [0,π].
|
||||
(n_1, n_2, n_3, tan(ω/2)), ǀnǀ = 1 and ω ∈ [0,π].
|
||||
normalize : boolean, optional
|
||||
Allow |n| ≠ 1. Defaults to False.
|
||||
Allow ǀnǀ ≠ 1. Defaults to False.
|
||||
P : int ∈ {-1,1}, optional
|
||||
Convention used. Defaults to -1.
|
||||
|
||||
|
@ -534,7 +536,7 @@ class Rotation:
|
|||
Parameters
|
||||
----------
|
||||
h : numpy.ndarray of shape (...,3)
|
||||
Homochoric vector: (h_1, h_2, h_3), |h| < (3/4*π)^(1/3).
|
||||
Homochoric vector: (h_1, h_2, h_3), ǀhǀ < (3/4*π)^(1/3).
|
||||
P : int ∈ {-1,1}, optional
|
||||
Convention used. Defaults to -1.
|
||||
|
||||
|
@ -647,13 +649,63 @@ class Rotation:
|
|||
|
||||
return Rotation(q.reshape(r.shape[:-1]+(4,)) if shape is not None else q)._standardize()
|
||||
|
||||
# for compatibility (old names do not follow convention)
|
||||
fromEulers = from_Eulers
|
||||
fromQuaternion = from_quaternion
|
||||
asAxisAngle = as_axis_angle
|
||||
# for compatibility
|
||||
__mul__ = __matmul__
|
||||
|
||||
|
||||
@staticmethod
|
||||
def from_ODF(weights,Eulers,N=500,degrees=True,fractions=True,seed=None):
|
||||
"""
|
||||
Sample discrete values from a binned ODF.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
weights : numpy.ndarray of shape (n)
|
||||
Texture intensity values (probability density or volume fraction) at Euler grid points.
|
||||
Eulers : numpy.ndarray of shape (n,3)
|
||||
Grid coordinates in Euler space at which weights are defined.
|
||||
N : integer, optional
|
||||
Number of discrete orientations to be sampled from the given ODF.
|
||||
Defaults to 500.
|
||||
degrees : boolean, optional
|
||||
Euler grid values are in degrees. Defaults to True.
|
||||
fractions : boolean, optional
|
||||
ODF values correspond to volume fractions, not probability density.
|
||||
Defaults to True.
|
||||
seed: {None, int, array_like[ints], SeedSequence, BitGenerator, Generator}, optional
|
||||
A seed to initialize the BitGenerator. Defaults to None, i.e. unpredictable entropy
|
||||
will be pulled from the OS.
|
||||
|
||||
Returns
|
||||
-------
|
||||
samples : damask.Rotation of shape (N)
|
||||
Array of sampled rotations closely representing the input ODF.
|
||||
|
||||
Notes
|
||||
-----
|
||||
Due to the distortion of Euler space in the vicinity of ϕ = 0, probability densities, p, defined on
|
||||
grid points with ϕ = 0 will never result in reconstructed orientations as their dV/V = p dγ = p × 0.
|
||||
Hence, it is recommended to transform any such dataset to cell centers that avoid grid points at ϕ = 0.
|
||||
|
||||
References
|
||||
----------
|
||||
P. Eisenlohr, F. Roters, Computational Materials Science 42(4), 670-678, 2008
|
||||
https://doi.org/10.1016/j.commatsci.2007.09.015
|
||||
|
||||
"""
|
||||
def _dg(eu,deg):
|
||||
"""Return infinitesimal Euler space volume of bin(s)."""
|
||||
Eulers_sorted = eu[np.lexsort((eu[:,0],eu[:,1],eu[:,2]))]
|
||||
steps,size,_ = grid_filters.cell_coord0_gridSizeOrigin(Eulers_sorted)
|
||||
delta = np.radians(size/steps) if deg else size/steps
|
||||
return delta[0]*2.0*np.sin(delta[1]/2.0)*delta[2] / 8.0 / np.pi**2 * np.sin(np.radians(eu[:,1]) if deg else eu[:,1])
|
||||
|
||||
dg = 1.0 if fractions else _dg(Eulers,degrees)
|
||||
dV_V = dg * np.maximum(0.0,weights.squeeze())
|
||||
|
||||
return Rotation.from_Eulers(Eulers[util.hybrid_IA(dV_V,N,seed)],degrees)
|
||||
|
||||
|
||||
@staticmethod
|
||||
def from_spherical_component(center,sigma,N=500,degrees=True,seed=None):
|
||||
"""
|
||||
|
|
|
@ -0,0 +1,113 @@
|
|||
from scipy import spatial as _spatial
|
||||
import numpy as _np
|
||||
|
||||
from . import util
|
||||
from . import grid_filters
|
||||
|
||||
|
||||
def from_random(size,N_seeds,grid=None,seed=None):
|
||||
"""
|
||||
Random seeding in space.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
size : numpy.ndarray of shape (3)
|
||||
Physical size of the seeding domain.
|
||||
N_seeds : int
|
||||
Number of seeds.
|
||||
grid : numpy.ndarray of shape (3), optional.
|
||||
If given, ensures that all seeds initiate one grain if using a
|
||||
standard Voronoi tessellation.
|
||||
seed : {None, int, array_like[ints], SeedSequence, BitGenerator, Generator}, optional
|
||||
A seed to initialize the BitGenerator. Defaults to None.
|
||||
If None, then fresh, unpredictable entropy will be pulled from the OS.
|
||||
|
||||
"""
|
||||
rng = _np.random.default_rng(seed)
|
||||
if grid is None:
|
||||
coords = rng.random((N_seeds,3)) * size
|
||||
else:
|
||||
grid_coords = grid_filters.cell_coord0(grid,size).reshape(-1,3,order='F')
|
||||
coords = grid_coords[rng.choice(_np.prod(grid),N_seeds, replace=False)] \
|
||||
+ _np.broadcast_to(size/grid,(N_seeds,3))*(rng.random((N_seeds,3))*.5-.25) # wobble without leaving grid
|
||||
|
||||
return coords
|
||||
|
||||
|
||||
def from_Poisson_disc(size,N_seeds,N_candidates,distance,periodic=True,seed=None):
|
||||
"""
|
||||
Seeding in space according to a Poisson disc distribution.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
size : numpy.ndarray of shape (3)
|
||||
Physical size of the seeding domain.
|
||||
N_seeds : int
|
||||
Number of seeds.
|
||||
N_candidates : int
|
||||
Number of candidates to consider for finding best candidate.
|
||||
distance : float
|
||||
Minimum acceptable distance to other seeds.
|
||||
periodic : boolean, optional
|
||||
Calculate minimum distance for periodically repeated grid.
|
||||
seed : {None, int, array_like[ints], SeedSequence, BitGenerator, Generator}, optional
|
||||
A seed to initialize the BitGenerator. Defaults to None.
|
||||
If None, then fresh, unpredictable entropy will be pulled from the OS.
|
||||
|
||||
"""
|
||||
rng = _np.random.default_rng(seed)
|
||||
coords = _np.empty((N_seeds,3))
|
||||
coords[0] = rng.random(3) * size
|
||||
|
||||
i = 1
|
||||
progress = util._ProgressBar(N_seeds+1,'',50)
|
||||
while i < N_seeds:
|
||||
candidates = rng.random((N_candidates,3))*_np.broadcast_to(size,(N_candidates,3))
|
||||
tree = _spatial.cKDTree(coords[:i],boxsize=size) if periodic else \
|
||||
_spatial.cKDTree(coords[:i])
|
||||
distances, dev_null = tree.query(candidates)
|
||||
best = distances.argmax()
|
||||
if distances[best] > distance: # require minimum separation
|
||||
coords[i] = candidates[best] # maximum separation to existing point cloud
|
||||
i += 1
|
||||
progress.update(i)
|
||||
|
||||
return coords
|
||||
|
||||
|
||||
def from_geom(geom,selection=None,invert=False,average=False,periodic=True):
|
||||
"""
|
||||
Create seed from existing geometry description.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
geom : damask.Geom
|
||||
Geometry, from which the material IDs are used as seeds.
|
||||
selection : iterable of integers, optional
|
||||
Material IDs to consider.
|
||||
invert : boolean, false
|
||||
Do not consider the material IDs given in selection. Defaults to False.
|
||||
average : boolean, optional
|
||||
Seed corresponds to center of gravity of material ID cloud.
|
||||
periodic : boolean, optional
|
||||
Center of gravity with periodic boundaries.
|
||||
|
||||
"""
|
||||
material = geom.material.reshape((-1,1),order='F')
|
||||
mask = _np.full(geom.grid.prod(),True,dtype=bool) if selection is None else \
|
||||
_np.isin(material,selection,invert=invert).flatten()
|
||||
coords = grid_filters.cell_coord0(geom.grid,geom.size).reshape(-1,3,order='F')
|
||||
|
||||
if not average:
|
||||
return (coords[mask],material[mask])
|
||||
else:
|
||||
materials = _np.unique(material[mask])
|
||||
coords_ = _np.zeros((materials.size,3),dtype=float)
|
||||
for i,mat in enumerate(materials):
|
||||
pc = (2*_np.pi*coords[material[:,0]==mat,:]-geom.origin)/geom.size
|
||||
coords_[i] = geom.origin + geom.size / 2 / _np.pi * (_np.pi +
|
||||
_np.arctan2(-_np.average(_np.sin(pc),axis=0),
|
||||
-_np.average(_np.cos(pc),axis=0))) \
|
||||
if periodic else \
|
||||
_np.average(coords[material[:,0]==mat,:],axis=0)
|
||||
return (coords_,materials)
|
|
@ -20,6 +20,7 @@ __all__=[
|
|||
'execute',
|
||||
'show_progress',
|
||||
'scale_to_coprime',
|
||||
'hybrid_IA',
|
||||
'return_message',
|
||||
'extendableOption',
|
||||
'execution_stamp'
|
||||
|
@ -173,7 +174,7 @@ def scale_to_coprime(v):
|
|||
m = (np.array(v) * reduce(lcm, map(lambda x: int(get_square_denominator(x)),v)) ** 0.5).astype(np.int)
|
||||
m = m//reduce(np.gcd,m)
|
||||
|
||||
with np.errstate(divide='ignore'):
|
||||
with np.errstate(invalid='ignore'):
|
||||
if not np.allclose(np.ma.masked_invalid(v/m),v[np.argmax(abs(v))]/m[np.argmax(abs(v))]):
|
||||
raise ValueError(f'Invalid result {m} for input {v}. Insufficient precision?')
|
||||
|
||||
|
@ -187,6 +188,20 @@ def execution_stamp(class_name,function_name=None):
|
|||
return f'damask.{class_name}{_function_name} v{version} ({now})'
|
||||
|
||||
|
||||
def hybrid_IA(dist,N,seed=None):
|
||||
N_opt_samples,N_inv_samples = (max(np.count_nonzero(dist),N),0) # random subsampling if too little samples requested
|
||||
|
||||
scale_,scale,inc_factor = (0.0,float(N_opt_samples),1.0)
|
||||
while (not np.isclose(scale, scale_)) and (N_inv_samples != N_opt_samples):
|
||||
repeats = np.rint(scale*dist).astype(int)
|
||||
N_inv_samples = np.sum(repeats)
|
||||
scale_,scale,inc_factor = (scale,scale+inc_factor*0.5*(scale - scale_), inc_factor*2.0) \
|
||||
if N_inv_samples < N_opt_samples else \
|
||||
(scale_,0.5*(scale_ + scale), 1.0)
|
||||
|
||||
return np.repeat(np.arange(len(dist)),repeats)[np.random.default_rng(seed).permutation(N_inv_samples)[:N]]
|
||||
|
||||
|
||||
####################################################################################################
|
||||
# Classes
|
||||
####################################################################################################
|
||||
|
|
|
@ -1,11 +1,16 @@
|
|||
<?xml version="1.0"?>
|
||||
<VTKFile type="RectilinearGrid" version="0.1" byte_order="LittleEndian" header_type="UInt32" compressor="vtkZLibDataCompressor">
|
||||
<RectilinearGrid WholeExtent="0 8 0 5 0 4">
|
||||
<FieldData>
|
||||
<Array type="String" Name="comments" NumberOfTuples="1" format="binary">
|
||||
AQAAAACAAABJAAAATgAAAA==eF4FwUEKgCAUBNCO4rIWX8ZJsbxA5/iUFqQVBJ2/9zZt+p52yXeza816mW+0sBCtz6HCGGSPE1wJjMX0BCGYhTQuJLrkKfDA0P0d3xK6
|
||||
</Array>
|
||||
</FieldData>
|
||||
<Piece Extent="0 8 0 5 0 4">
|
||||
<PointData>
|
||||
</PointData>
|
||||
<CellData>
|
||||
<DataArray type="Int64" Name="materialpoint" format="binary" RangeMin="1" RangeMax="41">
|
||||
<DataArray type="Int64" Name="material" format="binary" RangeMin="1" RangeMax="41">
|
||||
AQAAAACAAAAABQAAZwAAAA==eF7t0rcOgmAAhVEgNmyo2AuoWN//BR04EwsJcfzvcvabL47qxcFOJg177HPAIUdMOeaEU844Z8YFl1wx55obbrnjngceeeKZFxYseeWNd1Z88MkX3/zwy+Z/wf8YOqzX1uEPlgwHCA==
|
||||
</DataArray>
|
||||
</CellData>
|
||||
|
|
|
@ -1,11 +1,16 @@
|
|||
<?xml version="1.0"?>
|
||||
<VTKFile type="RectilinearGrid" version="0.1" byte_order="LittleEndian" header_type="UInt32" compressor="vtkZLibDataCompressor">
|
||||
<RectilinearGrid WholeExtent="0 8 0 5 0 4">
|
||||
<FieldData>
|
||||
<Array type="String" Name="comments" NumberOfTuples="1" format="binary">
|
||||
AQAAAACAAABJAAAATwAAAA==eF5LScxNLM7Wc0/Nz9VLzklNzFMoM9Yz0DPQTcwpyEjUNTI31U03tzAwTDM1Mk9T0DAyMDLQNbDUNTJSMDS1MjK0MgFyTQwMNBkAHc8SuA==
|
||||
</Array>
|
||||
</FieldData>
|
||||
<Piece Extent="0 8 0 5 0 4">
|
||||
<PointData>
|
||||
</PointData>
|
||||
<CellData>
|
||||
<DataArray type="Int64" Name="materialpoint" format="binary" RangeMin="1" RangeMax="41">
|
||||
<DataArray type="Int64" Name="material" format="binary" RangeMin="1" RangeMax="41">
|
||||
AQAAAACAAAAABQAAagAAAA==eF7t0rkOglAARFExLrgCKuKuqLj8/w9acCoSY7B+05x+cqNOvSj4l92GPfY54JAxRxxzwilnnDNhyowLLrlizjULbrjljnseeOSJZ15Y8sob76z44JMvvtn8L9jObz2GDuv96vADk5QHBg==
|
||||
</DataArray>
|
||||
</CellData>
|
||||
|
|
|
@ -1,11 +1,16 @@
|
|||
<?xml version="1.0"?>
|
||||
<VTKFile type="RectilinearGrid" version="0.1" byte_order="LittleEndian" header_type="UInt32" compressor="vtkZLibDataCompressor">
|
||||
<RectilinearGrid WholeExtent="0 8 0 5 0 4">
|
||||
<FieldData>
|
||||
<Array type="String" Name="comments" NumberOfTuples="1" format="binary">
|
||||
AQAAAACAAABJAAAATwAAAA==eF4FwdEJgDAMBUBH6ad+JLzElmoXcI6grYKtCoLze7dZs/fkJd+N15rtct/IYJDV5zDSGGiPE6QEjcX1CgVhJlUnIakkLwQPDN0PHdcSuQ==
|
||||
</Array>
|
||||
</FieldData>
|
||||
<Piece Extent="0 8 0 5 0 4">
|
||||
<PointData>
|
||||
</PointData>
|
||||
<CellData>
|
||||
<DataArray type="Int64" Name="materialpoint" format="binary" RangeMin="1" RangeMax="41">
|
||||
<DataArray type="Int64" Name="material" format="binary" RangeMin="1" RangeMax="41">
|
||||
AQAAAACAAAAABQAAZAAAAA==eF7t0scRglAAQEEBAyZUMCuomPtv0ANbgMNw/O+yDbyo1xQFWxkzYZ8DDjliyjEnnHLGOTMuuOSKOQuuueGWO+554JEnnlmy4oVX3ljzzgeffPHND7+Mg50aPmz698MfmvQHCg==
|
||||
</DataArray>
|
||||
</CellData>
|
||||
|
|
|
@ -1,11 +1,16 @@
|
|||
<?xml version="1.0"?>
|
||||
<VTKFile type="RectilinearGrid" version="0.1" byte_order="LittleEndian" header_type="UInt32" compressor="vtkZLibDataCompressor">
|
||||
<RectilinearGrid WholeExtent="0 8 0 5 0 4">
|
||||
<FieldData>
|
||||
<Array type="String" Name="comments" NumberOfTuples="1" format="binary">
|
||||
AQAAAACAAABJAAAATwAAAA==eF4FwVEKgCAQBcCO4md97PJcE9MLdI6ltCCtIOj8zuza9Lt4zU/jrWa9ze8YDNL6nkoSPB1hgS1eQjGjQECIJGKsT2KTi4QZmIYOHg4SwA==
|
||||
</Array>
|
||||
</FieldData>
|
||||
<Piece Extent="0 8 0 5 0 4">
|
||||
<PointData>
|
||||
</PointData>
|
||||
<CellData>
|
||||
<DataArray type="Int64" Name="materialpoint" format="binary" RangeMin="1" RangeMax="41">
|
||||
<DataArray type="Int64" Name="material" format="binary" RangeMin="1" RangeMax="41">
|
||||
AQAAAACAAAAABQAAYwAAAA==eF7t0scBgkAAAEHBgBEwgDmBsf8GfTANCN/bzzSwUa8pCrYyZp8DDjliwjEnnHLGORdMmTHnkiuuuWHBklvuuOeBR5545oVX3nhnxZoPPvnimx9+GQc7GT5sqvjvhz+ZtAcJ
|
||||
</DataArray>
|
||||
</CellData>
|
||||
|
|
|
@ -1,11 +1,16 @@
|
|||
<?xml version="1.0"?>
|
||||
<VTKFile type="RectilinearGrid" version="0.1" byte_order="LittleEndian" header_type="UInt32" compressor="vtkZLibDataCompressor">
|
||||
<RectilinearGrid WholeExtent="0 8 0 5 0 4">
|
||||
<FieldData>
|
||||
<Array type="String" Name="comments" NumberOfTuples="1" format="binary">
|
||||
AQAAAACAAABJAAAATwAAAA==eF4FwdEJgDAMBUBH6ad+JLzElmoXcI6grYKtCoLze7dZs/fkJd+N15rtct/IYJDV5zDSGGiPE6QEjcX1CgVhJlUnIakkLwQPDN0PHdcSuQ==
|
||||
</Array>
|
||||
</FieldData>
|
||||
<Piece Extent="0 8 0 5 0 4">
|
||||
<PointData>
|
||||
</PointData>
|
||||
<CellData>
|
||||
<DataArray type="Int64" Name="materialpoint" format="binary" RangeMin="1" RangeMax="2">
|
||||
<DataArray type="Int64" Name="material" format="binary" RangeMin="1" RangeMax="2">
|
||||
AQAAAACAAAAABQAAGwAAAA==eF5jZIAAxlF6lB4AmmmUpogeDUfKaAD7jwDw
|
||||
</DataArray>
|
||||
</CellData>
|
||||
|
|
|
@ -1,11 +1,16 @@
|
|||
<?xml version="1.0"?>
|
||||
<VTKFile type="RectilinearGrid" version="0.1" byte_order="LittleEndian" header_type="UInt32" compressor="vtkZLibDataCompressor">
|
||||
<RectilinearGrid WholeExtent="0 8 0 5 0 4">
|
||||
<FieldData>
|
||||
<Array type="String" Name="comments" NumberOfTuples="1" format="binary">
|
||||
AQAAAACAAABJAAAATwAAAA==eF4FwVEKgCAQBcCO4md97PJcE9MLdI6ltCCtIOj8zuza9Lt4zU/jrWa9ze8YDNL6nkoSPB1hgS1eQjGjQECIJGKsT2KTi4QZmIYOHg4SwA==
|
||||
</Array>
|
||||
</FieldData>
|
||||
<Piece Extent="0 8 0 5 0 4">
|
||||
<PointData>
|
||||
</PointData>
|
||||
<CellData>
|
||||
<DataArray type="Int64" Name="materialpoint" format="binary" RangeMin="1" RangeMax="2">
|
||||
<DataArray type="Int64" Name="material" format="binary" RangeMin="1" RangeMax="2">
|
||||
AQAAAACAAAAABQAAGQAAAA==eF5jZIAAxlF6lB4AmmmUHqUHkAYA/M8A8Q==
|
||||
</DataArray>
|
||||
</CellData>
|
||||
|
|
|
@ -1,11 +1,16 @@
|
|||
<?xml version="1.0"?>
|
||||
<VTKFile type="RectilinearGrid" version="0.1" byte_order="LittleEndian" header_type="UInt32" compressor="vtkZLibDataCompressor">
|
||||
<RectilinearGrid WholeExtent="0 8 0 5 0 4">
|
||||
<FieldData>
|
||||
<Array type="String" Name="comments" NumberOfTuples="1" format="binary">
|
||||
AQAAAACAAABJAAAATgAAAA==eF4FwUEKgCAUBNCO4rIWX8ZJsbxA5/iUFqQVBJ2/9zZt+p52yXeza816mW+0sBCtz6HCGGSPE1wJjMX0BCGYhTQuJLrkKfDA0P0d3xK6
|
||||
</Array>
|
||||
</FieldData>
|
||||
<Piece Extent="0 8 0 5 0 4">
|
||||
<PointData>
|
||||
</PointData>
|
||||
<CellData>
|
||||
<DataArray type="Int64" Name="materialpoint" format="binary" RangeMin="1" RangeMax="41">
|
||||
<DataArray type="Int64" Name="material" format="binary" RangeMin="1" RangeMax="41">
|
||||
AQAAAACAAAAABQAAZwAAAA==eF7t0rcOgmAAhVEgNmyo2AuoWN//BR04EwsJcfzvcvabL47qxcFOJg177HPAIUdMOeaEU844Z8YFl1wx55obbrnjngceeeKZFxYseeWNd1Z88MkX3/zwy+Z/wf8YOqzX1uEPlgwHCA==
|
||||
</DataArray>
|
||||
</CellData>
|
||||
|
|
|
@ -1,11 +1,16 @@
|
|||
<?xml version="1.0"?>
|
||||
<VTKFile type="RectilinearGrid" version="0.1" byte_order="LittleEndian" header_type="UInt32" compressor="vtkZLibDataCompressor">
|
||||
<RectilinearGrid WholeExtent="0 8 0 5 0 4">
|
||||
<FieldData>
|
||||
<Array type="String" Name="comments" NumberOfTuples="1" format="binary">
|
||||
AQAAAACAAABJAAAATwAAAA==eF5LScxNLM7Wc0/Nz9VLzklNzFMoM9Yz0DPQTcwpyEjUNTI31U03tzAwTDM1Mk9T0DAyMDLQNbDUNTJSMDS1MjK0MgFyTQwMNBkAHc8SuA==
|
||||
</Array>
|
||||
</FieldData>
|
||||
<Piece Extent="0 8 0 5 0 4">
|
||||
<PointData>
|
||||
</PointData>
|
||||
<CellData>
|
||||
<DataArray type="Int64" Name="materialpoint" format="binary" RangeMin="1" RangeMax="41">
|
||||
<DataArray type="Int64" Name="material" format="binary" RangeMin="1" RangeMax="41">
|
||||
AQAAAACAAAAABQAAagAAAA==eF7t0rkOglAARFExLrgCKuKuqLj8/w9acCoSY7B+05x+cqNOvSj4l92GPfY54JAxRxxzwilnnDNhyowLLrlizjULbrjljnseeOSJZ15Y8sob76z44JMvvtn8L9jObz2GDuv96vADk5QHBg==
|
||||
</DataArray>
|
||||
</CellData>
|
||||
|
|
|
@ -1,11 +1,16 @@
|
|||
<?xml version="1.0"?>
|
||||
<VTKFile type="RectilinearGrid" version="0.1" byte_order="LittleEndian" header_type="UInt32" compressor="vtkZLibDataCompressor">
|
||||
<RectilinearGrid WholeExtent="0 8 0 5 0 4">
|
||||
<FieldData>
|
||||
<Array type="String" Name="comments" NumberOfTuples="1" format="binary">
|
||||
AQAAAACAAABJAAAATwAAAA==eF4FwdEJgDAMBUBH6ad+JLzElmoXcI6grYKtCoLze7dZs/fkJd+N15rtct/IYJDV5zDSGGiPE6QEjcX1CgVhJlUnIakkLwQPDN0PHdcSuQ==
|
||||
</Array>
|
||||
</FieldData>
|
||||
<Piece Extent="0 8 0 5 0 4">
|
||||
<PointData>
|
||||
</PointData>
|
||||
<CellData>
|
||||
<DataArray type="Int64" Name="materialpoint" format="binary" RangeMin="1" RangeMax="41">
|
||||
<DataArray type="Int64" Name="material" format="binary" RangeMin="1" RangeMax="41">
|
||||
AQAAAACAAAAABQAAZAAAAA==eF7t0scRglAAQEEBAyZUMCuomPtv0ANbgMNw/O+yDbyo1xQFWxkzYZ8DDjliyjEnnHLGOTMuuOSKOQuuueGWO+554JEnnlmy4oVX3ljzzgeffPHND7+Mg50aPmz698MfmvQHCg==
|
||||
</DataArray>
|
||||
</CellData>
|
||||
|
|
|
@ -1,11 +1,16 @@
|
|||
<?xml version="1.0"?>
|
||||
<VTKFile type="RectilinearGrid" version="0.1" byte_order="LittleEndian" header_type="UInt32" compressor="vtkZLibDataCompressor">
|
||||
<RectilinearGrid WholeExtent="0 8 0 5 0 4">
|
||||
<FieldData>
|
||||
<Array type="String" Name="comments" NumberOfTuples="1" format="binary">
|
||||
AQAAAACAAABJAAAATwAAAA==eF5LScxNLM7Wc0/Nz9VLzklNzFMoM9Yz0DPQTcwpyEjUNTI31U03tzAwTDM1Mk9T0DAyMDLQNbDUNTJSMDS1MjK0MgFyTQwMNBkAHc8SuA==
|
||||
</Array>
|
||||
</FieldData>
|
||||
<Piece Extent="0 8 0 5 0 4">
|
||||
<PointData>
|
||||
</PointData>
|
||||
<CellData>
|
||||
<DataArray type="Int64" Name="materialpoint" format="binary" RangeMin="1" RangeMax="41">
|
||||
<DataArray type="Int64" Name="material" format="binary" RangeMin="1" RangeMax="41">
|
||||
AQAAAACAAAAABQAAYwAAAA==eF7t0scBgkAAAEHBgBEwgDmBsf8GfTANCN/bzzSwUa8pCrYyZp8DDjliwjEnnHLGORdMmTHnkiuuuWHBklvuuOeBR5545oVX3nhnxZoPPvnimx9+GQc7GT5sqvjvhz+ZtAcJ
|
||||
</DataArray>
|
||||
</CellData>
|
||||
|
|
|
@ -1,11 +1,16 @@
|
|||
<?xml version="1.0"?>
|
||||
<VTKFile type="RectilinearGrid" version="0.1" byte_order="LittleEndian" header_type="UInt32" compressor="vtkZLibDataCompressor">
|
||||
<RectilinearGrid WholeExtent="0 8 0 5 0 4">
|
||||
<FieldData>
|
||||
<Array type="String" Name="comments" NumberOfTuples="1" format="binary">
|
||||
AQAAAACAAABJAAAATwAAAA==eF4FwdEJgDAMBUBH6ad+JLzElmoXcI6grYKtCoLze7dZs/fkJd+N15rtct/IYJDV5zDSGGiPE6QEjcX1CgVhJlUnIakkLwQPDN0PHdcSuQ==
|
||||
</Array>
|
||||
</FieldData>
|
||||
<Piece Extent="0 8 0 5 0 4">
|
||||
<PointData>
|
||||
</PointData>
|
||||
<CellData>
|
||||
<DataArray type="Int64" Name="materialpoint" format="binary" RangeMin="1" RangeMax="2">
|
||||
<DataArray type="Int64" Name="material" format="binary" RangeMin="1" RangeMax="2">
|
||||
AQAAAACAAAAABQAAIgAAAA==eF5jZIAAxlGaLJoJjSakntr6hzqN7v9RepSmJw0AC04A9Q==
|
||||
</DataArray>
|
||||
</CellData>
|
||||
|
|
|
@ -1,11 +1,16 @@
|
|||
<?xml version="1.0"?>
|
||||
<VTKFile type="RectilinearGrid" version="0.1" byte_order="LittleEndian" header_type="UInt32" compressor="vtkZLibDataCompressor">
|
||||
<RectilinearGrid WholeExtent="0 8 0 5 0 4">
|
||||
<FieldData>
|
||||
<Array type="String" Name="comments" NumberOfTuples="1" format="binary">
|
||||
AQAAAACAAABJAAAATwAAAA==eF4FwVEKgCAQBcCO4md97PJcE9MLdI6ltCCtIOj8zuza9Lt4zU/jrWa9ze8YDNL6nkoSPB1hgS1eQjGjQECIJGKsT2KTi4QZmIYOHg4SwA==
|
||||
</Array>
|
||||
</FieldData>
|
||||
<Piece Extent="0 8 0 5 0 4">
|
||||
<PointData>
|
||||
</PointData>
|
||||
<CellData>
|
||||
<DataArray type="Int64" Name="materialpoint" format="binary" RangeMin="1" RangeMax="2">
|
||||
<DataArray type="Int64" Name="material" format="binary" RangeMin="1" RangeMax="2">
|
||||
AQAAAACAAAAABQAALwAAAA==eF5jZIAAxlGaLJoJjSakHpc+cvUTUkdrmlL3j9KU0dROF5TqH2iaVPcDAALOANU=
|
||||
</DataArray>
|
||||
</CellData>
|
||||
|
|
|
@ -1,11 +1,16 @@
|
|||
<?xml version="1.0"?>
|
||||
<VTKFile type="RectilinearGrid" version="0.1" byte_order="LittleEndian" header_type="UInt32" compressor="vtkZLibDataCompressor">
|
||||
<RectilinearGrid WholeExtent="0 8 0 5 0 4">
|
||||
<FieldData>
|
||||
<Array type="String" Name="comments" NumberOfTuples="1" format="binary">
|
||||
AQAAAACAAABJAAAATgAAAA==eF4FwUEKgCAUBNCO4rIWX8ZJsbxA5/iUFqQVBJ2/9zZt+p52yXeza816mW+0sBCtz6HCGGSPE1wJjMX0BCGYhTQuJLrkKfDA0P0d3xK6
|
||||
</Array>
|
||||
</FieldData>
|
||||
<Piece Extent="0 8 0 5 0 4">
|
||||
<PointData>
|
||||
</PointData>
|
||||
<CellData>
|
||||
<DataArray type="Int64" Name="materialpoint" format="binary" RangeMin="1" RangeMax="41">
|
||||
<DataArray type="Int64" Name="material" format="binary" RangeMin="1" RangeMax="41">
|
||||
AQAAAACAAAAABQAAcQAAAA==eF7t0rkOglAUBFAxKu6igvsKrv//gxYcm9fQGEPBNKe6yc1kolaZqPEndthljzH7HHDIEceccMoZE8654JIpM6645oZb7rjngUeeeOaFV+YseOOdDz754pthf+3Aqr7rdv9vw3+/NjssU7XDD0/8BuQ=
|
||||
</DataArray>
|
||||
</CellData>
|
||||
|
|
|
@ -1,11 +1,16 @@
|
|||
<?xml version="1.0"?>
|
||||
<VTKFile type="RectilinearGrid" version="0.1" byte_order="LittleEndian" header_type="UInt32" compressor="vtkZLibDataCompressor">
|
||||
<RectilinearGrid WholeExtent="0 8 0 5 0 4">
|
||||
<FieldData>
|
||||
<Array type="String" Name="comments" NumberOfTuples="1" format="binary">
|
||||
AQAAAACAAABJAAAATwAAAA==eF5LScxNLM7Wc0/Nz9VLzklNzFMoM9Yz0DPQTcwpyEjUNTI31U03tzAwTDM1Mk9T0DAyMDLQNbDUNTJSMDS1MjK0MgFyTQwMNBkAHc8SuA==
|
||||
</Array>
|
||||
</FieldData>
|
||||
<Piece Extent="0 8 0 5 0 4">
|
||||
<PointData>
|
||||
</PointData>
|
||||
<CellData>
|
||||
<DataArray type="Int64" Name="materialpoint" format="binary" RangeMin="1" RangeMax="41">
|
||||
<DataArray type="Int64" Name="material" format="binary" RangeMin="1" RangeMax="41">
|
||||
AQAAAACAAAAABQAAYQAAAA==eF7t0scVglAAAEHgqZgBA2ZExdR/gx6YCpDj38s0sEnUlgR7ccAhR0w55oRTzjjngktmzFlwxTU33LLkjnseeOSJZ15Y8cqaN975YMMnX3zzwy/j4F+GD9u6fvgD+gwHCA==
|
||||
</DataArray>
|
||||
</CellData>
|
||||
|
|
|
@ -1,11 +1,16 @@
|
|||
<?xml version="1.0"?>
|
||||
<VTKFile type="RectilinearGrid" version="0.1" byte_order="LittleEndian" header_type="UInt32" compressor="vtkZLibDataCompressor">
|
||||
<RectilinearGrid WholeExtent="0 8 0 5 0 4">
|
||||
<FieldData>
|
||||
<Array type="String" Name="comments" NumberOfTuples="1" format="binary">
|
||||
AQAAAACAAABJAAAATgAAAA==eF4FwUEKgCAUBNCO4rIWX8ZJsbxA5/iUFqQVBJ2/9zZt+p52yXeza816mW+0sBCtz6HCGGSPE1wJjMX0BCGYhTQuJLrkKfDA0P0d3xK6
|
||||
</Array>
|
||||
</FieldData>
|
||||
<Piece Extent="0 8 0 5 0 4">
|
||||
<PointData>
|
||||
</PointData>
|
||||
<CellData>
|
||||
<DataArray type="Int64" Name="materialpoint" format="binary" RangeMin="1" RangeMax="41">
|
||||
<DataArray type="Int64" Name="material" format="binary" RangeMin="1" RangeMax="41">
|
||||
AQAAAACAAAAABQAAZAAAAA==eF7t0scRglAAQEEBAyZUMCuomPtv0ANbgMNw/O+yDbyo1xQFWxkzYZ8DDjliyjEnnHLGOTMuuOSKOQuuueGWO+554JEnnlmy4oVX3ljzzgeffPHND7+Mg50aPmz698MfmvQHCg==
|
||||
</DataArray>
|
||||
</CellData>
|
||||
|
|
|
@ -1,11 +1,16 @@
|
|||
<?xml version="1.0"?>
|
||||
<VTKFile type="RectilinearGrid" version="0.1" byte_order="LittleEndian" header_type="UInt32" compressor="vtkZLibDataCompressor">
|
||||
<RectilinearGrid WholeExtent="0 8 0 5 0 4">
|
||||
<FieldData>
|
||||
<Array type="String" Name="comments" NumberOfTuples="1" format="binary">
|
||||
AQAAAACAAABJAAAATwAAAA==eF5LScxNLM7Wc0/Nz9VLzklNzFMoM9Yz0DPQTcwpyEjUNTI31U03tzAwTDM1Mk9T0DAyMDLQNbDUNTJSMDS1MjK0MgFyTQwMNBkAHc8SuA==
|
||||
</Array>
|
||||
</FieldData>
|
||||
<Piece Extent="0 8 0 5 0 4">
|
||||
<PointData>
|
||||
</PointData>
|
||||
<CellData>
|
||||
<DataArray type="Int64" Name="materialpoint" format="binary" RangeMin="2" RangeMax="41">
|
||||
<DataArray type="Int64" Name="material" format="binary" RangeMin="2" RangeMax="41">
|
||||
AQAAAACAAAAABQAAZAAAAA==eF7t0rcSglAARFEHE0bAgBkE8///oAWnF8b2bXP6nRv1mkXBv+xzwCFHHDPmhFPOOOeCSyZMmXHFNTfcMueOex545IlnXliw5JUVa95454NPvvjmh79+DXYzdNisbYdfSqMHMg==
|
||||
</DataArray>
|
||||
</CellData>
|
||||
|
|
|
@ -1,11 +1,16 @@
|
|||
<?xml version="1.0"?>
|
||||
<VTKFile type="RectilinearGrid" version="0.1" byte_order="LittleEndian" header_type="UInt32" compressor="vtkZLibDataCompressor">
|
||||
<RectilinearGrid WholeExtent="0 8 0 5 0 4">
|
||||
<FieldData>
|
||||
<Array type="String" Name="comments" NumberOfTuples="1" format="binary">
|
||||
AQAAAACAAABJAAAATwAAAA==eF4FwdEJgDAMBUBH6ad+JLzElmoXcI6grYKtCoLze7dZs/fkJd+N15rtct/IYJDV5zDSGGiPE6QEjcX1CgVhJlUnIakkLwQPDN0PHdcSuQ==
|
||||
</Array>
|
||||
</FieldData>
|
||||
<Piece Extent="0 8 0 5 0 4">
|
||||
<PointData>
|
||||
</PointData>
|
||||
<CellData>
|
||||
<DataArray type="Int64" Name="materialpoint" format="binary" RangeMin="1" RangeMax="2">
|
||||
<DataArray type="Int64" Name="material" format="binary" RangeMin="1" RangeMax="2">
|
||||
AQAAAACAAAAABQAAIAAAAA==eF5jZIAAxlF6lB4AmokAPdj1DzRNyP2jNH4aAMufANU=
|
||||
</DataArray>
|
||||
</CellData>
|
||||
|
|
|
@ -1,11 +1,16 @@
|
|||
<?xml version="1.0"?>
|
||||
<VTKFile type="RectilinearGrid" version="0.1" byte_order="LittleEndian" header_type="UInt32" compressor="vtkZLibDataCompressor">
|
||||
<RectilinearGrid WholeExtent="0 8 0 5 0 4">
|
||||
<FieldData>
|
||||
<Array type="String" Name="comments" NumberOfTuples="1" format="binary">
|
||||
AQAAAACAAABJAAAATwAAAA==eF4FwVEKgCAQBcCO4md97PJcE9MLdI6ltCCtIOj8zuza9Lt4zU/jrWa9ze8YDNL6nkoSPB1hgS1eQjGjQECIJGKsT2KTi4QZmIYOHg4SwA==
|
||||
</Array>
|
||||
</FieldData>
|
||||
<Piece Extent="0 8 0 5 0 4">
|
||||
<PointData>
|
||||
</PointData>
|
||||
<CellData>
|
||||
<DataArray type="Int64" Name="materialpoint" format="binary" RangeMin="1" RangeMax="2">
|
||||
<DataArray type="Int64" Name="material" format="binary" RangeMin="1" RangeMax="2">
|
||||
AQAAAACAAAAABQAAMAAAAA==eF5jYoAAJhw0IwEalz566aeUptT+oa6fUppS+4e6fkppSu0f6voppSm1HwBAngDh
|
||||
</DataArray>
|
||||
</CellData>
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -77,17 +77,17 @@ class TestColormap:
|
|||
|
||||
@pytest.mark.parametrize('format',['ASCII','paraview','GOM','gmsh'])
|
||||
@pytest.mark.parametrize('model',['rgb','hsv','hsl','xyz','lab','msh'])
|
||||
def test_from_range(self,model,format,tmpdir):
|
||||
def test_from_range(self,model,format,tmp_path):
|
||||
N = np.random.randint(2,256)
|
||||
c = Colormap.from_range(np.random.rand(3),np.random.rand(3),model=model,N=N) # noqa
|
||||
eval(f'c.save_{format}(tmpdir/"color_out")')
|
||||
eval(f'c.save_{format}(tmp_path/"color_out")')
|
||||
|
||||
@pytest.mark.parametrize('format',['ASCII','paraview','GOM','gmsh'])
|
||||
@pytest.mark.parametrize('name',['strain','gnuplot','Greys','PRGn','viridis'])
|
||||
def test_from_predefined(self,name,format,tmpdir):
|
||||
def test_from_predefined(self,name,format,tmp_path):
|
||||
N = np.random.randint(2,256)
|
||||
c = Colormap.from_predefined(name,N) # noqa
|
||||
os.chdir(tmpdir)
|
||||
os.chdir(tmp_path)
|
||||
eval(f'c.save_{format}()')
|
||||
|
||||
@pytest.mark.parametrize('format,name',[('ASCII','test.txt'),
|
||||
|
@ -95,9 +95,9 @@ class TestColormap:
|
|||
('GOM','test.legend'),
|
||||
('gmsh','test.msh')
|
||||
])
|
||||
def test_write_filehandle(self,format,name,tmpdir):
|
||||
def test_write_filehandle(self,format,name,tmp_path):
|
||||
c = Colormap.from_predefined('Dark2') # noqa
|
||||
fname = tmpdir/name
|
||||
fname = tmp_path/name
|
||||
with open(fname,'w') as f: # noqa
|
||||
eval(f'c.save_{format}(f)')
|
||||
for i in range(10):
|
||||
|
@ -146,14 +146,14 @@ class TestColormap:
|
|||
('GOM','.legend'),
|
||||
('gmsh','.msh')
|
||||
])
|
||||
def test_compare_reference(self,format,ext,tmpdir,reference_dir,update):
|
||||
def test_compare_reference(self,format,ext,tmp_path,reference_dir,update):
|
||||
name = 'binary'
|
||||
c = Colormap.from_predefined(name) # noqa
|
||||
if update:
|
||||
os.chdir(reference_dir)
|
||||
eval(f'c.save_{format}()')
|
||||
else:
|
||||
os.chdir(tmpdir)
|
||||
os.chdir(tmp_path)
|
||||
eval(f'c.save_{format}()')
|
||||
time.sleep(.5)
|
||||
assert filecmp.cmp(tmpdir/(name+ext),reference_dir/(name+ext))
|
||||
assert filecmp.cmp(tmp_path/(name+ext),reference_dir/(name+ext))
|
||||
|
|
|
@ -11,9 +11,9 @@ from damask import util
|
|||
|
||||
|
||||
def geom_equal(a,b):
|
||||
return np.all(a.get_microstructure() == b.get_microstructure()) and \
|
||||
np.all(a.get_grid() == b.get_grid()) and \
|
||||
np.allclose(a.get_size(), b.get_size()) and \
|
||||
return np.all(a.material == b.material) and \
|
||||
np.all(a.grid == b.grid) and \
|
||||
np.allclose(a.size, b.size) and \
|
||||
str(a.diff(b)) == str(b.diff(a))
|
||||
|
||||
@pytest.fixture
|
||||
|
@ -33,104 +33,96 @@ def reference_dir(reference_dir_base):
|
|||
|
||||
class TestGeom:
|
||||
|
||||
@pytest.mark.parametrize('flavor',['plain','explicit'])
|
||||
def test_duplicate(self,default,flavor):
|
||||
if flavor == 'plain':
|
||||
modified = default.duplicate()
|
||||
elif flavor == 'explicit':
|
||||
modified = default.duplicate(
|
||||
default.get_microstructure(),
|
||||
default.get_size(),
|
||||
default.get_origin()
|
||||
)
|
||||
print(modified)
|
||||
assert geom_equal(default,modified)
|
||||
|
||||
def test_diff_equal(self,default):
|
||||
assert str(default.diff(default)) == ''
|
||||
|
||||
|
||||
def test_diff_not_equal(self,default):
|
||||
new = Geom(default.microstructure[1:,1:,1:]+1,default.size*.9,np.ones(3)-default.origin,comments=['modified'])
|
||||
new = Geom(default.material[1:,1:,1:]+1,default.size*.9,np.ones(3)-default.origin,comments=['modified'])
|
||||
assert str(default.diff(new)) != ''
|
||||
|
||||
|
||||
@pytest.mark.parametrize('masked',[True,False])
|
||||
def test_set_microstructure(self,default,masked):
|
||||
old = default.get_microstructure()
|
||||
new = np.random.randint(200,size=default.grid)
|
||||
default.set_microstructure(np.ma.MaskedArray(new,np.full_like(new,masked)))
|
||||
assert np.all(default.microstructure==(old if masked else new))
|
||||
|
||||
|
||||
def test_write_read_str(self,default,tmpdir):
|
||||
default.save_ASCII(str(tmpdir/'default.geom'))
|
||||
new = Geom.load_ASCII(str(tmpdir/'default.geom'))
|
||||
def test_write_read_str(self,default,tmp_path):
|
||||
default.save_ASCII(str(tmp_path/'default.geom'))
|
||||
new = Geom.load_ASCII(str(tmp_path/'default.geom'))
|
||||
assert geom_equal(default,new)
|
||||
|
||||
def test_write_read_file(self,default,tmpdir):
|
||||
with open(tmpdir/'default.geom','w') as f:
|
||||
|
||||
def test_write_read_file(self,default,tmp_path):
|
||||
with open(tmp_path/'default.geom','w') as f:
|
||||
default.save_ASCII(f,compress=True)
|
||||
with open(tmpdir/'default.geom') as f:
|
||||
with open(tmp_path/'default.geom') as f:
|
||||
new = Geom.load_ASCII(f)
|
||||
assert geom_equal(default,new)
|
||||
|
||||
def test_read_write_vtr(self,default,tmpdir):
|
||||
default.save(tmpdir/'default')
|
||||
|
||||
def test_read_write_vtr(self,default,tmp_path):
|
||||
default.save(tmp_path/'default')
|
||||
for _ in range(10):
|
||||
time.sleep(.2)
|
||||
if os.path.exists(tmpdir/'default.vtr'): break
|
||||
if os.path.exists(tmp_path/'default.vtr'): break
|
||||
|
||||
new = Geom.load(tmpdir/'default.vtr')
|
||||
new = Geom.load(tmp_path/'default.vtr')
|
||||
assert geom_equal(new,default)
|
||||
|
||||
def test_invalid_geom(self,tmpdir):
|
||||
with open('invalid_file','w') as f:
|
||||
|
||||
def test_invalid_geom(self,tmp_path):
|
||||
with open(tmp_path/'invalid_file','w') as f:
|
||||
f.write('this is not a valid header')
|
||||
with open('invalid_file','r') as f:
|
||||
with open(tmp_path/'invalid_file','r') as f:
|
||||
with pytest.raises(TypeError):
|
||||
Geom.load_ASCII(f)
|
||||
|
||||
def test_invalid_vtr(self,tmpdir):
|
||||
|
||||
def test_invalid_vtr(self,tmp_path):
|
||||
v = VTK.from_rectilinearGrid(np.random.randint(5,10,3)*2,np.random.random(3) + 1.0)
|
||||
v.save(tmpdir/'no_materialpoint.vtr')
|
||||
v.save(tmp_path/'no_materialpoint.vtr')
|
||||
for _ in range(10):
|
||||
time.sleep(.2)
|
||||
if os.path.exists(tmpdir/'no_materialpoint.vtr'): break
|
||||
if os.path.exists(tmp_path/'no_materialpoint.vtr'): break
|
||||
with pytest.raises(ValueError):
|
||||
Geom.load(tmpdir/'no_materialpoint.vtr')
|
||||
Geom.load(tmp_path/'no_materialpoint.vtr')
|
||||
|
||||
def test_invalid_material(self):
|
||||
with pytest.raises(TypeError):
|
||||
Geom(np.zeros((3,3,3),dtype='complex'),np.ones(3))
|
||||
|
||||
def test_cast_to_int(self):
|
||||
g = Geom(np.zeros((3,3,3)),np.ones(3))
|
||||
assert g.material.dtype in np.sctypes['int']
|
||||
|
||||
@pytest.mark.parametrize('compress',[True,False])
|
||||
def test_compress(self,default,tmpdir,compress):
|
||||
default.save_ASCII(tmpdir/'default.geom',compress=compress)
|
||||
new = Geom.load_ASCII(tmpdir/'default.geom')
|
||||
def test_compress(self,default,tmp_path,compress):
|
||||
default.save_ASCII(tmp_path/'default.geom',compress=compress)
|
||||
new = Geom.load_ASCII(tmp_path/'default.geom')
|
||||
assert geom_equal(new,default)
|
||||
|
||||
def test_invalid_combination(self,default):
|
||||
with pytest.raises(ValueError):
|
||||
default.duplicate(default.microstructure[1:,1:,1:],size=np.ones(3), autosize=True)
|
||||
|
||||
def test_invalid_size(self,default):
|
||||
with pytest.raises(ValueError):
|
||||
default.duplicate(default.microstructure[1:,1:,1:],size=np.ones(2))
|
||||
Geom(default.material[1:,1:,1:],
|
||||
size=np.ones(2))
|
||||
|
||||
|
||||
def test_invalid_origin(self,default):
|
||||
with pytest.raises(ValueError):
|
||||
default.duplicate(default.microstructure[1:,1:,1:],origin=np.ones(4))
|
||||
Geom(default.material[1:,1:,1:],
|
||||
size=np.ones(3),
|
||||
origin=np.ones(4))
|
||||
|
||||
def test_invalid_microstructure_size(self,default):
|
||||
microstructure = np.ones((3,3))
|
||||
|
||||
def test_invalid_materials_shape(self,default):
|
||||
material = np.ones((3,3))
|
||||
with pytest.raises(ValueError):
|
||||
default.duplicate(microstructure)
|
||||
Geom(material,
|
||||
size=np.ones(3))
|
||||
|
||||
def test_invalid_microstructure_type(self,default):
|
||||
microstructure = np.random.randint(1,300,(3,4,5))==1
|
||||
with pytest.raises(TypeError):
|
||||
default.duplicate(microstructure)
|
||||
|
||||
def test_invalid_homogenization(self,default):
|
||||
def test_invalid_materials_type(self,default):
|
||||
material = np.random.randint(1,300,(3,4,5))==1
|
||||
with pytest.raises(TypeError):
|
||||
default.set_homogenization(homogenization=0)
|
||||
Geom(material)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('directions,reflect',[
|
||||
(['x'], False),
|
||||
|
@ -147,6 +139,7 @@ class TestGeom:
|
|||
assert geom_equal(Geom.load_ASCII(reference),
|
||||
modified)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('directions',[(1,2,'y'),('a','b','x'),[1]])
|
||||
def test_mirror_invalid(self,default,directions):
|
||||
with pytest.raises(ValueError):
|
||||
|
@ -168,13 +161,16 @@ class TestGeom:
|
|||
assert geom_equal(Geom.load_ASCII(reference),
|
||||
modified)
|
||||
|
||||
|
||||
def test_flip_invariant(self,default):
|
||||
assert geom_equal(default,default.flip([]))
|
||||
|
||||
|
||||
@pytest.mark.parametrize('direction',[['x'],['x','y']])
|
||||
def test_flip_double(self,default,direction):
|
||||
assert geom_equal(default,default.flip(direction).flip(direction))
|
||||
|
||||
|
||||
@pytest.mark.parametrize('directions',[(1,2,'y'),('a','b','x'),[1]])
|
||||
def test_flip_invalid(self,default,directions):
|
||||
with pytest.raises(ValueError):
|
||||
|
@ -196,6 +192,7 @@ class TestGeom:
|
|||
current
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('grid',[
|
||||
(10,11,10),
|
||||
[10,13,10],
|
||||
|
@ -213,22 +210,29 @@ class TestGeom:
|
|||
assert geom_equal(Geom.load_ASCII(reference),
|
||||
modified)
|
||||
|
||||
|
||||
def test_renumber(self,default):
|
||||
microstructure = default.get_microstructure()
|
||||
for m in np.unique(microstructure):
|
||||
microstructure[microstructure==m] = microstructure.max() + np.random.randint(1,30)
|
||||
modified = default.duplicate(microstructure)
|
||||
material = default.material.copy()
|
||||
for m in np.unique(material):
|
||||
material[material==m] = material.max() + np.random.randint(1,30)
|
||||
modified = Geom(material,
|
||||
default.size,
|
||||
default.origin)
|
||||
assert not geom_equal(modified,default)
|
||||
assert geom_equal(default,
|
||||
modified.renumber())
|
||||
|
||||
|
||||
def test_substitute(self,default):
|
||||
offset = np.random.randint(1,500)
|
||||
modified = default.duplicate(default.get_microstructure() + offset)
|
||||
modified = Geom(default.material + offset,
|
||||
default.size,
|
||||
default.origin)
|
||||
assert not geom_equal(modified,default)
|
||||
assert geom_equal(default,
|
||||
modified.substitute(np.arange(default.microstructure.max())+1+offset,
|
||||
np.arange(default.microstructure.max())+1))
|
||||
modified.substitute(np.arange(default.material.max())+1+offset,
|
||||
np.arange(default.material.max())+1))
|
||||
|
||||
|
||||
@pytest.mark.parametrize('axis_angle',[np.array([1,0,0,86.7]), np.array([0,1,0,90.4]), np.array([0,0,1,90]),
|
||||
np.array([1,0,0,175]),np.array([0,-1,0,178]),np.array([0,0,1,180])])
|
||||
|
@ -238,6 +242,7 @@ class TestGeom:
|
|||
modified.rotate(Rotation.from_axis_angle(axis_angle,degrees=True))
|
||||
assert geom_equal(default,modified)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('Eulers',[[32.0,68.0,21.0],
|
||||
[0.0,32.0,240.0]])
|
||||
def test_rotate(self,default,update,reference_dir,Eulers):
|
||||
|
@ -248,11 +253,13 @@ class TestGeom:
|
|||
assert geom_equal(Geom.load_ASCII(reference),
|
||||
modified)
|
||||
|
||||
|
||||
def test_canvas(self,default):
|
||||
grid = default.grid
|
||||
grid_add = np.random.randint(0,30,(3))
|
||||
modified = default.canvas(grid + grid_add)
|
||||
assert np.all(modified.microstructure[:grid[0],:grid[1],:grid[2]] == default.microstructure)
|
||||
assert np.all(modified.material[:grid[0],:grid[1],:grid[2]] == default.material)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('center1,center2',[(np.random.random(3)*.5,np.random.random()*8),
|
||||
(np.random.randint(4,8,(3)),np.random.randint(9,12,(3)))])
|
||||
|
@ -265,13 +272,14 @@ class TestGeom:
|
|||
np.random.rand()*4,
|
||||
np.random.randint(20)])
|
||||
def test_add_primitive_shift(self,center1,center2,diameter,exponent):
|
||||
"""Same volume fraction for periodic microstructures and different center."""
|
||||
"""Same volume fraction for periodic geometries and different center."""
|
||||
o = np.random.random(3)-.5
|
||||
g = np.random.randint(8,32,(3))
|
||||
s = np.random.random(3)+.5
|
||||
G_1 = Geom(np.ones(g,'i'),s,o).add_primitive(diameter,center1,exponent)
|
||||
G_2 = Geom(np.ones(g,'i'),s,o).add_primitive(diameter,center2,exponent)
|
||||
assert np.count_nonzero(G_1.microstructure!=2) == np.count_nonzero(G_2.microstructure!=2)
|
||||
assert np.count_nonzero(G_1.material!=2) == np.count_nonzero(G_2.material!=2)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('center',[np.random.randint(4,10,(3)),
|
||||
np.random.randint(2,10),
|
||||
|
@ -288,6 +296,7 @@ class TestGeom:
|
|||
G_2 = Geom(np.ones(g,'i'),[1.,1.,1.]).add_primitive(.3,center,1,fill,Rotation.from_Eulers(eu),inverse,periodic=periodic)
|
||||
assert geom_equal(G_1,G_2)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('trigger',[[1],[]])
|
||||
def test_vicinity_offset(self,trigger):
|
||||
offset = np.random.randint(2,4)
|
||||
|
@ -306,13 +315,15 @@ class TestGeom:
|
|||
|
||||
geom = Geom(m,np.random.rand(3)).vicinity_offset(vicinity,offset,trigger=trigger)
|
||||
|
||||
assert np.all(m2==geom.microstructure)
|
||||
assert np.all(m2==geom.material)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('periodic',[True,False])
|
||||
def test_vicinity_offset_invariant(self,default,periodic):
|
||||
old = default.get_microstructure()
|
||||
default.vicinity_offset(trigger=[old.max()+1,old.min()-1])
|
||||
assert np.all(old==default.microstructure)
|
||||
offset = default.vicinity_offset(trigger=[default.material.max()+1,
|
||||
default.material.min()-1])
|
||||
assert np.all(offset.material==default.material)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('periodic',[True,False])
|
||||
def test_tessellation_approaches(self,periodic):
|
||||
|
@ -320,10 +331,11 @@ class TestGeom:
|
|||
size = np.random.random(3) + 1.0
|
||||
N_seeds= np.random.randint(10,30)
|
||||
seeds = np.random.rand(N_seeds,3) * np.broadcast_to(size,(N_seeds,3))
|
||||
Voronoi = Geom.from_Voronoi_tessellation( grid,size,seeds, periodic)
|
||||
Laguerre = Geom.from_Laguerre_tessellation(grid,size,seeds,np.ones(N_seeds),periodic)
|
||||
Voronoi = Geom.from_Voronoi_tessellation( grid,size,seeds, np.arange(N_seeds)+5,periodic)
|
||||
Laguerre = Geom.from_Laguerre_tessellation(grid,size,seeds,np.ones(N_seeds),np.arange(N_seeds)+5,periodic)
|
||||
assert geom_equal(Laguerre,Voronoi)
|
||||
|
||||
|
||||
def test_Laguerre_weights(self):
|
||||
grid = np.random.randint(10,20,3)
|
||||
size = np.random.random(3) + 1.0
|
||||
|
@ -332,18 +344,61 @@ class TestGeom:
|
|||
weights= np.full((N_seeds),-np.inf)
|
||||
ms = np.random.randint(1, N_seeds+1)
|
||||
weights[ms-1] = np.random.random()
|
||||
Laguerre = Geom.from_Laguerre_tessellation(grid,size,seeds,weights,np.random.random()>0.5)
|
||||
assert np.all(Laguerre.microstructure == ms)
|
||||
Laguerre = Geom.from_Laguerre_tessellation(grid,size,seeds,weights,periodic=np.random.random()>0.5)
|
||||
assert np.all(Laguerre.material == ms)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('approach',['Laguerre','Voronoi'])
|
||||
def test_tessellate_bicrystal(self,approach):
|
||||
grid = np.random.randint(5,10,3)*2
|
||||
size = grid.astype(np.float)
|
||||
seeds = np.vstack((size*np.array([0.5,0.25,0.5]),size*np.array([0.5,0.75,0.5])))
|
||||
microstructure = np.ones(grid)
|
||||
microstructure[:,grid[1]//2:,:] = 2
|
||||
material = np.ones(grid)
|
||||
material[:,grid[1]//2:,:] = 2
|
||||
if approach == 'Laguerre':
|
||||
geom = Geom.from_Laguerre_tessellation(grid,size,seeds,np.ones(2),np.random.random()>0.5)
|
||||
geom = Geom.from_Laguerre_tessellation(grid,size,seeds,np.ones(2),periodic=np.random.random()>0.5)
|
||||
elif approach == 'Voronoi':
|
||||
geom = Geom.from_Voronoi_tessellation(grid,size,seeds, np.random.random()>0.5)
|
||||
assert np.all(geom.microstructure == microstructure)
|
||||
geom = Geom.from_Voronoi_tessellation(grid,size,seeds, periodic=np.random.random()>0.5)
|
||||
assert np.all(geom.material == material)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('surface',['Schwarz P',
|
||||
'Double Primitive',
|
||||
'Schwarz D',
|
||||
'Complementary D',
|
||||
'Double Diamond',
|
||||
'Dprime',
|
||||
'Gyroid',
|
||||
'Gprime',
|
||||
'Karcher K',
|
||||
'Lidinoid',
|
||||
'Neovius',
|
||||
'Fisher-Koch S',
|
||||
])
|
||||
def test_minimal_surface_basic_properties(self,surface):
|
||||
grid = np.random.randint(60,100,3)
|
||||
size = np.ones(3)+np.random.rand(3)
|
||||
threshold = 2*np.random.rand()-1.
|
||||
periods = np.random.randint(2)+1
|
||||
materials = np.random.randint(0,40,2)
|
||||
geom = Geom.from_minimal_surface(grid,size,surface,threshold,periods,materials)
|
||||
assert set(geom.material.flatten()) | set(materials) == set(materials) \
|
||||
and (geom.size == size).all() and (geom.grid == grid).all()
|
||||
|
||||
@pytest.mark.parametrize('surface,threshold',[('Schwarz P',0),
|
||||
('Double Primitive',-1./6.),
|
||||
('Schwarz D',0),
|
||||
('Complementary D',0),
|
||||
('Double Diamond',-0.133),
|
||||
('Dprime',-0.0395),
|
||||
('Gyroid',0),
|
||||
('Gprime',0.22913),
|
||||
('Karcher K',0.17045),
|
||||
('Lidinoid',0.14455),
|
||||
('Neovius',0),
|
||||
('Fisher-Koch S',0),
|
||||
])
|
||||
def test_minimal_surface_volume(self,surface,threshold):
|
||||
grid = np.ones(3,dtype=int)*64
|
||||
geom = Geom.from_minimal_surface(grid,np.ones(3),surface,threshold)
|
||||
assert np.isclose(np.count_nonzero(geom.material==1)/np.prod(geom.grid),.5,rtol=1e-3)
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import os
|
||||
|
||||
import pytest
|
||||
import numpy as np
|
||||
from scipy import stats
|
||||
|
||||
from damask import Rotation
|
||||
from damask import Table
|
||||
from damask import _rotation
|
||||
from damask import grid_filters
|
||||
|
||||
n = 1000
|
||||
atol=1.e-4
|
||||
|
@ -13,7 +13,7 @@ atol=1.e-4
|
|||
@pytest.fixture
|
||||
def reference_dir(reference_dir_base):
|
||||
"""Directory containing reference results."""
|
||||
return os.path.join(reference_dir_base,'Rotation')
|
||||
return reference_dir_base/'Rotation'
|
||||
|
||||
@pytest.fixture
|
||||
def set_of_rotations(set_of_quaternions):
|
||||
|
@ -943,3 +943,39 @@ class TestRotation:
|
|||
sigma_out = np.degrees(np.std(dist))
|
||||
p = np.average(p)
|
||||
assert (.9 < sigma/sigma_out < 1.1) and p > 1e-2, f'{sigma/sigma_out},{p}'
|
||||
|
||||
|
||||
@pytest.mark.parametrize('fractions',[True,False])
|
||||
@pytest.mark.parametrize('degrees',[True,False])
|
||||
@pytest.mark.parametrize('N',[2**13,2**14,2**15])
|
||||
def test_ODF_cell(self,reference_dir,fractions,degrees,N):
|
||||
steps = np.array([144,36,36])
|
||||
limits = np.array([360.,90.,90.])
|
||||
rng = tuple(zip(np.zeros(3),limits))
|
||||
|
||||
weights = Table.load(reference_dir/'ODF_experimental_cell.txt').get('intensity').flatten()
|
||||
Eulers = grid_filters.cell_coord0(steps,limits)
|
||||
Eulers = np.radians(Eulers) if not degrees else Eulers
|
||||
|
||||
Eulers_r = Rotation.from_ODF(weights,Eulers.reshape(-1,3,order='F'),N,degrees,fractions).as_Eulers(True)
|
||||
weights_r = np.histogramdd(Eulers_r,steps,rng)[0].flatten(order='F')/N * np.sum(weights)
|
||||
|
||||
if fractions: assert np.sqrt(((weights_r - weights) ** 2).mean()) < 4
|
||||
|
||||
@pytest.mark.parametrize('degrees',[True,False])
|
||||
@pytest.mark.parametrize('N',[2**13,2**14,2**15])
|
||||
def test_ODF_node(self,reference_dir,degrees,N):
|
||||
steps = np.array([144,36,36])
|
||||
limits = np.array([360.,90.,90.])
|
||||
rng = tuple(zip(-limits/steps*.5,limits-limits/steps*.5))
|
||||
|
||||
weights = Table.load(reference_dir/'ODF_experimental.txt').get('intensity')
|
||||
weights = weights.reshape(steps+1,order='F')[:-1,:-1,:-1].reshape(-1,order='F')
|
||||
|
||||
Eulers = grid_filters.node_coord0(steps,limits)[:-1,:-1,:-1]
|
||||
Eulers = np.radians(Eulers) if not degrees else Eulers
|
||||
|
||||
Eulers_r = Rotation.from_ODF(weights,Eulers.reshape(-1,3,order='F'),N,degrees).as_Eulers(True)
|
||||
weights_r = np.histogramdd(Eulers_r,steps,rng)[0].flatten(order='F')/N * np.sum(weights)
|
||||
|
||||
assert np.sqrt(((weights_r - weights) ** 2).mean()) < 5
|
||||
|
|
|
@ -34,31 +34,31 @@ class TestTable:
|
|||
assert np.allclose(d,1.0) and d.shape[1:] == (1,)
|
||||
|
||||
@pytest.mark.parametrize('mode',['str','path'])
|
||||
def test_write_read(self,default,tmpdir,mode):
|
||||
default.save(tmpdir/'default.txt')
|
||||
def test_write_read(self,default,tmp_path,mode):
|
||||
default.save(tmp_path/'default.txt')
|
||||
if mode == 'path':
|
||||
new = Table.load(tmpdir/'default.txt')
|
||||
new = Table.load(tmp_path/'default.txt')
|
||||
elif mode == 'str':
|
||||
new = Table.load(str(tmpdir/'default.txt'))
|
||||
new = Table.load(str(tmp_path/'default.txt'))
|
||||
assert all(default.data==new.data) and default.shapes == new.shapes
|
||||
|
||||
def test_write_read_file(self,default,tmpdir):
|
||||
with open(tmpdir/'default.txt','w') as f:
|
||||
def test_write_read_file(self,default,tmp_path):
|
||||
with open(tmp_path/'default.txt','w') as f:
|
||||
default.save(f)
|
||||
with open(tmpdir/'default.txt') as f:
|
||||
with open(tmp_path/'default.txt') as f:
|
||||
new = Table.load(f)
|
||||
assert all(default.data==new.data) and default.shapes == new.shapes
|
||||
|
||||
def test_write_read_legacy_style(self,default,tmpdir):
|
||||
with open(tmpdir/'legacy.txt','w') as f:
|
||||
def test_write_read_legacy_style(self,default,tmp_path):
|
||||
with open(tmp_path/'legacy.txt','w') as f:
|
||||
default.save(f,legacy=True)
|
||||
with open(tmpdir/'legacy.txt') as f:
|
||||
with open(tmp_path/'legacy.txt') as f:
|
||||
new = Table.load(f)
|
||||
assert all(default.data==new.data) and default.shapes == new.shapes
|
||||
|
||||
def test_write_invalid_format(self,default,tmpdir):
|
||||
def test_write_invalid_format(self,default,tmp_path):
|
||||
with pytest.raises(TypeError):
|
||||
default.save(tmpdir/'shouldnotbethere.txt',format='invalid')
|
||||
default.save(tmp_path/'shouldnotbethere.txt',format='invalid')
|
||||
|
||||
@pytest.mark.parametrize('mode',['str','path'])
|
||||
def test_read_ang(self,reference_dir,mode):
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
import pytest
|
||||
import numpy as np
|
||||
from scipy.spatial import cKDTree
|
||||
|
||||
from damask import seeds
|
||||
from damask import grid_filters
|
||||
from damask import Geom
|
||||
|
||||
class TestSeeds:
|
||||
|
||||
@pytest.mark.parametrize('grid',[None,np.ones(3,dtype='i')*10])
|
||||
def test_from_random(self,grid):
|
||||
N_seeds = np.random.randint(30,300)
|
||||
size = np.ones(3) + np.random.random(3)
|
||||
coords = seeds.from_random(size,N_seeds,grid)
|
||||
assert (0<=coords).all() and (coords<size).all()
|
||||
|
||||
@pytest.mark.parametrize('periodic',[True,False])
|
||||
def test_from_Poisson_disc(self,periodic):
|
||||
N_seeds = np.random.randint(30,300)
|
||||
N_candidates = N_seeds//15
|
||||
distance = np.random.random()
|
||||
size = np.ones(3)*distance*N_seeds
|
||||
coords = seeds.from_Poisson_disc(size,N_seeds,N_candidates,distance,periodic=periodic)
|
||||
min_dists, _ = cKDTree(coords,boxsize=size).query(coords, 2) if periodic else \
|
||||
cKDTree(coords).query(coords, 2)
|
||||
assert (0<= coords).all() and (coords<size).all() and np.min(min_dists[:,1])>=distance
|
||||
|
||||
def test_from_geom_reconstruct(self):
|
||||
grid = np.random.randint(10,20,3)
|
||||
N_seeds = np.random.randint(30,300)
|
||||
size = np.ones(3) + np.random.random(3)
|
||||
coords = seeds.from_random(size,N_seeds,grid)
|
||||
geom_1 = Geom.from_Voronoi_tessellation(grid,size,coords)
|
||||
coords,material = seeds.from_geom(geom_1)
|
||||
geom_2 = Geom.from_Voronoi_tessellation(grid,size,coords,material)
|
||||
assert (geom_2.material==geom_1.material).all()
|
||||
|
||||
@pytest.mark.parametrize('periodic',[True,False])
|
||||
@pytest.mark.parametrize('average',[True,False])
|
||||
def test_from_geom_grid(self,periodic,average):
|
||||
grid = np.random.randint(10,20,3)
|
||||
size = np.ones(3) + np.random.random(3)
|
||||
coords = grid_filters.cell_coord0(grid,size).reshape(-1,3)
|
||||
np.random.shuffle(coords)
|
||||
geom_1 = Geom.from_Voronoi_tessellation(grid,size,coords)
|
||||
coords,material = seeds.from_geom(geom_1,average=average,periodic=periodic)
|
||||
geom_2 = Geom.from_Voronoi_tessellation(grid,size,coords,material)
|
||||
assert (geom_2.material==geom_1.material).all()
|
||||
|
||||
@pytest.mark.parametrize('periodic',[True,False])
|
||||
@pytest.mark.parametrize('average',[True,False])
|
||||
@pytest.mark.parametrize('invert',[True,False])
|
||||
def test_from_geom_selection(self,periodic,average,invert):
|
||||
grid = np.random.randint(10,20,3)
|
||||
N_seeds = np.random.randint(30,300)
|
||||
size = np.ones(3) + np.random.random(3)
|
||||
coords = seeds.from_random(size,N_seeds,grid)
|
||||
geom = Geom.from_Voronoi_tessellation(grid,size,coords)
|
||||
selection=np.random.randint(N_seeds)+1
|
||||
coords,material = seeds.from_geom(geom,average=average,periodic=periodic,invert=invert,selection=[selection])
|
||||
assert selection not in material if invert else (selection==material).all()
|
|
@ -1,5 +1,7 @@
|
|||
import pytest
|
||||
import numpy as np
|
||||
from scipy import stats
|
||||
|
||||
from damask import util
|
||||
|
||||
|
||||
|
@ -31,3 +33,14 @@ class TestUtil:
|
|||
def test_lackofprecision(self):
|
||||
with pytest.raises(ValueError):
|
||||
util.scale_to_coprime(np.array([1/333.333,1,1]))
|
||||
|
||||
|
||||
@pytest.mark.parametrize('rv',[stats.rayleigh(),stats.weibull_min(1.2),stats.halfnorm(),stats.pareto(2.62)])
|
||||
def test_hybridIA(self,rv):
|
||||
bins = np.linspace(0,10,100000)
|
||||
centers = (bins[1:]+bins[:-1])/2
|
||||
N_samples = bins.shape[0]-1000
|
||||
dist = rv.pdf(centers)
|
||||
selected = util.hybrid_IA(dist,N_samples)
|
||||
dist_sampled = np.histogram(centers[selected],bins)[0]/N_samples*np.sum(dist)
|
||||
assert np.sqrt(((dist - dist_sampled) ** 2).mean()) < .025 and selected.shape[0]==N_samples
|
||||
|
|
|
@ -103,7 +103,6 @@ end subroutine CPFEM_initAll
|
|||
subroutine CPFEM_init
|
||||
|
||||
class(tNode), pointer :: &
|
||||
num_commercialFEM, &
|
||||
debug_CPFEM
|
||||
|
||||
print'(/,a)', ' <<<+- CPFEM init -+>>>'; flush(IO_STDOUT)
|
||||
|
@ -112,12 +111,6 @@ subroutine CPFEM_init
|
|||
allocate(CPFEM_dcsdE( 6,6,discretization_nIP,discretization_nElem), source= 0.0_pReal)
|
||||
allocate(CPFEM_dcsdE_knownGood(6,6,discretization_nIP,discretization_nElem), source= 0.0_pReal)
|
||||
|
||||
!------------------------------------------------------------------------------
|
||||
! read numerical parameters and do sanity check
|
||||
num_commercialFEM => config_numerics%get('commercialFEM',defaultVal=emptyDict)
|
||||
num%iJacoStiffness = num_commercialFEM%get_asInt('ijacostiffness',defaultVal=1)
|
||||
if (num%iJacoStiffness < 1) call IO_error(301,ext_msg='iJacoStiffness')
|
||||
|
||||
!------------------------------------------------------------------------------
|
||||
! read debug options
|
||||
|
||||
|
@ -161,7 +154,6 @@ subroutine CPFEM_general(mode, ffn, ffn1, temperature_inp, dt, elFE, ip, cauchyS
|
|||
|
||||
integer(pInt) elCP, & ! crystal plasticity element number
|
||||
i, j, k, l, m, n, ph, homog, mySource
|
||||
logical updateJaco ! flag indicating if Jacobian has to be updated
|
||||
|
||||
real(pReal), parameter :: ODD_STRESS = 1e15_pReal, & !< return value for stress if terminallyIll
|
||||
ODD_JACOBIAN = 1e50_pReal !< return value for jacobian if terminallyIll
|
||||
|
@ -204,12 +196,11 @@ subroutine CPFEM_general(mode, ffn, ffn1, temperature_inp, dt, elFE, ip, cauchyS
|
|||
CPFEM_dcsde(1:6,1:6,ip,elCP) = ODD_JACOBIAN * math_eye(6)
|
||||
|
||||
else validCalculation
|
||||
updateJaco = mod(cycleCounter,num%iJacoStiffness) == 0
|
||||
FEsolving_execElem = elCP
|
||||
FEsolving_execIP = ip
|
||||
if (debugCPFEM%extensive) &
|
||||
print'(a,i8,1x,i2)', '<< CPFEM >> calculation for elFE ip ',elFE,ip
|
||||
call materialpoint_stressAndItsTangent(updateJaco, dt)
|
||||
call materialpoint_stressAndItsTangent(dt)
|
||||
|
||||
terminalIllness: if (terminallyIll) then
|
||||
|
||||
|
|
|
@ -61,13 +61,13 @@ void signalusr2_c(void (*handler)(int)){
|
|||
|
||||
void inflate_c(const uLong *s_deflated, const uLong *s_inflated, const Byte deflated[], Byte inflated[]){
|
||||
/* make writable copy, uncompress will write to it */
|
||||
uLong s_inflated_;
|
||||
uLong s_inflated_,i;
|
||||
s_inflated_ = *s_inflated;
|
||||
|
||||
if(uncompress((Bytef *)inflated, &s_inflated_, (Bytef *)deflated, *s_deflated) == Z_OK)
|
||||
return;
|
||||
else{
|
||||
for(uLong i=0;i<*s_inflated;i++){
|
||||
for(i=0;i<*s_inflated;i++){
|
||||
inflated[i] = 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -82,7 +82,7 @@ subroutine DAMASK_interface_init
|
|||
|
||||
print'(/,a)', ' <<<+- DAMASK_interface init -+>>>'
|
||||
|
||||
open(OUTPUT_unit, encoding='UTF-8') ! for special characters in output
|
||||
if(worldrank == 0) open(OUTPUT_UNIT, encoding='UTF-8') ! for special characters in output
|
||||
|
||||
! http://patorjk.com/software/taag/#p=display&f=Lean&t=DAMASK%203
|
||||
#ifdef DEBUG
|
||||
|
|
10
src/IO.f90
10
src/IO.f90
|
@ -427,20 +427,20 @@ subroutine IO_error(error_ID,el,ip,g,instance,ext_msg)
|
|||
case (146)
|
||||
msg = 'number of values does not match'
|
||||
case (148)
|
||||
msg = 'Nconstituents mismatch between homogenization and microstructure'
|
||||
msg = 'Nconstituents mismatch between homogenization and material'
|
||||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! material error messages and related messages in mesh
|
||||
case (150)
|
||||
msg = 'index out of bounds'
|
||||
case (151)
|
||||
msg = 'microstructure has no constituents'
|
||||
msg = 'material has no constituents'
|
||||
case (153)
|
||||
msg = 'sum of phase fractions differs from 1'
|
||||
case (155)
|
||||
msg = 'microstructure index out of bounds'
|
||||
msg = 'material index out of bounds'
|
||||
case (180)
|
||||
msg = 'missing/invalid microstructure definition via State Variable 2'
|
||||
msg = 'missing/invalid material definition via State Variable 2'
|
||||
case (190)
|
||||
msg = 'unknown element type:'
|
||||
case (191)
|
||||
|
@ -526,7 +526,7 @@ subroutine IO_error(error_ID,el,ip,g,instance,ext_msg)
|
|||
case (842)
|
||||
msg = 'incomplete information in grid mesh header'
|
||||
case (843)
|
||||
msg = 'microstructure count mismatch'
|
||||
msg = 'material count mismatch'
|
||||
case (844)
|
||||
msg = 'invalid VTR file'
|
||||
case (846)
|
||||
|
|
|
@ -17,18 +17,18 @@ submodule(constitutive:constitutive_plastic) plastic_disloTungsten
|
|||
D_0 = 1.0_pReal, & !< prefactor for self-diffusion coefficient
|
||||
Q_cl = 1.0_pReal !< activation energy for dislocation climb
|
||||
real(pReal), allocatable, dimension(:) :: &
|
||||
b_sl, & !< magnitude of burgers vector [m]
|
||||
b_sl, & !< magnitude of Burgers vector [m]
|
||||
D_a, &
|
||||
i_sl, & !< Adj. parameter for distance between 2 forest dislocations
|
||||
atomicVolume, & !< factor to calculate atomic volume
|
||||
tau_0, & !< Peierls stress
|
||||
f_at, & !< factor to calculate atomic volume
|
||||
tau_Peierls, & !< Peierls stress
|
||||
!* mobility law parameters
|
||||
delta_F, & !< activation energy for glide [J]
|
||||
v0, & !< dislocation velocity prefactor [m/s]
|
||||
Q_s, & !< activation energy for glide [J]
|
||||
v_0, & !< dislocation velocity prefactor [m/s]
|
||||
p, & !< p-exponent in glide velocity
|
||||
q, & !< q-exponent in glide velocity
|
||||
B, & !< friction coefficient
|
||||
kink_height, & !< height of the kink pair
|
||||
h, & !< height of the kink pair
|
||||
w, & !< width of the kink pair
|
||||
omega !< attempt frequency for kink pair nucleation
|
||||
real(pReal), allocatable, dimension(:,:) :: &
|
||||
|
@ -142,7 +142,7 @@ module function plastic_disloTungsten_init() result(myPlasticity)
|
|||
phase%get_asFloat('c/a',defaultVal=0.0_pReal))
|
||||
|
||||
if(trim(phase%get_asString('lattice')) == 'bcc') then
|
||||
a = pl%get_asFloats('nonSchmid_coefficients',defaultVal = emptyRealArray)
|
||||
a = pl%get_asFloats('a_nonSchmid',defaultVal = emptyRealArray)
|
||||
prm%nonSchmid_pos = lattice_nonSchmidMatrix(N_sl,a,+1)
|
||||
prm%nonSchmid_neg = lattice_nonSchmidMatrix(N_sl,a,-1)
|
||||
else
|
||||
|
@ -158,17 +158,17 @@ module function plastic_disloTungsten_init() result(myPlasticity)
|
|||
|
||||
rho_mob_0 = pl%get_asFloats('rho_mob_0', requiredSize=size(N_sl))
|
||||
rho_dip_0 = pl%get_asFloats('rho_dip_0', requiredSize=size(N_sl))
|
||||
prm%v0 = pl%get_asFloats('v_0', requiredSize=size(N_sl))
|
||||
prm%v_0 = pl%get_asFloats('v_0', requiredSize=size(N_sl))
|
||||
prm%b_sl = pl%get_asFloats('b_sl', requiredSize=size(N_sl))
|
||||
prm%delta_F = pl%get_asFloats('Q_s', requiredSize=size(N_sl))
|
||||
prm%Q_s = pl%get_asFloats('Q_s', requiredSize=size(N_sl))
|
||||
|
||||
prm%i_sl = pl%get_asFloats('i_sl', requiredSize=size(N_sl))
|
||||
prm%tau_0 = pl%get_asFloats('tau_peierls', requiredSize=size(N_sl))
|
||||
prm%tau_Peierls = pl%get_asFloats('tau_Peierls', requiredSize=size(N_sl))
|
||||
prm%p = pl%get_asFloats('p_sl', requiredSize=size(N_sl), &
|
||||
defaultVal=[(1.0_pReal,i=1,size(N_sl))])
|
||||
prm%q = pl%get_asFloats('q_sl', requiredSize=size(N_sl), &
|
||||
defaultVal=[(1.0_pReal,i=1,size(N_sl))])
|
||||
prm%kink_height = pl%get_asFloats('h', requiredSize=size(N_sl))
|
||||
prm%h = pl%get_asFloats('h', requiredSize=size(N_sl))
|
||||
prm%w = pl%get_asFloats('w', requiredSize=size(N_sl))
|
||||
prm%omega = pl%get_asFloats('omega', requiredSize=size(N_sl))
|
||||
prm%B = pl%get_asFloats('B', requiredSize=size(N_sl))
|
||||
|
@ -176,7 +176,7 @@ module function plastic_disloTungsten_init() result(myPlasticity)
|
|||
prm%D = pl%get_asFloat('D')
|
||||
prm%D_0 = pl%get_asFloat('D_0')
|
||||
prm%Q_cl = pl%get_asFloat('Q_cl')
|
||||
prm%atomicVolume = pl%get_asFloat('f_at') * prm%b_sl**3.0_pReal
|
||||
prm%f_at = pl%get_asFloat('f_at') * prm%b_sl**3.0_pReal
|
||||
prm%D_a = pl%get_asFloat('D_a') * prm%b_sl
|
||||
|
||||
prm%dipoleformation = pl%get_asBool('dipole_formation_factor', defaultVal = .true.)
|
||||
|
@ -186,16 +186,16 @@ module function plastic_disloTungsten_init() result(myPlasticity)
|
|||
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%Q_s = math_expand(prm%Q_s, N_sl)
|
||||
prm%b_sl = math_expand(prm%b_sl, N_sl)
|
||||
prm%kink_height = math_expand(prm%kink_height, N_sl)
|
||||
prm%h = math_expand(prm%h, 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%tau_Peierls = math_expand(prm%tau_Peierls, N_sl)
|
||||
prm%v_0 = math_expand(prm%v_0, 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%f_at = math_expand(prm%f_at, N_sl)
|
||||
prm%D_a = math_expand(prm%D_a, N_sl)
|
||||
|
||||
! sanity checks
|
||||
|
@ -203,17 +203,17 @@ module function plastic_disloTungsten_init() result(myPlasticity)
|
|||
if ( prm%Q_cl <= 0.0_pReal) extmsg = trim(extmsg)//' Q_cl'
|
||||
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)//' v_0'
|
||||
if (any(prm%v_0 < 0.0_pReal)) extmsg = trim(extmsg)//' v_0'
|
||||
if (any(prm%b_sl <= 0.0_pReal)) extmsg = trim(extmsg)//' b_sl'
|
||||
if (any(prm%delta_F <= 0.0_pReal)) extmsg = trim(extmsg)//' Q_s'
|
||||
if (any(prm%tau_0 < 0.0_pReal)) extmsg = trim(extmsg)//' tau_peierls'
|
||||
if (any(prm%Q_s <= 0.0_pReal)) extmsg = trim(extmsg)//' Q_s'
|
||||
if (any(prm%tau_Peierls < 0.0_pReal)) extmsg = trim(extmsg)//' tau_Peierls'
|
||||
if (any(prm%D_a <= 0.0_pReal)) extmsg = trim(extmsg)//' D_a or b_sl'
|
||||
if (any(prm%atomicVolume <= 0.0_pReal)) extmsg = trim(extmsg)//' f_at or b_sl'
|
||||
if (any(prm%f_at <= 0.0_pReal)) extmsg = trim(extmsg)//' f_at or b_sl'
|
||||
|
||||
else slipActive
|
||||
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, &
|
||||
allocate(prm%b_sl,prm%D_a,prm%i_sl,prm%f_at,prm%tau_Peierls, &
|
||||
prm%Q_s,prm%v_0,prm%p,prm%q,prm%B,prm%h,prm%w,prm%omega, &
|
||||
source = emptyRealArray)
|
||||
allocate(prm%forestProjection(0,0))
|
||||
allocate(prm%h_sl_sl (0,0))
|
||||
|
@ -354,7 +354,7 @@ module subroutine plastic_disloTungsten_dotState(Mp,T,instance,of)
|
|||
dot_rho_dip_formation = merge(2.0_pReal*dip_distance* stt%rho_mob(:,of)*abs(dot%gamma_sl(:,of))/prm%b_sl, & ! ToDo: ignore region of spontaneous annihilation
|
||||
0.0_pReal, &
|
||||
prm%dipoleformation)
|
||||
v_cl = (3.0_pReal*prm%mu*VacancyDiffusion*prm%atomicVolume/(2.0_pReal*pi*kB*T)) &
|
||||
v_cl = (3.0_pReal*prm%mu*VacancyDiffusion*prm%f_at/(2.0_pReal*pi*kB*T)) &
|
||||
* (1.0_pReal/(dip_distance+prm%D_a))
|
||||
dot_rho_dip_climb = (4.0_pReal*v_cl*stt%rho_dip(:,of))/(dip_distance-prm%D_a) ! ToDo: Discuss with Franz: Stress dependency?
|
||||
end where
|
||||
|
@ -477,12 +477,12 @@ pure subroutine kinetics(Mp,T,instance,of, &
|
|||
if (present(tau_pos_out)) tau_pos_out = tau_pos
|
||||
if (present(tau_neg_out)) tau_neg_out = tau_neg
|
||||
|
||||
associate(BoltzmannRatio => prm%delta_F/(kB*T), &
|
||||
dot_gamma_0 => stt%rho_mob(:,of)*prm%b_sl*prm%v0, &
|
||||
associate(BoltzmannRatio => prm%Q_s/(kB*T), &
|
||||
dot_gamma_0 => stt%rho_mob(:,of)*prm%b_sl*prm%v_0, &
|
||||
effectiveLength => dst%Lambda_sl(:,of) - prm%w)
|
||||
|
||||
significantPositiveTau: where(abs(tau_pos)-dst%threshold_stress(:,of) > tol_math_check)
|
||||
StressRatio = (abs(tau_pos)-dst%threshold_stress(:,of))/prm%tau_0
|
||||
StressRatio = (abs(tau_pos)-dst%threshold_stress(:,of))/prm%tau_Peierls
|
||||
StressRatio_p = StressRatio** prm%p
|
||||
StressRatio_pminus1 = StressRatio**(prm%p-1.0_pReal)
|
||||
needsGoodName = exp(-BoltzmannRatio*(1-StressRatio_p) ** prm%q)
|
||||
|
@ -490,7 +490,7 @@ pure subroutine kinetics(Mp,T,instance,of, &
|
|||
t_n = prm%b_sl/(needsGoodName*prm%omega*effectiveLength)
|
||||
t_k = effectiveLength * prm%B /(2.0_pReal*prm%b_sl*tau_pos)
|
||||
|
||||
vel = prm%kink_height/(t_n + t_k)
|
||||
vel = prm%h/(t_n + t_k)
|
||||
|
||||
dot_gamma_pos = dot_gamma_0 * sign(vel,tau_pos) * 0.5_pReal
|
||||
else where significantPositiveTau
|
||||
|
@ -500,10 +500,10 @@ pure subroutine kinetics(Mp,T,instance,of, &
|
|||
if (present(ddot_gamma_dtau_pos)) then
|
||||
significantPositiveTau2: where(abs(tau_pos)-dst%threshold_stress(:,of) > tol_math_check)
|
||||
dtn = -1.0_pReal * t_n * BoltzmannRatio * prm%p * prm%q * (1.0_pReal-StressRatio_p)**(prm%q - 1.0_pReal) &
|
||||
* (StressRatio)**(prm%p - 1.0_pReal) / prm%tau_0
|
||||
* (StressRatio)**(prm%p - 1.0_pReal) / prm%tau_Peierls
|
||||
dtk = -1.0_pReal * t_k / tau_pos
|
||||
|
||||
dvel = -1.0_pReal * prm%kink_height * (dtk + dtn) / (t_n + t_k)**2.0_pReal
|
||||
dvel = -1.0_pReal * prm%h * (dtk + dtn) / (t_n + t_k)**2.0_pReal
|
||||
|
||||
ddot_gamma_dtau_pos = dot_gamma_0 * dvel* 0.5_pReal
|
||||
else where significantPositiveTau2
|
||||
|
@ -512,7 +512,7 @@ pure subroutine kinetics(Mp,T,instance,of, &
|
|||
endif
|
||||
|
||||
significantNegativeTau: where(abs(tau_neg)-dst%threshold_stress(:,of) > tol_math_check)
|
||||
StressRatio = (abs(tau_neg)-dst%threshold_stress(:,of))/prm%tau_0
|
||||
StressRatio = (abs(tau_neg)-dst%threshold_stress(:,of))/prm%tau_Peierls
|
||||
StressRatio_p = StressRatio** prm%p
|
||||
StressRatio_pminus1 = StressRatio**(prm%p-1.0_pReal)
|
||||
needsGoodName = exp(-BoltzmannRatio*(1-StressRatio_p) ** prm%q)
|
||||
|
@ -520,7 +520,7 @@ pure subroutine kinetics(Mp,T,instance,of, &
|
|||
t_n = prm%b_sl/(needsGoodName*prm%omega*effectiveLength)
|
||||
t_k = effectiveLength * prm%B /(2.0_pReal*prm%b_sl*tau_pos)
|
||||
|
||||
vel = prm%kink_height/(t_n + t_k)
|
||||
vel = prm%h/(t_n + t_k)
|
||||
|
||||
dot_gamma_neg = dot_gamma_0 * sign(vel,tau_neg) * 0.5_pReal
|
||||
else where significantNegativeTau
|
||||
|
@ -530,10 +530,10 @@ pure subroutine kinetics(Mp,T,instance,of, &
|
|||
if (present(ddot_gamma_dtau_neg)) then
|
||||
significantNegativeTau2: where(abs(tau_neg)-dst%threshold_stress(:,of) > tol_math_check)
|
||||
dtn = -1.0_pReal * t_n * BoltzmannRatio * prm%p * prm%q * (1.0_pReal-StressRatio_p)**(prm%q - 1.0_pReal) &
|
||||
* (StressRatio)**(prm%p - 1.0_pReal) / prm%tau_0
|
||||
* (StressRatio)**(prm%p - 1.0_pReal) / prm%tau_Peierls
|
||||
dtk = -1.0_pReal * t_k / tau_neg
|
||||
|
||||
dvel = -1.0_pReal * prm%kink_height * (dtk + dtn) / (t_n + t_k)**2.0_pReal
|
||||
dvel = -1.0_pReal * prm%h * (dtk + dtn) / (t_n + t_k)**2.0_pReal
|
||||
|
||||
ddot_gamma_dtau_neg = dot_gamma_0 * dvel * 0.5_pReal
|
||||
else where significantNegativeTau2
|
||||
|
|
|
@ -16,38 +16,38 @@ submodule(constitutive:constitutive_plastic) plastic_dislotwin
|
|||
real(pReal) :: &
|
||||
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
|
||||
D_0 = 1.0_pReal, & !< prefactor for self-diffusion coefficient
|
||||
Q_cl = 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, & !< adjustment parameter to calculate minimum dipole distance
|
||||
D_a = 1.0_pReal, & !< adjustment parameter to calculate minimum dipole distance
|
||||
i_tw = 1.0_pReal, & !< adjustment parameter to calculate MFP for twinning
|
||||
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
|
||||
x_c_tw = 1.0_pReal, & !< critical distance for formation of twin nucleus
|
||||
x_c_tr = 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
|
||||
xi_sb = 1.0_pReal, & !< value for shearband resistance
|
||||
v_sb = 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
|
||||
Gamma_sf_0K = 1.0_pReal, & !< stacking fault energy at zero K
|
||||
dGamma_sf_dT = 1.0_pReal, & !< temperature dependence of stacking fault energy
|
||||
delta_G = 1.0_pReal, & !< Free energy difference between austensite and martensite
|
||||
i_tr = 1.0_pReal, & !< adjustment parameter to calculate MFP for transformation
|
||||
h = 1.0_pReal !< Stack height of hex nucleus
|
||||
real(pReal), allocatable, dimension(:) :: &
|
||||
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
|
||||
Delta_F,& !< activation energy for glide [J] for each slip system
|
||||
v0, & !< dislocation velocity prefactor [m/s] for each slip system
|
||||
b_sl, & !< absolute length of Burgers vector [m] for each slip system
|
||||
b_tw, & !< absolute length of Burgers vector [m] for each twin system
|
||||
b_tr, & !< absolute length of Burgers vector [m] for each transformation system
|
||||
Q_s,& !< activation energy for glide [J] for each slip system
|
||||
v_0, & !< dislocation velocity prefactor [m/s] for each slip system
|
||||
dot_N_0_tw, & !< twin nucleation rate [1/m³s] for each twin system
|
||||
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
|
||||
i_sl, & !< Adj. parameter for distance between 2 forest dislocations for each slip system
|
||||
t_tr, & !< martensite lamellar thickness [m] for each trans system and instance
|
||||
p, & !< p-exponent in glide velocity
|
||||
q, & !< q-exponent in glide velocity
|
||||
|
@ -209,23 +209,23 @@ module function plastic_dislotwin_init() result(myPlasticity)
|
|||
|
||||
rho_mob_0 = pl%get_asFloats('rho_mob_0', requiredSize=size(N_sl))
|
||||
rho_dip_0 = pl%get_asFloats('rho_dip_0', requiredSize=size(N_sl))
|
||||
prm%v0 = pl%get_asFloats('v_0', requiredSize=size(N_sl))
|
||||
prm%v_0 = pl%get_asFloats('v_0', requiredSize=size(N_sl))
|
||||
prm%b_sl = pl%get_asFloats('b_sl', requiredSize=size(N_sl))
|
||||
prm%Delta_F = pl%get_asFloats('Q_s', requiredSize=size(N_sl))
|
||||
prm%CLambdaSlip = pl%get_asFloats('i_sl', requiredSize=size(N_sl))
|
||||
prm%Q_s = pl%get_asFloats('Q_s', requiredSize=size(N_sl))
|
||||
prm%i_sl = pl%get_asFloats('i_sl', requiredSize=size(N_sl))
|
||||
prm%p = pl%get_asFloats('p_sl', requiredSize=size(N_sl))
|
||||
prm%q = pl%get_asFloats('q_sl', requiredSize=size(N_sl))
|
||||
prm%B = pl%get_asFloats('B', requiredSize=size(N_sl), &
|
||||
defaultVal=[(0.0_pReal, i=1,size(N_sl))])
|
||||
|
||||
prm%tau_0 = pl%get_asFloat('tau_0')
|
||||
prm%CEdgeDipMinDistance = pl%get_asFloat('D_a')
|
||||
prm%D0 = pl%get_asFloat('D_0')
|
||||
prm%Qsd = pl%get_asFloat('Q_cl')
|
||||
prm%D_a = pl%get_asFloat('D_a')
|
||||
prm%D_0 = pl%get_asFloat('D_0')
|
||||
prm%Q_cl = pl%get_asFloat('Q_cl')
|
||||
prm%ExtendedDislocations = pl%get_asBool('extend_dislocations',defaultVal = .false.)
|
||||
if (prm%ExtendedDislocations) then
|
||||
prm%SFE_0K = pl%get_asFloat('Gamma_sf_0K')
|
||||
prm%dSFE_dT = pl%get_asFloat('dGamma_sf_dT')
|
||||
prm%Gamma_sf_0K = pl%get_asFloat('Gamma_sf_0K')
|
||||
prm%dGamma_sf_dT = pl%get_asFloat('dGamma_sf_dT')
|
||||
endif
|
||||
|
||||
prm%dipoleformation = .not. pl%get_asBool('no_dipole_formation',defaultVal = .false.)
|
||||
|
@ -238,29 +238,29 @@ module function plastic_dislotwin_init() result(myPlasticity)
|
|||
! expand: family => system
|
||||
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%v_0 = math_expand(prm%v_0, 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%Q_s = math_expand(prm%Q_s, N_sl)
|
||||
prm%i_sl = math_expand(prm%i_sl, 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)//' D_0'
|
||||
if ( prm%Qsd <= 0.0_pReal) extmsg = trim(extmsg)//' Q_cl'
|
||||
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(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)//' v_0'
|
||||
if (any(prm%v_0 < 0.0_pReal)) extmsg = trim(extmsg)//' v_0'
|
||||
if (any(prm%b_sl <= 0.0_pReal)) extmsg = trim(extmsg)//' b_sl'
|
||||
if (any(prm%Delta_F <= 0.0_pReal)) extmsg = trim(extmsg)//' Q_s'
|
||||
if (any(prm%CLambdaSlip <= 0.0_pReal)) extmsg = trim(extmsg)//' i_sl'
|
||||
if (any(prm%Q_s <= 0.0_pReal)) extmsg = trim(extmsg)//' Q_s'
|
||||
if (any(prm%i_sl <= 0.0_pReal)) extmsg = trim(extmsg)//' i_sl'
|
||||
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_sl'
|
||||
if (any(prm%q< 1.0_pReal .or. prm%q>2.0_pReal)) extmsg = trim(extmsg)//' q_sl'
|
||||
else slipActive
|
||||
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%b_sl,prm%Q_s,prm%v_0,prm%i_sl,prm%p,prm%q,prm%B,source=emptyRealArray)
|
||||
allocate(prm%forestProjection(0,0),prm%h_sl_sl(0,0))
|
||||
endif slipActive
|
||||
|
||||
|
@ -279,7 +279,7 @@ module function plastic_dislotwin_init() result(myPlasticity)
|
|||
prm%t_tw = pl%get_asFloats('t_tw', requiredSize=size(N_tw))
|
||||
prm%r = pl%get_asFloats('p_tw', requiredSize=size(N_tw))
|
||||
|
||||
prm%xc_twin = pl%get_asFloat('x_c_tw')
|
||||
prm%x_c_tw = pl%get_asFloat('x_c_tw')
|
||||
prm%L_tw = pl%get_asFloat('L_tw')
|
||||
prm%i_tw = pl%get_asFloat('i_tw')
|
||||
|
||||
|
@ -300,7 +300,7 @@ module function plastic_dislotwin_init() result(myPlasticity)
|
|||
prm%r = math_expand(prm%r,N_tw)
|
||||
|
||||
! sanity checks
|
||||
if ( prm%xc_twin < 0.0_pReal) extmsg = trim(extmsg)//' x_c_twin'
|
||||
if ( prm%x_c_tw < 0.0_pReal) extmsg = trim(extmsg)//' x_c_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'
|
||||
|
@ -324,8 +324,8 @@ module function plastic_dislotwin_init() result(myPlasticity)
|
|||
|
||||
prm%h = pl%get_asFloat('h', defaultVal=0.0_pReal) ! ToDo: How to handle that???
|
||||
prm%i_tr = pl%get_asFloat('i_tr', defaultVal=0.0_pReal) ! ToDo: How to handle that???
|
||||
prm%gamma_fcc_hex = pl%get_asFloat('delta_G')
|
||||
prm%xc_trans = pl%get_asFloat('x_c_tr', defaultVal=0.0_pReal) ! ToDo: How to handle that???
|
||||
prm%delta_G = pl%get_asFloat('delta_G')
|
||||
prm%x_c_tr = pl%get_asFloat('x_c_tr', defaultVal=0.0_pReal) ! ToDo: How to handle that???
|
||||
prm%L_tr = pl%get_asFloat('L_tr')
|
||||
|
||||
prm%h_tr_tr = lattice_interaction_TransByTrans(N_tr,pl%get_asFloats('h_tr_tr'), &
|
||||
|
@ -351,7 +351,7 @@ module function plastic_dislotwin_init() result(myPlasticity)
|
|||
prm%s = math_expand(prm%s,N_tr)
|
||||
|
||||
! sanity checks
|
||||
if ( prm%xc_trans < 0.0_pReal) extmsg = trim(extmsg)//' x_c_trans'
|
||||
if ( prm%x_c_tr < 0.0_pReal) extmsg = trim(extmsg)//' x_c_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'
|
||||
|
@ -366,15 +366,15 @@ module function plastic_dislotwin_init() result(myPlasticity)
|
|||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! shearband related parameters
|
||||
prm%sbVelocity = pl%get_asFloat('v_sb',defaultVal=0.0_pReal)
|
||||
if (prm%sbVelocity > 0.0_pReal) then
|
||||
prm%sbResistance = pl%get_asFloat('xi_sb')
|
||||
prm%v_sb = pl%get_asFloat('v_sb',defaultVal=0.0_pReal)
|
||||
if (prm%v_sb > 0.0_pReal) then
|
||||
prm%xi_sb = pl%get_asFloat('xi_sb')
|
||||
prm%E_sb = pl%get_asFloat('Q_sb')
|
||||
prm%p_sb = pl%get_asFloat('p_sb')
|
||||
prm%q_sb = pl%get_asFloat('q_sb')
|
||||
|
||||
! sanity checks
|
||||
if (prm%sbResistance < 0.0_pReal) extmsg = trim(extmsg)//' xi_sb'
|
||||
if (prm%xi_sb < 0.0_pReal) extmsg = trim(extmsg)//' xi_sb'
|
||||
if (prm%E_sb < 0.0_pReal) extmsg = trim(extmsg)//' Q_sb'
|
||||
if (prm%p_sb <= 0.0_pReal) extmsg = trim(extmsg)//' p_sb'
|
||||
if (prm%q_sb <= 0.0_pReal) extmsg = trim(extmsg)//' q_sb'
|
||||
|
@ -386,8 +386,8 @@ module function plastic_dislotwin_init() result(myPlasticity)
|
|||
prm%D = pl%get_asFloat('D')
|
||||
|
||||
twinOrSlipActive: if (prm%sum_N_tw + prm%sum_N_tr > 0) then
|
||||
prm%SFE_0K = pl%get_asFloat('Gamma_sf_0K')
|
||||
prm%dSFE_dT = pl%get_asFloat('dGamma_sf_dT')
|
||||
prm%Gamma_sf_0K = pl%get_asFloat('Gamma_sf_0K')
|
||||
prm%dGamma_sf_dT = pl%get_asFloat('dGamma_sf_dT')
|
||||
prm%V_cs = pl%get_asFloat('V_cs')
|
||||
endif twinOrSlipActive
|
||||
|
||||
|
@ -602,7 +602,7 @@ module subroutine plastic_dislotwin_LpAndItsTangent(Lp,dLp_dMp,Mp,T,instance,of)
|
|||
Lp = Lp * f_unrotated
|
||||
dLp_dMp = dLp_dMp * f_unrotated
|
||||
|
||||
shearBandingContribution: if(dNeq0(prm%sbVelocity)) then
|
||||
shearBandingContribution: if(dNeq0(prm%v_sb)) then
|
||||
|
||||
BoltzmannRatio = prm%E_sb/(kB*T)
|
||||
call math_eigh33(eigValues,eigVectors,Mp) ! is Mp symmetric by design?
|
||||
|
@ -613,10 +613,10 @@ module subroutine plastic_dislotwin_LpAndItsTangent(Lp,dLp_dMp,Mp,T,instance,of)
|
|||
tau = math_tensordot(Mp,P_sb)
|
||||
|
||||
significantShearBandStress: if (abs(tau) > tol_math_check) then
|
||||
StressRatio_p = (abs(tau)/prm%sbResistance)**prm%p_sb
|
||||
dot_gamma_sb = sign(prm%sbVelocity*exp(-BoltzmannRatio*(1-StressRatio_p)**prm%q_sb), tau)
|
||||
ddot_gamma_dtau = abs(dot_gamma_sb)*BoltzmannRatio* prm%p_sb*prm%q_sb/ prm%sbResistance &
|
||||
* (abs(tau)/prm%sbResistance)**(prm%p_sb-1.0_pReal) &
|
||||
StressRatio_p = (abs(tau)/prm%xi_sb)**prm%p_sb
|
||||
dot_gamma_sb = sign(prm%v_sb*exp(-BoltzmannRatio*(1-StressRatio_p)**prm%q_sb), tau)
|
||||
ddot_gamma_dtau = abs(dot_gamma_sb)*BoltzmannRatio* prm%p_sb*prm%q_sb/ prm%xi_sb &
|
||||
* (abs(tau)/prm%xi_sb)**(prm%p_sb-1.0_pReal) &
|
||||
* (1.0_pReal-StressRatio_p)**(prm%q_sb-1.0_pReal)
|
||||
|
||||
Lp = Lp + dot_gamma_sb * P_sb
|
||||
|
@ -654,7 +654,7 @@ module subroutine plastic_dislotwin_dotState(Mp,T,instance,of)
|
|||
Gamma, & !< stacking fault energy
|
||||
tau, &
|
||||
sigma_cl, & !< climb stress
|
||||
b_d !< ratio of burgers vector to stacking fault width
|
||||
b_d !< ratio of Burgers vector to stacking fault width
|
||||
real(pReal), dimension(param(instance)%sum_N_sl) :: &
|
||||
dot_rho_dip_formation, &
|
||||
dot_rho_dip_climb, &
|
||||
|
@ -675,7 +675,7 @@ module subroutine plastic_dislotwin_dotState(Mp,T,instance,of)
|
|||
call kinetics_slip(Mp,T,instance,of,dot_gamma_sl)
|
||||
dot%gamma_sl(:,of) = abs(dot_gamma_sl)
|
||||
|
||||
rho_dip_distance_min = prm%CEdgeDipMinDistance*prm%b_sl
|
||||
rho_dip_distance_min = prm%D_a*prm%b_sl
|
||||
|
||||
slipState: do i = 1, prm%sum_N_sl
|
||||
tau = math_tensordot(Mp,prm%P_sl(1:3,1:3,i))
|
||||
|
@ -701,12 +701,12 @@ module subroutine plastic_dislotwin_dotState(Mp,T,instance,of)
|
|||
!@details: Refer: Argon & Moffat, Acta Metallurgica, Vol. 29, pg 293 to 299, 1981
|
||||
sigma_cl = dot_product(prm%n0_sl(1:3,i),matmul(Mp,prm%n0_sl(1:3,i)))
|
||||
if (prm%ExtendedDislocations) then
|
||||
Gamma = prm%SFE_0K + prm%dSFE_dT * T
|
||||
Gamma = prm%Gamma_sf_0K + prm%dGamma_sf_dT * T
|
||||
b_d = 24.0_pReal*PI*(1.0_pReal - prm%nu)/(2.0_pReal + prm%nu)* Gamma/(prm%mu*prm%b_sl(i))
|
||||
else
|
||||
b_d = 1.0_pReal
|
||||
endif
|
||||
v_cl = 2.0_pReal*prm%omega*b_d**2.0_pReal*exp(-prm%Qsd/(kB*T)) &
|
||||
v_cl = 2.0_pReal*prm%omega*b_d**2.0_pReal*exp(-prm%Q_cl/(kB*T)) &
|
||||
* (exp(abs(sigma_cl)*prm%b_sl(i)**3.0_pReal/(kB*T)) - 1.0_pReal)
|
||||
|
||||
dot_rho_dip_climb(i) = 4.0_pReal*v_cl*stt%rho_dip(i,of) &
|
||||
|
@ -768,7 +768,7 @@ module subroutine plastic_dislotwin_dependentState(T,instance,of)
|
|||
sumf_twin = sum(stt%f_tw(1:prm%sum_N_tw,of))
|
||||
sumf_trans = sum(stt%f_tr(1:prm%sum_N_tr,of))
|
||||
|
||||
Gamma = prm%SFE_0K + prm%dSFE_dT * T
|
||||
Gamma = prm%Gamma_sf_0K + prm%dGamma_sf_dT * T
|
||||
|
||||
!* rescaled volume fraction for topology
|
||||
f_over_t_tw = stt%f_tw(1:prm%sum_N_tw,of)/prm%t_tw ! this is per system ...
|
||||
|
@ -776,7 +776,7 @@ module subroutine plastic_dislotwin_dependentState(T,instance,of)
|
|||
! ToDo ...Physically correct, but naming could be adjusted
|
||||
|
||||
inv_lambda_sl_sl = sqrt(matmul(prm%forestProjection, &
|
||||
stt%rho_mob(:,of)+stt%rho_dip(:,of)))/prm%CLambdaSlip
|
||||
stt%rho_mob(:,of)+stt%rho_dip(:,of)))/prm%i_sl
|
||||
|
||||
if (prm%sum_N_tw > 0 .and. prm%sum_N_sl > 0) &
|
||||
inv_lambda_sl_tw = matmul(prm%h_sl_tw,f_over_t_tw)/(1.0_pReal-sumf_twin)
|
||||
|
@ -805,21 +805,21 @@ module subroutine plastic_dislotwin_dependentState(T,instance,of)
|
|||
!* threshold stress for growing twin/martensite
|
||||
if(prm%sum_N_tw == prm%sum_N_sl) &
|
||||
dst%tau_hat_tw(:,of) = Gamma/(3.0_pReal*prm%b_tw) &
|
||||
+ 3.0_pReal*prm%b_tw*prm%mu/(prm%L_tw*prm%b_sl) ! slip burgers here correct?
|
||||
+ 3.0_pReal*prm%b_tw*prm%mu/(prm%L_tw*prm%b_sl) ! slip Burgers here correct?
|
||||
if(prm%sum_N_tr == prm%sum_N_sl) &
|
||||
dst%tau_hat_tr(:,of) = Gamma/(3.0_pReal*prm%b_tr) &
|
||||
+ 3.0_pReal*prm%b_tr*prm%mu/(prm%L_tr*prm%b_sl) & ! slip burgers here correct?
|
||||
+ prm%h*prm%gamma_fcc_hex/ (3.0_pReal*prm%b_tr)
|
||||
+ 3.0_pReal*prm%b_tr*prm%mu/(prm%L_tr*prm%b_sl) & ! slip Burgers here correct?
|
||||
+ prm%h*prm%delta_G/ (3.0_pReal*prm%b_tr)
|
||||
|
||||
dst%V_tw(:,of) = (PI/4.0_pReal)*prm%t_tw*dst%Lambda_tw(:,of)**2.0_pReal
|
||||
dst%V_tr(:,of) = (PI/4.0_pReal)*prm%t_tr*dst%Lambda_tr(:,of)**2.0_pReal
|
||||
|
||||
|
||||
x0 = prm%mu*prm%b_tw**2.0_pReal/(Gamma*8.0_pReal*PI)*(2.0_pReal+prm%nu)/(1.0_pReal-prm%nu) ! ToDo: In the paper, this is the burgers vector for slip and is the same for twin and trans
|
||||
dst%tau_r_tw(:,of) = prm%mu*prm%b_tw/(2.0_pReal*PI)*(1.0_pReal/(x0+prm%xc_twin)+cos(pi/3.0_pReal)/x0)
|
||||
x0 = prm%mu*prm%b_tw**2.0_pReal/(Gamma*8.0_pReal*PI)*(2.0_pReal+prm%nu)/(1.0_pReal-prm%nu) ! ToDo: In the paper, this is the Burgers vector for slip and is the same for twin and trans
|
||||
dst%tau_r_tw(:,of) = prm%mu*prm%b_tw/(2.0_pReal*PI)*(1.0_pReal/(x0+prm%x_c_tw)+cos(pi/3.0_pReal)/x0)
|
||||
|
||||
x0 = prm%mu*prm%b_tr**2.0_pReal/(Gamma*8.0_pReal*PI)*(2.0_pReal+prm%nu)/(1.0_pReal-prm%nu) ! ToDo: In the paper, this is the burgers vector for slip
|
||||
dst%tau_r_tr(:,of) = prm%mu*prm%b_tr/(2.0_pReal*PI)*(1.0_pReal/(x0+prm%xc_trans)+cos(pi/3.0_pReal)/x0)
|
||||
x0 = prm%mu*prm%b_tr**2.0_pReal/(Gamma*8.0_pReal*PI)*(2.0_pReal+prm%nu)/(1.0_pReal-prm%nu) ! ToDo: In the paper, this is the Burgers vector for slip
|
||||
dst%tau_r_tr(:,of) = prm%mu*prm%b_tr/(2.0_pReal*PI)*(1.0_pReal/(x0+prm%x_c_tr)+cos(pi/3.0_pReal)/x0)
|
||||
|
||||
end associate
|
||||
|
||||
|
@ -927,8 +927,8 @@ pure subroutine kinetics_slip(Mp,T,instance,of, &
|
|||
significantStress: where(tau_eff > tol_math_check)
|
||||
stressRatio = tau_eff/prm%tau_0
|
||||
StressRatio_p = stressRatio** prm%p
|
||||
BoltzmannRatio = prm%Delta_F/(kB*T)
|
||||
v_wait_inverse = prm%v0**(-1.0_pReal) * exp(BoltzmannRatio*(1.0_pReal-StressRatio_p)** prm%q)
|
||||
BoltzmannRatio = prm%Q_s/(kB*T)
|
||||
v_wait_inverse = prm%v_0**(-1.0_pReal) * exp(BoltzmannRatio*(1.0_pReal-StressRatio_p)** prm%q)
|
||||
v_run_inverse = prm%B/(tau_eff*prm%b_sl)
|
||||
|
||||
dot_gamma_sl = sign(stt%rho_mob(:,of)*prm%b_sl/(v_wait_inverse+v_run_inverse),tau)
|
||||
|
|
|
@ -14,7 +14,7 @@ submodule(constitutive:constitutive_plastic) plastic_isotropic
|
|||
M, & !< Taylor factor
|
||||
dot_gamma_0, & !< reference strain rate
|
||||
n, & !< stress exponent
|
||||
h0, &
|
||||
h_0, &
|
||||
h_ln, &
|
||||
xi_inf, & !< maximum critical stress
|
||||
a, &
|
||||
|
@ -109,7 +109,7 @@ module function plastic_isotropic_init() result(myPlasticity)
|
|||
prm%xi_inf = pl%get_asFloat('xi_inf')
|
||||
prm%dot_gamma_0 = pl%get_asFloat('dot_gamma_0')
|
||||
prm%n = pl%get_asFloat('n')
|
||||
prm%h0 = pl%get_asFloat('h_0')
|
||||
prm%h_0 = pl%get_asFloat('h_0')
|
||||
prm%M = pl%get_asFloat('M')
|
||||
prm%h_ln = pl%get_asFloat('h_ln', defaultVal=0.0_pReal)
|
||||
prm%c_1 = pl%get_asFloat('c_1', defaultVal=0.0_pReal)
|
||||
|
@ -310,7 +310,7 @@ module subroutine plastic_isotropic_dotState(Mp,instance,of)
|
|||
/ prm%c_4 * (dot_gamma / prm%dot_gamma_0)**(1.0_pReal / prm%n)
|
||||
endif
|
||||
dot%xi(of) = dot_gamma &
|
||||
* ( prm%h0 + prm%h_ln * log(dot_gamma) ) &
|
||||
* ( prm%h_0 + prm%h_ln * log(dot_gamma) ) &
|
||||
* abs( 1.0_pReal - stt%xi(of)/xi_inf_star )**prm%a &
|
||||
* sign(1.0_pReal, 1.0_pReal - stt%xi(of)/xi_inf_star)
|
||||
else
|
||||
|
|
|
@ -9,15 +9,15 @@ submodule(constitutive:constitutive_plastic) plastic_kinehardening
|
|||
|
||||
type :: tParameters
|
||||
real(pReal) :: &
|
||||
gdot0 = 1.0_pReal, & !< reference shear strain rate for slip
|
||||
n = 1.0_pReal !< stress exponent for slip
|
||||
n = 1.0_pReal, & !< stress exponent for slip
|
||||
dot_gamma_0 = 1.0_pReal !< reference shear strain rate for slip
|
||||
real(pReal), allocatable, dimension(:) :: &
|
||||
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
|
||||
h_0_f, & !< initial hardening rate of forward stress for each slip
|
||||
h_inf_f, & !< asymptotic hardening rate of forward stress for each slip
|
||||
h_0_b, & !< initial hardening rate of back stress for each slip
|
||||
h_inf_b, & !< asymptotic hardening rate of back stress for each slip
|
||||
xi_inf_f, &
|
||||
xi_inf_b
|
||||
real(pReal), allocatable, dimension(:,:) :: &
|
||||
interaction_slipslip !< slip resistance from slip activity
|
||||
real(pReal), allocatable, dimension(:,:,:) :: &
|
||||
|
@ -125,7 +125,7 @@ module function plastic_kinehardening_init() result(myPlasticity)
|
|||
phase%get_asFloat('c/a',defaultVal=0.0_pReal))
|
||||
|
||||
if(trim(phase%get_asString('lattice')) == 'bcc') then
|
||||
a = pl%get_asFloats('nonSchmid_coefficients',defaultVal = emptyRealArray)
|
||||
a = pl%get_asFloats('a_nonSchmid',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)
|
||||
|
@ -138,37 +138,37 @@ module function plastic_kinehardening_init() result(myPlasticity)
|
|||
phase%get_asString('lattice'))
|
||||
|
||||
xi_0 = pl%get_asFloats('xi_0', requiredSize=size(N_sl))
|
||||
prm%tau1 = pl%get_asFloats('xi_inf_f', requiredSize=size(N_sl))
|
||||
prm%tau1_b = pl%get_asFloats('xi_inf_b', requiredSize=size(N_sl))
|
||||
prm%theta0 = pl%get_asFloats('h_0_f', requiredSize=size(N_sl))
|
||||
prm%theta1 = pl%get_asFloats('h_inf_f', requiredSize=size(N_sl))
|
||||
prm%theta0_b = pl%get_asFloats('h_0_b', requiredSize=size(N_sl))
|
||||
prm%theta1_b = pl%get_asFloats('h_inf_b', requiredSize=size(N_sl))
|
||||
prm%xi_inf_f = pl%get_asFloats('xi_inf_f', requiredSize=size(N_sl))
|
||||
prm%xi_inf_b = pl%get_asFloats('xi_inf_b', requiredSize=size(N_sl))
|
||||
prm%h_0_f = pl%get_asFloats('h_0_f', requiredSize=size(N_sl))
|
||||
prm%h_inf_f = pl%get_asFloats('h_inf_f', requiredSize=size(N_sl))
|
||||
prm%h_0_b = pl%get_asFloats('h_0_b', requiredSize=size(N_sl))
|
||||
prm%h_inf_b = pl%get_asFloats('h_inf_b', requiredSize=size(N_sl))
|
||||
|
||||
prm%gdot0 = pl%get_asFloat('dot_gamma_0')
|
||||
prm%dot_gamma_0 = pl%get_asFloat('dot_gamma_0')
|
||||
prm%n = pl%get_asFloat('n')
|
||||
|
||||
! expand: family => system
|
||||
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)
|
||||
prm%xi_inf_f = math_expand(prm%xi_inf_f, N_sl)
|
||||
prm%xi_inf_b = math_expand(prm%xi_inf_b, N_sl)
|
||||
prm%h_0_f = math_expand(prm%h_0_f, N_sl)
|
||||
prm%h_inf_f = math_expand(prm%h_inf_f, N_sl)
|
||||
prm%h_0_b = math_expand(prm%h_0_b, N_sl)
|
||||
prm%h_inf_b = math_expand(prm%h_inf_b, N_sl)
|
||||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! sanity checks
|
||||
if ( prm%gdot0 <= 0.0_pReal) extmsg = trim(extmsg)//' dot_gamma_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 (any(xi_0 <= 0.0_pReal)) extmsg = trim(extmsg)//' xi_0'
|
||||
if (any(prm%tau1 <= 0.0_pReal)) extmsg = trim(extmsg)//' xi_inf_f'
|
||||
if (any(prm%tau1_b <= 0.0_pReal)) extmsg = trim(extmsg)//' xi_inf_b'
|
||||
if (any(prm%xi_inf_f <= 0.0_pReal)) extmsg = trim(extmsg)//' xi_inf_f'
|
||||
if (any(prm%xi_inf_b <= 0.0_pReal)) extmsg = trim(extmsg)//' xi_inf_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%xi_inf_f,prm%xi_inf_b,prm%h_0_f,prm%h_inf_f,prm%h_0_b,prm%h_inf_b,source=emptyRealArray)
|
||||
allocate(prm%interaction_SlipSlip(0,0))
|
||||
endif slipActive
|
||||
|
||||
|
@ -303,16 +303,16 @@ module subroutine plastic_kinehardening_dotState(Mp,instance,of)
|
|||
|
||||
|
||||
dot%crss(:,of) = matmul(prm%interaction_SlipSlip,dot%accshear(:,of)) &
|
||||
* ( prm%theta1 &
|
||||
+ (prm%theta0 - prm%theta1 + prm%theta0*prm%theta1*sumGamma/prm%tau1) &
|
||||
* exp(-sumGamma*prm%theta0/prm%tau1) &
|
||||
* ( prm%h_inf_f &
|
||||
+ (prm%h_0_f - prm%h_inf_f + prm%h_0_f*prm%h_inf_f*sumGamma/prm%xi_inf_f) &
|
||||
* exp(-sumGamma*prm%h_0_f/prm%xi_inf_f) &
|
||||
)
|
||||
|
||||
dot%crss_back(:,of) = stt%sense(:,of)*dot%accshear(:,of) * &
|
||||
( prm%theta1_b + &
|
||||
(prm%theta0_b - prm%theta1_b &
|
||||
+ prm%theta0_b*prm%theta1_b/(prm%tau1_b+stt%chi0(:,of))*(stt%accshear(:,of)-stt%gamma0(:,of))&
|
||||
) *exp(-(stt%accshear(:,of)-stt%gamma0(:,of)) *prm%theta0_b/(prm%tau1_b+stt%chi0(:,of))) &
|
||||
( prm%h_inf_b + &
|
||||
(prm%h_0_b - prm%h_inf_b &
|
||||
+ prm%h_0_b*prm%h_inf_b/(prm%xi_inf_b+stt%chi0(:,of))*(stt%accshear(:,of)-stt%gamma0(:,of))&
|
||||
) *exp(-(stt%accshear(:,of)-stt%gamma0(:,of)) *prm%h_0_b/(prm%xi_inf_b+stt%chi0(:,of))) &
|
||||
)
|
||||
|
||||
end associate
|
||||
|
@ -442,14 +442,14 @@ pure subroutine kinetics(Mp,instance,of, &
|
|||
enddo
|
||||
|
||||
where(dNeq0(tau_pos))
|
||||
gdot_pos = prm%gdot0 * merge(0.5_pReal,1.0_pReal, prm%nonSchmidActive) & ! 1/2 if non-Schmid active
|
||||
gdot_pos = prm%dot_gamma_0 * 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
|
||||
end where
|
||||
|
||||
where(dNeq0(tau_neg))
|
||||
gdot_neg = prm%gdot0 * 0.5_pReal & ! only used if non-Schmid active, always 1/2
|
||||
gdot_neg = prm%dot_gamma_0 * 0.5_pReal & ! only used if non-Schmid active, always 1/2
|
||||
* sign(abs(tau_neg/stt%crss(:,of))**prm%n, tau_neg)
|
||||
else where
|
||||
gdot_neg = 0.0_pReal
|
||||
|
|
|
@ -46,58 +46,58 @@ submodule(constitutive:constitutive_plastic) plastic_nonlocal
|
|||
|
||||
type :: tInitialParameters !< container type for internal constitutive parameters
|
||||
real(pReal) :: &
|
||||
rhoSglScatter, & !< standard deviation of scatter in initial dislocation density
|
||||
rhoSglRandom, &
|
||||
rhoSglRandomBinning
|
||||
sigma_rho_u, & !< standard deviation of scatter in initial dislocation density
|
||||
random_rho_u, &
|
||||
random_rho_u_binning
|
||||
real(pReal), dimension(:), allocatable :: &
|
||||
rhoSglEdgePos0, & !< initial edge_pos dislocation density
|
||||
rhoSglEdgeNeg0, & !< initial edge_neg dislocation density
|
||||
rhoSglScrewPos0, & !< initial screw_pos dislocation density
|
||||
rhoSglScrewNeg0, & !< initial screw_neg dislocation density
|
||||
rhoDipEdge0, & !< initial edge dipole dislocation density
|
||||
rhoDipScrew0 !< initial screw dipole dislocation density
|
||||
rho_u_ed_pos_0, & !< initial edge_pos dislocation density
|
||||
rho_u_ed_neg_0, & !< initial edge_neg dislocation density
|
||||
rho_u_sc_pos_0, & !< initial screw_pos dislocation density
|
||||
rho_u_sc_neg_0, & !< initial screw_neg dislocation density
|
||||
rho_d_ed_0, & !< initial edge dipole dislocation density
|
||||
rho_d_sc_0 !< initial screw dipole dislocation density
|
||||
integer, dimension(:), allocatable :: &
|
||||
N_sl
|
||||
end type tInitialParameters
|
||||
|
||||
type :: tParameters !< container type for internal constitutive parameters
|
||||
real(pReal) :: &
|
||||
atomicVolume, & !< atomic volume
|
||||
Dsd0, & !< prefactor for self-diffusion coefficient
|
||||
selfDiffusionEnergy, & !< activation enthalpy for diffusion
|
||||
V_at, & !< atomic volume
|
||||
D_0, & !< prefactor for self-diffusion coefficient
|
||||
Q_cl, & !< activation enthalpy for diffusion
|
||||
atol_rho, & !< absolute tolerance for dislocation density in state integration
|
||||
significantRho, & !< density considered significant
|
||||
significantN, & !< number of dislocations considered significant
|
||||
doublekinkwidth, & !< width of a doubkle kink in multiples of the burgers vector length b
|
||||
solidSolutionEnergy, & !< activation energy for solid solution in J
|
||||
solidSolutionSize, & !< solid solution obstacle size in multiples of the burgers vector length
|
||||
solidSolutionConcentration, & !< concentration of solid solution in atomic parts
|
||||
rho_significant, & !< density considered significant
|
||||
rho_min, & !< number of dislocations considered significant
|
||||
w, & !< width of a doubkle kink in multiples of the Burgers vector length b
|
||||
Q_sol, & !< activation energy for solid solution in J
|
||||
f_sol, & !< solid solution obstacle size in multiples of the Burgers vector length
|
||||
c_sol, & !< concentration of solid solution in atomic parts
|
||||
p, & !< parameter for kinetic law (Kocks,Argon,Ashby)
|
||||
q, & !< parameter for kinetic law (Kocks,Argon,Ashby)
|
||||
viscosity, & !< viscosity for dislocation glide in Pa s
|
||||
fattack, & !< attack frequency in Hz
|
||||
surfaceTransmissivity, & !< transmissivity at free surface
|
||||
grainboundaryTransmissivity, & !< transmissivity at grain boundary (identified by different texture)
|
||||
CFLfactor, & !< safety factor for CFL flux condition
|
||||
fEdgeMultiplication, & !< factor that determines how much edge dislocations contribute to multiplication (0...1)
|
||||
linetensionEffect, &
|
||||
edgeJogFactor, &
|
||||
eta, & !< viscosity for dislocation glide in Pa s
|
||||
nu_a, & !< attack frequency in Hz
|
||||
chi_surface, & !< transmissivity at free surface
|
||||
chi_GB, & !< transmissivity at grain boundary (identified by different texture)
|
||||
f_c, & !< safety factor for CFL flux condition
|
||||
f_ed_mult, & !< factor that determines how much edge dislocations contribute to multiplication (0...1)
|
||||
f_F, &
|
||||
f_ed, &
|
||||
mu, &
|
||||
nu
|
||||
real(pReal), dimension(:), allocatable :: &
|
||||
minDipoleHeight_edge, & !< minimum stable edge dipole height
|
||||
minDipoleHeight_screw, & !< minimum stable screw dipole height
|
||||
peierlsstress_edge, &
|
||||
peierlsstress_screw, &
|
||||
lambda0, & !< mean free path prefactor for each
|
||||
burgers !< absolute length of burgers vector [m]
|
||||
d_ed, & !< minimum stable edge dipole height
|
||||
d_sc, & !< minimum stable screw dipole height
|
||||
tau_Peierls_ed, &
|
||||
tau_Peierls_sc, &
|
||||
i_sl, & !< mean free path prefactor for each
|
||||
b_sl !< absolute length of Burgers vector [m]
|
||||
real(pReal), dimension(:,:), allocatable :: &
|
||||
slip_normal, &
|
||||
slip_direction, &
|
||||
slip_transverse, &
|
||||
minDipoleHeight, & ! edge and screw
|
||||
peierlsstress, & ! edge and screw
|
||||
interactionSlipSlip ,& !< coefficients for slip-slip interaction
|
||||
h_sl_sl ,& !< coefficients for slip-slip interaction
|
||||
forestProjection_Edge, & !< matrix of forest projections of edge dislocations
|
||||
forestProjection_Screw !< matrix of forest projections of screw dislocations
|
||||
real(pReal), dimension(:,:,:), allocatable :: &
|
||||
|
@ -244,7 +244,7 @@ module function plastic_nonlocal_init() result(myPlasticity)
|
|||
phase%get_asFloat('c/a',defaultVal=0.0_pReal))
|
||||
|
||||
if(trim(phase%get_asString('lattice')) == 'bcc') then
|
||||
a = pl%get_asFloats('nonSchmid_coefficients',defaultVal = emptyRealArray)
|
||||
a = pl%get_asFloats('a_nonSchmid',defaultVal = emptyRealArray)
|
||||
if(size(a) > 0) prm%nonSchmidActive = .true.
|
||||
prm%nonSchmid_pos = lattice_nonSchmidMatrix(ini%N_sl,a,+1)
|
||||
prm%nonSchmid_neg = lattice_nonSchmidMatrix(ini%N_sl,a,-1)
|
||||
|
@ -253,7 +253,7 @@ module function plastic_nonlocal_init() result(myPlasticity)
|
|||
prm%nonSchmid_neg = prm%Schmid
|
||||
endif
|
||||
|
||||
prm%interactionSlipSlip = lattice_interaction_SlipBySlip(ini%N_sl, &
|
||||
prm%h_sl_sl = lattice_interaction_SlipBySlip(ini%N_sl, &
|
||||
pl%get_asFloats('h_sl_sl'), &
|
||||
phase%get_asString('lattice'))
|
||||
|
||||
|
@ -279,112 +279,112 @@ module function plastic_nonlocal_init() result(myPlasticity)
|
|||
enddo
|
||||
enddo
|
||||
|
||||
ini%rhoSglEdgePos0 = pl%get_asFloats('rho_u_ed_pos_0', requiredSize=size(ini%N_sl))
|
||||
ini%rhoSglEdgeNeg0 = pl%get_asFloats('rho_u_ed_neg_0', requiredSize=size(ini%N_sl))
|
||||
ini%rhoSglScrewPos0 = pl%get_asFloats('rho_u_sc_pos_0', requiredSize=size(ini%N_sl))
|
||||
ini%rhoSglScrewNeg0 = pl%get_asFloats('rho_u_sc_neg_0', requiredSize=size(ini%N_sl))
|
||||
ini%rhoDipEdge0 = pl%get_asFloats('rho_d_ed_0', requiredSize=size(ini%N_sl))
|
||||
ini%rhoDipScrew0 = pl%get_asFloats('rho_d_sc_0', requiredSize=size(ini%N_sl))
|
||||
ini%rho_u_ed_pos_0 = pl%get_asFloats('rho_u_ed_pos_0', requiredSize=size(ini%N_sl))
|
||||
ini%rho_u_ed_neg_0 = pl%get_asFloats('rho_u_ed_neg_0', requiredSize=size(ini%N_sl))
|
||||
ini%rho_u_sc_pos_0 = pl%get_asFloats('rho_u_sc_pos_0', requiredSize=size(ini%N_sl))
|
||||
ini%rho_u_sc_neg_0 = pl%get_asFloats('rho_u_sc_neg_0', requiredSize=size(ini%N_sl))
|
||||
ini%rho_d_ed_0 = pl%get_asFloats('rho_d_ed_0', requiredSize=size(ini%N_sl))
|
||||
ini%rho_d_sc_0 = pl%get_asFloats('rho_d_sc_0', requiredSize=size(ini%N_sl))
|
||||
|
||||
prm%lambda0 = pl%get_asFloats('i_sl', requiredSize=size(ini%N_sl))
|
||||
prm%burgers = pl%get_asFloats('b_sl', requiredSize=size(ini%N_sl))
|
||||
prm%i_sl = pl%get_asFloats('i_sl', requiredSize=size(ini%N_sl))
|
||||
prm%b_sl = pl%get_asFloats('b_sl', requiredSize=size(ini%N_sl))
|
||||
|
||||
prm%lambda0 = math_expand(prm%lambda0,ini%N_sl)
|
||||
prm%burgers = math_expand(prm%burgers,ini%N_sl)
|
||||
prm%i_sl = math_expand(prm%i_sl,ini%N_sl)
|
||||
prm%b_sl = math_expand(prm%b_sl,ini%N_sl)
|
||||
|
||||
prm%minDipoleHeight_edge = pl%get_asFloats('d_ed', requiredSize=size(ini%N_sl))
|
||||
prm%minDipoleHeight_screw = pl%get_asFloats('d_sc', requiredSize=size(ini%N_sl))
|
||||
prm%minDipoleHeight_edge = math_expand(prm%minDipoleHeight_edge, ini%N_sl)
|
||||
prm%minDipoleHeight_screw = math_expand(prm%minDipoleHeight_screw,ini%N_sl)
|
||||
prm%d_ed = pl%get_asFloats('d_ed', requiredSize=size(ini%N_sl))
|
||||
prm%d_sc = pl%get_asFloats('d_sc', requiredSize=size(ini%N_sl))
|
||||
prm%d_ed = math_expand(prm%d_ed,ini%N_sl)
|
||||
prm%d_sc = math_expand(prm%d_sc,ini%N_sl)
|
||||
allocate(prm%minDipoleHeight(prm%sum_N_sl,2))
|
||||
prm%minDipoleHeight(:,1) = prm%minDipoleHeight_edge
|
||||
prm%minDipoleHeight(:,2) = prm%minDipoleHeight_screw
|
||||
prm%minDipoleHeight(:,1) = prm%d_ed
|
||||
prm%minDipoleHeight(:,2) = prm%d_sc
|
||||
|
||||
prm%peierlsstress_edge = pl%get_asFloats('tau_peierls_ed', requiredSize=size(ini%N_sl))
|
||||
prm%peierlsstress_screw = pl%get_asFloats('tau_peierls_sc', requiredSize=size(ini%N_sl))
|
||||
prm%peierlsstress_edge = math_expand(prm%peierlsstress_edge, ini%N_sl)
|
||||
prm%peierlsstress_screw = math_expand(prm%peierlsstress_screw,ini%N_sl)
|
||||
prm%tau_Peierls_ed = pl%get_asFloats('tau_Peierls_ed', requiredSize=size(ini%N_sl))
|
||||
prm%tau_Peierls_sc = pl%get_asFloats('tau_Peierls_sc', requiredSize=size(ini%N_sl))
|
||||
prm%tau_Peierls_ed = math_expand(prm%tau_Peierls_ed,ini%N_sl)
|
||||
prm%tau_Peierls_sc = math_expand(prm%tau_Peierls_sc,ini%N_sl)
|
||||
allocate(prm%peierlsstress(prm%sum_N_sl,2))
|
||||
prm%peierlsstress(:,1) = prm%peierlsstress_edge
|
||||
prm%peierlsstress(:,2) = prm%peierlsstress_screw
|
||||
prm%peierlsstress(:,1) = prm%tau_Peierls_ed
|
||||
prm%peierlsstress(:,2) = prm%tau_Peierls_sc
|
||||
|
||||
prm%significantRho = pl%get_asFloat('rho_significant')
|
||||
prm%significantN = pl%get_asFloat('rho_num_significant', 0.0_pReal)
|
||||
prm%CFLfactor = pl%get_asFloat('f_c',defaultVal=2.0_pReal)
|
||||
prm%rho_significant = pl%get_asFloat('rho_significant')
|
||||
prm%rho_min = pl%get_asFloat('rho_min', 0.0_pReal)
|
||||
prm%f_c = pl%get_asFloat('f_c',defaultVal=2.0_pReal)
|
||||
|
||||
prm%atomicVolume = pl%get_asFloat('V_at')
|
||||
prm%Dsd0 = pl%get_asFloat('D_0') !,'dsd0'
|
||||
prm%selfDiffusionEnergy = pl%get_asFloat('Q_cl') !,'qsd'
|
||||
prm%linetensionEffect = pl%get_asFloat('f_F')
|
||||
prm%edgeJogFactor = pl%get_asFloat('f_ed') !,'edgejogs'
|
||||
prm%doublekinkwidth = pl%get_asFloat('w')
|
||||
prm%solidSolutionEnergy = pl%get_asFloat('Q_sol')
|
||||
prm%solidSolutionSize = pl%get_asFloat('f_sol')
|
||||
prm%solidSolutionConcentration = pl%get_asFloat('c_sol')
|
||||
prm%V_at = pl%get_asFloat('V_at')
|
||||
prm%D_0 = pl%get_asFloat('D_0')
|
||||
prm%Q_cl = pl%get_asFloat('Q_cl')
|
||||
prm%f_F = pl%get_asFloat('f_F')
|
||||
prm%f_ed = pl%get_asFloat('f_ed') !,'edgejogs'
|
||||
prm%w = pl%get_asFloat('w')
|
||||
prm%Q_sol = pl%get_asFloat('Q_sol')
|
||||
prm%f_sol = pl%get_asFloat('f_sol')
|
||||
prm%c_sol = pl%get_asFloat('c_sol')
|
||||
|
||||
prm%p = pl%get_asFloat('p_sl')
|
||||
prm%q = pl%get_asFloat('q_sl')
|
||||
prm%viscosity = pl%get_asFloat('eta')
|
||||
prm%fattack = pl%get_asFloat('nu_a')
|
||||
prm%eta = pl%get_asFloat('eta')
|
||||
prm%nu_a = pl%get_asFloat('nu_a')
|
||||
|
||||
! ToDo: discuss logic
|
||||
ini%rhoSglScatter = pl%get_asFloat('sigma_rho_u')
|
||||
ini%rhoSglRandom = pl%get_asFloat('random_rho_u',defaultVal= 0.0_pReal)
|
||||
ini%sigma_rho_u = pl%get_asFloat('sigma_rho_u')
|
||||
ini%random_rho_u = pl%get_asFloat('random_rho_u',defaultVal= 0.0_pReal)
|
||||
if (pl%contains('random_rho_u')) &
|
||||
ini%rhoSglRandomBinning = pl%get_asFloat('random_rho_u_binning',defaultVal=0.0_pReal) !ToDo: useful default?
|
||||
ini%random_rho_u_binning = pl%get_asFloat('random_rho_u_binning',defaultVal=0.0_pReal) !ToDo: useful default?
|
||||
! if (rhoSglRandom(instance) < 0.0_pReal) &
|
||||
! if (rhoSglRandomBinning(instance) <= 0.0_pReal) &
|
||||
|
||||
prm%surfaceTransmissivity = pl%get_asFloat('chi_surface',defaultVal=1.0_pReal)
|
||||
prm%grainboundaryTransmissivity = pl%get_asFloat('chi_GB', defaultVal=-1.0_pReal)
|
||||
prm%fEdgeMultiplication = pl%get_asFloat('f_ed_mult')
|
||||
prm%chi_surface = pl%get_asFloat('chi_surface',defaultVal=1.0_pReal)
|
||||
prm%chi_GB = pl%get_asFloat('chi_GB', defaultVal=-1.0_pReal)
|
||||
prm%f_ed_mult = pl%get_asFloat('f_ed_mult')
|
||||
prm%shortRangeStressCorrection = pl%get_asBool('short_range_stress_correction', defaultVal = .false.)
|
||||
|
||||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! sanity checks
|
||||
if (any(prm%burgers < 0.0_pReal)) extmsg = trim(extmsg)//' b_sl'
|
||||
if (any(prm%lambda0 <= 0.0_pReal)) extmsg = trim(extmsg)//' i_sl'
|
||||
if (any(prm%b_sl < 0.0_pReal)) extmsg = trim(extmsg)//' b_sl'
|
||||
if (any(prm%i_sl <= 0.0_pReal)) extmsg = trim(extmsg)//' i_sl'
|
||||
|
||||
if (any(ini%rhoSglEdgePos0 < 0.0_pReal)) extmsg = trim(extmsg)//' rho_u_ed_pos_0'
|
||||
if (any(ini%rhoSglEdgeNeg0 < 0.0_pReal)) extmsg = trim(extmsg)//' rho_u_ed_neg_0'
|
||||
if (any(ini%rhoSglScrewPos0 < 0.0_pReal)) extmsg = trim(extmsg)//' rho_u_sc_pos_0'
|
||||
if (any(ini%rhoSglScrewNeg0 < 0.0_pReal)) extmsg = trim(extmsg)//' rho_u_sc_neg_0'
|
||||
if (any(ini%rhoDipEdge0 < 0.0_pReal)) extmsg = trim(extmsg)//' rho_d_ed_0'
|
||||
if (any(ini%rhoDipScrew0 < 0.0_pReal)) extmsg = trim(extmsg)//' rho_d_sc_0'
|
||||
if (any(ini%rho_u_ed_pos_0 < 0.0_pReal)) extmsg = trim(extmsg)//' rho_u_ed_pos_0'
|
||||
if (any(ini%rho_u_ed_neg_0 < 0.0_pReal)) extmsg = trim(extmsg)//' rho_u_ed_neg_0'
|
||||
if (any(ini%rho_u_sc_pos_0 < 0.0_pReal)) extmsg = trim(extmsg)//' rho_u_sc_pos_0'
|
||||
if (any(ini%rho_u_sc_neg_0 < 0.0_pReal)) extmsg = trim(extmsg)//' rho_u_sc_neg_0'
|
||||
if (any(ini%rho_d_ed_0 < 0.0_pReal)) extmsg = trim(extmsg)//' rho_d_ed_0'
|
||||
if (any(ini%rho_d_sc_0 < 0.0_pReal)) extmsg = trim(extmsg)//' rho_d_sc_0'
|
||||
|
||||
if (any(prm%peierlsstress < 0.0_pReal)) extmsg = trim(extmsg)//' tau_peierls'
|
||||
if (any(prm%minDipoleHeight < 0.0_pReal)) extmsg = trim(extmsg)//' d_ed or d_sc'
|
||||
|
||||
if (prm%viscosity <= 0.0_pReal) extmsg = trim(extmsg)//' eta'
|
||||
if (prm%selfDiffusionEnergy <= 0.0_pReal) extmsg = trim(extmsg)//' Q_cl'
|
||||
if (prm%fattack <= 0.0_pReal) extmsg = trim(extmsg)//' nu_a'
|
||||
if (prm%doublekinkwidth <= 0.0_pReal) extmsg = trim(extmsg)//' w'
|
||||
if (prm%Dsd0 < 0.0_pReal) extmsg = trim(extmsg)//' D_0'
|
||||
if (prm%atomicVolume <= 0.0_pReal) extmsg = trim(extmsg)//' V_at' ! ToDo: in disloTungsten, the atomic volume is given as a factor
|
||||
if (prm%eta <= 0.0_pReal) extmsg = trim(extmsg)//' eta'
|
||||
if (prm%Q_cl <= 0.0_pReal) extmsg = trim(extmsg)//' Q_cl'
|
||||
if (prm%nu_a <= 0.0_pReal) extmsg = trim(extmsg)//' nu_a'
|
||||
if (prm%w <= 0.0_pReal) extmsg = trim(extmsg)//' w'
|
||||
if (prm%D_0 < 0.0_pReal) extmsg = trim(extmsg)//' D_0'
|
||||
if (prm%V_at <= 0.0_pReal) extmsg = trim(extmsg)//' V_at' ! ToDo: in disloTungsten, the atomic volume is given as a factor
|
||||
|
||||
if (prm%significantN < 0.0_pReal) extmsg = trim(extmsg)//' rho_num_significant'
|
||||
if (prm%significantrho < 0.0_pReal) extmsg = trim(extmsg)//' rho_significant'
|
||||
if (prm%rho_min < 0.0_pReal) extmsg = trim(extmsg)//' rho_min'
|
||||
if (prm%rho_significant < 0.0_pReal) extmsg = trim(extmsg)//' rho_significant'
|
||||
if (prm%atol_rho < 0.0_pReal) extmsg = trim(extmsg)//' atol_rho'
|
||||
if (prm%CFLfactor < 0.0_pReal) extmsg = trim(extmsg)//' f_c'
|
||||
if (prm%f_c < 0.0_pReal) extmsg = trim(extmsg)//' f_c'
|
||||
|
||||
if (prm%p <= 0.0_pReal .or. prm%p > 1.0_pReal) extmsg = trim(extmsg)//' p_sl'
|
||||
if (prm%q < 1.0_pReal .or. prm%q > 2.0_pReal) extmsg = trim(extmsg)//' q_sl'
|
||||
|
||||
if (prm%linetensionEffect < 0.0_pReal .or. prm%linetensionEffect > 1.0_pReal) &
|
||||
if (prm%f_F < 0.0_pReal .or. prm%f_F > 1.0_pReal) &
|
||||
extmsg = trim(extmsg)//' f_F'
|
||||
if (prm%edgeJogFactor < 0.0_pReal .or. prm%edgeJogFactor > 1.0_pReal) &
|
||||
if (prm%f_ed < 0.0_pReal .or. prm%f_ed > 1.0_pReal) &
|
||||
extmsg = trim(extmsg)//' f_ed'
|
||||
|
||||
if (prm%solidSolutionEnergy <= 0.0_pReal) extmsg = trim(extmsg)//' Q_sol'
|
||||
if (prm%solidSolutionSize <= 0.0_pReal) extmsg = trim(extmsg)//' f_sol'
|
||||
if (prm%solidSolutionConcentration <= 0.0_pReal) extmsg = trim(extmsg)//' c_sol'
|
||||
if (prm%Q_sol <= 0.0_pReal) extmsg = trim(extmsg)//' Q_sol'
|
||||
if (prm%f_sol <= 0.0_pReal) extmsg = trim(extmsg)//' f_sol'
|
||||
if (prm%c_sol <= 0.0_pReal) extmsg = trim(extmsg)//' c_sol'
|
||||
|
||||
if (prm%grainboundaryTransmissivity > 1.0_pReal) extmsg = trim(extmsg)//' chi_GB'
|
||||
if (prm%surfaceTransmissivity < 0.0_pReal .or. prm%surfaceTransmissivity > 1.0_pReal) &
|
||||
if (prm%chi_GB > 1.0_pReal) extmsg = trim(extmsg)//' chi_GB'
|
||||
if (prm%chi_surface < 0.0_pReal .or. prm%chi_surface > 1.0_pReal) &
|
||||
extmsg = trim(extmsg)//' chi_surface'
|
||||
|
||||
if (prm%fEdgeMultiplication < 0.0_pReal .or. prm%fEdgeMultiplication > 1.0_pReal) &
|
||||
if (prm%f_ed_mult < 0.0_pReal .or. prm%f_ed_mult > 1.0_pReal) &
|
||||
extmsg = trim(extmsg)//' f_ed_mult'
|
||||
|
||||
endif slipActive
|
||||
|
@ -620,16 +620,16 @@ module subroutine plastic_nonlocal_dependentState(F, Fp, instance, of, ip, el)
|
|||
! coefficients are corrected for the line tension effect
|
||||
! (see Kubin,Devincre,Hoc; 2008; Modeling dislocation storage rates and mean free paths in face-centered cubic crystals)
|
||||
if (any(lattice_structure(material_phaseAt(1,el)) == [LATTICE_bcc_ID,LATTICE_fcc_ID])) then
|
||||
myInteractionMatrix = prm%interactionSlipSlip &
|
||||
* spread(( 1.0_pReal - prm%linetensionEffect &
|
||||
+ prm%linetensionEffect &
|
||||
* log(0.35_pReal * prm%burgers * sqrt(max(stt%rho_forest(:,of),prm%significantRho))) &
|
||||
/ log(0.35_pReal * prm%burgers * 1e6_pReal))** 2.0_pReal,2,prm%sum_N_sl)
|
||||
myInteractionMatrix = prm%h_sl_sl &
|
||||
* spread(( 1.0_pReal - prm%f_F &
|
||||
+ prm%f_F &
|
||||
* log(0.35_pReal * prm%b_sl * sqrt(max(stt%rho_forest(:,of),prm%rho_significant))) &
|
||||
/ log(0.35_pReal * prm%b_sl * 1e6_pReal))** 2.0_pReal,2,prm%sum_N_sl)
|
||||
else
|
||||
myInteractionMatrix = prm%interactionSlipSlip
|
||||
myInteractionMatrix = prm%h_sl_sl
|
||||
endif
|
||||
|
||||
dst%tau_pass(:,of) = prm%mu * prm%burgers &
|
||||
dst%tau_pass(:,of) = prm%mu * prm%b_sl &
|
||||
* sqrt(matmul(myInteractionMatrix,sum(abs(rho),2)))
|
||||
|
||||
!*** calculate the dislocation stress of the neighboring excess dislocation densities
|
||||
|
@ -731,7 +731,7 @@ module subroutine plastic_nonlocal_dependentState(F, Fp, instance, of, ip, el)
|
|||
where(rhoTotal > 0.0_pReal) rhoExcessGradient_over_rho = rhoExcessGradient / rhoTotal
|
||||
|
||||
! ... gives the local stress correction when multiplied with a factor
|
||||
dst%tau_back(s,of) = - prm%mu * prm%burgers(s) / (2.0_pReal * PI) &
|
||||
dst%tau_back(s,of) = - prm%mu * prm%b_sl(s) / (2.0_pReal * PI) &
|
||||
* ( rhoExcessGradient_over_rho(1) / (1.0_pReal - prm%nu) &
|
||||
+ rhoExcessGradient_over_rho(2))
|
||||
enddo
|
||||
|
@ -841,7 +841,7 @@ module subroutine plastic_nonlocal_LpAndItsTangent(Lp,dLp_dMp, &
|
|||
forall (s = 1:ns, t = 5:8, rhoSgl(s,t) * v(s,t-4) < 0.0_pReal) &
|
||||
rhoSgl(s,t-4) = rhoSgl(s,t-4) + abs(rhoSgl(s,t))
|
||||
|
||||
gdotTotal = sum(rhoSgl(:,1:4) * v, 2) * prm%burgers
|
||||
gdotTotal = sum(rhoSgl(:,1:4) * v, 2) * prm%b_sl
|
||||
|
||||
Lp = 0.0_pReal
|
||||
dLp_dMp = 0.0_pReal
|
||||
|
@ -850,10 +850,10 @@ module subroutine plastic_nonlocal_LpAndItsTangent(Lp,dLp_dMp, &
|
|||
forall (i=1:3,j=1:3,k=1:3,l=1:3) &
|
||||
dLp_dMp(i,j,k,l) = dLp_dMp(i,j,k,l) &
|
||||
+ prm%Schmid(i,j,s) * prm%Schmid(k,l,s) &
|
||||
* sum(rhoSgl(s,1:4) * dv_dtau(s,1:4)) * prm%burgers(s) &
|
||||
* sum(rhoSgl(s,1:4) * dv_dtau(s,1:4)) * prm%b_sl(s) &
|
||||
+ prm%Schmid(i,j,s) &
|
||||
* ( prm%nonSchmid_pos(k,l,s) * rhoSgl(s,3) * dv_dtauNS(s,3) &
|
||||
- prm%nonSchmid_neg(k,l,s) * rhoSgl(s,4) * dv_dtauNS(s,4)) * prm%burgers(s)
|
||||
- prm%nonSchmid_neg(k,l,s) * rhoSgl(s,4) * dv_dtauNS(s,4)) * prm%b_sl(s)
|
||||
enddo
|
||||
|
||||
end associate
|
||||
|
@ -929,8 +929,8 @@ module subroutine plastic_nonlocal_deltaState(Mp,instance,of,ip,el)
|
|||
if (abs(tau(s)) < 1.0e-15_pReal) tau(s) = 1.0e-15_pReal
|
||||
enddo
|
||||
|
||||
dUpper(:,1) = prm%mu * prm%burgers/(8.0_pReal * PI * (1.0_pReal - prm%nu) * abs(tau))
|
||||
dUpper(:,2) = prm%mu * prm%burgers/(4.0_pReal * PI * abs(tau))
|
||||
dUpper(:,1) = prm%mu * prm%b_sl/(8.0_pReal * PI * (1.0_pReal - prm%nu) * abs(tau))
|
||||
dUpper(:,2) = prm%mu * prm%b_sl/(4.0_pReal * PI * abs(tau))
|
||||
|
||||
where(dNeq0(sqrt(sum(abs(rho(:,edg)),2)))) &
|
||||
dUpper(:,1) = min(1.0_pReal/sqrt(sum(abs(rho(:,edg)),2)),dUpper(:,1))
|
||||
|
@ -1041,7 +1041,7 @@ module subroutine plastic_nonlocal_dotState(Mp, F, Fp, Temperature,timestep, &
|
|||
my_rhoSgl0 = rho0(:,sgl)
|
||||
|
||||
forall (s = 1:ns, t = 1:4) v(s,t) = plasticState(ph)%state(iV(s,t,instance),of)
|
||||
gdot = rhoSgl(:,1:4) * v * spread(prm%burgers,2,4)
|
||||
gdot = rhoSgl(:,1:4) * v * spread(prm%b_sl,2,4)
|
||||
|
||||
#ifdef DEBUG
|
||||
if (debugConstitutive%basic &
|
||||
|
@ -1060,8 +1060,8 @@ module subroutine plastic_nonlocal_dotState(Mp, F, Fp, Temperature,timestep, &
|
|||
enddo
|
||||
|
||||
dLower = prm%minDipoleHeight
|
||||
dUpper(:,1) = prm%mu * prm%burgers/(8.0_pReal * PI * (1.0_pReal - prm%nu) * abs(tau))
|
||||
dUpper(:,2) = prm%mu * prm%burgers/(4.0_pReal * PI * abs(tau))
|
||||
dUpper(:,1) = prm%mu * prm%b_sl/(8.0_pReal * PI * (1.0_pReal - prm%nu) * abs(tau))
|
||||
dUpper(:,2) = prm%mu * prm%b_sl/(4.0_pReal * PI * abs(tau))
|
||||
|
||||
where(dNeq0(sqrt(sum(abs(rho(:,edg)),2)))) &
|
||||
dUpper(:,1) = min(1.0_pReal/sqrt(sum(abs(rho(:,edg)),2)),dUpper(:,1))
|
||||
|
@ -1075,18 +1075,18 @@ module subroutine plastic_nonlocal_dotState(Mp, F, Fp, Temperature,timestep, &
|
|||
rhoDotMultiplication = 0.0_pReal
|
||||
isBCC: if (lattice_structure(ph) == LATTICE_bcc_ID) then
|
||||
forall (s = 1:ns, sum(abs(v(s,1:4))) > 0.0_pReal)
|
||||
rhoDotMultiplication(s,1:2) = sum(abs(gdot(s,3:4))) / prm%burgers(s) & ! assuming double-cross-slip of screws to be decisive for multiplication
|
||||
* sqrt(stt%rho_forest(s,of)) / prm%lambda0(s) ! & ! mean free path
|
||||
rhoDotMultiplication(s,1:2) = sum(abs(gdot(s,3:4))) / prm%b_sl(s) & ! assuming double-cross-slip of screws to be decisive for multiplication
|
||||
* sqrt(stt%rho_forest(s,of)) / prm%i_sl(s) ! & ! mean free path
|
||||
! * 2.0_pReal * sum(abs(v(s,3:4))) / sum(abs(v(s,1:4))) ! ratio of screw to overall velocity determines edge generation
|
||||
rhoDotMultiplication(s,3:4) = sum(abs(gdot(s,3:4))) /prm%burgers(s) & ! assuming double-cross-slip of screws to be decisive for multiplication
|
||||
* sqrt(stt%rho_forest(s,of)) / prm%lambda0(s) ! & ! mean free path
|
||||
rhoDotMultiplication(s,3:4) = sum(abs(gdot(s,3:4))) /prm%b_sl(s) & ! assuming double-cross-slip of screws to be decisive for multiplication
|
||||
* sqrt(stt%rho_forest(s,of)) / prm%i_sl(s) ! & ! mean free path
|
||||
! * 2.0_pReal * sum(abs(v(s,1:2))) / sum(abs(v(s,1:4))) ! ratio of edge to overall velocity determines screw generation
|
||||
endforall
|
||||
|
||||
else isBCC
|
||||
rhoDotMultiplication(:,1:4) = spread( &
|
||||
(sum(abs(gdot(:,1:2)),2) * prm%fEdgeMultiplication + sum(abs(gdot(:,3:4)),2)) &
|
||||
* sqrt(stt%rho_forest(:,of)) / prm%lambda0 / prm%burgers, 2, 4)
|
||||
(sum(abs(gdot(:,1:2)),2) * prm%f_ed_mult + sum(abs(gdot(:,3:4)),2)) &
|
||||
* sqrt(stt%rho_forest(:,of)) / prm%i_sl / prm%b_sl, 2, 4)
|
||||
endif isBCC
|
||||
|
||||
forall (s = 1:ns, t = 1:4) v0(s,t) = plasticState(ph)%state0(iV(s,t,instance),of)
|
||||
|
@ -1097,20 +1097,20 @@ module subroutine plastic_nonlocal_dotState(Mp, F, Fp, Temperature,timestep, &
|
|||
|
||||
!*** formation by glide
|
||||
do c = 1,2
|
||||
rhoDotSingle2DipoleGlide(:,2*c-1) = -2.0_pReal * dUpper(:,c) / prm%burgers &
|
||||
rhoDotSingle2DipoleGlide(:,2*c-1) = -2.0_pReal * dUpper(:,c) / prm%b_sl &
|
||||
* ( rhoSgl(:,2*c-1) * abs(gdot(:,2*c)) & ! negative mobile --> positive mobile
|
||||
+ rhoSgl(:,2*c) * abs(gdot(:,2*c-1)) & ! positive mobile --> negative mobile
|
||||
+ abs(rhoSgl(:,2*c+4)) * abs(gdot(:,2*c-1))) ! positive mobile --> negative immobile
|
||||
|
||||
rhoDotSingle2DipoleGlide(:,2*c) = -2.0_pReal * dUpper(:,c) / prm%burgers &
|
||||
rhoDotSingle2DipoleGlide(:,2*c) = -2.0_pReal * dUpper(:,c) / prm%b_sl &
|
||||
* ( rhoSgl(:,2*c-1) * abs(gdot(:,2*c)) & ! negative mobile --> positive mobile
|
||||
+ rhoSgl(:,2*c) * abs(gdot(:,2*c-1)) & ! positive mobile --> negative mobile
|
||||
+ abs(rhoSgl(:,2*c+3)) * abs(gdot(:,2*c))) ! negative mobile --> positive immobile
|
||||
|
||||
rhoDotSingle2DipoleGlide(:,2*c+3) = -2.0_pReal * dUpper(:,c) / prm%burgers &
|
||||
rhoDotSingle2DipoleGlide(:,2*c+3) = -2.0_pReal * dUpper(:,c) / prm%b_sl &
|
||||
* rhoSgl(:,2*c+3) * abs(gdot(:,2*c)) ! negative mobile --> positive immobile
|
||||
|
||||
rhoDotSingle2DipoleGlide(:,2*c+4) = -2.0_pReal * dUpper(:,c) / prm%burgers &
|
||||
rhoDotSingle2DipoleGlide(:,2*c+4) = -2.0_pReal * dUpper(:,c) / prm%b_sl &
|
||||
* rhoSgl(:,2*c+4) * abs(gdot(:,2*c-1)) ! positive mobile --> negative immobile
|
||||
|
||||
rhoDotSingle2DipoleGlide(:,c+8) = abs(rhoDotSingle2DipoleGlide(:,2*c+3)) &
|
||||
|
@ -1123,7 +1123,7 @@ module subroutine plastic_nonlocal_dotState(Mp, F, Fp, Temperature,timestep, &
|
|||
!*** athermal annihilation
|
||||
rhoDotAthermalAnnihilation = 0.0_pReal
|
||||
forall (c=1:2) &
|
||||
rhoDotAthermalAnnihilation(:,c+8) = -2.0_pReal * dLower(:,c) / prm%burgers &
|
||||
rhoDotAthermalAnnihilation(:,c+8) = -2.0_pReal * dLower(:,c) / prm%b_sl &
|
||||
* ( 2.0_pReal * (rhoSgl(:,2*c-1) * abs(gdot(:,2*c)) + rhoSgl(:,2*c) * abs(gdot(:,2*c-1))) & ! was single hitting single
|
||||
+ 2.0_pReal * (abs(rhoSgl(:,2*c+3)) * abs(gdot(:,2*c)) + abs(rhoSgl(:,2*c+4)) * abs(gdot(:,2*c-1))) & ! was single hitting immobile single or was immobile single hit by single
|
||||
+ rhoDip(:,c) * (abs(gdot(:,2*c-1)) + abs(gdot(:,2*c)))) ! single knocks dipole constituent
|
||||
|
@ -1132,13 +1132,13 @@ module subroutine plastic_nonlocal_dotState(Mp, F, Fp, Temperature,timestep, &
|
|||
if (lattice_structure(ph) == LATTICE_fcc_ID) &
|
||||
forall (s = 1:ns, prm%colinearSystem(s) > 0) &
|
||||
rhoDotAthermalAnnihilation(prm%colinearSystem(s),1:2) = - rhoDotAthermalAnnihilation(s,10) &
|
||||
* 0.25_pReal * sqrt(stt%rho_forest(s,of)) * (dUpper(s,2) + dLower(s,2)) * prm%edgeJogFactor
|
||||
* 0.25_pReal * sqrt(stt%rho_forest(s,of)) * (dUpper(s,2) + dLower(s,2)) * prm%f_ed
|
||||
|
||||
|
||||
!*** thermally activated annihilation of edge dipoles by climb
|
||||
rhoDotThermalAnnihilation = 0.0_pReal
|
||||
selfDiffusion = prm%Dsd0 * exp(-prm%selfDiffusionEnergy / (kB * Temperature))
|
||||
vClimb = prm%atomicVolume * selfDiffusion * prm%mu &
|
||||
selfDiffusion = prm%D_0 * exp(-prm%Q_cl / (kB * Temperature))
|
||||
vClimb = prm%V_at * selfDiffusion * prm%mu &
|
||||
/ ( kB * Temperature * PI * (1.0_pReal-prm%nu) * (dUpper(:,1) + dLower(:,1)))
|
||||
forall (s = 1:ns, dUpper(s,1) > dLower(s,1)) &
|
||||
rhoDotThermalAnnihilation(s,9) = max(- 4.0_pReal * rhoDip(s,1) * vClimb(s) / (dUpper(s,1) - dLower(s,1)), &
|
||||
|
@ -1252,7 +1252,7 @@ function rhoDotFlux(F,Fp,timestep, instance,of,ip,el)
|
|||
my_rhoSgl0 = rho0(:,sgl)
|
||||
|
||||
forall (s = 1:ns, t = 1:4) v(s,t) = plasticState(ph)%state(iV(s,t,instance),of) !ToDo: MD: I think we should use state0 here
|
||||
gdot = rhoSgl(:,1:4) * v * spread(prm%burgers,2,4)
|
||||
gdot = rhoSgl(:,1:4) * v * spread(prm%b_sl,2,4)
|
||||
|
||||
|
||||
forall (s = 1:ns, t = 1:4) v0(s,t) = plasticState(ph)%state0(iV(s,t,instance),of)
|
||||
|
@ -1264,14 +1264,14 @@ function rhoDotFlux(F,Fp,timestep, instance,of,ip,el)
|
|||
|
||||
!*** check CFL (Courant-Friedrichs-Lewy) condition for flux
|
||||
if (any( abs(gdot) > 0.0_pReal & ! any active slip system ...
|
||||
.and. prm%CFLfactor * abs(v0) * timestep &
|
||||
.and. prm%f_c * abs(v0) * timestep &
|
||||
> IPvolume(ip,el) / maxval(IParea(:,ip,el)))) then ! ...with velocity above critical value (we use the reference volume and area for simplicity here)
|
||||
#ifdef DEBUG
|
||||
if (debugConstitutive%extensive) then
|
||||
print'(a,i5,a,i2)', '<< CONST >> CFL condition not fullfilled at el ',el,' ip ',ip
|
||||
print'(a,e10.3,a,e10.3)', '<< CONST >> velocity is at ', &
|
||||
maxval(abs(v0), abs(gdot) > 0.0_pReal &
|
||||
.and. prm%CFLfactor * abs(v0) * timestep &
|
||||
.and. prm%f_c * abs(v0) * timestep &
|
||||
> IPvolume(ip,el) / maxval(IParea(:,ip,el))), &
|
||||
' at a timestep of ',timestep
|
||||
print*, '<< CONST >> enforcing cutback !!!'
|
||||
|
@ -1334,8 +1334,8 @@ function rhoDotFlux(F,Fp,timestep, instance,of,ip,el)
|
|||
neighbor_rhoSgl0(s,t) = max(plasticState(np)%state0(iRhoU(s,t,neighbor_instance),no),0.0_pReal)
|
||||
endforall
|
||||
|
||||
where (neighbor_rhoSgl0 * IPvolume(neighbor_ip,neighbor_el) ** 0.667_pReal < prm%significantN &
|
||||
.or. neighbor_rhoSgl0 < prm%significantRho) &
|
||||
where (neighbor_rhoSgl0 * IPvolume(neighbor_ip,neighbor_el) ** 0.667_pReal < prm%rho_min &
|
||||
.or. neighbor_rhoSgl0 < prm%rho_significant) &
|
||||
neighbor_rhoSgl0 = 0.0_pReal
|
||||
normal_neighbor2me_defConf = math_det33(Favg) * matmul(math_inv33(transpose(Favg)), &
|
||||
IPareaNormal(1:3,neighbor_n,neighbor_ip,neighbor_el)) ! normal of the interface in (average) deformed configuration (pointing neighbor => me)
|
||||
|
@ -1460,7 +1460,7 @@ module subroutine plastic_nonlocal_updateCompatibility(orientation,instance,i,e)
|
|||
if (neighbor_e <= 0 .or. neighbor_i <= 0) then
|
||||
!* FREE SURFACE
|
||||
!* Set surface transmissivity to the value specified in the material.config
|
||||
forall(s1 = 1:ns) my_compatibility(:,s1,s1,n) = sqrt(prm%surfaceTransmissivity)
|
||||
forall(s1 = 1:ns) my_compatibility(:,s1,s1,n) = sqrt(prm%chi_surface)
|
||||
elseif (neighbor_phase /= ph) then
|
||||
!* PHASE BOUNDARY
|
||||
!* If we encounter a different nonlocal phase at the neighbor,
|
||||
|
@ -1469,13 +1469,13 @@ module subroutine plastic_nonlocal_updateCompatibility(orientation,instance,i,e)
|
|||
!* we do not consider this to be a phase boundary, so completely compatible.
|
||||
if (.not. phase_localPlasticity(neighbor_phase) .and. .not. phase_localPlasticity(ph)) &
|
||||
forall(s1 = 1:ns) my_compatibility(:,s1,s1,n) = 0.0_pReal
|
||||
elseif (prm%grainboundaryTransmissivity >= 0.0_pReal) then
|
||||
elseif (prm%chi_GB >= 0.0_pReal) then
|
||||
!* GRAIN BOUNDARY !
|
||||
!* fixed transmissivity for adjacent ips with different texture (only if explicitly given in material.config)
|
||||
if (any(dNeq(material_orientation0(1,i,e)%asQuaternion(), &
|
||||
material_orientation0(1,neighbor_i,neighbor_e)%asQuaternion())) .and. &
|
||||
(.not. phase_localPlasticity(neighbor_phase))) &
|
||||
forall(s1 = 1:ns) my_compatibility(:,s1,s1,n) = sqrt(prm%grainboundaryTransmissivity)
|
||||
forall(s1 = 1:ns) my_compatibility(:,s1,s1,n) = sqrt(prm%chi_GB)
|
||||
else
|
||||
!* GRAIN BOUNDARY ?
|
||||
!* Compatibility defined by relative orientation of slip systems:
|
||||
|
@ -1631,7 +1631,7 @@ subroutine stateInit(ini,phase,NipcMyPhase,instance)
|
|||
|
||||
associate(stt => state(instance))
|
||||
|
||||
if (ini%rhoSglRandom > 0.0_pReal) then ! randomly distribute dislocation segments on random slip system and of random type in the volume
|
||||
if (ini%random_rho_u > 0.0_pReal) then ! randomly distribute dislocation segments on random slip system and of random type in the volume
|
||||
do e = 1,discretization_nElem
|
||||
do i = 1,discretization_nIP
|
||||
if (material_phaseAt(1,e) == phase) volume(material_phasememberAt(1,i,e)) = IPvolume(i,e)
|
||||
|
@ -1639,11 +1639,11 @@ subroutine stateInit(ini,phase,NipcMyPhase,instance)
|
|||
enddo
|
||||
totalVolume = sum(volume)
|
||||
minimumIPVolume = minval(volume)
|
||||
densityBinning = ini%rhoSglRandomBinning / minimumIpVolume ** (2.0_pReal / 3.0_pReal)
|
||||
densityBinning = ini%random_rho_u_binning / minimumIpVolume ** (2.0_pReal / 3.0_pReal)
|
||||
|
||||
! fill random material points with dislocation segments until the desired overall density is reached
|
||||
meanDensity = 0.0_pReal
|
||||
do while(meanDensity < ini%rhoSglRandom)
|
||||
do while(meanDensity < ini%random_rho_u)
|
||||
call random_number(rnd)
|
||||
phasemember = nint(rnd(1)*real(NipcMyPhase,pReal) + 0.5_pReal)
|
||||
s = nint(rnd(2)*real(sum(ini%N_sl),pReal)*4.0_pReal + 0.5_pReal)
|
||||
|
@ -1656,15 +1656,15 @@ subroutine stateInit(ini,phase,NipcMyPhase,instance)
|
|||
from = 1 + sum(ini%N_sl(1:f-1))
|
||||
upto = sum(ini%N_sl(1:f))
|
||||
do s = from,upto
|
||||
noise = [math_sampleGaussVar(0.0_pReal, ini%rhoSglScatter), &
|
||||
math_sampleGaussVar(0.0_pReal, ini%rhoSglScatter)]
|
||||
stt%rho_sgl_mob_edg_pos(s,e) = ini%rhoSglEdgePos0(f) + noise(1)
|
||||
stt%rho_sgl_mob_edg_neg(s,e) = ini%rhoSglEdgeNeg0(f) + noise(1)
|
||||
stt%rho_sgl_mob_scr_pos(s,e) = ini%rhoSglScrewPos0(f) + noise(2)
|
||||
stt%rho_sgl_mob_scr_neg(s,e) = ini%rhoSglScrewNeg0(f) + noise(2)
|
||||
noise = [math_sampleGaussVar(0.0_pReal, ini%sigma_rho_u), &
|
||||
math_sampleGaussVar(0.0_pReal, ini%sigma_rho_u)]
|
||||
stt%rho_sgl_mob_edg_pos(s,e) = ini%rho_u_ed_pos_0(f) + noise(1)
|
||||
stt%rho_sgl_mob_edg_neg(s,e) = ini%rho_u_ed_neg_0(f) + noise(1)
|
||||
stt%rho_sgl_mob_scr_pos(s,e) = ini%rho_u_sc_pos_0(f) + noise(2)
|
||||
stt%rho_sgl_mob_scr_neg(s,e) = ini%rho_u_sc_neg_0(f) + noise(2)
|
||||
enddo
|
||||
stt%rho_dip_edg(from:upto,e) = ini%rhoDipEdge0(f)
|
||||
stt%rho_dip_scr(from:upto,e) = ini%rhoDipScrew0(f)
|
||||
stt%rho_dip_edg(from:upto,e) = ini%rho_d_ed_0(f)
|
||||
stt%rho_dip_scr(from:upto,e) = ini%rho_d_sc_0(f)
|
||||
enddo
|
||||
enddo
|
||||
endif
|
||||
|
@ -1732,14 +1732,14 @@ pure subroutine kinetics(v, dv_dtau, dv_dtauNS, tau, tauNS, tauThreshold, c, Tem
|
|||
!* Effective stress includes non Schmid constributions
|
||||
!* The derivative only gives absolute values; the correct sign is taken care of in the formula for the derivative of the velocity
|
||||
tauEff = max(0.0_pReal, abs(tauNS(s)) - tauThreshold(s)) ! ensure that the effective stress is positive
|
||||
meanfreepath_P = prm%burgers(s)
|
||||
jumpWidth_P = prm%burgers(s)
|
||||
activationLength_P = prm%doublekinkwidth *prm%burgers(s)
|
||||
activationVolume_P = activationLength_P * jumpWidth_P * prm%burgers(s)
|
||||
meanfreepath_P = prm%b_sl(s)
|
||||
jumpWidth_P = prm%b_sl(s)
|
||||
activationLength_P = prm%w *prm%b_sl(s)
|
||||
activationVolume_P = activationLength_P * jumpWidth_P * prm%b_sl(s)
|
||||
criticalStress_P = prm%peierlsStress(s,c)
|
||||
activationEnergy_P = criticalStress_P * activationVolume_P
|
||||
tauRel_P = min(1.0_pReal, tauEff / criticalStress_P) ! ensure that the activation probability cannot become greater than one
|
||||
tPeierls = 1.0_pReal / prm%fattack &
|
||||
tPeierls = 1.0_pReal / prm%nu_a &
|
||||
* exp(activationEnergy_P / (kB * Temperature) &
|
||||
* (1.0_pReal - tauRel_P**prm%p)**prm%q)
|
||||
if (tauEff < criticalStress_P) then
|
||||
|
@ -1752,14 +1752,14 @@ pure subroutine kinetics(v, dv_dtau, dv_dtauNS, tau, tauNS, tauThreshold, c, Tem
|
|||
!* Contribution from solid solution strengthening
|
||||
!* The derivative only gives absolute values; the correct sign is taken care of in the formula for the derivative of the velocity
|
||||
tauEff = abs(tau(s)) - tauThreshold(s)
|
||||
meanfreepath_S = prm%burgers(s) / sqrt(prm%solidSolutionConcentration)
|
||||
jumpWidth_S = prm%solidSolutionSize * prm%burgers(s)
|
||||
activationLength_S = prm%burgers(s) / sqrt(prm%solidSolutionConcentration)
|
||||
activationVolume_S = activationLength_S * jumpWidth_S * prm%burgers(s)
|
||||
activationEnergy_S = prm%solidSolutionEnergy
|
||||
meanfreepath_S = prm%b_sl(s) / sqrt(prm%c_sol)
|
||||
jumpWidth_S = prm%f_sol * prm%b_sl(s)
|
||||
activationLength_S = prm%b_sl(s) / sqrt(prm%c_sol)
|
||||
activationVolume_S = activationLength_S * jumpWidth_S * prm%b_sl(s)
|
||||
activationEnergy_S = prm%Q_sol
|
||||
criticalStress_S = activationEnergy_S / activationVolume_S
|
||||
tauRel_S = min(1.0_pReal, tauEff / criticalStress_S) ! ensure that the activation probability cannot become greater than one
|
||||
tSolidSolution = 1.0_pReal / prm%fattack &
|
||||
tSolidSolution = 1.0_pReal / prm%nu_a &
|
||||
* exp(activationEnergy_S / (kB * Temperature)* (1.0_pReal - tauRel_S**prm%p)**prm%q)
|
||||
if (tauEff < criticalStress_S) then
|
||||
dtSolidSolution_dtau = tSolidSolution * prm%p * prm%q * activationVolume_S / (kB * Temperature) &
|
||||
|
@ -1770,7 +1770,7 @@ pure subroutine kinetics(v, dv_dtau, dv_dtauNS, tau, tauNS, tauThreshold, c, Tem
|
|||
|
||||
!* viscous glide velocity
|
||||
tauEff = abs(tau(s)) - tauThreshold(s)
|
||||
mobility = prm%burgers(s) / prm%viscosity
|
||||
mobility = prm%b_sl(s) / prm%eta
|
||||
vViscous = mobility * tauEff
|
||||
|
||||
!* Mean velocity results from waiting time at peierls barriers and solid solution obstacles with respective meanfreepath of
|
||||
|
@ -1805,7 +1805,7 @@ pure function getRho(instance,of,ip,el)
|
|||
getRho(:,mob) = max(getRho(:,mob),0.0_pReal)
|
||||
getRho(:,dip) = max(getRho(:,dip),0.0_pReal)
|
||||
|
||||
where(abs(getRho) < max(prm%significantN/IPvolume(ip,el)**(2.0_pReal/3.0_pReal),prm%significantRho)) &
|
||||
where(abs(getRho) < max(prm%rho_min/IPvolume(ip,el)**(2.0_pReal/3.0_pReal),prm%rho_significant)) &
|
||||
getRho = 0.0_pReal
|
||||
|
||||
end associate
|
||||
|
@ -1830,7 +1830,7 @@ pure function getRho0(instance,of,ip,el)
|
|||
getRho0(:,mob) = max(getRho0(:,mob),0.0_pReal)
|
||||
getRho0(:,dip) = max(getRho0(:,dip),0.0_pReal)
|
||||
|
||||
where(abs(getRho0) < max(prm%significantN/IPvolume(ip,el)**(2.0_pReal/3.0_pReal),prm%significantRho)) &
|
||||
where(abs(getRho0) < max(prm%rho_min/IPvolume(ip,el)**(2.0_pReal/3.0_pReal),prm%rho_significant)) &
|
||||
getRho0 = 0.0_pReal
|
||||
|
||||
end associate
|
||||
|
|
|
@ -8,28 +8,28 @@ submodule(constitutive:constitutive_plastic) plastic_phenopowerlaw
|
|||
|
||||
type :: tParameters
|
||||
real(pReal) :: &
|
||||
gdot0_slip = 1.0_pReal, & !< reference shear strain rate for slip
|
||||
gdot0_twin = 1.0_pReal, & !< reference shear strain rate for twin
|
||||
n_slip = 1.0_pReal, & !< stress exponent for slip
|
||||
n_twin = 1.0_pReal, & !< stress exponent for twin
|
||||
spr = 1.0_pReal, & !< push-up factor for slip saturation due to twinning
|
||||
dot_gamma_0_sl = 1.0_pReal, & !< reference shear strain rate for slip
|
||||
dot_gamma_0_tw = 1.0_pReal, & !< reference shear strain rate for twin
|
||||
n_sl = 1.0_pReal, & !< stress exponent for slip
|
||||
n_tw = 1.0_pReal, & !< stress exponent for twin
|
||||
f_sl_sat_tw = 1.0_pReal, & !< push-up factor for slip saturation due to twinning
|
||||
c_1 = 1.0_pReal, &
|
||||
c_2 = 1.0_pReal, &
|
||||
c_3 = 1.0_pReal, &
|
||||
c_4 = 1.0_pReal, &
|
||||
h0_SlipSlip = 1.0_pReal, & !< reference hardening slip - slip
|
||||
h0_TwinSlip = 1.0_pReal, & !< reference hardening twin - slip
|
||||
h0_TwinTwin = 1.0_pReal, & !< reference hardening twin - twin
|
||||
a_slip = 1.0_pReal
|
||||
h_0_sl_sl = 1.0_pReal, & !< reference hardening slip - slip
|
||||
h_0_tw_sl = 1.0_pReal, & !< reference hardening twin - slip
|
||||
h_0_tw_tw = 1.0_pReal, & !< reference hardening twin - twin
|
||||
a_sl = 1.0_pReal
|
||||
real(pReal), allocatable, dimension(:) :: &
|
||||
xi_slip_sat, & !< maximum critical shear stress for slip
|
||||
H_int, & !< per family hardening activity (optional)
|
||||
gamma_twin_char !< characteristic shear for twins
|
||||
xi_inf_sl, & !< maximum critical shear stress for slip
|
||||
h_int, & !< per family hardening activity (optional)
|
||||
gamma_tw_char !< characteristic shear for twins
|
||||
real(pReal), allocatable, dimension(:,:) :: &
|
||||
interaction_SlipSlip, & !< slip resistance from slip activity
|
||||
interaction_SlipTwin, & !< slip resistance from twin activity
|
||||
interaction_TwinSlip, & !< twin resistance from slip activity
|
||||
interaction_TwinTwin !< twin resistance from twin activity
|
||||
h_sl_sl, & !< slip resistance from slip activity
|
||||
h_sl_tw, & !< slip resistance from twin activity
|
||||
h_tw_sl, & !< twin resistance from slip activity
|
||||
h_tw_tw !< twin resistance from twin activity
|
||||
real(pReal), allocatable, dimension(:,:,:) :: &
|
||||
P_sl, &
|
||||
P_tw, &
|
||||
|
@ -78,8 +78,8 @@ module function plastic_phenopowerlaw_init() result(myPlasticity)
|
|||
integer, dimension(:), allocatable :: &
|
||||
N_sl, N_tw
|
||||
real(pReal), dimension(:), allocatable :: &
|
||||
xi_slip_0, & !< initial critical shear stress for slip
|
||||
xi_twin_0, & !< initial critical shear stress for twin
|
||||
xi_0_sl, & !< initial critical shear stress for slip
|
||||
xi_0_tw, & !< initial critical shear stress for twin
|
||||
a !< non-Schmid coefficients
|
||||
character(len=pStringLen) :: &
|
||||
extmsg = ''
|
||||
|
@ -120,7 +120,7 @@ module function plastic_phenopowerlaw_init() result(myPlasticity)
|
|||
phase%get_asFloat('c/a',defaultVal=0.0_pReal))
|
||||
|
||||
if(phase%get_asString('lattice') == 'bcc') then
|
||||
a = pl%get_asFloats('nonSchmid_coefficients',defaultVal=emptyRealArray)
|
||||
a = pl%get_asFloats('a_nonSchmid',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)
|
||||
|
@ -128,36 +128,36 @@ module function plastic_phenopowerlaw_init() result(myPlasticity)
|
|||
prm%nonSchmid_pos = prm%P_sl
|
||||
prm%nonSchmid_neg = prm%P_sl
|
||||
endif
|
||||
prm%interaction_SlipSlip = lattice_interaction_SlipBySlip(N_sl, &
|
||||
prm%h_sl_sl = lattice_interaction_SlipBySlip(N_sl, &
|
||||
pl%get_asFloats('h_sl_sl'), &
|
||||
phase%get_asString('lattice'))
|
||||
|
||||
xi_slip_0 = pl%get_asFloats('xi_0_sl', requiredSize=size(N_sl))
|
||||
prm%xi_slip_sat = pl%get_asFloats('xi_inf_sl', requiredSize=size(N_sl))
|
||||
prm%H_int = pl%get_asFloats('h_int', requiredSize=size(N_sl), &
|
||||
xi_0_sl = pl%get_asFloats('xi_0_sl', requiredSize=size(N_sl))
|
||||
prm%xi_inf_sl = pl%get_asFloats('xi_inf_sl', requiredSize=size(N_sl))
|
||||
prm%h_int = pl%get_asFloats('h_int', requiredSize=size(N_sl), &
|
||||
defaultVal=[(0.0_pReal,i=1,size(N_sl))])
|
||||
|
||||
prm%gdot0_slip = pl%get_asFloat('dot_gamma_0_sl')
|
||||
prm%n_slip = pl%get_asFloat('n_sl')
|
||||
prm%a_slip = pl%get_asFloat('a_sl')
|
||||
prm%h0_SlipSlip = pl%get_asFloat('h_0_sl_sl')
|
||||
prm%dot_gamma_0_sl = pl%get_asFloat('dot_gamma_0_sl')
|
||||
prm%n_sl = pl%get_asFloat('n_sl')
|
||||
prm%a_sl = pl%get_asFloat('a_sl')
|
||||
prm%h_0_sl_sl = pl%get_asFloat('h_0_sl_sl')
|
||||
|
||||
! expand: family => system
|
||||
xi_slip_0 = math_expand(xi_slip_0, N_sl)
|
||||
prm%xi_slip_sat = math_expand(prm%xi_slip_sat,N_sl)
|
||||
prm%H_int = math_expand(prm%H_int, N_sl)
|
||||
xi_0_sl = math_expand(xi_0_sl, N_sl)
|
||||
prm%xi_inf_sl = math_expand(prm%xi_inf_sl,N_sl)
|
||||
prm%h_int = math_expand(prm%h_int, N_sl)
|
||||
|
||||
! sanity checks
|
||||
if ( prm%gdot0_slip <= 0.0_pReal) extmsg = trim(extmsg)//' dot_gamma_0_sl'
|
||||
if ( prm%a_slip <= 0.0_pReal) extmsg = trim(extmsg)//' a_sl'
|
||||
if ( prm%n_slip <= 0.0_pReal) extmsg = trim(extmsg)//' n_sl'
|
||||
if (any(xi_slip_0 <= 0.0_pReal)) extmsg = trim(extmsg)//' xi_0_sl'
|
||||
if (any(prm%xi_slip_sat <= 0.0_pReal)) extmsg = trim(extmsg)//' xi_inf_sl'
|
||||
if ( prm%dot_gamma_0_sl <= 0.0_pReal) extmsg = trim(extmsg)//' dot_gamma_0_sl'
|
||||
if ( prm%a_sl <= 0.0_pReal) extmsg = trim(extmsg)//' a_sl'
|
||||
if ( prm%n_sl <= 0.0_pReal) extmsg = trim(extmsg)//' n_sl'
|
||||
if (any(xi_0_sl <= 0.0_pReal)) extmsg = trim(extmsg)//' xi_0_sl'
|
||||
if (any(prm%xi_inf_sl <= 0.0_pReal)) extmsg = trim(extmsg)//' xi_inf_sl'
|
||||
|
||||
else slipActive
|
||||
xi_slip_0 = emptyRealArray
|
||||
allocate(prm%xi_slip_sat,prm%H_int,source=emptyRealArray)
|
||||
allocate(prm%interaction_SlipSlip(0,0))
|
||||
xi_0_sl = emptyRealArray
|
||||
allocate(prm%xi_inf_sl,prm%h_int,source=emptyRealArray)
|
||||
allocate(prm%h_sl_sl(0,0))
|
||||
endif slipActive
|
||||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
|
@ -167,50 +167,50 @@ module function plastic_phenopowerlaw_init() result(myPlasticity)
|
|||
twinActive: if (prm%sum_N_tw > 0) then
|
||||
prm%P_tw = lattice_SchmidMatrix_twin(N_tw,phase%get_asString('lattice'),&
|
||||
phase%get_asFloat('c/a',defaultVal=0.0_pReal))
|
||||
prm%interaction_TwinTwin = lattice_interaction_TwinByTwin(N_tw,&
|
||||
prm%h_tw_tw = lattice_interaction_TwinByTwin(N_tw,&
|
||||
pl%get_asFloats('h_tw_tw'), &
|
||||
phase%get_asString('lattice'))
|
||||
prm%gamma_twin_char = lattice_characteristicShear_twin(N_tw,phase%get_asString('lattice'),&
|
||||
prm%gamma_tw_char = lattice_characteristicShear_twin(N_tw,phase%get_asString('lattice'),&
|
||||
phase%get_asFloat('c/a',defaultVal=0.0_pReal))
|
||||
|
||||
xi_twin_0 = pl%get_asFloats('xi_0_tw',requiredSize=size(N_tw))
|
||||
xi_0_tw = pl%get_asFloats('xi_0_tw',requiredSize=size(N_tw))
|
||||
|
||||
prm%c_1 = pl%get_asFloat('c_1',defaultVal=0.0_pReal)
|
||||
prm%c_2 = pl%get_asFloat('c_2',defaultVal=1.0_pReal)
|
||||
prm%c_3 = pl%get_asFloat('c_3',defaultVal=0.0_pReal)
|
||||
prm%c_4 = pl%get_asFloat('c_4',defaultVal=0.0_pReal)
|
||||
prm%gdot0_twin = pl%get_asFloat('dot_gamma_0_tw')
|
||||
prm%n_twin = pl%get_asFloat('n_tw')
|
||||
prm%spr = pl%get_asFloat('f_sl_sat_tw')
|
||||
prm%h0_TwinTwin = pl%get_asFloat('h_0_tw_tw')
|
||||
prm%dot_gamma_0_tw = pl%get_asFloat('dot_gamma_0_tw')
|
||||
prm%n_tw = pl%get_asFloat('n_tw')
|
||||
prm%f_sl_sat_tw = pl%get_asFloat('f_sl_sat_tw')
|
||||
prm%h_0_tw_tw = pl%get_asFloat('h_0_tw_tw')
|
||||
|
||||
! expand: family => system
|
||||
xi_twin_0 = math_expand(xi_twin_0,N_tw)
|
||||
xi_0_tw = math_expand(xi_0_tw,N_tw)
|
||||
|
||||
! sanity checks
|
||||
if (prm%gdot0_twin <= 0.0_pReal) extmsg = trim(extmsg)//' dot_gamma_0_tw'
|
||||
if (prm%n_twin <= 0.0_pReal) extmsg = trim(extmsg)//' n_tw'
|
||||
if (prm%dot_gamma_0_tw <= 0.0_pReal) extmsg = trim(extmsg)//' dot_gamma_0_tw'
|
||||
if (prm%n_tw <= 0.0_pReal) extmsg = trim(extmsg)//' n_tw'
|
||||
|
||||
else twinActive
|
||||
xi_twin_0 = emptyRealArray
|
||||
allocate(prm%gamma_twin_char,source=emptyRealArray)
|
||||
allocate(prm%interaction_TwinTwin(0,0))
|
||||
xi_0_tw = emptyRealArray
|
||||
allocate(prm%gamma_tw_char,source=emptyRealArray)
|
||||
allocate(prm%h_tw_tw(0,0))
|
||||
endif twinActive
|
||||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! slip-twin related parameters
|
||||
slipAndTwinActive: if (prm%sum_N_sl > 0 .and. prm%sum_N_tw > 0) then
|
||||
prm%h0_TwinSlip = pl%get_asFloat('h_0_tw_sl')
|
||||
prm%interaction_SlipTwin = lattice_interaction_SlipByTwin(N_sl,N_tw,&
|
||||
prm%h_0_tw_sl = pl%get_asFloat('h_0_tw_sl')
|
||||
prm%h_sl_tw = lattice_interaction_SlipByTwin(N_sl,N_tw,&
|
||||
pl%get_asFloats('h_sl_tw'), &
|
||||
phase%get_asString('lattice'))
|
||||
prm%interaction_TwinSlip = lattice_interaction_TwinBySlip(N_tw,N_sl,&
|
||||
prm%h_tw_sl = lattice_interaction_TwinBySlip(N_tw,N_sl,&
|
||||
pl%get_asFloats('h_tw_sl'), &
|
||||
phase%get_asString('lattice'))
|
||||
else slipAndTwinActive
|
||||
allocate(prm%interaction_SlipTwin(prm%sum_N_sl,prm%sum_N_tw)) ! at least one dimension is 0
|
||||
allocate(prm%interaction_TwinSlip(prm%sum_N_tw,prm%sum_N_sl)) ! at least one dimension is 0
|
||||
prm%h0_TwinSlip = 0.0_pReal
|
||||
allocate(prm%h_sl_tw(prm%sum_N_sl,prm%sum_N_tw)) ! at least one dimension is 0
|
||||
allocate(prm%h_tw_sl(prm%sum_N_tw,prm%sum_N_sl)) ! at least one dimension is 0
|
||||
prm%h_0_tw_sl = 0.0_pReal
|
||||
endif slipAndTwinActive
|
||||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
|
@ -237,7 +237,7 @@ module function plastic_phenopowerlaw_init() result(myPlasticity)
|
|||
startIndex = 1
|
||||
endIndex = prm%sum_N_sl
|
||||
stt%xi_slip => plasticState(p)%state (startIndex:endIndex,:)
|
||||
stt%xi_slip = spread(xi_slip_0, 2, NipcMyPhase)
|
||||
stt%xi_slip = spread(xi_0_sl, 2, NipcMyPhase)
|
||||
dot%xi_slip => plasticState(p)%dotState(startIndex:endIndex,:)
|
||||
plasticState(p)%atol(startIndex:endIndex) = pl%get_asFloat('atol_xi',defaultVal=1.0_pReal)
|
||||
if(any(plasticState(p)%atol(startIndex:endIndex) < 0.0_pReal)) extmsg = trim(extmsg)//' atol_xi'
|
||||
|
@ -245,7 +245,7 @@ module function plastic_phenopowerlaw_init() result(myPlasticity)
|
|||
startIndex = endIndex + 1
|
||||
endIndex = endIndex + prm%sum_N_tw
|
||||
stt%xi_twin => plasticState(p)%state (startIndex:endIndex,:)
|
||||
stt%xi_twin = spread(xi_twin_0, 2, NipcMyPhase)
|
||||
stt%xi_twin = spread(xi_0_tw, 2, NipcMyPhase)
|
||||
dot%xi_twin => plasticState(p)%dotState(startIndex:endIndex,:)
|
||||
plasticState(p)%atol(startIndex:endIndex) = pl%get_asFloat('atol_xi',defaultVal=1.0_pReal)
|
||||
if(any(plasticState(p)%atol(startIndex:endIndex) < 0.0_pReal)) extmsg = trim(extmsg)//' atol_xi'
|
||||
|
@ -354,20 +354,20 @@ module subroutine plastic_phenopowerlaw_dotState(Mp,instance,of)
|
|||
associate(prm => param(instance), stt => state(instance), dot => dotState(instance))
|
||||
|
||||
sumGamma = sum(stt%gamma_slip(:,of))
|
||||
sumF = sum(stt%gamma_twin(:,of)/prm%gamma_twin_char)
|
||||
sumF = sum(stt%gamma_twin(:,of)/prm%gamma_tw_char)
|
||||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! system-independent (nonlinear) prefactors to M_Xx (X influenced by x) matrices
|
||||
c_SlipSlip = prm%h0_slipslip * (1.0_pReal + prm%c_1*sumF** prm%c_2)
|
||||
c_TwinSlip = prm%h0_TwinSlip * sumGamma**prm%c_3
|
||||
c_TwinTwin = prm%h0_TwinTwin * sumF**prm%c_4
|
||||
c_SlipSlip = prm%h_0_sl_sl * (1.0_pReal + prm%c_1*sumF** prm%c_2)
|
||||
c_TwinSlip = prm%h_0_tw_sl * sumGamma**prm%c_3
|
||||
c_TwinTwin = prm%h_0_tw_tw * sumF**prm%c_4
|
||||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! calculate left and right vectors
|
||||
left_SlipSlip = 1.0_pReal + prm%H_int
|
||||
xi_slip_sat_offset = prm%spr*sqrt(sumF)
|
||||
right_SlipSlip = abs(1.0_pReal-stt%xi_slip(:,of) / (prm%xi_slip_sat+xi_slip_sat_offset)) **prm%a_slip &
|
||||
* sign(1.0_pReal,1.0_pReal-stt%xi_slip(:,of) / (prm%xi_slip_sat+xi_slip_sat_offset))
|
||||
left_SlipSlip = 1.0_pReal + prm%h_int
|
||||
xi_slip_sat_offset = prm%f_sl_sat_tw*sqrt(sumF)
|
||||
right_SlipSlip = abs(1.0_pReal-stt%xi_slip(:,of) / (prm%xi_inf_sl+xi_slip_sat_offset)) **prm%a_sl &
|
||||
* sign(1.0_pReal,1.0_pReal-stt%xi_slip(:,of) / (prm%xi_inf_sl+xi_slip_sat_offset))
|
||||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! shear rates
|
||||
|
@ -378,11 +378,11 @@ module subroutine plastic_phenopowerlaw_dotState(Mp,instance,of)
|
|||
!--------------------------------------------------------------------------------------------------
|
||||
! hardening
|
||||
dot%xi_slip(:,of) = c_SlipSlip * left_SlipSlip * &
|
||||
matmul(prm%interaction_SlipSlip,dot%gamma_slip(:,of)*right_SlipSlip) &
|
||||
+ matmul(prm%interaction_SlipTwin,dot%gamma_twin(:,of))
|
||||
matmul(prm%h_sl_sl,dot%gamma_slip(:,of)*right_SlipSlip) &
|
||||
+ matmul(prm%h_sl_tw,dot%gamma_twin(:,of))
|
||||
|
||||
dot%xi_twin(:,of) = c_TwinSlip * matmul(prm%interaction_TwinSlip,dot%gamma_slip(:,of)) &
|
||||
+ c_TwinTwin * matmul(prm%interaction_TwinTwin,dot%gamma_twin(:,of))
|
||||
dot%xi_twin(:,of) = c_TwinSlip * matmul(prm%h_tw_sl,dot%gamma_slip(:,of)) &
|
||||
+ c_TwinTwin * matmul(prm%h_tw_tw,dot%gamma_twin(:,of))
|
||||
end associate
|
||||
|
||||
end subroutine plastic_phenopowerlaw_dotState
|
||||
|
@ -460,29 +460,29 @@ pure subroutine kinetics_slip(Mp,instance,of, &
|
|||
enddo
|
||||
|
||||
where(dNeq0(tau_slip_pos))
|
||||
gdot_slip_pos = prm%gdot0_slip * merge(0.5_pReal,1.0_pReal, prm%nonSchmidActive) & ! 1/2 if non-Schmid active
|
||||
* sign(abs(tau_slip_pos/stt%xi_slip(:,of))**prm%n_slip, tau_slip_pos)
|
||||
gdot_slip_pos = prm%dot_gamma_0_sl * merge(0.5_pReal,1.0_pReal, prm%nonSchmidActive) & ! 1/2 if non-Schmid active
|
||||
* sign(abs(tau_slip_pos/stt%xi_slip(:,of))**prm%n_sl, tau_slip_pos)
|
||||
else where
|
||||
gdot_slip_pos = 0.0_pReal
|
||||
end where
|
||||
|
||||
where(dNeq0(tau_slip_neg))
|
||||
gdot_slip_neg = prm%gdot0_slip * 0.5_pReal & ! only used if non-Schmid active, always 1/2
|
||||
* sign(abs(tau_slip_neg/stt%xi_slip(:,of))**prm%n_slip, tau_slip_neg)
|
||||
gdot_slip_neg = prm%dot_gamma_0_sl * 0.5_pReal & ! only used if non-Schmid active, always 1/2
|
||||
* sign(abs(tau_slip_neg/stt%xi_slip(:,of))**prm%n_sl, tau_slip_neg)
|
||||
else where
|
||||
gdot_slip_neg = 0.0_pReal
|
||||
end where
|
||||
|
||||
if (present(dgdot_dtau_slip_pos)) then
|
||||
where(dNeq0(gdot_slip_pos))
|
||||
dgdot_dtau_slip_pos = gdot_slip_pos*prm%n_slip/tau_slip_pos
|
||||
dgdot_dtau_slip_pos = gdot_slip_pos*prm%n_sl/tau_slip_pos
|
||||
else where
|
||||
dgdot_dtau_slip_pos = 0.0_pReal
|
||||
end where
|
||||
endif
|
||||
if (present(dgdot_dtau_slip_neg)) then
|
||||
where(dNeq0(gdot_slip_neg))
|
||||
dgdot_dtau_slip_neg = gdot_slip_neg*prm%n_slip/tau_slip_neg
|
||||
dgdot_dtau_slip_neg = gdot_slip_neg*prm%n_sl/tau_slip_neg
|
||||
else where
|
||||
dgdot_dtau_slip_neg = 0.0_pReal
|
||||
end where
|
||||
|
@ -524,15 +524,15 @@ pure subroutine kinetics_twin(Mp,instance,of,&
|
|||
enddo
|
||||
|
||||
where(tau_twin > 0.0_pReal)
|
||||
gdot_twin = (1.0_pReal-sum(stt%gamma_twin(:,of)/prm%gamma_twin_char)) & ! only twin in untwinned volume fraction
|
||||
* prm%gdot0_twin*(abs(tau_twin)/stt%xi_twin(:,of))**prm%n_twin
|
||||
gdot_twin = (1.0_pReal-sum(stt%gamma_twin(:,of)/prm%gamma_tw_char)) & ! only twin in untwinned volume fraction
|
||||
* prm%dot_gamma_0_tw*(abs(tau_twin)/stt%xi_twin(:,of))**prm%n_tw
|
||||
else where
|
||||
gdot_twin = 0.0_pReal
|
||||
end where
|
||||
|
||||
if (present(dgdot_dtau_twin)) then
|
||||
where(dNeq0(gdot_twin))
|
||||
dgdot_dtau_twin = gdot_twin*prm%n_twin/tau_twin
|
||||
dgdot_dtau_twin = gdot_twin*prm%n_tw/tau_twin
|
||||
else where
|
||||
dgdot_dtau_twin = 0.0_pReal
|
||||
end where
|
||||
|
|
|
@ -35,37 +35,40 @@ module crystallite
|
|||
crystallite_subStep !< size of next integration step
|
||||
type(rotation), dimension(:,:,:), allocatable :: &
|
||||
crystallite_orientation !< current orientation
|
||||
real(pReal), dimension(:,:,:,:,:), allocatable, public, protected :: &
|
||||
crystallite_Fe, & !< current "elastic" def grad (end of converged time step)
|
||||
crystallite_P, & !< 1st Piola-Kirchhoff stress per grain
|
||||
crystallite_S0, & !< 2nd Piola-Kirchhoff stress vector at start of FE inc
|
||||
crystallite_Fp0, & !< plastic def grad at start of FE inc
|
||||
crystallite_Fi0, & !< intermediate def grad at start of FE inc
|
||||
crystallite_F0, & !< def grad at start of FE inc
|
||||
crystallite_Lp0, & !< plastic velocitiy grad at start of FE inc
|
||||
crystallite_Li0 !< intermediate velocitiy grad at start of FE inc
|
||||
real(pReal), dimension(:,:,:,:,:), allocatable, public :: &
|
||||
crystallite_S, & !< current 2nd Piola-Kirchhoff stress vector (end of converged time step)
|
||||
crystallite_partionedS0, & !< 2nd Piola-Kirchhoff stress vector at start of homog inc
|
||||
crystallite_Fp, & !< current plastic def grad (end of converged time step)
|
||||
crystallite_partionedFp0,& !< plastic def grad at start of homog inc
|
||||
crystallite_Fi, & !< current intermediate def grad (end of converged time step)
|
||||
crystallite_partionedFi0,& !< intermediate def grad at start of homog inc
|
||||
crystallite_partionedF, & !< def grad to be reached at end of homog inc
|
||||
crystallite_partionedF0, & !< def grad at start of homog inc
|
||||
crystallite_Lp, & !< current plastic velocitiy grad (end of converged time step)
|
||||
crystallite_partionedLp0, & !< plastic velocity grad at start of homog inc
|
||||
crystallite_Li, & !< current intermediate velocitiy grad (end of converged time step)
|
||||
crystallite_partionedLi0 !< intermediate velocity grad at start of homog inc
|
||||
real(pReal), dimension(:,:,:,:,:), allocatable :: &
|
||||
crystallite_subFp0,& !< plastic def grad at start of crystallite inc
|
||||
crystallite_subFi0,& !< intermediate def grad at start of crystallite inc
|
||||
crystallite_F0, & !< def grad at start of FE inc
|
||||
crystallite_subF, & !< def grad to be reached at end of crystallite inc
|
||||
crystallite_subF0, & !< def grad at start of crystallite inc
|
||||
crystallite_subLp0,& !< plastic velocity grad at start of crystallite inc
|
||||
crystallite_subLi0 !< intermediate velocity grad at start of crystallite inc
|
||||
real(pReal), dimension(:,:,:,:,:,:,:), allocatable, public, protected :: &
|
||||
crystallite_dPdF !< current individual dPdF per grain (end of converged time step)
|
||||
!
|
||||
crystallite_Fe, & !< current "elastic" def grad (end of converged time step)
|
||||
!
|
||||
crystallite_Fp, & !< current plastic def grad (end of converged time step)
|
||||
crystallite_Fp0, & !< plastic def grad at start of FE inc
|
||||
crystallite_partionedFp0,& !< plastic def grad at start of homog inc
|
||||
crystallite_subFp0,& !< plastic def grad at start of crystallite inc
|
||||
!
|
||||
crystallite_Fi, & !< current intermediate def grad (end of converged time step)
|
||||
crystallite_Fi0, & !< intermediate def grad at start of FE inc
|
||||
crystallite_partionedFi0,& !< intermediate def grad at start of homog inc
|
||||
crystallite_subFi0,& !< intermediate def grad at start of crystallite inc
|
||||
!
|
||||
crystallite_Lp0, & !< plastic velocitiy grad at start of FE inc
|
||||
crystallite_partionedLp0, & !< plastic velocity grad at start of homog inc
|
||||
!
|
||||
crystallite_Li, & !< current intermediate velocitiy grad (end of converged time step)
|
||||
crystallite_Li0, & !< intermediate velocitiy grad at start of FE inc
|
||||
crystallite_partionedLi0, & !< intermediate velocity grad at start of homog inc
|
||||
!
|
||||
crystallite_S0, & !< 2nd Piola-Kirchhoff stress vector at start of FE inc
|
||||
crystallite_partionedS0 !< 2nd Piola-Kirchhoff stress vector at start of homog inc
|
||||
real(pReal), dimension(:,:,:,:,:), allocatable, public, protected :: &
|
||||
crystallite_P, & !< 1st Piola-Kirchhoff stress per grain
|
||||
crystallite_Lp, & !< current plastic velocitiy grad (end of converged time step)
|
||||
crystallite_S, & !< current 2nd Piola-Kirchhoff stress vector (end of converged time step)
|
||||
crystallite_partionedF0 !< def grad at start of homog inc
|
||||
real(pReal), dimension(:,:,:,:,:), allocatable, public :: &
|
||||
crystallite_partionedF !< def grad to be reached at end of homog inc
|
||||
|
||||
logical, dimension(:,:,:), allocatable, public :: &
|
||||
crystallite_requested !< used by upper level (homogenization) to request crystallite calculation
|
||||
logical, dimension(:,:,:), allocatable :: &
|
||||
|
@ -119,7 +122,10 @@ module crystallite
|
|||
crystallite_results, &
|
||||
crystallite_restartWrite, &
|
||||
crystallite_restartRead, &
|
||||
crystallite_forward
|
||||
crystallite_forward, &
|
||||
crystallite_initializeRestorationPoints, &
|
||||
crystallite_windForward, &
|
||||
crystallite_restore
|
||||
|
||||
contains
|
||||
|
||||
|
@ -136,8 +142,8 @@ subroutine crystallite_init
|
|||
e, & !< counter in element loop
|
||||
cMax, & !< maximum number of integration point components
|
||||
iMax, & !< maximum number of integration points
|
||||
eMax, & !< maximum number of elements
|
||||
myNcomponents !< number of components at current IP
|
||||
eMax !< maximum number of elements
|
||||
|
||||
|
||||
class(tNode), pointer :: &
|
||||
num_crystallite, &
|
||||
|
@ -173,11 +179,8 @@ subroutine crystallite_init
|
|||
crystallite_Li,crystallite_Lp, &
|
||||
crystallite_subF,crystallite_subF0, &
|
||||
crystallite_subFp0,crystallite_subFi0, &
|
||||
crystallite_subLi0,crystallite_subLp0, &
|
||||
source = crystallite_partionedF)
|
||||
|
||||
allocate(crystallite_dPdF(3,3,3,3,cMax,iMax,eMax),source=0.0_pReal)
|
||||
|
||||
allocate(crystallite_dt(cMax,iMax,eMax),source=0.0_pReal)
|
||||
allocate(crystallite_subdt,crystallite_subFrac,crystallite_subStep, &
|
||||
source = crystallite_dt)
|
||||
|
@ -248,10 +251,9 @@ subroutine crystallite_init
|
|||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! initialize
|
||||
!$OMP PARALLEL DO PRIVATE(myNcomponents,i,c)
|
||||
!$OMP PARALLEL DO PRIVATE(i,c)
|
||||
do e = FEsolving_execElem(1),FEsolving_execElem(2)
|
||||
myNcomponents = homogenization_Ngrains(material_homogenizationAt(e))
|
||||
do i = FEsolving_execIP(1), FEsolving_execIP(2); do c = 1, myNcomponents
|
||||
do i = FEsolving_execIP(1), FEsolving_execIP(2); do c = 1, homogenization_Ngrains(material_homogenizationAt(e))
|
||||
crystallite_Fp0(1:3,1:3,c,i,e) = material_orientation0(c,i,e)%asMatrix() ! Fp reflects initial orientation (see 10.1016/j.actamat.2006.01.005)
|
||||
crystallite_Fp0(1:3,1:3,c,i,e) = crystallite_Fp0(1:3,1:3,c,i,e) &
|
||||
/ math_det33(crystallite_Fp0(1:3,1:3,c,i,e))**(1.0_pReal/3.0_pReal)
|
||||
|
@ -287,7 +289,6 @@ subroutine crystallite_init
|
|||
!$OMP END PARALLEL DO
|
||||
|
||||
devNull = crystallite_stress()
|
||||
call crystallite_stressTangent
|
||||
|
||||
#ifdef DEBUG
|
||||
if (debugCrystallite%basic) then
|
||||
|
@ -296,7 +297,6 @@ subroutine crystallite_init
|
|||
print'(a42,1x,i10)', 'max # of constituents/integration point: ', cMax
|
||||
flush(IO_STDOUT)
|
||||
endif
|
||||
|
||||
#endif
|
||||
|
||||
end subroutine crystallite_init
|
||||
|
@ -318,34 +318,17 @@ function crystallite_stress()
|
|||
startIP, endIP, &
|
||||
s
|
||||
logical, dimension(homogenization_maxNgrains,discretization_nIP,discretization_nElem) :: todo !ToDo: need to set some values to false for different Ngrains
|
||||
real(pReal), dimension(:,:,:,:,:), allocatable :: &
|
||||
subLp0,& !< plastic velocity grad at start of crystallite inc
|
||||
subLi0 !< intermediate velocity grad at start of crystallite inc
|
||||
|
||||
|
||||
todo = .false.
|
||||
|
||||
#ifdef DEBUG
|
||||
if (debugCrystallite%selective &
|
||||
.and. FEsolving_execElem(1) <= debugCrystallite%element &
|
||||
.and. debugCrystallite%element <= FEsolving_execElem(2)) then
|
||||
print'(/,a,i8,1x,i2,1x,i3)', '<< CRYST stress >> boundary and initial values at el ip ipc ', &
|
||||
debugCrystallite%element,debugCrystallite%ip, debugCrystallite%grain
|
||||
print'(a,/,3(12x,3(f14.9,1x)/))', '<< CRYST stress >> F ', &
|
||||
transpose(crystallite_partionedF(1:3,1:3,debugCrystallite%grain, &
|
||||
debugCrystallite%ip,debugCrystallite%element))
|
||||
print'(a,/,3(12x,3(f14.9,1x)/))', '<< CRYST stress >> F0 ', &
|
||||
transpose(crystallite_partionedF0(1:3,1:3,debugCrystallite%grain, &
|
||||
debugCrystallite%ip,debugCrystallite%element))
|
||||
print'(a,/,3(12x,3(f14.9,1x)/))', '<< CRYST stress >> Fp0', &
|
||||
transpose(crystallite_partionedFp0(1:3,1:3,debugCrystallite%grain, &
|
||||
debugCrystallite%ip,debugCrystallite%element))
|
||||
print'(a,/,3(12x,3(f14.9,1x)/))', '<< CRYST stress >> Fi0', &
|
||||
transpose(crystallite_partionedFi0(1:3,1:3,debugCrystallite%grain, &
|
||||
debugCrystallite%ip,debugCrystallite%element))
|
||||
print'(a,/,3(12x,3(f14.9,1x)/))', '<< CRYST stress >> Lp0', &
|
||||
transpose(crystallite_partionedLp0(1:3,1:3,debugCrystallite%grain, &
|
||||
debugCrystallite%ip,debugCrystallite%element))
|
||||
print'(a,/,3(12x,3(f14.9,1x)/))', '<< CRYST stress >> Li0', &
|
||||
transpose(crystallite_partionedLi0(1:3,1:3,debugCrystallite%grain, &
|
||||
debugCrystallite%ip,debugCrystallite%element))
|
||||
endif
|
||||
#endif
|
||||
subLp0 = crystallite_partionedLp0
|
||||
subLi0 = crystallite_partionedLi0
|
||||
|
||||
|
||||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! initialize to starting condition
|
||||
|
@ -362,9 +345,7 @@ function crystallite_stress()
|
|||
sourceState(material_phaseAt(c,e))%p(s)%partionedState0(:,material_phaseMemberAt(c,i,e))
|
||||
enddo
|
||||
crystallite_subFp0(1:3,1:3,c,i,e) = crystallite_partionedFp0(1:3,1:3,c,i,e)
|
||||
crystallite_subLp0(1:3,1:3,c,i,e) = crystallite_partionedLp0(1:3,1:3,c,i,e)
|
||||
crystallite_subFi0(1:3,1:3,c,i,e) = crystallite_partionedFi0(1:3,1:3,c,i,e)
|
||||
crystallite_subLi0(1:3,1:3,c,i,e) = crystallite_partionedLi0(1:3,1:3,c,i,e)
|
||||
crystallite_subF0(1:3,1:3,c,i,e) = crystallite_partionedF0(1:3,1:3,c,i,e)
|
||||
crystallite_subFrac(c,i,e) = 0.0_pReal
|
||||
crystallite_subStep(c,i,e) = 1.0_pReal/num%subStepSizeCryst
|
||||
|
@ -407,11 +388,10 @@ function crystallite_stress()
|
|||
todo(c,i,e) = crystallite_subStep(c,i,e) > 0.0_pReal ! still time left to integrate on?
|
||||
if (todo(c,i,e)) then
|
||||
crystallite_subF0 (1:3,1:3,c,i,e) = crystallite_subF(1:3,1:3,c,i,e)
|
||||
crystallite_subLp0(1:3,1:3,c,i,e) = crystallite_Lp (1:3,1:3,c,i,e)
|
||||
crystallite_subLi0(1:3,1:3,c,i,e) = crystallite_Li (1:3,1:3,c,i,e)
|
||||
subLp0(1:3,1:3,c,i,e) = crystallite_Lp (1:3,1:3,c,i,e)
|
||||
subLi0(1:3,1:3,c,i,e) = crystallite_Li (1:3,1:3,c,i,e)
|
||||
crystallite_subFp0(1:3,1:3,c,i,e) = crystallite_Fp (1:3,1:3,c,i,e)
|
||||
crystallite_subFi0(1:3,1:3,c,i,e) = crystallite_Fi (1:3,1:3,c,i,e)
|
||||
!if abbrevation, make c and p private in omp
|
||||
plasticState( material_phaseAt(c,e))%subState0(:,material_phaseMemberAt(c,i,e)) &
|
||||
= plasticState(material_phaseAt(c,e))%state( :,material_phaseMemberAt(c,i,e))
|
||||
do s = 1, phase_Nsources(material_phaseAt(c,e))
|
||||
|
@ -428,8 +408,8 @@ function crystallite_stress()
|
|||
crystallite_Fi (1:3,1:3,c,i,e) = crystallite_subFi0(1:3,1:3,c,i,e)
|
||||
crystallite_S (1:3,1:3,c,i,e) = crystallite_S0 (1:3,1:3,c,i,e)
|
||||
if (crystallite_subStep(c,i,e) < 1.0_pReal) then ! actual (not initial) cutback
|
||||
crystallite_Lp (1:3,1:3,c,i,e) = crystallite_subLp0(1:3,1:3,c,i,e)
|
||||
crystallite_Li (1:3,1:3,c,i,e) = crystallite_subLi0(1:3,1:3,c,i,e)
|
||||
crystallite_Lp (1:3,1:3,c,i,e) = subLp0(1:3,1:3,c,i,e)
|
||||
crystallite_Li (1:3,1:3,c,i,e) = subLi0(1:3,1:3,c,i,e)
|
||||
endif
|
||||
plasticState (material_phaseAt(c,e))%state( :,material_phaseMemberAt(c,i,e)) &
|
||||
= plasticState(material_phaseAt(c,e))%subState0(:,material_phaseMemberAt(c,i,e))
|
||||
|
@ -453,6 +433,7 @@ function crystallite_stress()
|
|||
math_inv33(crystallite_Fi(1:3,1:3,c,i,e)))
|
||||
crystallite_subdt(c,i,e) = crystallite_subStep(c,i,e) * crystallite_dt(c,i,e)
|
||||
crystallite_converged(c,i,e) = .false.
|
||||
call integrateState(c,i,e)
|
||||
endif
|
||||
|
||||
enddo
|
||||
|
@ -460,9 +441,10 @@ function crystallite_stress()
|
|||
enddo elementLooping3
|
||||
!$OMP END PARALLEL DO
|
||||
|
||||
call nonlocalConvergenceCheck
|
||||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! integrate --- requires fully defined state array (basic + dependent state)
|
||||
if (any(todo)) call integrateState(todo) ! TODO: unroll into proper elementloop to avoid N^2 for single point evaluation
|
||||
where(.not. crystallite_converged .and. crystallite_subStep > num%subStepMinCryst) & ! do not try non-converged but fully cutbacked any further
|
||||
todo = .true. ! TODO: again unroll this into proper elementloop to avoid N^2 for single point evaluation
|
||||
|
||||
|
@ -481,14 +463,112 @@ end function crystallite_stress
|
|||
|
||||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
!> @brief calculate tangent (dPdF)
|
||||
!> @brief Backup data for homog cutback.
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
subroutine crystallite_stressTangent
|
||||
subroutine crystallite_initializeRestorationPoints(i,e)
|
||||
|
||||
integer, intent(in) :: &
|
||||
i, & !< integration point number
|
||||
e !< element number
|
||||
integer :: &
|
||||
c, & !< counter in integration point component loop
|
||||
c, & !< constituent number
|
||||
s
|
||||
|
||||
do c = 1,homogenization_Ngrains(material_homogenizationAt(e))
|
||||
crystallite_partionedFp0(1:3,1:3,c,i,e) = crystallite_Fp0(1:3,1:3,c,i,e)
|
||||
crystallite_partionedLp0(1:3,1:3,c,i,e) = crystallite_Lp0(1:3,1:3,c,i,e)
|
||||
crystallite_partionedFi0(1:3,1:3,c,i,e) = crystallite_Fi0(1:3,1:3,c,i,e)
|
||||
crystallite_partionedLi0(1:3,1:3,c,i,e) = crystallite_Li0(1:3,1:3,c,i,e)
|
||||
crystallite_partionedF0(1:3,1:3,c,i,e) = crystallite_F0(1:3,1:3,c,i,e)
|
||||
crystallite_partionedS0(1:3,1:3,c,i,e) = crystallite_S0(1:3,1:3,c,i,e)
|
||||
|
||||
plasticState(material_phaseAt(c,e))%partionedState0(:,material_phasememberAt(c,i,e)) = &
|
||||
plasticState(material_phaseAt(c,e))%state0( :,material_phasememberAt(c,i,e))
|
||||
do s = 1, phase_Nsources(material_phaseAt(c,e))
|
||||
sourceState(material_phaseAt(c,e))%p(s)%partionedState0(:,material_phasememberAt(c,i,e)) = &
|
||||
sourceState(material_phaseAt(c,e))%p(s)%state0( :,material_phasememberAt(c,i,e))
|
||||
enddo
|
||||
enddo
|
||||
|
||||
end subroutine crystallite_initializeRestorationPoints
|
||||
|
||||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
!> @brief Wind homog inc forward.
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
subroutine crystallite_windForward(i,e)
|
||||
|
||||
integer, intent(in) :: &
|
||||
i, & !< integration point number
|
||||
e !< element number
|
||||
integer :: &
|
||||
c, & !< constituent number
|
||||
s
|
||||
|
||||
do c = 1,homogenization_Ngrains(material_homogenizationAt(e))
|
||||
crystallite_partionedF0 (1:3,1:3,c,i,e) = crystallite_partionedF(1:3,1:3,c,i,e)
|
||||
crystallite_partionedFp0(1:3,1:3,c,i,e) = crystallite_Fp (1:3,1:3,c,i,e)
|
||||
crystallite_partionedLp0(1:3,1:3,c,i,e) = crystallite_Lp (1:3,1:3,c,i,e)
|
||||
crystallite_partionedFi0(1:3,1:3,c,i,e) = crystallite_Fi (1:3,1:3,c,i,e)
|
||||
crystallite_partionedLi0(1:3,1:3,c,i,e) = crystallite_Li (1:3,1:3,c,i,e)
|
||||
crystallite_partionedS0 (1:3,1:3,c,i,e) = crystallite_S (1:3,1:3,c,i,e)
|
||||
|
||||
plasticState (material_phaseAt(c,e))%partionedState0(:,material_phasememberAt(c,i,e)) = &
|
||||
plasticState (material_phaseAt(c,e))%state (:,material_phasememberAt(c,i,e))
|
||||
do s = 1, phase_Nsources(material_phaseAt(c,e))
|
||||
sourceState(material_phaseAt(c,e))%p(s)%partionedState0(:,material_phasememberAt(c,i,e)) = &
|
||||
sourceState(material_phaseAt(c,e))%p(s)%state (:,material_phasememberAt(c,i,e))
|
||||
enddo
|
||||
enddo
|
||||
|
||||
end subroutine crystallite_windForward
|
||||
|
||||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
!> @brief Restore data after homog cutback.
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
subroutine crystallite_restore(i,e,includeL)
|
||||
|
||||
integer, intent(in) :: &
|
||||
i, & !< integration point number
|
||||
e !< element number
|
||||
logical, intent(in) :: &
|
||||
includeL !< protect agains fake cutback
|
||||
integer :: &
|
||||
c, & !< constituent number
|
||||
s
|
||||
|
||||
do c = 1,homogenization_Ngrains(material_homogenizationAt(e))
|
||||
if (includeL) then
|
||||
crystallite_Lp(1:3,1:3,c,i,e) = crystallite_partionedLp0(1:3,1:3,c,i,e)
|
||||
crystallite_Li(1:3,1:3,c,i,e) = crystallite_partionedLi0(1:3,1:3,c,i,e)
|
||||
endif ! maybe protecting everything from overwriting makes more sense
|
||||
crystallite_Fp(1:3,1:3,c,i,e) = crystallite_partionedFp0(1:3,1:3,c,i,e)
|
||||
crystallite_Fi(1:3,1:3,c,i,e) = crystallite_partionedFi0(1:3,1:3,c,i,e)
|
||||
crystallite_S (1:3,1:3,c,i,e) = crystallite_partionedS0 (1:3,1:3,c,i,e)
|
||||
|
||||
plasticState (material_phaseAt(c,e))%state( :,material_phasememberAt(c,i,e)) = &
|
||||
plasticState (material_phaseAt(c,e))%partionedState0(:,material_phasememberAt(c,i,e))
|
||||
do s = 1, phase_Nsources(material_phaseAt(c,e))
|
||||
sourceState(material_phaseAt(c,e))%p(s)%state( :,material_phasememberAt(c,i,e)) = &
|
||||
sourceState(material_phaseAt(c,e))%p(s)%partionedState0(:,material_phasememberAt(c,i,e))
|
||||
enddo
|
||||
enddo
|
||||
|
||||
end subroutine crystallite_restore
|
||||
|
||||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
!> @brief Calculate tangent (dPdF).
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
function crystallite_stressTangent(c,i,e) result(dPdF)
|
||||
|
||||
real(pReal), dimension(3,3,3,3) :: dPdF
|
||||
integer, intent(in) :: &
|
||||
c, & !< counter in constituent loop
|
||||
i, & !< counter in integration point loop
|
||||
e, & !< counter in element loop
|
||||
e !< counter in element loop
|
||||
integer :: &
|
||||
o, &
|
||||
p
|
||||
|
||||
|
@ -510,12 +590,6 @@ subroutine crystallite_stressTangent
|
|||
real(pReal), dimension(9,9):: temp_99
|
||||
logical :: error
|
||||
|
||||
!$OMP PARALLEL DO PRIVATE(dSdF,dSdFe,dSdFi,dLpdS,dLpdFi,dFpinvdF,dLidS,dLidFi,dFidS,o,p, &
|
||||
!$OMP invSubFp0,invSubFi0,invFp,invFi, &
|
||||
!$OMP rhs_3333,lhs_3333,temp_99,temp_33_1,temp_33_2,temp_33_3,temp_33_4,temp_3333,error)
|
||||
elementLooping: do e = FEsolving_execElem(1),FEsolving_execElem(2)
|
||||
do i = FEsolving_execIP(1),FEsolving_execIP(2)
|
||||
do c = 1,homogenization_Ngrains(material_homogenizationAt(e))
|
||||
|
||||
call constitutive_SandItsTangents(devNull,dSdFe,dSdFi, &
|
||||
crystallite_Fe(1:3,1:3,c,i,e), &
|
||||
|
@ -596,12 +670,12 @@ subroutine crystallite_stressTangent
|
|||
temp_33_3 = matmul(crystallite_subF(1:3,1:3,c,i,e),invFp)
|
||||
temp_33_4 = matmul(temp_33_3,crystallite_S(1:3,1:3,c,i,e))
|
||||
|
||||
crystallite_dPdF(1:3,1:3,1:3,1:3,c,i,e) = 0.0_pReal
|
||||
dPdF = 0.0_pReal
|
||||
do p=1,3
|
||||
crystallite_dPdF(p,1:3,p,1:3,c,i,e) = transpose(temp_33_2)
|
||||
dPdF(p,1:3,p,1:3) = transpose(temp_33_2)
|
||||
enddo
|
||||
do o=1,3; do p=1,3
|
||||
crystallite_dPdF(1:3,1:3,p,o,c,i,e) = crystallite_dPdF(1:3,1:3,p,o,c,i,e) &
|
||||
dPdF(1:3,1:3,p,o) = dPdF(1:3,1:3,p,o) &
|
||||
+ matmul(matmul(crystallite_subF(1:3,1:3,c,i,e), &
|
||||
dFpinvdF(1:3,1:3,p,o)),temp_33_1) &
|
||||
+ matmul(matmul(temp_33_3,dSdF(1:3,1:3,p,o)), &
|
||||
|
@ -609,11 +683,7 @@ subroutine crystallite_stressTangent
|
|||
+ matmul(temp_33_4,transpose(dFpinvdF(1:3,1:3,p,o)))
|
||||
enddo; enddo
|
||||
|
||||
enddo; enddo
|
||||
enddo elementLooping
|
||||
!$OMP END PARALLEL DO
|
||||
|
||||
end subroutine crystallite_stressTangent
|
||||
end function crystallite_stressTangent
|
||||
|
||||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
|
@ -1022,14 +1092,14 @@ end function integrateStress
|
|||
!> @brief integrate stress, state with adaptive 1st order explicit Euler method
|
||||
!> using Fixed Point Iteration to adapt the stepsize
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
subroutine integrateStateFPI(todo)
|
||||
subroutine integrateStateFPI(g,i,e)
|
||||
|
||||
logical, dimension(:,:,:), intent(in) :: todo
|
||||
integer :: &
|
||||
NiterationState, & !< number of iterations in state loop
|
||||
integer, intent(in) :: &
|
||||
e, & !< element index in element loop
|
||||
i, & !< integration point index in ip loop
|
||||
g, & !< grain index in grain loop
|
||||
g !< grain index in grain loop
|
||||
integer :: &
|
||||
NiterationState, & !< number of iterations in state loop
|
||||
p, &
|
||||
c, &
|
||||
s, &
|
||||
|
@ -1044,16 +1114,9 @@ subroutine integrateStateFPI(todo)
|
|||
plastic_dotState
|
||||
real(pReal), dimension(constitutive_source_maxSizeDotState,2,maxval(phase_Nsources)) :: source_dotState
|
||||
logical :: &
|
||||
nonlocalBroken, broken
|
||||
broken
|
||||
|
||||
nonlocalBroken = .false.
|
||||
!$OMP PARALLEL DO PRIVATE(size_pl,size_so,r,zeta,p,c,plastic_dotState,source_dotState,broken)
|
||||
do e = FEsolving_execElem(1),FEsolving_execElem(2)
|
||||
do i = FEsolving_execIP(1),FEsolving_execIP(2)
|
||||
do g = 1,homogenization_Ngrains(material_homogenizationAt(e))
|
||||
p = material_phaseAt(g,e)
|
||||
if(todo(g,i,e) .and. .not. (nonlocalBroken .and. plasticState(p)%nonlocal)) then
|
||||
|
||||
c = material_phaseMemberAt(g,i,e)
|
||||
|
||||
broken = constitutive_collectDotState(crystallite_S(1:3,1:3,g,i,e), &
|
||||
|
@ -1061,8 +1124,7 @@ subroutine integrateStateFPI(todo)
|
|||
crystallite_Fi(1:3,1:3,g,i,e), &
|
||||
crystallite_partionedFp0, &
|
||||
crystallite_subdt(g,i,e), g,i,e,p,c)
|
||||
if(broken .and. plasticState(p)%nonlocal) nonlocalBroken = .true.
|
||||
if(broken) cycle
|
||||
if(broken) return
|
||||
|
||||
size_pl = plasticState(p)%sizeDotState
|
||||
plasticState(p)%state(1:size_pl,c) = plasticState(p)%subState0(1:size_pl,c) &
|
||||
|
@ -1133,12 +1195,7 @@ subroutine integrateStateFPI(todo)
|
|||
endif
|
||||
|
||||
enddo iteration
|
||||
if(broken .and. plasticState(p)%nonlocal) nonlocalBroken = .true.
|
||||
endif
|
||||
enddo; enddo; enddo
|
||||
!$OMP END PARALLEL DO
|
||||
|
||||
if (nonlocalBroken) call nonlocalConvergenceCheck
|
||||
|
||||
contains
|
||||
|
||||
|
@ -1168,29 +1225,21 @@ end subroutine integrateStateFPI
|
|||
!--------------------------------------------------------------------------------------------------
|
||||
!> @brief integrate state with 1st order explicit Euler method
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
subroutine integrateStateEuler(todo)
|
||||
subroutine integrateStateEuler(g,i,e)
|
||||
|
||||
logical, dimension(:,:,:), intent(in) :: todo
|
||||
|
||||
integer :: &
|
||||
integer, intent(in) :: &
|
||||
e, & !< element index in element loop
|
||||
i, & !< integration point index in ip loop
|
||||
g, & !< grain index in grain loop
|
||||
g !< grain index in grain loop
|
||||
integer :: &
|
||||
p, &
|
||||
c, &
|
||||
s, &
|
||||
sizeDotState
|
||||
logical :: &
|
||||
nonlocalBroken, broken
|
||||
broken
|
||||
|
||||
nonlocalBroken = .false.
|
||||
!$OMP PARALLEL DO PRIVATE (sizeDotState,p,c,broken)
|
||||
do e = FEsolving_execElem(1),FEsolving_execElem(2)
|
||||
do i = FEsolving_execIP(1),FEsolving_execIP(2)
|
||||
do g = 1,homogenization_Ngrains(material_homogenizationAt(e))
|
||||
p = material_phaseAt(g,e)
|
||||
if(todo(g,i,e) .and. .not. (nonlocalBroken .and. plasticState(p)%nonlocal)) then
|
||||
|
||||
c = material_phaseMemberAt(g,i,e)
|
||||
|
||||
broken = constitutive_collectDotState(crystallite_S(1:3,1:3,g,i,e), &
|
||||
|
@ -1198,8 +1247,7 @@ subroutine integrateStateEuler(todo)
|
|||
crystallite_Fi(1:3,1:3,g,i,e), &
|
||||
crystallite_partionedFp0, &
|
||||
crystallite_subdt(g,i,e), g,i,e,p,c)
|
||||
if(broken .and. plasticState(p)%nonlocal) nonlocalBroken = .true.
|
||||
if(broken) cycle
|
||||
if(broken) return
|
||||
|
||||
sizeDotState = plasticState(p)%sizeDotState
|
||||
plasticState(p)%state(1:sizeDotState,c) = plasticState(p)%subState0(1:sizeDotState,c) &
|
||||
|
@ -1215,17 +1263,10 @@ subroutine integrateStateEuler(todo)
|
|||
broken = constitutive_deltaState(crystallite_S(1:3,1:3,g,i,e), &
|
||||
crystallite_Fe(1:3,1:3,g,i,e), &
|
||||
crystallite_Fi(1:3,1:3,g,i,e),g,i,e,p,c)
|
||||
if(broken .and. plasticState(p)%nonlocal) nonlocalBroken = .true.
|
||||
if(broken) cycle
|
||||
if(broken) return
|
||||
|
||||
broken = integrateStress(g,i,e)
|
||||
if(broken .and. plasticState(p)%nonlocal) nonlocalBroken = .true.
|
||||
crystallite_converged(g,i,e) = .not. broken
|
||||
endif
|
||||
enddo; enddo; enddo
|
||||
!$OMP END PARALLEL DO
|
||||
|
||||
if (nonlocalBroken) call nonlocalConvergenceCheck
|
||||
|
||||
end subroutine integrateStateEuler
|
||||
|
||||
|
@ -1233,33 +1274,25 @@ end subroutine integrateStateEuler
|
|||
!--------------------------------------------------------------------------------------------------
|
||||
!> @brief integrate stress, state with 1st order Euler method with adaptive step size
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
subroutine integrateStateAdaptiveEuler(todo)
|
||||
|
||||
logical, dimension(:,:,:), intent(in) :: todo
|
||||
subroutine integrateStateAdaptiveEuler(g,i,e)
|
||||
|
||||
integer, intent(in) :: &
|
||||
e, & !< element index in element loop
|
||||
i, & !< integration point index in ip loop
|
||||
g !< grain index in grain loop
|
||||
integer :: &
|
||||
e, & ! element index in element loop
|
||||
i, & ! integration point index in ip loop
|
||||
g, & ! grain index in grain loop
|
||||
p, &
|
||||
c, &
|
||||
s, &
|
||||
sizeDotState
|
||||
logical :: &
|
||||
nonlocalBroken, broken
|
||||
broken
|
||||
|
||||
real(pReal), dimension(constitutive_plasticity_maxSizeDotState) :: residuum_plastic
|
||||
real(pReal), dimension(constitutive_source_maxSizeDotState,maxval(phase_Nsources)) :: residuum_source
|
||||
|
||||
nonlocalBroken = .false.
|
||||
!$OMP PARALLEL DO PRIVATE(sizeDotState,p,c,residuum_plastic,residuum_source,broken)
|
||||
do e = FEsolving_execElem(1),FEsolving_execElem(2)
|
||||
do i = FEsolving_execIP(1),FEsolving_execIP(2)
|
||||
do g = 1,homogenization_Ngrains(material_homogenizationAt(e))
|
||||
broken = .false.
|
||||
p = material_phaseAt(g,e)
|
||||
if(todo(g,i,e) .and. .not. (nonlocalBroken .and. plasticState(p)%nonlocal)) then
|
||||
|
||||
p = material_phaseAt(g,e)
|
||||
c = material_phaseMemberAt(g,i,e)
|
||||
|
||||
broken = constitutive_collectDotState(crystallite_S(1:3,1:3,g,i,e), &
|
||||
|
@ -1267,7 +1300,7 @@ subroutine integrateStateAdaptiveEuler(todo)
|
|||
crystallite_Fi(1:3,1:3,g,i,e), &
|
||||
crystallite_partionedFp0, &
|
||||
crystallite_subdt(g,i,e), g,i,e,p,c)
|
||||
if(broken) cycle
|
||||
if(broken) return
|
||||
|
||||
sizeDotState = plasticState(p)%sizeDotState
|
||||
|
||||
|
@ -1286,17 +1319,17 @@ subroutine integrateStateAdaptiveEuler(todo)
|
|||
broken = constitutive_deltaState(crystallite_S(1:3,1:3,g,i,e), &
|
||||
crystallite_Fe(1:3,1:3,g,i,e), &
|
||||
crystallite_Fi(1:3,1:3,g,i,e),g,i,e,p,c)
|
||||
if(broken) cycle
|
||||
if(broken) return
|
||||
|
||||
broken = integrateStress(g,i,e)
|
||||
if(broken) cycle
|
||||
if(broken) return
|
||||
|
||||
broken = constitutive_collectDotState(crystallite_S(1:3,1:3,g,i,e), &
|
||||
crystallite_partionedF0, &
|
||||
crystallite_Fi(1:3,1:3,g,i,e), &
|
||||
crystallite_partionedFp0, &
|
||||
crystallite_subdt(g,i,e), g,i,e,p,c)
|
||||
if(broken) cycle
|
||||
if(broken) return
|
||||
|
||||
|
||||
sizeDotState = plasticState(p)%sizeDotState
|
||||
|
@ -1314,22 +1347,15 @@ subroutine integrateStateAdaptiveEuler(todo)
|
|||
sourceState(p)%p(s)%atol(1:sizeDotState))
|
||||
enddo
|
||||
|
||||
endif
|
||||
if(broken .and. plasticState(p)%nonlocal) nonlocalBroken = .true.
|
||||
enddo; enddo; enddo
|
||||
!$OMP END PARALLEL DO
|
||||
|
||||
if (nonlocalBroken) call nonlocalConvergenceCheck
|
||||
|
||||
end subroutine integrateStateAdaptiveEuler
|
||||
|
||||
|
||||
!---------------------------------------------------------------------------------------------------
|
||||
!> @brief Integrate state (including stress integration) with the classic Runge Kutta method
|
||||
!---------------------------------------------------------------------------------------------------
|
||||
subroutine integrateStateRK4(todo)
|
||||
subroutine integrateStateRK4(g,i,e)
|
||||
|
||||
logical, dimension(:,:,:), intent(in) :: todo
|
||||
integer, intent(in) :: g,i,e
|
||||
|
||||
real(pReal), dimension(3,3), parameter :: &
|
||||
A = reshape([&
|
||||
|
@ -1342,7 +1368,7 @@ subroutine integrateStateRK4(todo)
|
|||
real(pReal), dimension(4), parameter :: &
|
||||
B = [1.0_pReal/6.0_pReal, 1.0_pReal/3.0_pReal, 1.0_pReal/3.0_pReal, 1.0_pReal/6.0_pReal]
|
||||
|
||||
call integrateStateRK(todo,A,B,C)
|
||||
call integrateStateRK(g,i,e,A,B,C)
|
||||
|
||||
end subroutine integrateStateRK4
|
||||
|
||||
|
@ -1350,9 +1376,9 @@ end subroutine integrateStateRK4
|
|||
!---------------------------------------------------------------------------------------------------
|
||||
!> @brief Integrate state (including stress integration) with the Cash-Carp method
|
||||
!---------------------------------------------------------------------------------------------------
|
||||
subroutine integrateStateRKCK45(todo)
|
||||
subroutine integrateStateRKCK45(g,i,e)
|
||||
|
||||
logical, dimension(:,:,:), intent(in) :: todo
|
||||
integer, intent(in) :: g,i,e
|
||||
|
||||
real(pReal), dimension(5,5), parameter :: &
|
||||
A = reshape([&
|
||||
|
@ -1372,7 +1398,7 @@ subroutine integrateStateRKCK45(todo)
|
|||
[2825.0_pReal/27648.0_pReal, .0_pReal, 18575.0_pReal/48384.0_pReal,&
|
||||
13525.0_pReal/55296.0_pReal, 277.0_pReal/14336.0_pReal, 1._pReal/4._pReal]
|
||||
|
||||
call integrateStateRK(todo,A,B,C,DB)
|
||||
call integrateStateRK(g,i,e,A,B,C,DB)
|
||||
|
||||
end subroutine integrateStateRKCK45
|
||||
|
||||
|
@ -1381,18 +1407,18 @@ end subroutine integrateStateRKCK45
|
|||
!> @brief Integrate state (including stress integration) with an explicit Runge-Kutta method or an
|
||||
!! embedded explicit Runge-Kutta method
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
subroutine integrateStateRK(todo,A,B,CC,DB)
|
||||
subroutine integrateStateRK(g,i,e,A,B,CC,DB)
|
||||
|
||||
logical, dimension(:,:,:), intent(in) :: todo
|
||||
|
||||
real(pReal), dimension(:,:), intent(in) :: A
|
||||
real(pReal), dimension(:), intent(in) :: B, CC
|
||||
real(pReal), dimension(:), intent(in), optional :: DB
|
||||
|
||||
integer, intent(in) :: &
|
||||
e, & !< element index in element loop
|
||||
i, & !< integration point index in ip loop
|
||||
g !< grain index in grain loop
|
||||
integer :: &
|
||||
e, & ! element index in element loop
|
||||
i, & ! integration point index in ip loop
|
||||
g, & ! grain index in grain loop
|
||||
stage, & ! stage index in integration stage loop
|
||||
n, &
|
||||
p, &
|
||||
|
@ -1400,19 +1426,11 @@ subroutine integrateStateRK(todo,A,B,CC,DB)
|
|||
s, &
|
||||
sizeDotState
|
||||
logical :: &
|
||||
nonlocalBroken, broken
|
||||
broken
|
||||
real(pReal), dimension(constitutive_source_maxSizeDotState,size(B),maxval(phase_Nsources)) :: source_RKdotState
|
||||
real(pReal), dimension(constitutive_plasticity_maxSizeDotState,size(B)) :: plastic_RKdotState
|
||||
|
||||
nonlocalBroken = .false.
|
||||
!$OMP PARALLEL DO PRIVATE(sizeDotState,p,c,plastic_RKdotState,source_RKdotState,broken)
|
||||
do e = FEsolving_execElem(1),FEsolving_execElem(2)
|
||||
do i = FEsolving_execIP(1),FEsolving_execIP(2)
|
||||
do g = 1,homogenization_Ngrains(material_homogenizationAt(e))
|
||||
broken = .false.
|
||||
p = material_phaseAt(g,e)
|
||||
if(todo(g,i,e) .and. .not. (nonlocalBroken .and. plasticState(p)%nonlocal)) then
|
||||
|
||||
c = material_phaseMemberAt(g,i,e)
|
||||
|
||||
broken = constitutive_collectDotState(crystallite_S(1:3,1:3,g,i,e), &
|
||||
|
@ -1420,7 +1438,7 @@ subroutine integrateStateRK(todo,A,B,CC,DB)
|
|||
crystallite_Fi(1:3,1:3,g,i,e), &
|
||||
crystallite_partionedFp0, &
|
||||
crystallite_subdt(g,i,e), g,i,e,p,c)
|
||||
if(broken) cycle
|
||||
if(broken) return
|
||||
|
||||
do stage = 1,size(A,1)
|
||||
sizeDotState = plasticState(p)%sizeDotState
|
||||
|
@ -1465,7 +1483,7 @@ subroutine integrateStateRK(todo,A,B,CC,DB)
|
|||
if(broken) exit
|
||||
|
||||
enddo
|
||||
if(broken) cycle
|
||||
if(broken) return
|
||||
|
||||
sizeDotState = plasticState(p)%sizeDotState
|
||||
|
||||
|
@ -1494,22 +1512,16 @@ subroutine integrateStateRK(todo,A,B,CC,DB)
|
|||
sourceState(p)%p(s)%state(1:sizeDotState,c), &
|
||||
sourceState(p)%p(s)%atol(1:sizeDotState))
|
||||
enddo
|
||||
if(broken) cycle
|
||||
if(broken) return
|
||||
|
||||
broken = constitutive_deltaState(crystallite_S(1:3,1:3,g,i,e), &
|
||||
crystallite_Fe(1:3,1:3,g,i,e), &
|
||||
crystallite_Fi(1:3,1:3,g,i,e),g,i,e,p,c)
|
||||
if(broken) cycle
|
||||
if(broken) return
|
||||
|
||||
broken = integrateStress(g,i,e)
|
||||
crystallite_converged(g,i,e) = .not. broken
|
||||
|
||||
endif
|
||||
if(broken .and. plasticState(p)%nonlocal) nonlocalBroken = .true.
|
||||
enddo; enddo; enddo
|
||||
!$OMP END PARALLEL DO
|
||||
|
||||
if(nonlocalBroken) call nonlocalConvergenceCheck
|
||||
|
||||
end subroutine integrateStateRK
|
||||
|
||||
|
@ -1521,7 +1533,19 @@ end subroutine integrateStateRK
|
|||
subroutine nonlocalConvergenceCheck
|
||||
|
||||
integer :: e,i,p
|
||||
logical :: nonlocal_broken
|
||||
|
||||
nonlocal_broken = .false.
|
||||
!$OMP PARALLEL DO PRIVATE(p)
|
||||
do e = FEsolving_execElem(1),FEsolving_execElem(2)
|
||||
p = material_phaseAt(1,e)
|
||||
do i = FEsolving_execIP(1),FEsolving_execIP(2)
|
||||
if(plasticState(p)%nonlocal .and. .not. crystallite_converged(1,i,e)) nonlocal_broken = .true.
|
||||
enddo
|
||||
enddo
|
||||
!$OMP END PARALLEL DO
|
||||
|
||||
if(.not. nonlocal_broken) return
|
||||
!$OMP PARALLEL DO PRIVATE(p)
|
||||
do e = FEsolving_execElem(1),FEsolving_execElem(2)
|
||||
p = material_phaseAt(1,e)
|
||||
|
|
|
@ -134,7 +134,7 @@ function damage_nonlocal_getDiffusion(ip,el)
|
|||
damage_nonlocal_getDiffusion = 0.0_pReal
|
||||
do grain = 1, homogenization_Ngrains(homog)
|
||||
damage_nonlocal_getDiffusion = damage_nonlocal_getDiffusion + &
|
||||
crystallite_push33ToRef(grain,ip,el,lattice_DamageDiffusion(1:3,1:3,material_phaseAt(grain,el)))
|
||||
crystallite_push33ToRef(grain,ip,el,lattice_D(1:3,1:3,material_phaseAt(grain,el)))
|
||||
enddo
|
||||
|
||||
damage_nonlocal_getDiffusion = &
|
||||
|
@ -157,7 +157,7 @@ real(pReal) function damage_nonlocal_getMobility(ip,el)
|
|||
damage_nonlocal_getMobility = 0.0_pReal
|
||||
|
||||
do ipc = 1, homogenization_Ngrains(material_homogenizationAt(el))
|
||||
damage_nonlocal_getMobility = damage_nonlocal_getMobility + lattice_DamageMobility(material_phaseAt(ipc,el))
|
||||
damage_nonlocal_getMobility = damage_nonlocal_getMobility + lattice_M(material_phaseAt(ipc,el))
|
||||
enddo
|
||||
|
||||
damage_nonlocal_getMobility = damage_nonlocal_getMobility/&
|
||||
|
|
|
@ -15,7 +15,7 @@ module discretization
|
|||
discretization_nElem
|
||||
|
||||
integer, public, protected, dimension(:), allocatable :: &
|
||||
discretization_microstructureAt
|
||||
discretization_materialAt
|
||||
|
||||
real(pReal), public, protected, dimension(:,:), allocatable :: &
|
||||
discretization_IPcoords0, &
|
||||
|
@ -37,12 +37,12 @@ contains
|
|||
!--------------------------------------------------------------------------------------------------
|
||||
!> @brief stores the relevant information in globally accesible variables
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
subroutine discretization_init(microstructureAt,&
|
||||
subroutine discretization_init(materialAt,&
|
||||
IPcoords0,NodeCoords0,&
|
||||
sharedNodesBegin)
|
||||
|
||||
integer, dimension(:), intent(in) :: &
|
||||
microstructureAt
|
||||
materialAt
|
||||
real(pReal), dimension(:,:), intent(in) :: &
|
||||
IPcoords0, &
|
||||
NodeCoords0
|
||||
|
@ -51,10 +51,10 @@ subroutine discretization_init(microstructureAt,&
|
|||
|
||||
print'(/,a)', ' <<<+- discretization init -+>>>'; flush(6)
|
||||
|
||||
discretization_nElem = size(microstructureAt,1)
|
||||
discretization_nElem = size(materialAt,1)
|
||||
discretization_nIP = size(IPcoords0,2)/discretization_nElem
|
||||
|
||||
discretization_microstructureAt = microstructureAt
|
||||
discretization_materialAt = materialAt
|
||||
|
||||
discretization_IPcoords0 = IPcoords0
|
||||
discretization_IPcoords = IPcoords0
|
||||
|
|
|
@ -181,7 +181,7 @@ program DAMASK_grid
|
|||
if ((N_def /= N_n) .or. (N_n /= N_t) .or. N_n < 1) & ! sanity check
|
||||
call IO_error(error_ID=837,el=currentLoadCase,ext_msg = trim(interface_loadFile)) ! error message for incomplete loadcase
|
||||
|
||||
newLoadCase%stress%myType='stress'
|
||||
newLoadCase%stress%myType='p'
|
||||
field = 1
|
||||
newLoadCase%ID(field) = FIELD_MECH_ID ! mechanical active by default
|
||||
thermalActive: if (any(thermal_type == THERMAL_conduction_ID)) then
|
||||
|
@ -210,8 +210,7 @@ program DAMASK_grid
|
|||
temp_maskVector(j) = IO_stringValue(line,chunkPos,i+j) /= '*' ! true if not a *
|
||||
if (temp_maskVector(j)) temp_valueVector(j) = IO_floatValue(line,chunkPos,i+j) ! read value where applicable
|
||||
enddo
|
||||
newLoadCase%deformation%maskLogical = transpose(reshape(temp_maskVector,[ 3,3])) ! logical mask in 3x3 notation
|
||||
newLoadCase%deformation%maskFloat = merge(ones,zeros,newLoadCase%deformation%maskLogical) ! float (1.0/0.0) mask in 3x3 notation
|
||||
newLoadCase%deformation%mask = transpose(reshape(temp_maskVector,[ 3,3])) ! mask in 3x3 notation
|
||||
newLoadCase%deformation%values = math_9to33(temp_valueVector) ! values in 3x3 notation
|
||||
case('p','stress', 's')
|
||||
temp_valueVector = 0.0_pReal
|
||||
|
@ -219,8 +218,7 @@ program DAMASK_grid
|
|||
temp_maskVector(j) = IO_stringValue(line,chunkPos,i+j) /= '*' ! true if not an asterisk
|
||||
if (temp_maskVector(j)) temp_valueVector(j) = IO_floatValue(line,chunkPos,i+j) ! read value where applicable
|
||||
enddo
|
||||
newLoadCase%stress%maskLogical = transpose(reshape(temp_maskVector,[ 3,3]))
|
||||
newLoadCase%stress%maskFloat = merge(ones,zeros,newLoadCase%stress%maskLogical)
|
||||
newLoadCase%stress%mask = transpose(reshape(temp_maskVector,[ 3,3]))
|
||||
newLoadCase%stress%values = math_9to33(temp_valueVector)
|
||||
case('t','time','delta') ! increment time
|
||||
newLoadCase%time = IO_floatValue(line,chunkPos,i+1)
|
||||
|
@ -268,8 +266,8 @@ program DAMASK_grid
|
|||
print*, ' drop guessing along trajectory'
|
||||
if (newLoadCase%deformation%myType == 'l') then
|
||||
do j = 1, 3
|
||||
if (any(newLoadCase%deformation%maskLogical(j,1:3) .eqv. .true.) .and. &
|
||||
any(newLoadCase%deformation%maskLogical(j,1:3) .eqv. .false.)) errorID = 832 ! each row should be either fully or not at all defined
|
||||
if (any(newLoadCase%deformation%mask(j,1:3) .eqv. .true.) .and. &
|
||||
any(newLoadCase%deformation%mask(j,1:3) .eqv. .false.)) errorID = 832 ! each row should be either fully or not at all defined
|
||||
enddo
|
||||
print*, ' velocity gradient:'
|
||||
else if (newLoadCase%deformation%myType == 'f') then
|
||||
|
@ -278,20 +276,19 @@ program DAMASK_grid
|
|||
print*, ' deformation gradient rate:'
|
||||
endif
|
||||
do i = 1, 3; do j = 1, 3
|
||||
if(newLoadCase%deformation%maskLogical(i,j)) then
|
||||
if(newLoadCase%deformation%mask(i,j)) then
|
||||
write(IO_STDOUT,'(2x,f12.7)',advance='no') newLoadCase%deformation%values(i,j)
|
||||
else
|
||||
write(IO_STDOUT,'(2x,12a)',advance='no') ' * '
|
||||
endif
|
||||
enddo; write(IO_STDOUT,'(/)',advance='no')
|
||||
enddo
|
||||
if (any(newLoadCase%stress%maskLogical .eqv. &
|
||||
newLoadCase%deformation%maskLogical)) errorID = 831 ! exclusive or masking only
|
||||
if (any(newLoadCase%stress%maskLogical .and. transpose(newLoadCase%stress%maskLogical) &
|
||||
.and. (math_I3<1))) errorID = 838 ! no rotation is allowed by stress BC
|
||||
if (any(newLoadCase%stress%mask .eqv. newLoadCase%deformation%mask)) errorID = 831 ! exclusive or masking only
|
||||
if (any(newLoadCase%stress%mask .and. transpose(newLoadCase%stress%mask) .and. (math_I3<1))) &
|
||||
errorID = 838 ! no rotation is allowed by stress BC
|
||||
print*, ' stress / GPa:'
|
||||
do i = 1, 3; do j = 1, 3
|
||||
if(newLoadCase%stress%maskLogical(i,j)) then
|
||||
if(newLoadCase%stress%mask(i,j)) then
|
||||
write(IO_STDOUT,'(2x,f12.7)',advance='no') newLoadCase%stress%values(i,j)*1e-9_pReal
|
||||
else
|
||||
write(IO_STDOUT,'(2x,12a)',advance='no') ' * '
|
||||
|
@ -368,11 +365,7 @@ program DAMASK_grid
|
|||
timeinc = loadCases(currentLoadCase)%time/real(loadCases(currentLoadCase)%incs,pReal)
|
||||
else
|
||||
if (currentLoadCase == 1) then ! 1st load case of logarithmic scale
|
||||
if (inc == 1) then ! 1st inc of 1st load case of logarithmic scale
|
||||
timeinc = loadCases(1)%time*(2.0_pReal**real( 1-loadCases(1)%incs ,pReal)) ! assume 1st inc is equal to 2nd
|
||||
else ! not-1st inc of 1st load case of logarithmic scale
|
||||
timeinc = loadCases(1)%time*(2.0_pReal**real(inc-1-loadCases(1)%incs ,pReal))
|
||||
endif
|
||||
timeinc = loadCases(1)%time*(2.0_pReal**real(max(inc-1,1)-loadCases(1)%incs ,pReal)) ! assume 1st inc is equal to 2nd
|
||||
else ! not-1st load case of logarithmic scale
|
||||
timeinc = time0 * &
|
||||
( (1.0_pReal + loadCases(currentLoadCase)%time/time0 )**(real( inc ,pReal)/&
|
||||
|
@ -432,17 +425,11 @@ program DAMASK_grid
|
|||
do field = 1, nActiveFields
|
||||
select case(loadCases(currentLoadCase)%ID(field))
|
||||
case(FIELD_MECH_ID)
|
||||
solres(field) = mech_solution (&
|
||||
incInfo,timeinc,timeIncOld, &
|
||||
stress_BC = loadCases(currentLoadCase)%stress, &
|
||||
rotation_BC = loadCases(currentLoadCase)%rot)
|
||||
|
||||
solres(field) = mech_solution(incInfo)
|
||||
case(FIELD_THERMAL_ID)
|
||||
solres(field) = grid_thermal_spectral_solution(timeinc,timeIncOld)
|
||||
|
||||
solres(field) = grid_thermal_spectral_solution(timeinc)
|
||||
case(FIELD_DAMAGE_ID)
|
||||
solres(field) = grid_damage_spectral_solution(timeinc,timeIncOld)
|
||||
|
||||
solres(field) = grid_damage_spectral_solution(timeinc)
|
||||
end select
|
||||
|
||||
if (.not. solres(field)%converged) exit ! no solution found
|
||||
|
|
|
@ -56,7 +56,7 @@ subroutine discretization_grid_init(restart)
|
|||
myGrid !< domain grid of this process
|
||||
|
||||
integer, dimension(:), allocatable :: &
|
||||
microstructureAt
|
||||
materialAt
|
||||
|
||||
integer :: &
|
||||
j, &
|
||||
|
@ -68,9 +68,9 @@ subroutine discretization_grid_init(restart)
|
|||
print'(/,a)', ' <<<+- discretization_grid init -+>>>'; flush(IO_STDOUT)
|
||||
|
||||
if(index(interface_geomFile,'.vtr') /= 0) then
|
||||
call readVTR(grid,geomSize,origin,microstructureAt)
|
||||
call readVTR(grid,geomSize,origin,materialAt)
|
||||
else
|
||||
call readGeom(grid,geomSize,origin,microstructureAt)
|
||||
call readGeom(grid,geomSize,origin,materialAt)
|
||||
endif
|
||||
|
||||
print'(/,a,3(i12 ))', ' grid a b c: ', grid
|
||||
|
@ -102,15 +102,14 @@ subroutine discretization_grid_init(restart)
|
|||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! general discretization
|
||||
microstructureAt = microstructureAt(product(grid(1:2))*grid3Offset+1: &
|
||||
product(grid(1:2))*(grid3Offset+grid3)) ! reallocate/shrink in case of MPI
|
||||
materialAt = materialAt(product(grid(1:2))*grid3Offset+1:product(grid(1:2))*(grid3Offset+grid3)) ! reallocate/shrink in case of MPI
|
||||
|
||||
call discretization_init(microstructureAt, &
|
||||
call discretization_init(materialAt, &
|
||||
IPcoordinates0(myGrid,mySize,grid3Offset), &
|
||||
Nodes0(myGrid,mySize,grid3Offset),&
|
||||
merge((grid(1)+1) * (grid(2)+1) * (grid3+1),& ! write bottom layer
|
||||
(grid(1)+1) * (grid(2)+1) * grid3,& ! do not write bottom layer (is top of rank-1)
|
||||
worldrank<1))
|
||||
merge((grid(1)+1) * (grid(2)+1) * (grid3+1),& ! write top layer...
|
||||
(grid(1)+1) * (grid(2)+1) * grid3,& ! ...unless not last process
|
||||
worldrank+1==worldsize))
|
||||
|
||||
FEsolving_execElem = [1,product(myGrid)] ! parallel loop bounds set to comprise all elements
|
||||
FEsolving_execIP = [1,1] ! parallel loop bounds set to comprise the only IP
|
||||
|
@ -147,7 +146,7 @@ end subroutine discretization_grid_init
|
|||
!> @details important variables have an implicit "save" attribute. Therefore, this function is
|
||||
! supposed to be called only once!
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
subroutine readGeom(grid,geomSize,origin,microstructure)
|
||||
subroutine readGeom(grid,geomSize,origin,material)
|
||||
|
||||
integer, dimension(3), intent(out) :: &
|
||||
grid ! grid (across all processes!)
|
||||
|
@ -155,7 +154,7 @@ subroutine readGeom(grid,geomSize,origin,microstructure)
|
|||
geomSize, & ! size (across all processes!)
|
||||
origin ! origin (across all processes!)
|
||||
integer, dimension(:), intent(out), allocatable :: &
|
||||
microstructure
|
||||
material
|
||||
|
||||
character(len=:), allocatable :: rawData
|
||||
character(len=65536) :: line
|
||||
|
@ -167,7 +166,7 @@ subroutine readGeom(grid,geomSize,origin,microstructure)
|
|||
startPos, endPos, &
|
||||
myStat, &
|
||||
l, & !< line counter
|
||||
c, & !< counter for # microstructures in line
|
||||
c, & !< counter for # materials in line
|
||||
o, & !< order of "to" packing
|
||||
e, & !< "element", i.e. spectral collocation point
|
||||
i, j
|
||||
|
@ -266,7 +265,7 @@ subroutine readGeom(grid,geomSize,origin,microstructure)
|
|||
if(any(geomSize < 0.0_pReal)) &
|
||||
call IO_error(error_ID = 842, ext_msg='size (readGeom)')
|
||||
|
||||
allocate(microstructure(product(grid)), source = -1) ! too large in case of MPI (shrink later, not very elegant)
|
||||
allocate(material(product(grid)), source = -1) ! too large in case of MPI (shrink later, not very elegant)
|
||||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! read and interpret content
|
||||
|
@ -281,18 +280,18 @@ subroutine readGeom(grid,geomSize,origin,microstructure)
|
|||
|
||||
noCompression: if (chunkPos(1) /= 3) then
|
||||
c = chunkPos(1)
|
||||
microstructure(e:e+c-1) = [(IO_intValue(line,chunkPos,i+1), i=0, c-1)]
|
||||
material(e:e+c-1) = [(IO_intValue(line,chunkPos,i+1), i=0, c-1)]
|
||||
else noCompression
|
||||
compression: if (IO_lc(IO_stringValue(line,chunkPos,2)) == 'of') then
|
||||
c = IO_intValue(line,chunkPos,1)
|
||||
microstructure(e:e+c-1) = [(IO_intValue(line,chunkPos,3),i = 1,IO_intValue(line,chunkPos,1))]
|
||||
material(e:e+c-1) = [(IO_intValue(line,chunkPos,3),i = 1,IO_intValue(line,chunkPos,1))]
|
||||
else if (IO_lc(IO_stringValue(line,chunkPos,2)) == 'to') then compression
|
||||
c = abs(IO_intValue(line,chunkPos,3) - IO_intValue(line,chunkPos,1)) + 1
|
||||
o = merge(+1, -1, IO_intValue(line,chunkPos,3) > IO_intValue(line,chunkPos,1))
|
||||
microstructure(e:e+c-1) = [(i, i = IO_intValue(line,chunkPos,1),IO_intValue(line,chunkPos,3),o)]
|
||||
material(e:e+c-1) = [(i, i = IO_intValue(line,chunkPos,1),IO_intValue(line,chunkPos,3),o)]
|
||||
else compression
|
||||
c = chunkPos(1)
|
||||
microstructure(e:e+c-1) = [(IO_intValue(line,chunkPos,i+1), i=0, c-1)]
|
||||
material(e:e+c-1) = [(IO_intValue(line,chunkPos,i+1), i=0, c-1)]
|
||||
endif compression
|
||||
endif noCompression
|
||||
|
||||
|
@ -308,7 +307,7 @@ end subroutine readGeom
|
|||
!> @brief Parse vtk rectilinear grid (.vtr)
|
||||
!> @details https://vtk.org/Wiki/VTK_XML_Formats
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
subroutine readVTR(grid,geomSize,origin,microstructure)
|
||||
subroutine readVTR(grid,geomSize,origin,material)
|
||||
|
||||
integer, dimension(3), intent(out) :: &
|
||||
grid ! grid (across all processes!)
|
||||
|
@ -316,7 +315,7 @@ subroutine readVTR(grid,geomSize,origin,microstructure)
|
|||
geomSize, & ! size (across all processes!)
|
||||
origin ! origin (across all processes!)
|
||||
integer, dimension(:), intent(out), allocatable :: &
|
||||
microstructure
|
||||
material
|
||||
|
||||
character(len=:), allocatable :: fileContent, dataType, headerType
|
||||
logical :: inFile,inGrid,gotCoordinates,gotCellData,compressed
|
||||
|
@ -364,11 +363,9 @@ subroutine readVTR(grid,geomSize,origin,microstructure)
|
|||
else
|
||||
if(index(fileContent(startPos:endPos),'<CellData>',kind=pI64) /= 0_pI64) then
|
||||
gotCellData = .true.
|
||||
startPos = endPos + 2_pI64
|
||||
do while (index(fileContent(startPos:endPos),'</CellData>',kind=pI64) == 0_pI64)
|
||||
endPos = startPos + index(fileContent(startPos:),IO_EOL,kind=pI64) - 2_pI64
|
||||
if(index(fileContent(startPos:endPos),'<DataArray',kind=pI64) /= 0_pI64 .and. &
|
||||
getXMLValue(fileContent(startPos:endPos),'Name') == 'materialpoint' ) then
|
||||
getXMLValue(fileContent(startPos:endPos),'Name') == 'material' ) then
|
||||
|
||||
if(getXMLValue(fileContent(startPos:endPos),'format') /= 'binary') &
|
||||
call IO_error(error_ID = 844, ext_msg='format (materialpoint)')
|
||||
|
@ -377,10 +374,11 @@ subroutine readVTR(grid,geomSize,origin,microstructure)
|
|||
startPos = endPos + 2_pI64
|
||||
endPos = startPos + index(fileContent(startPos:),IO_EOL,kind=pI64) - 2_pI64
|
||||
s = startPos + verify(fileContent(startPos:endPos),IO_WHITESPACE,kind=pI64) -1_pI64 ! start (no leading whitespace)
|
||||
microstructure = as_Int(fileContent(s:endPos),headerType,compressed,dataType)
|
||||
material = as_Int(fileContent(s:endPos),headerType,compressed,dataType)
|
||||
exit
|
||||
endif
|
||||
startPos = endPos + 2_pI64
|
||||
endPos = startPos + index(fileContent(startPos:),IO_EOL,kind=pI64) - 2_pI64
|
||||
enddo
|
||||
elseif(index(fileContent(startPos:endPos),'<Coordinates>',kind=pI64) /= 0_pI64) then
|
||||
gotCoordinates = .true.
|
||||
|
@ -415,8 +413,8 @@ subroutine readVTR(grid,geomSize,origin,microstructure)
|
|||
|
||||
end do
|
||||
|
||||
if(.not. allocated(microstructure)) call IO_error(error_ID = 844, ext_msg='materialpoint not found')
|
||||
if(size(microstructure) /= product(grid)) call IO_error(error_ID = 844, ext_msg='size(materialpoint)')
|
||||
if(.not. allocated(material)) call IO_error(error_ID = 844, ext_msg='material data not found')
|
||||
if(size(material) /= product(grid)) call IO_error(error_ID = 844, ext_msg='size(material)')
|
||||
if(any(geomSize<=0)) call IO_error(error_ID = 844, ext_msg='size')
|
||||
if(any(grid<1)) call IO_error(error_ID = 844, ext_msg='grid')
|
||||
|
||||
|
|
|
@ -156,11 +156,10 @@ end subroutine grid_damage_spectral_init
|
|||
!--------------------------------------------------------------------------------------------------
|
||||
!> @brief solution for the spectral damage scheme with internal iterations
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
function grid_damage_spectral_solution(timeinc,timeinc_old) result(solution)
|
||||
function grid_damage_spectral_solution(timeinc) result(solution)
|
||||
|
||||
real(pReal), intent(in) :: &
|
||||
timeinc, & !< increment in time for current solution
|
||||
timeinc_old !< increment in time of last increment
|
||||
timeinc !< increment in time for current solution
|
||||
integer :: i, j, k, cell
|
||||
type(tSolutionState) :: solution
|
||||
PetscInt :: devNull
|
||||
|
@ -174,7 +173,6 @@ function grid_damage_spectral_solution(timeinc,timeinc_old) result(solution)
|
|||
!--------------------------------------------------------------------------------------------------
|
||||
! set module wide availabe data
|
||||
params%timeinc = timeinc
|
||||
params%timeincOld = timeinc_old
|
||||
|
||||
call SNESSolve(damage_snes,PETSC_NULL_VEC,solution_vec,ierr); CHKERRQ(ierr)
|
||||
call SNESGetConvergedReason(damage_snes,reason,ierr); CHKERRQ(ierr)
|
||||
|
|
|
@ -25,63 +25,56 @@ module grid_mech_FEM
|
|||
implicit none
|
||||
private
|
||||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! derived types
|
||||
type(tSolutionParams), private :: params
|
||||
type(tSolutionParams) :: params
|
||||
|
||||
type, private :: tNumerics
|
||||
type :: tNumerics
|
||||
integer :: &
|
||||
itmin, & !< minimum number of iterations
|
||||
itmax !< maximum number of iterations
|
||||
real(pReal) :: &
|
||||
err_div, &
|
||||
divTol, &
|
||||
BCTol, &
|
||||
eps_div_atol, & !< absolute tolerance for equilibrium
|
||||
eps_div_rtol, & !< relative tolerance for equilibrium
|
||||
eps_stress_atol, & !< absolute tolerance for fullfillment of stress BC
|
||||
eps_stress_rtol !< relative tolerance for fullfillment of stress BC
|
||||
end type tNumerics
|
||||
|
||||
type(tNumerics), private :: num
|
||||
logical, private:: &
|
||||
debugRotation
|
||||
type(tNumerics) :: num ! numerics parameters. Better name?
|
||||
|
||||
logical :: debugRotation
|
||||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! PETSc data
|
||||
DM, private :: mech_grid
|
||||
SNES, private :: mech_snes
|
||||
Vec, private :: solution_current, solution_lastInc, solution_rate
|
||||
DM :: mech_grid
|
||||
SNES :: mech_snes
|
||||
Vec :: solution_current, solution_lastInc, solution_rate
|
||||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! common pointwise data
|
||||
real(pReal), private, dimension(:,:,:,:,:), allocatable :: F, P_current, F_lastInc
|
||||
real(pReal), private :: detJ
|
||||
real(pReal), private, dimension(3) :: delta
|
||||
real(pReal), private, dimension(3,8) :: BMat
|
||||
real(pReal), private, dimension(8,8) :: HGMat
|
||||
PetscInt, private :: xstart,ystart,zstart,xend,yend,zend
|
||||
real(pReal), dimension(:,:,:,:,:), allocatable :: F, P_current, F_lastInc
|
||||
real(pReal) :: detJ
|
||||
real(pReal), dimension(3) :: delta
|
||||
real(pReal), dimension(3,8) :: BMat
|
||||
real(pReal), dimension(8,8) :: HGMat
|
||||
PetscInt :: xstart,ystart,zstart,xend,yend,zend
|
||||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! stress, stiffness and compliance average etc.
|
||||
real(pReal), private, dimension(3,3) :: &
|
||||
real(pReal), dimension(3,3) :: &
|
||||
F_aimDot = 0.0_pReal, & !< assumed rate of average deformation gradient
|
||||
F_aim = math_I3, & !< current prescribed deformation gradient
|
||||
F_aim_lastIter = math_I3, &
|
||||
F_aim_lastInc = math_I3, & !< previous average deformation gradient
|
||||
P_av = 0.0_pReal !< average 1st Piola--Kirchhoff stress
|
||||
|
||||
character(len=:), allocatable, private :: incInfo !< time and increment information
|
||||
|
||||
real(pReal), private, dimension(3,3,3,3) :: &
|
||||
P_av = 0.0_pReal, & !< average 1st Piola--Kirchhoff stress
|
||||
P_aim = 0.0_pReal
|
||||
character(len=:), allocatable :: incInfo !< time and increment information
|
||||
real(pReal), dimension(3,3,3,3) :: &
|
||||
C_volAvg = 0.0_pReal, & !< current volume average stiffness
|
||||
C_volAvgLastInc = 0.0_pReal, & !< previous volume average stiffness
|
||||
S = 0.0_pReal !< current compliance (filled up with zeros)
|
||||
|
||||
real(pReal), private :: &
|
||||
real(pReal) :: &
|
||||
err_BC !< deviation from stress BC
|
||||
|
||||
integer, private :: &
|
||||
integer :: &
|
||||
totalIter = 0 !< total iteration in current increment
|
||||
|
||||
public :: &
|
||||
|
@ -99,7 +92,6 @@ contains
|
|||
subroutine grid_mech_FEM_init
|
||||
|
||||
real(pReal) :: HGCoeff = 0.0e-2_pReal
|
||||
PetscInt, dimension(0:worldsize-1) :: localK
|
||||
real(pReal), dimension(3,3) :: &
|
||||
temp33_Real = 0.0_pReal
|
||||
real(pReal), dimension(4,8) :: &
|
||||
|
@ -111,20 +103,21 @@ subroutine grid_mech_FEM_init
|
|||
-1.0_pReal, 1.0_pReal,-1.0_pReal,-1.0_pReal, &
|
||||
1.0_pReal,-1.0_pReal,-1.0_pReal,-1.0_pReal, &
|
||||
1.0_pReal, 1.0_pReal, 1.0_pReal, 1.0_pReal], [4,8])
|
||||
real(pReal), dimension(3,3,3,3) :: devNull
|
||||
PetscErrorCode :: ierr
|
||||
PetscScalar, pointer, dimension(:,:,:,:) :: &
|
||||
u_current,u_lastInc
|
||||
PetscInt, dimension(0:worldsize-1) :: localK
|
||||
integer(HID_T) :: fileHandle, groupHandle
|
||||
character(len=pStringLen) :: &
|
||||
fileName
|
||||
class(tNode), pointer :: &
|
||||
num_grid, &
|
||||
debug_grid
|
||||
real(pReal), dimension(3,3,3,3) :: devNull
|
||||
PetscScalar, pointer, dimension(:,:,:,:) :: &
|
||||
u_current,u_lastInc
|
||||
|
||||
print'(/,a)', ' <<<+- grid_mech_FEM init -+>>>'; flush(IO_STDOUT)
|
||||
|
||||
!-----------------------------------------------------------------------------------------------
|
||||
!-------------------------------------------------------------------------------------------------
|
||||
! debugging options
|
||||
debug_grid => config_debug%get('grid', defaultVal=emptyList)
|
||||
debugRotation = debug_grid%contains('rotation')
|
||||
|
@ -135,7 +128,7 @@ subroutine grid_mech_FEM_init
|
|||
num%eps_div_atol = num_grid%get_asFloat('eps_div_atol', defaultVal=1.0e-4_pReal)
|
||||
num%eps_div_rtol = num_grid%get_asFloat('eps_div_rtol', defaultVal=5.0e-4_pReal)
|
||||
num%eps_stress_atol = num_grid%get_asFloat('eps_stress_atol',defaultVal=1.0e3_pReal)
|
||||
num%eps_stress_rtol = num_grid%get_asFloat ('eps_stress_rtol', defaultVal=0.01_pReal)
|
||||
num%eps_stress_rtol = num_grid%get_asFloat('eps_stress_rtol',defaultVal=1.0e-3_pReal)
|
||||
num%itmin = num_grid%get_asInt ('itmin', defaultVal=1)
|
||||
num%itmax = num_grid%get_asInt ('itmax', defaultVal=250)
|
||||
|
||||
|
@ -242,6 +235,7 @@ subroutine grid_mech_FEM_init
|
|||
F_lastInc = spread(spread(spread(math_I3,3,grid(1)),4,grid(2)),5,grid3) ! initialize to identity
|
||||
F = spread(spread(spread(math_I3,3,grid(1)),4,grid(2)),5,grid3)
|
||||
endif restartRead
|
||||
|
||||
materialpoint_F0 = reshape(F_lastInc, [3,3,1,product(grid(1:2))*grid3]) ! set starting condition for materialpoint_stressAndItsTangent
|
||||
call utilities_updateCoords(F)
|
||||
call utilities_constitutiveResponse(P_current,temp33_Real,C_volAvg,devNull, & ! stress field, stress avg, global average of stiffness and (min+max)/2
|
||||
|
@ -268,19 +262,12 @@ end subroutine grid_mech_FEM_init
|
|||
!--------------------------------------------------------------------------------------------------
|
||||
!> @brief solution for the FEM scheme with internal iterations
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
function grid_mech_FEM_solution(incInfoIn,timeinc,timeinc_old,stress_BC,rotation_BC) result(solution)
|
||||
function grid_mech_FEM_solution(incInfoIn) result(solution)
|
||||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! input data for solution
|
||||
character(len=*), intent(in) :: &
|
||||
incInfoIn
|
||||
real(pReal), intent(in) :: &
|
||||
timeinc, & !< time increment of current solution
|
||||
timeinc_old !< time increment of last successful increment
|
||||
type(tBoundaryCondition), intent(in) :: &
|
||||
stress_BC
|
||||
type(rotation), intent(in) :: &
|
||||
rotation_BC
|
||||
type(tSolutionState) :: &
|
||||
solution
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
|
@ -292,14 +279,7 @@ function grid_mech_FEM_solution(incInfoIn,timeinc,timeinc_old,stress_BC,rotation
|
|||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! update stiffness (and gamma operator)
|
||||
S = utilities_maskedCompliance(rotation_BC,stress_BC%maskLogical,C_volAvg)
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! set module wide available data
|
||||
params%stress_mask = stress_BC%maskFloat
|
||||
params%stress_BC = stress_BC%values
|
||||
params%rotation_BC = rotation_BC
|
||||
params%timeinc = timeinc
|
||||
params%timeincOld = timeinc_old
|
||||
S = utilities_maskedCompliance(params%rotation_BC,params%stress_mask,C_volAvg)
|
||||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! solve BVP
|
||||
|
@ -341,6 +321,14 @@ subroutine grid_mech_FEM_forward(cutBack,guess,timeinc,timeinc_old,loadCaseTime,
|
|||
PetscScalar, pointer, dimension(:,:,:,:) :: &
|
||||
u_current,u_lastInc
|
||||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! set module wide available data
|
||||
params%stress_mask = stress_BC%mask
|
||||
params%rotation_BC = rotation_BC
|
||||
params%timeinc = timeinc
|
||||
params%timeincOld = timeinc_old
|
||||
|
||||
|
||||
call DMDAVecGetArrayF90(mech_grid,solution_current,u_current,ierr); CHKERRQ(ierr)
|
||||
call DMDAVecGetArrayF90(mech_grid,solution_lastInc,u_lastInc,ierr); CHKERRQ(ierr)
|
||||
|
||||
|
@ -349,20 +337,20 @@ subroutine grid_mech_FEM_forward(cutBack,guess,timeinc,timeinc_old,loadCaseTime,
|
|||
else
|
||||
C_volAvgLastInc = C_volAvg
|
||||
|
||||
F_aimDot = merge(stress_BC%maskFloat*(F_aim-F_aim_lastInc)/timeinc_old, 0.0_pReal, guess)
|
||||
F_aimDot = merge(merge((F_aim-F_aim_lastInc)/timeinc_old,0.0_pReal,stress_BC%mask), 0.0_pReal, guess)
|
||||
F_aim_lastInc = F_aim
|
||||
|
||||
!-----------------------------------------------------------------------------------------------
|
||||
! calculate rate for aim
|
||||
if (deformation_BC%myType=='l') then ! calculate F_aimDot from given L and current F
|
||||
F_aimDot = &
|
||||
F_aimDot + deformation_BC%maskFloat * matmul(deformation_BC%values, F_aim_lastInc)
|
||||
F_aimDot = F_aimDot &
|
||||
+ merge(matmul(deformation_BC%values, F_aim_lastInc),.0_pReal,deformation_BC%mask)
|
||||
elseif(deformation_BC%myType=='fdot') then ! F_aimDot is prescribed
|
||||
F_aimDot = &
|
||||
F_aimDot + deformation_BC%maskFloat * deformation_BC%values
|
||||
F_aimDot = F_aimDot &
|
||||
+ merge(deformation_BC%values,.0_pReal,deformation_BC%mask)
|
||||
elseif (deformation_BC%myType=='f') then ! aim at end of load case is prescribed
|
||||
F_aimDot = &
|
||||
F_aimDot + deformation_BC%maskFloat * (deformation_BC%values - F_aim_lastInc)/loadCaseTime
|
||||
F_aimDot = F_aimDot &
|
||||
+ merge((deformation_BC%values - F_aim_lastInc)/loadCaseTime,.0_pReal,deformation_BC%mask)
|
||||
endif
|
||||
|
||||
if (guess) then
|
||||
|
@ -382,6 +370,12 @@ subroutine grid_mech_FEM_forward(cutBack,guess,timeinc,timeinc_old,loadCaseTime,
|
|||
!--------------------------------------------------------------------------------------------------
|
||||
! update average and local deformation gradients
|
||||
F_aim = F_aim_lastInc + F_aimDot * timeinc
|
||||
if (stress_BC%myType=='p') then
|
||||
P_aim = P_aim + merge((stress_BC%values - P_aim)/loadCaseTime*timeinc,.0_pReal,stress_BC%mask)
|
||||
elseif (stress_BC%myType=='pdot') then !UNTESTED
|
||||
P_aim = P_aim + merge(stress_BC%values*timeinc,.0_pReal,stress_BC%mask)
|
||||
endif
|
||||
|
||||
call VecAXPY(solution_current,timeinc,solution_rate,ierr); CHKERRQ(ierr)
|
||||
|
||||
call DMDAVecRestoreArrayF90(mech_grid,solution_current,u_current,ierr);CHKERRQ(ierr)
|
||||
|
@ -497,8 +491,6 @@ subroutine formResidual(da_local,x_local, &
|
|||
PetscScalar, pointer,dimension(:,:,:,:) :: x_scal, f_scal
|
||||
PetscScalar, dimension(8,3) :: x_elem, f_elem
|
||||
PetscInt :: i, ii, j, jj, k, kk, ctr, ele
|
||||
real(pReal), dimension(3,3) :: &
|
||||
deltaF_aim
|
||||
PetscInt :: &
|
||||
PETScIter, &
|
||||
nfuncs
|
||||
|
@ -547,10 +539,8 @@ subroutine formResidual(da_local,x_local, &
|
|||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! stress BC handling
|
||||
F_aim_lastIter = F_aim
|
||||
deltaF_aim = math_mul3333xx33(S, P_av - params%stress_BC)
|
||||
F_aim = F_aim - deltaF_aim
|
||||
err_BC = maxval(abs(params%stress_mask * (P_av - params%stress_BC))) ! mask = 0.0 when no stress bc
|
||||
F_aim = F_aim - math_mul3333xx33(S, P_av - P_aim) ! S = 0.0 for no bc
|
||||
err_BC = maxval(abs(merge(P_av - P_aim,.0_pReal,params%stress_mask)))
|
||||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! constructing residual
|
||||
|
|
|
@ -24,11 +24,9 @@ module grid_mech_spectral_basic
|
|||
implicit none
|
||||
private
|
||||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! derived types
|
||||
type(tSolutionParams) :: params
|
||||
|
||||
type, private :: tNumerics
|
||||
type :: tNumerics
|
||||
logical :: update_gamma !< update gamma operator with current stiffness
|
||||
integer :: &
|
||||
itmin, & !< minimum number of iterations
|
||||
|
@ -42,7 +40,7 @@ module grid_mech_spectral_basic
|
|||
|
||||
type(tNumerics) :: num ! numerics parameters. Better name?
|
||||
|
||||
logical, private :: debugRotation
|
||||
logical :: debugRotation
|
||||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! PETSc data
|
||||
|
@ -62,10 +60,10 @@ module grid_mech_spectral_basic
|
|||
F_aimDot = 0.0_pReal, & !< assumed rate of average deformation gradient
|
||||
F_aim = math_I3, & !< current prescribed deformation gradient
|
||||
F_aim_lastInc = math_I3, & !< previous average deformation gradient
|
||||
P_av = 0.0_pReal !< average 1st Piola--Kirchhoff stress
|
||||
|
||||
P_av = 0.0_pReal, & !< average 1st Piola--Kirchhoff stress
|
||||
P_aim = 0.0_pReal
|
||||
character(len=:), allocatable :: incInfo !< time and increment information
|
||||
real(pReal), private, dimension(3,3,3,3) :: &
|
||||
real(pReal), dimension(3,3,3,3) :: &
|
||||
C_volAvg = 0.0_pReal, & !< current volume average stiffness
|
||||
C_volAvgLastInc = 0.0_pReal, & !< previous volume average stiffness
|
||||
C_minMaxAvg = 0.0_pReal, & !< current (min+max)/2 stiffness
|
||||
|
@ -96,18 +94,17 @@ subroutine grid_mech_spectral_basic_init
|
|||
real(pReal), dimension(3,3,grid(1),grid(2),grid3) :: P
|
||||
real(pReal), dimension(3,3) :: &
|
||||
temp33_Real = 0.0_pReal
|
||||
class (tNode), pointer :: &
|
||||
num_grid, &
|
||||
debug_grid
|
||||
|
||||
PetscErrorCode :: ierr
|
||||
PetscScalar, pointer, dimension(:,:,:,:) :: &
|
||||
F ! pointer to solution data
|
||||
PetscInt, dimension(worldsize) :: localK
|
||||
PetscInt, dimension(0:worldsize-1) :: localK
|
||||
integer(HID_T) :: fileHandle, groupHandle
|
||||
integer :: fileUnit
|
||||
character(len=pStringLen) :: &
|
||||
fileName
|
||||
class (tNode), pointer :: &
|
||||
num_grid, &
|
||||
debug_grid
|
||||
|
||||
print'(/,a)', ' <<<+- grid_mech_spectral_basic init -+>>>'; flush(IO_STDOUT)
|
||||
|
||||
|
@ -130,7 +127,7 @@ subroutine grid_mech_spectral_basic_init
|
|||
num%eps_div_atol = num_grid%get_asFloat ('eps_div_atol', defaultVal=1.0e-4_pReal)
|
||||
num%eps_div_rtol = num_grid%get_asFloat ('eps_div_rtol', defaultVal=5.0e-4_pReal)
|
||||
num%eps_stress_atol = num_grid%get_asFloat ('eps_stress_atol',defaultVal=1.0e3_pReal)
|
||||
num%eps_stress_rtol = num_grid%get_asFloat ('eps_stress_rtol',defaultVal=0.01_pReal)
|
||||
num%eps_stress_rtol = num_grid%get_asFloat ('eps_stress_rtol',defaultVal=1.0e-3_pReal)
|
||||
num%itmin = num_grid%get_asInt ('itmin',defaultVal=1)
|
||||
num%itmax = num_grid%get_asInt ('itmax',defaultVal=250)
|
||||
|
||||
|
@ -158,7 +155,7 @@ subroutine grid_mech_spectral_basic_init
|
|||
call SNESCreate(PETSC_COMM_WORLD,snes,ierr); CHKERRQ(ierr)
|
||||
call SNESSetOptionsPrefix(snes,'mech_',ierr);CHKERRQ(ierr)
|
||||
localK = 0
|
||||
localK(worldrank+1) = grid3
|
||||
localK(worldrank) = grid3
|
||||
call MPI_Allreduce(MPI_IN_PLACE,localK,worldsize,MPI_INTEGER,MPI_SUM,PETSC_COMM_WORLD,ierr)
|
||||
call DMDACreate3d(PETSC_COMM_WORLD, &
|
||||
DM_BOUNDARY_NONE, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE, & ! cut off stencil at boundary
|
||||
|
@ -202,8 +199,8 @@ subroutine grid_mech_spectral_basic_init
|
|||
endif restartRead
|
||||
|
||||
materialpoint_F0 = reshape(F_lastInc, [3,3,1,product(grid(1:2))*grid3]) ! set starting condition for materialpoint_stressAndItsTangent
|
||||
call Utilities_updateCoords(reshape(F,shape(F_lastInc)))
|
||||
call Utilities_constitutiveResponse(P,temp33_Real,C_volAvg,C_minMaxAvg, & ! stress field, stress avg, global average of stiffness and (min+max)/2
|
||||
call utilities_updateCoords(reshape(F,shape(F_lastInc)))
|
||||
call utilities_constitutiveResponse(P,temp33_Real,C_volAvg,C_minMaxAvg, & ! stress field, stress avg, global average of stiffness and (min+max)/2
|
||||
reshape(F,shape(F_lastInc)), & ! target F
|
||||
0.0_pReal) ! time increment
|
||||
call DMDAVecRestoreArrayF90(da,solution_vec,F,ierr); CHKERRQ(ierr) ! deassociate pointer
|
||||
|
@ -231,19 +228,12 @@ end subroutine grid_mech_spectral_basic_init
|
|||
!--------------------------------------------------------------------------------------------------
|
||||
!> @brief solution for the basic scheme with internal iterations
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
function grid_mech_spectral_basic_solution(incInfoIn,timeinc,timeinc_old,stress_BC,rotation_BC) result(solution)
|
||||
function grid_mech_spectral_basic_solution(incInfoIn) result(solution)
|
||||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! input data for solution
|
||||
character(len=*), intent(in) :: &
|
||||
incInfoIn
|
||||
real(pReal), intent(in) :: &
|
||||
timeinc, & !< time increment of current solution
|
||||
timeinc_old !< time increment of last successful increment
|
||||
type(tBoundaryCondition), intent(in) :: &
|
||||
stress_BC
|
||||
type(rotation), intent(in) :: &
|
||||
rotation_BC
|
||||
type(tSolutionState) :: &
|
||||
solution
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
|
@ -255,17 +245,9 @@ function grid_mech_spectral_basic_solution(incInfoIn,timeinc,timeinc_old,stress_
|
|||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! update stiffness (and gamma operator)
|
||||
S = utilities_maskedCompliance(rotation_BC,stress_BC%maskLogical,C_volAvg)
|
||||
S = utilities_maskedCompliance(params%rotation_BC,params%stress_mask,C_volAvg)
|
||||
if(num%update_gamma) call utilities_updateGamma(C_minMaxAvg)
|
||||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! set module wide available data
|
||||
params%stress_mask = stress_BC%maskFloat
|
||||
params%stress_BC = stress_BC%values
|
||||
params%rotation_BC = rotation_BC
|
||||
params%timeinc = timeinc
|
||||
params%timeincOld = timeinc_old
|
||||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! solve BVP
|
||||
call SNESsolve(snes,PETSC_NULL_VEC,solution_vec,ierr); CHKERRQ(ierr)
|
||||
|
@ -303,7 +285,14 @@ subroutine grid_mech_spectral_basic_forward(cutBack,guess,timeinc,timeinc_old,lo
|
|||
type(rotation), intent(in) :: &
|
||||
rotation_BC
|
||||
PetscErrorCode :: ierr
|
||||
PetscScalar, dimension(:,:,:,:), pointer :: F
|
||||
PetscScalar, pointer, dimension(:,:,:,:) :: F
|
||||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! set module wide available data
|
||||
params%stress_mask = stress_BC%mask
|
||||
params%rotation_BC = rotation_BC
|
||||
params%timeinc = timeinc
|
||||
params%timeincOld = timeinc_old
|
||||
|
||||
call DMDAVecGetArrayF90(da,solution_vec,F,ierr); CHKERRQ(ierr)
|
||||
|
||||
|
@ -314,20 +303,20 @@ subroutine grid_mech_spectral_basic_forward(cutBack,guess,timeinc,timeinc_old,lo
|
|||
C_volAvgLastInc = C_volAvg
|
||||
C_minMaxAvgLastInc = C_minMaxAvg
|
||||
|
||||
F_aimDot = merge(stress_BC%maskFloat*(F_aim-F_aim_lastInc)/timeinc_old, 0.0_pReal, guess)
|
||||
F_aimDot = merge(merge((F_aim-F_aim_lastInc)/timeinc_old,0.0_pReal,stress_BC%mask), 0.0_pReal, guess)
|
||||
F_aim_lastInc = F_aim
|
||||
|
||||
!-----------------------------------------------------------------------------------------------
|
||||
! calculate rate for aim
|
||||
if (deformation_BC%myType=='l') then ! calculate F_aimDot from given L and current F
|
||||
F_aimDot = &
|
||||
F_aimDot + deformation_BC%maskFloat * matmul(deformation_BC%values, F_aim_lastInc)
|
||||
F_aimDot = F_aimDot &
|
||||
+ merge(matmul(deformation_BC%values, F_aim_lastInc),.0_pReal,deformation_BC%mask)
|
||||
elseif(deformation_BC%myType=='fdot') then ! F_aimDot is prescribed
|
||||
F_aimDot = &
|
||||
F_aimDot + deformation_BC%maskFloat * deformation_BC%values
|
||||
F_aimDot = F_aimDot &
|
||||
+ merge(deformation_BC%values,.0_pReal,deformation_BC%mask)
|
||||
elseif (deformation_BC%myType=='f') then ! aim at end of load case is prescribed
|
||||
F_aimDot = &
|
||||
F_aimDot + deformation_BC%maskFloat * (deformation_BC%values - F_aim_lastInc)/loadCaseTime
|
||||
F_aimDot = F_aimDot &
|
||||
+ merge((deformation_BC%values - F_aim_lastInc)/loadCaseTime,.0_pReal,deformation_BC%mask)
|
||||
endif
|
||||
|
||||
Fdot = utilities_calculateRate(guess, &
|
||||
|
@ -341,7 +330,13 @@ subroutine grid_mech_spectral_basic_forward(cutBack,guess,timeinc,timeinc_old,lo
|
|||
!--------------------------------------------------------------------------------------------------
|
||||
! update average and local deformation gradients
|
||||
F_aim = F_aim_lastInc + F_aimDot * timeinc
|
||||
F = reshape(Utilities_forwardField(timeinc,F_lastInc,Fdot, & ! estimate of F at end of time+timeinc that matches rotated F_aim on average
|
||||
if (stress_BC%myType=='p') then
|
||||
P_aim = P_aim + merge((stress_BC%values - P_aim)/loadCaseTime*timeinc,.0_pReal,stress_BC%mask)
|
||||
elseif (stress_BC%myType=='pdot') then !UNTESTED
|
||||
P_aim = P_aim + merge(stress_BC%values*timeinc,.0_pReal,stress_BC%mask)
|
||||
endif
|
||||
|
||||
F = reshape(utilities_forwardField(timeinc,F_lastInc,Fdot, & ! estimate of F at end of time+timeinc that matches rotated F_aim on average
|
||||
rotation_BC%rotate(F_aim,active=.true.)),[9,grid(1),grid(2),grid3])
|
||||
call DMDAVecRestoreArrayF90(da,solution_vec,F,ierr); CHKERRQ(ierr)
|
||||
|
||||
|
@ -375,7 +370,7 @@ subroutine grid_mech_spectral_basic_restartWrite
|
|||
|
||||
call DMDAVecGetArrayF90(da,solution_vec,F,ierr); CHKERRQ(ierr)
|
||||
|
||||
print'(a)', ' writing solver data required for restart to file'; flush(IO_STDOUT)
|
||||
print*, 'writing solver data required for restart to file'; flush(IO_STDOUT)
|
||||
|
||||
write(fileName,'(a,a,i0,a)') trim(getSolverJobName()),'_',worldrank,'.hdf5'
|
||||
fileHandle = HDF5_openFile(fileName,'w')
|
||||
|
@ -469,6 +464,7 @@ subroutine formResidual(in, F, &
|
|||
call SNESGetIterationNumber(snes,PETScIter,ierr); CHKERRQ(ierr)
|
||||
|
||||
if (nfuncs == 0 .and. PETScIter == 0) totalIter = -1 ! new increment
|
||||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! begin of new iteration
|
||||
newIteration: if (totalIter <= PETScIter) then
|
||||
|
@ -491,16 +487,16 @@ subroutine formResidual(in, F, &
|
|||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! stress BC handling
|
||||
deltaF_aim = math_mul3333xx33(S, P_av - params%stress_BC)
|
||||
deltaF_aim = math_mul3333xx33(S, P_av - P_aim) ! S = 0.0 for no bc
|
||||
F_aim = F_aim - deltaF_aim
|
||||
err_BC = maxval(abs(params%stress_mask * (P_av - params%stress_BC))) ! mask = 0.0 when no stress bc
|
||||
err_BC = maxval(abs(merge(P_av - P_aim,.0_pReal,params%stress_mask)))
|
||||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! updated deformation gradient using fix point algorithm of basic scheme
|
||||
tensorField_real = 0.0_pReal
|
||||
tensorField_real(1:3,1:3,1:grid(1),1:grid(2),1:grid3) = residuum ! store fPK field for subsequent FFT forward transform
|
||||
call utilities_FFTtensorForward ! FFT forward of global "tensorField_real"
|
||||
err_div = Utilities_divergenceRMS() ! divRMS of tensorField_fourier for later use
|
||||
err_div = utilities_divergenceRMS() ! divRMS of tensorField_fourier for later use
|
||||
call utilities_fourierGammaConvolution(params%rotation_BC%rotate(deltaF_aim,active=.true.)) ! convolution of Gamma and tensorField_fourier
|
||||
call utilities_FFTtensorBackward ! FFT backward of global tensorField_fourier
|
||||
|
||||
|
|
|
@ -15,7 +15,6 @@ module grid_mech_spectral_polarisation
|
|||
use DAMASK_interface
|
||||
use HDF5_utilities
|
||||
use math
|
||||
use rotations
|
||||
use spectral_utilities
|
||||
use FEsolving
|
||||
use config
|
||||
|
@ -25,8 +24,6 @@ module grid_mech_spectral_polarisation
|
|||
implicit none
|
||||
private
|
||||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! derived types
|
||||
type(tSolutionParams) :: params
|
||||
|
||||
type :: tNumerics
|
||||
|
@ -48,7 +45,7 @@ module grid_mech_spectral_polarisation
|
|||
|
||||
type(tNumerics) :: num ! numerics parameters. Better name?
|
||||
|
||||
logical, private :: debugRotation
|
||||
logical :: debugRotation
|
||||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! PETSc data
|
||||
|
@ -71,8 +68,8 @@ module grid_mech_spectral_polarisation
|
|||
F_aim = math_I3, & !< current prescribed deformation gradient
|
||||
F_aim_lastInc = math_I3, & !< previous average deformation gradient
|
||||
F_av = 0.0_pReal, & !< average incompatible def grad field
|
||||
P_av = 0.0_pReal !< average 1st Piola--Kirchhoff stress
|
||||
|
||||
P_av = 0.0_pReal, & !< average 1st Piola--Kirchhoff stress
|
||||
P_aim = 0.0_pReal
|
||||
character(len=:), allocatable :: incInfo !< time and increment information
|
||||
real(pReal), dimension(3,3,3,3) :: &
|
||||
C_volAvg = 0.0_pReal, & !< current volume average stiffness
|
||||
|
@ -108,10 +105,6 @@ subroutine grid_mech_spectral_polarisation_init
|
|||
real(pReal), dimension(3,3,grid(1),grid(2),grid3) :: P
|
||||
real(pReal), dimension(3,3) :: &
|
||||
temp33_Real = 0.0_pReal
|
||||
class (tNode), pointer :: &
|
||||
num_grid, &
|
||||
debug_grid
|
||||
|
||||
PetscErrorCode :: ierr
|
||||
PetscScalar, pointer, dimension(:,:,:,:) :: &
|
||||
FandF_tau, & ! overall pointer to solution data
|
||||
|
@ -122,13 +115,16 @@ subroutine grid_mech_spectral_polarisation_init
|
|||
integer :: fileUnit
|
||||
character(len=pStringLen) :: &
|
||||
fileName
|
||||
class (tNode), pointer :: &
|
||||
num_grid, &
|
||||
debug_grid
|
||||
|
||||
print'(/,a)', ' <<<+- grid_mech_spectral_polarisation init -+>>>'; flush(IO_STDOUT)
|
||||
|
||||
print*, 'Shanthraj et al., International Journal of Plasticity 66:31–45, 2015'
|
||||
print*, 'https://doi.org/10.1016/j.ijplas.2014.02.006'
|
||||
|
||||
!------------------------------------------------------------------------------------------------
|
||||
!-------------------------------------------------------------------------------------------------
|
||||
! debugging options
|
||||
debug_grid => config_debug%get('grid',defaultVal=emptyList)
|
||||
debugRotation = debug_grid%contains('rotation')
|
||||
|
@ -136,13 +132,14 @@ subroutine grid_mech_spectral_polarisation_init
|
|||
!-------------------------------------------------------------------------------------------------
|
||||
! read numerical parameters and do sanity checks
|
||||
num_grid => config_numerics%get('grid',defaultVal=emptyDict)
|
||||
|
||||
num%update_gamma = num_grid%get_asBool ('update_gamma', defaultVal=.false.)
|
||||
num%eps_div_atol = num_grid%get_asFloat('eps_div_atol', defaultVal=1.0e-4_pReal)
|
||||
num%eps_div_rtol = num_grid%get_asFloat('eps_div_rtol', defaultVal=5.0e-4_pReal)
|
||||
num%eps_curl_atol = num_grid%get_asFloat('eps_curl_atol', defaultVal=1.0e-10_pReal)
|
||||
num%eps_curl_rtol = num_grid%get_asFloat('eps_curl_rtol', defaultVal=5.0e-4_pReal)
|
||||
num%eps_stress_atol = num_grid%get_asFloat('eps_stress_atol',defaultVal=1.0e3_pReal)
|
||||
num%eps_stress_rtol = num_grid%get_asFloat ('eps_stress_rtol', defaultVal=0.01_pReal)
|
||||
num%eps_stress_rtol = num_grid%get_asFloat('eps_stress_rtol',defaultVal=1.0e-3_pReal)
|
||||
num%itmin = num_grid%get_asInt ('itmin', defaultVal=1)
|
||||
num%itmax = num_grid%get_asInt ('itmax', defaultVal=250)
|
||||
num%alpha = num_grid%get_asFloat('alpha', defaultVal=1.0_pReal)
|
||||
|
@ -228,8 +225,8 @@ subroutine grid_mech_spectral_polarisation_init
|
|||
endif restartRead
|
||||
|
||||
materialpoint_F0 = reshape(F_lastInc, [3,3,1,product(grid(1:2))*grid3]) ! set starting condition for materialpoint_stressAndItsTangent
|
||||
call Utilities_updateCoords(reshape(F,shape(F_lastInc)))
|
||||
call Utilities_constitutiveResponse(P,temp33_Real,C_volAvg,C_minMaxAvg, & ! stress field, stress avg, global average of stiffness and (min+max)/2
|
||||
call utilities_updateCoords(reshape(F,shape(F_lastInc)))
|
||||
call utilities_constitutiveResponse(P,temp33_Real,C_volAvg,C_minMaxAvg, & ! stress field, stress avg, global average of stiffness and (min+max)/2
|
||||
reshape(F,shape(F_lastInc)), & ! target F
|
||||
0.0_pReal) ! time increment
|
||||
call DMDAVecRestoreArrayF90(da,solution_vec,FandF_tau,ierr); CHKERRQ(ierr) ! deassociate pointer
|
||||
|
@ -259,19 +256,12 @@ end subroutine grid_mech_spectral_polarisation_init
|
|||
!--------------------------------------------------------------------------------------------------
|
||||
!> @brief solution for the Polarisation scheme with internal iterations
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
function grid_mech_spectral_polarisation_solution(incInfoIn,timeinc,timeinc_old,stress_BC,rotation_BC) result(solution)
|
||||
function grid_mech_spectral_polarisation_solution(incInfoIn) result(solution)
|
||||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! input data for solution
|
||||
character(len=*), intent(in) :: &
|
||||
incInfoIn
|
||||
real(pReal), intent(in) :: &
|
||||
timeinc, & !< time increment of current solution
|
||||
timeinc_old !< time increment of last successful increment
|
||||
type(tBoundaryCondition), intent(in) :: &
|
||||
stress_BC
|
||||
type(rotation), intent(in) :: &
|
||||
rotation_BC
|
||||
type(tSolutionState) :: &
|
||||
solution
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
|
@ -283,21 +273,13 @@ function grid_mech_spectral_polarisation_solution(incInfoIn,timeinc,timeinc_old,
|
|||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! update stiffness (and gamma operator)
|
||||
S = utilities_maskedCompliance(rotation_BC,stress_BC%maskLogical,C_volAvg)
|
||||
S = utilities_maskedCompliance(params%rotation_BC,params%stress_mask,C_volAvg)
|
||||
if(num%update_gamma) then
|
||||
call utilities_updateGamma(C_minMaxAvg)
|
||||
C_scale = C_minMaxAvg
|
||||
S_scale = math_invSym3333(C_minMaxAvg)
|
||||
endif
|
||||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! set module wide available data
|
||||
params%stress_mask = stress_BC%maskFloat
|
||||
params%stress_BC = stress_BC%values
|
||||
params%rotation_BC = rotation_BC
|
||||
params%timeinc = timeinc
|
||||
params%timeincOld = timeinc_old
|
||||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! solve BVP
|
||||
call SNESsolve(snes,PETSC_NULL_VEC,solution_vec,ierr); CHKERRQ(ierr)
|
||||
|
@ -335,10 +317,17 @@ subroutine grid_mech_spectral_polarisation_forward(cutBack,guess,timeinc,timeinc
|
|||
type(rotation), intent(in) :: &
|
||||
rotation_BC
|
||||
PetscErrorCode :: ierr
|
||||
PetscScalar, dimension(:,:,:,:), pointer :: FandF_tau, F, F_tau
|
||||
PetscScalar, pointer, dimension(:,:,:,:) :: FandF_tau, F, F_tau
|
||||
integer :: i, j, k
|
||||
real(pReal), dimension(3,3) :: F_lambda33
|
||||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! set module wide available data
|
||||
params%stress_mask = stress_BC%mask
|
||||
params%rotation_BC = rotation_BC
|
||||
params%timeinc = timeinc
|
||||
params%timeincOld = timeinc_old
|
||||
|
||||
call DMDAVecGetArrayF90(da,solution_vec,FandF_tau,ierr); CHKERRQ(ierr)
|
||||
F => FandF_tau(0: 8,:,:,:)
|
||||
F_tau => FandF_tau(9:17,:,:,:)
|
||||
|
@ -350,20 +339,20 @@ subroutine grid_mech_spectral_polarisation_forward(cutBack,guess,timeinc,timeinc
|
|||
C_volAvgLastInc = C_volAvg
|
||||
C_minMaxAvgLastInc = C_minMaxAvg
|
||||
|
||||
F_aimDot = merge(stress_BC%maskFloat*(F_aim-F_aim_lastInc)/timeinc_old, 0.0_pReal, guess)
|
||||
F_aimDot = merge(merge((F_aim-F_aim_lastInc)/timeinc_old,0.0_pReal,stress_BC%mask), 0.0_pReal, guess)
|
||||
F_aim_lastInc = F_aim
|
||||
|
||||
!-----------------------------------------------------------------------------------------------
|
||||
! calculate rate for aim
|
||||
if (deformation_BC%myType=='l') then ! calculate F_aimDot from given L and current F
|
||||
F_aimDot = &
|
||||
F_aimDot + deformation_BC%maskFloat * matmul(deformation_BC%values, F_aim_lastInc)
|
||||
F_aimDot = F_aimDot &
|
||||
+ merge(matmul(deformation_BC%values, F_aim_lastInc),.0_pReal,deformation_BC%mask)
|
||||
elseif(deformation_BC%myType=='fdot') then ! F_aimDot is prescribed
|
||||
F_aimDot = &
|
||||
F_aimDot + deformation_BC%maskFloat * deformation_BC%values
|
||||
F_aimDot = F_aimDot &
|
||||
+ merge(deformation_BC%values,.0_pReal,deformation_BC%mask)
|
||||
elseif (deformation_BC%myType=='f') then ! aim at end of load case is prescribed
|
||||
F_aimDot = &
|
||||
F_aimDot + deformation_BC%maskFloat * (deformation_BC%values - F_aim_lastInc)/loadCaseTime
|
||||
F_aimDot = F_aimDot &
|
||||
+ merge((deformation_BC%values - F_aim_lastInc)/loadCaseTime,.0_pReal,deformation_BC%mask)
|
||||
endif
|
||||
|
||||
Fdot = utilities_calculateRate(guess, &
|
||||
|
@ -381,6 +370,12 @@ subroutine grid_mech_spectral_polarisation_forward(cutBack,guess,timeinc,timeinc
|
|||
!--------------------------------------------------------------------------------------------------
|
||||
! update average and local deformation gradients
|
||||
F_aim = F_aim_lastInc + F_aimDot * timeinc
|
||||
if (stress_BC%myType=='p') then
|
||||
P_aim = P_aim + merge((stress_BC%values - P_aim)/loadCaseTime*timeinc,.0_pReal,stress_BC%mask)
|
||||
elseif (stress_BC%myType=='pdot') then !UNTESTED
|
||||
P_aim = P_aim + merge(stress_BC%values*timeinc,.0_pReal,stress_BC%mask)
|
||||
endif
|
||||
|
||||
F = reshape(utilities_forwardField(timeinc,F_lastInc,Fdot, & ! estimate of F at end of time+timeinc that matches rotated F_aim on average
|
||||
rotation_BC%rotate(F_aim,active=.true.)),&
|
||||
[9,grid(1),grid(2),grid3])
|
||||
|
@ -595,15 +590,15 @@ subroutine formResidual(in, FandF_tau, &
|
|||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! stress BC handling
|
||||
F_aim = F_aim - math_mul3333xx33(S, ((P_av - params%stress_BC))) ! S = 0.0 for no bc
|
||||
err_BC = maxval(abs((1.0_pReal-params%stress_mask) * math_mul3333xx33(C_scale,F_aim &
|
||||
-params%rotation_BC%rotate(F_av)) + &
|
||||
params%stress_mask * (P_av-params%stress_BC))) ! mask = 0.0 for no bc
|
||||
F_aim = F_aim - math_mul3333xx33(S, P_av - P_aim) ! S = 0.0 for no bc
|
||||
err_BC = maxval(abs(merge(P_av-P_aim, &
|
||||
math_mul3333xx33(C_scale,F_aim-params%rotation_BC%rotate(F_av)),&
|
||||
params%stress_mask)))
|
||||
! calculate divergence
|
||||
tensorField_real = 0.0_pReal
|
||||
tensorField_real(1:3,1:3,1:grid(1),1:grid(2),1:grid3) = residual_F !< stress field in disguise
|
||||
call utilities_FFTtensorForward
|
||||
err_div = Utilities_divergenceRMS() !< root mean squared error in divergence of stress
|
||||
err_div = utilities_divergenceRMS() !< root mean squared error in divergence of stress
|
||||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! constructing residual
|
||||
|
@ -622,7 +617,7 @@ subroutine formResidual(in, FandF_tau, &
|
|||
tensorField_real = 0.0_pReal
|
||||
tensorField_real(1:3,1:3,1:grid(1),1:grid(2),1:grid3) = F
|
||||
call utilities_FFTtensorForward
|
||||
err_curl = Utilities_curlRMS()
|
||||
err_curl = utilities_curlRMS()
|
||||
|
||||
end subroutine formResidual
|
||||
|
||||
|
|
|
@ -148,11 +148,10 @@ end subroutine grid_thermal_spectral_init
|
|||
!--------------------------------------------------------------------------------------------------
|
||||
!> @brief solution for the spectral thermal scheme with internal iterations
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
function grid_thermal_spectral_solution(timeinc,timeinc_old) result(solution)
|
||||
function grid_thermal_spectral_solution(timeinc) result(solution)
|
||||
|
||||
real(pReal), intent(in) :: &
|
||||
timeinc, & !< increment in time for current solution
|
||||
timeinc_old !< increment in time of last increment
|
||||
timeinc !< increment in time for current solution
|
||||
integer :: i, j, k, cell
|
||||
type(tSolutionState) :: solution
|
||||
PetscInt :: devNull
|
||||
|
@ -166,7 +165,6 @@ function grid_thermal_spectral_solution(timeinc,timeinc_old) result(solution)
|
|||
!--------------------------------------------------------------------------------------------------
|
||||
! set module wide availabe data
|
||||
params%timeinc = timeinc
|
||||
params%timeincOld = timeinc_old
|
||||
|
||||
call SNESSolve(thermal_snes,PETSC_NULL_VEC,solution_vec,ierr); CHKERRQ(ierr)
|
||||
call SNESGetConvergedReason(thermal_snes,reason,ierr); CHKERRQ(ierr)
|
||||
|
|
|
@ -47,15 +47,15 @@ module spectral_utilities
|
|||
complex(C_DOUBLE_COMPLEX),public, dimension(:,:,:,:), pointer :: vectorField_fourier !< vector field fourier representation for fftw
|
||||
real(C_DOUBLE), public, dimension(:,:,:), pointer :: scalarField_real !< scalar field real representation for fftw
|
||||
complex(C_DOUBLE_COMPLEX),public, dimension(:,:,:), pointer :: scalarField_fourier !< scalar field fourier representation for fftw
|
||||
complex(pReal), private, dimension(:,:,:,:,:,:,:), allocatable :: gamma_hat !< gamma operator (field) for spectral method
|
||||
complex(pReal), private, dimension(:,:,:,:), allocatable :: xi1st !< wave vector field for first derivatives
|
||||
complex(pReal), private, dimension(:,:,:,:), allocatable :: xi2nd !< wave vector field for second derivatives
|
||||
real(pReal), private, dimension(3,3,3,3) :: C_ref !< mechanic reference stiffness
|
||||
complex(pReal), dimension(:,:,:,:,:,:,:), allocatable :: gamma_hat !< gamma operator (field) for spectral method
|
||||
complex(pReal), dimension(:,:,:,:), allocatable :: xi1st !< wave vector field for first derivatives
|
||||
complex(pReal), dimension(:,:,:,:), allocatable :: xi2nd !< wave vector field for second derivatives
|
||||
real(pReal), dimension(3,3,3,3) :: C_ref !< mechanic reference stiffness
|
||||
|
||||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! plans for FFTW
|
||||
type(C_PTR), private :: &
|
||||
type(C_PTR) :: &
|
||||
planTensorForth, & !< FFTW MPI plan P(x) to P(k)
|
||||
planTensorBack, & !< FFTW MPI plan F(k) to F(x)
|
||||
planVectorForth, & !< FFTW MPI plan v(x) to v(k)
|
||||
|
@ -65,7 +65,7 @@ module spectral_utilities
|
|||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! variables controlling debugging
|
||||
logical, private :: &
|
||||
logical :: &
|
||||
debugGeneral, & !< general debugging of spectral solver
|
||||
debugRotation, & !< also printing out results in lab frame
|
||||
debugPETSc !< use some in debug defined options for more verbose PETSc solution
|
||||
|
@ -82,9 +82,8 @@ module spectral_utilities
|
|||
end type tSolutionState
|
||||
|
||||
type, public :: tBoundaryCondition !< set of parameters defining a boundary condition
|
||||
real(pReal), dimension(3,3) :: values = 0.0_pReal, &
|
||||
maskFloat = 0.0_pReal
|
||||
logical, dimension(3,3) :: maskLogical = .false.
|
||||
real(pReal), dimension(3,3) :: values = 0.0_pReal
|
||||
logical, dimension(3,3) :: mask = .false.
|
||||
character(len=pStringLen) :: myType = 'None'
|
||||
end type tBoundaryCondition
|
||||
|
||||
|
@ -101,21 +100,21 @@ module spectral_utilities
|
|||
integer(kind(FIELD_UNDEFINED_ID)), allocatable :: ID(:)
|
||||
end type tLoadCase
|
||||
|
||||
type, public :: tSolutionParams !< @todo use here the type definition for a full loadcase
|
||||
real(pReal), dimension(3,3) :: stress_mask, stress_BC
|
||||
type, public :: tSolutionParams
|
||||
real(pReal), dimension(3,3) :: stress_BC
|
||||
logical, dimension(3,3) :: stress_mask
|
||||
type(rotation) :: rotation_BC
|
||||
real(pReal) :: timeinc
|
||||
real(pReal) :: timeincOld
|
||||
real(pReal) :: timeinc, timeincOld
|
||||
end type tSolutionParams
|
||||
|
||||
type, private :: tNumerics
|
||||
type :: tNumerics
|
||||
integer :: &
|
||||
divergence_correction !< scale divergence/curl calculation: [0: no correction, 1: size scaled to 1, 2: size scaled to Npoints]
|
||||
logical :: &
|
||||
memory_efficient !< calculate gamma operator on the fly
|
||||
end type tNumerics
|
||||
|
||||
type(tNumerics), private :: num ! numerics parameters. Better name?
|
||||
type(tNumerics) :: num ! numerics parameters. Better name?
|
||||
|
||||
enum, bind(c); enumerator :: &
|
||||
DERIVATIVE_CONTINUOUS_ID, &
|
||||
|
@ -827,7 +826,7 @@ subroutine utilities_constitutiveResponse(P,P_av,C_volAvg,C_minmaxAvg,&
|
|||
|
||||
materialpoint_F = reshape(F,[3,3,1,product(grid(1:2))*grid3]) ! set materialpoint target F to estimated field
|
||||
|
||||
call materialpoint_stressAndItsTangent(.true.,timeinc) ! calculate P field
|
||||
call materialpoint_stressAndItsTangent(timeinc) ! calculate P field
|
||||
|
||||
P = reshape(materialpoint_P, [3,3,grid(1),grid(2),grid3])
|
||||
P_av = sum(sum(sum(P,dim=5),dim=4),dim=3) * wgt ! average of P
|
||||
|
|
|
@ -204,17 +204,14 @@ end subroutine homogenization_init
|
|||
!--------------------------------------------------------------------------------------------------
|
||||
!> @brief parallelized calculation of stress and corresponding tangent at material points
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
subroutine materialpoint_stressAndItsTangent(updateJaco,dt)
|
||||
subroutine materialpoint_stressAndItsTangent(dt)
|
||||
|
||||
real(pReal), intent(in) :: dt !< time increment
|
||||
logical, intent(in) :: updateJaco !< initiating Jacobian update
|
||||
integer :: &
|
||||
NiterationHomog, &
|
||||
NiterationMPstate, &
|
||||
g, & !< grain number
|
||||
i, & !< integration point number
|
||||
e, & !< element number
|
||||
mySource, &
|
||||
myNgrains
|
||||
real(pReal), dimension(discretization_nIP,discretization_nElem) :: &
|
||||
subFrac, &
|
||||
|
@ -225,40 +222,13 @@ subroutine materialpoint_stressAndItsTangent(updateJaco,dt)
|
|||
logical, dimension(2,discretization_nIP,discretization_nElem) :: &
|
||||
doneAndHappy
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
if (debugHomog%basic) then
|
||||
print'(/a,i5,1x,i2)', ' << HOMOG >> Material Point start at el ip ', debugHomog%element, debugHomog%ip
|
||||
|
||||
print'(a,/,3(12x,3(f14.9,1x)/))', ' << HOMOG >> F0', &
|
||||
transpose(materialpoint_F0(1:3,1:3,debugHomog%ip,debugHomog%element))
|
||||
print'(a,/,3(12x,3(f14.9,1x)/))', ' << HOMOG >> F', &
|
||||
transpose(materialpoint_F(1:3,1:3,debugHomog%ip,debugHomog%element))
|
||||
endif
|
||||
#endif
|
||||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! initialize restoration points
|
||||
do e = FEsolving_execElem(1),FEsolving_execElem(2)
|
||||
myNgrains = homogenization_Ngrains(material_homogenizationAt(e))
|
||||
do i = FEsolving_execIP(1),FEsolving_execIP(2);
|
||||
do g = 1,myNgrains
|
||||
|
||||
plasticState (material_phaseAt(g,e))%partionedState0(:,material_phasememberAt(g,i,e)) = &
|
||||
plasticState (material_phaseAt(g,e))%state0( :,material_phasememberAt(g,i,e))
|
||||
do mySource = 1, phase_Nsources(material_phaseAt(g,e))
|
||||
sourceState(material_phaseAt(g,e))%p(mySource)%partionedState0(:,material_phasememberAt(g,i,e)) = &
|
||||
sourceState(material_phaseAt(g,e))%p(mySource)%state0( :,material_phasememberAt(g,i,e))
|
||||
enddo
|
||||
|
||||
crystallite_partionedFp0(1:3,1:3,g,i,e) = crystallite_Fp0(1:3,1:3,g,i,e)
|
||||
crystallite_partionedLp0(1:3,1:3,g,i,e) = crystallite_Lp0(1:3,1:3,g,i,e)
|
||||
crystallite_partionedFi0(1:3,1:3,g,i,e) = crystallite_Fi0(1:3,1:3,g,i,e)
|
||||
crystallite_partionedLi0(1:3,1:3,g,i,e) = crystallite_Li0(1:3,1:3,g,i,e)
|
||||
crystallite_partionedF0(1:3,1:3,g,i,e) = crystallite_F0(1:3,1:3,g,i,e)
|
||||
crystallite_partionedS0(1:3,1:3,g,i,e) = crystallite_S0(1:3,1:3,g,i,e)
|
||||
|
||||
enddo
|
||||
call crystallite_initializeRestorationPoints(i,e)
|
||||
|
||||
subFrac(i,e) = 0.0_pReal
|
||||
converged(i,e) = .false. ! pretend failed step ...
|
||||
|
@ -285,44 +255,19 @@ subroutine materialpoint_stressAndItsTangent(updateJaco,dt)
|
|||
any(subStep(FEsolving_execIP(1):FEsolving_execIP(2),&
|
||||
FEsolving_execElem(1):FEsolving_execElem(2)) > num%subStepMinHomog))
|
||||
|
||||
!$OMP PARALLEL DO PRIVATE(myNgrains)
|
||||
!$OMP PARALLEL DO
|
||||
elementLooping1: do e = FEsolving_execElem(1),FEsolving_execElem(2)
|
||||
myNgrains = homogenization_Ngrains(material_homogenizationAt(e))
|
||||
IpLooping1: do i = FEsolving_execIP(1),FEsolving_execIP(2)
|
||||
|
||||
if (converged(i,e)) then
|
||||
#ifdef DEBUG
|
||||
if (debugHomog%extensive .and. ((e == debugHomog%element .and. i == debugHomog%ip) &
|
||||
.or. .not. debugHomog%selective)) then
|
||||
print'(a,f12.8,a,f12.8,a,i8,1x,i2/)', ' << HOMOG >> winding forward from ', &
|
||||
subFrac(i,e), ' to current subFrac ', &
|
||||
subFrac(i,e)+subStep(i,e),' in materialpoint_stressAndItsTangent at el ip ',e,i
|
||||
endif
|
||||
#endif
|
||||
|
||||
!---------------------------------------------------------------------------------------------------
|
||||
! calculate new subStep and new subFrac
|
||||
subFrac(i,e) = subFrac(i,e) + subStep(i,e)
|
||||
subStep(i,e) = min(1.0_pReal-subFrac(i,e),num%stepIncreaseHomog*subStep(i,e)) ! introduce flexibility for step increase/acceleration
|
||||
|
||||
steppingNeeded: if (subStep(i,e) > num%subStepMinHomog) then
|
||||
|
||||
! wind forward grain starting point
|
||||
crystallite_partionedF0 (1:3,1:3,1:myNgrains,i,e) = crystallite_partionedF(1:3,1:3,1:myNgrains,i,e)
|
||||
crystallite_partionedFp0(1:3,1:3,1:myNgrains,i,e) = crystallite_Fp (1:3,1:3,1:myNgrains,i,e)
|
||||
crystallite_partionedLp0(1:3,1:3,1:myNgrains,i,e) = crystallite_Lp (1:3,1:3,1:myNgrains,i,e)
|
||||
crystallite_partionedFi0(1:3,1:3,1:myNgrains,i,e) = crystallite_Fi (1:3,1:3,1:myNgrains,i,e)
|
||||
crystallite_partionedLi0(1:3,1:3,1:myNgrains,i,e) = crystallite_Li (1:3,1:3,1:myNgrains,i,e)
|
||||
crystallite_partionedS0 (1:3,1:3,1:myNgrains,i,e) = crystallite_S (1:3,1:3,1:myNgrains,i,e)
|
||||
|
||||
do g = 1,myNgrains
|
||||
plasticState (material_phaseAt(g,e))%partionedState0(:,material_phasememberAt(g,i,e)) = &
|
||||
plasticState (material_phaseAt(g,e))%state (:,material_phasememberAt(g,i,e))
|
||||
do mySource = 1, phase_Nsources(material_phaseAt(g,e))
|
||||
sourceState(material_phaseAt(g,e))%p(mySource)%partionedState0(:,material_phasememberAt(g,i,e)) = &
|
||||
sourceState(material_phaseAt(g,e))%p(mySource)%state (:,material_phasememberAt(g,i,e))
|
||||
enddo
|
||||
enddo
|
||||
call crystallite_windForward(i,e)
|
||||
|
||||
if(homogState(material_homogenizationAt(e))%sizeState > 0) &
|
||||
homogState(material_homogenizationAt(e))%subState0(:,material_homogenizationMemberAt(i,e)) = &
|
||||
|
@ -347,32 +292,8 @@ subroutine materialpoint_stressAndItsTangent(updateJaco,dt)
|
|||
else ! cutback makes sense
|
||||
subStep(i,e) = num%subStepSizeHomog * subStep(i,e) ! crystallite had severe trouble, so do a significant cutback
|
||||
|
||||
#ifdef DEBUG
|
||||
if (debugHomog%extensive .and. ((e == debugHomog%element .and. i == debugHomog%ip) &
|
||||
.or. .not. debugHomog%selective)) then
|
||||
print'(a,f12.8,a,i8,1x,i2/)', &
|
||||
'<< HOMOG >> cutback step in materialpoint_stressAndItsTangent with new subStep: ',&
|
||||
subStep(i,e),' at el ip',e,i
|
||||
endif
|
||||
#endif
|
||||
call crystallite_restore(i,e,subStep(i,e) < 1.0_pReal)
|
||||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! restore
|
||||
if (subStep(i,e) < 1.0_pReal) then ! protect against fake cutback from \Delta t = 2 to 1. Maybe that "trick" is not necessary anymore at all? I.e. start with \Delta t = 1
|
||||
crystallite_Lp(1:3,1:3,1:myNgrains,i,e) = crystallite_partionedLp0(1:3,1:3,1:myNgrains,i,e)
|
||||
crystallite_Li(1:3,1:3,1:myNgrains,i,e) = crystallite_partionedLi0(1:3,1:3,1:myNgrains,i,e)
|
||||
endif ! maybe protecting everything from overwriting (not only L) makes even more sense
|
||||
crystallite_Fp(1:3,1:3,1:myNgrains,i,e) = crystallite_partionedFp0(1:3,1:3,1:myNgrains,i,e)
|
||||
crystallite_Fi(1:3,1:3,1:myNgrains,i,e) = crystallite_partionedFi0(1:3,1:3,1:myNgrains,i,e)
|
||||
crystallite_S (1:3,1:3,1:myNgrains,i,e) = crystallite_partionedS0 (1:3,1:3,1:myNgrains,i,e)
|
||||
do g = 1, myNgrains
|
||||
plasticState (material_phaseAt(g,e))%state( :,material_phasememberAt(g,i,e)) = &
|
||||
plasticState (material_phaseAt(g,e))%partionedState0(:,material_phasememberAt(g,i,e))
|
||||
do mySource = 1, phase_Nsources(material_phaseAt(g,e))
|
||||
sourceState(material_phaseAt(g,e))%p(mySource)%state( :,material_phasememberAt(g,i,e)) = &
|
||||
sourceState(material_phaseAt(g,e))%p(mySource)%partionedState0(:,material_phasememberAt(g,i,e))
|
||||
enddo
|
||||
enddo
|
||||
if(homogState(material_homogenizationAt(e))%sizeState > 0) &
|
||||
homogState(material_homogenizationAt(e))%State( :,material_homogenizationMemberAt(i,e)) = &
|
||||
homogState(material_homogenizationAt(e))%subState0(:,material_homogenizationMemberAt(i,e))
|
||||
|
@ -453,8 +374,6 @@ subroutine materialpoint_stressAndItsTangent(updateJaco,dt)
|
|||
|
||||
enddo cutBackLooping
|
||||
|
||||
if(updateJaco) call crystallite_stressTangent
|
||||
|
||||
if (.not. terminallyIll ) then
|
||||
call crystallite_orientations() ! calculate crystal orientations
|
||||
!$OMP PARALLEL DO
|
||||
|
@ -516,11 +435,16 @@ function updateState(subdt,subF,ip,el)
|
|||
integer, intent(in) :: &
|
||||
ip, & !< integration point
|
||||
el !< element number
|
||||
integer :: c
|
||||
logical, dimension(2) :: updateState
|
||||
real(pReal) :: dPdFs(3,3,3,3,homogenization_Ngrains(material_homogenizationAt(el)))
|
||||
|
||||
updateState = .true.
|
||||
chosenHomogenization: select case(homogenization_type(material_homogenizationAt(el)))
|
||||
case (HOMOGENIZATION_RGC_ID) chosenHomogenization
|
||||
do c=1,homogenization_Ngrains(material_homogenizationAt(el))
|
||||
dPdFs(:,:,:,:,c) = crystallite_stressTangent(c,ip,el)
|
||||
enddo
|
||||
updateState = &
|
||||
updateState .and. &
|
||||
mech_RGC_updateState(crystallite_P(1:3,1:3,1:homogenization_Ngrains(material_homogenizationAt(el)),ip,el), &
|
||||
|
@ -528,7 +452,7 @@ function updateState(subdt,subF,ip,el)
|
|||
crystallite_partionedF0(1:3,1:3,1:homogenization_Ngrains(material_homogenizationAt(el)),ip,el),&
|
||||
subF,&
|
||||
subdt, &
|
||||
crystallite_dPdF(1:3,1:3,1:3,1:3,1:homogenization_Ngrains(material_homogenizationAt(el)),ip,el), &
|
||||
dPdFs, &
|
||||
ip, &
|
||||
el)
|
||||
end select chosenHomogenization
|
||||
|
@ -562,26 +486,35 @@ subroutine averageStressAndItsTangent(ip,el)
|
|||
integer, intent(in) :: &
|
||||
ip, & !< integration point
|
||||
el !< element number
|
||||
integer :: c
|
||||
real(pReal) :: dPdFs(3,3,3,3,homogenization_Ngrains(material_homogenizationAt(el)))
|
||||
|
||||
|
||||
chosenHomogenization: select case(homogenization_type(material_homogenizationAt(el)))
|
||||
case (HOMOGENIZATION_NONE_ID) chosenHomogenization
|
||||
materialpoint_P(1:3,1:3,ip,el) = crystallite_P(1:3,1:3,1,ip,el)
|
||||
materialpoint_dPdF(1:3,1:3,1:3,1:3,ip,el) = crystallite_dPdF(1:3,1:3,1:3,1:3,1,ip,el)
|
||||
materialpoint_dPdF(1:3,1:3,1:3,1:3,ip,el) = crystallite_stressTangent(1,ip,el)
|
||||
|
||||
case (HOMOGENIZATION_ISOSTRAIN_ID) chosenHomogenization
|
||||
do c = 1, homogenization_Ngrains(material_homogenizationAt(el))
|
||||
dPdFs(:,:,:,:,c) = crystallite_stressTangent(c,ip,el)
|
||||
enddo
|
||||
call mech_isostrain_averageStressAndItsTangent(&
|
||||
materialpoint_P(1:3,1:3,ip,el), &
|
||||
materialpoint_dPdF(1:3,1:3,1:3,1:3,ip,el),&
|
||||
crystallite_P(1:3,1:3,1:homogenization_Ngrains(material_homogenizationAt(el)),ip,el), &
|
||||
crystallite_dPdF(1:3,1:3,1:3,1:3,1:homogenization_Ngrains(material_homogenizationAt(el)),ip,el), &
|
||||
dPdFs, &
|
||||
homogenization_typeInstance(material_homogenizationAt(el)))
|
||||
|
||||
case (HOMOGENIZATION_RGC_ID) chosenHomogenization
|
||||
do c = 1, homogenization_Ngrains(material_homogenizationAt(el))
|
||||
dPdFs(:,:,:,:,c) = crystallite_stressTangent(c,ip,el)
|
||||
enddo
|
||||
call mech_RGC_averageStressAndItsTangent(&
|
||||
materialpoint_P(1:3,1:3,ip,el), &
|
||||
materialpoint_dPdF(1:3,1:3,1:3,1:3,ip,el),&
|
||||
crystallite_P(1:3,1:3,1:homogenization_Ngrains(material_homogenizationAt(el)),ip,el), &
|
||||
crystallite_dPdF(1:3,1:3,1:3,1:3,1:homogenization_Ngrains(material_homogenizationAt(el)),ip,el), &
|
||||
dPdFs, &
|
||||
homogenization_typeInstance(material_homogenizationAt(el)))
|
||||
end select chosenHomogenization
|
||||
|
||||
|
|
|
@ -4,20 +4,20 @@
|
|||
!> @author Franz Roters, Max-Planck-Institut für Eisenforschung GmbH
|
||||
!> @author Philip Eisenlohr, Max-Planck-Institut für Eisenforschung GmbH
|
||||
!> @brief Relaxed grain cluster (RGC) homogenization scheme
|
||||
!> Nconstituents is defined as p x q x r (cluster)
|
||||
!> N_constituents is defined as p x q x r (cluster)
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
submodule(homogenization) homogenization_mech_RGC
|
||||
use rotations
|
||||
|
||||
type :: tParameters
|
||||
integer, dimension(:), allocatable :: &
|
||||
Nconstituents
|
||||
N_constituents
|
||||
real(pReal) :: &
|
||||
xiAlpha, &
|
||||
ciAlpha
|
||||
xi_alpha, &
|
||||
c_Alpha
|
||||
real(pReal), dimension(:), allocatable :: &
|
||||
dAlpha, &
|
||||
angles
|
||||
D_alpha, &
|
||||
a_g
|
||||
integer :: &
|
||||
of_debug = 0
|
||||
character(len=pStringLen), allocatable, dimension(:) :: &
|
||||
|
@ -163,20 +163,20 @@ module subroutine mech_RGC_init(num_homogMech)
|
|||
prm%output = homogMech%get_asStrings('output',defaultVal=emptyStringArray)
|
||||
#endif
|
||||
|
||||
prm%Nconstituents = homogMech%get_asInts('cluster_size',requiredSize=3)
|
||||
if (homogenization_Ngrains(h) /= product(prm%Nconstituents)) &
|
||||
prm%N_constituents = homogMech%get_asInts('cluster_size',requiredSize=3)
|
||||
if (homogenization_Ngrains(h) /= product(prm%N_constituents)) &
|
||||
call IO_error(211,ext_msg='clustersize (mech_rgc)')
|
||||
|
||||
prm%xiAlpha = homogMech%get_asFloat('xi_alpha')
|
||||
prm%ciAlpha = homogMech%get_asFloat('c_alpha')
|
||||
prm%xi_alpha = homogMech%get_asFloat('xi_alpha')
|
||||
prm%c_alpha = homogMech%get_asFloat('c_alpha')
|
||||
|
||||
prm%dAlpha = homogMech%get_asFloats('D_alpha', requiredSize=3)
|
||||
prm%angles = homogMech%get_asFloats('a_g', requiredSize=3)
|
||||
prm%D_alpha = homogMech%get_asFloats('D_alpha', requiredSize=3)
|
||||
prm%a_g = homogMech%get_asFloats('a_g', requiredSize=3)
|
||||
|
||||
NofMyHomog = count(material_homogenizationAt == h)
|
||||
nIntFaceTot = 3*( (prm%Nconstituents(1)-1)*prm%Nconstituents(2)*prm%Nconstituents(3) &
|
||||
+ prm%Nconstituents(1)*(prm%Nconstituents(2)-1)*prm%Nconstituents(3) &
|
||||
+ prm%Nconstituents(1)*prm%Nconstituents(2)*(prm%Nconstituents(3)-1))
|
||||
nIntFaceTot = 3*( (prm%N_constituents(1)-1)*prm%N_constituents(2)*prm%N_constituents(3) &
|
||||
+ prm%N_constituents(1)*(prm%N_constituents(2)-1)*prm%N_constituents(3) &
|
||||
+ prm%N_constituents(1)*prm%N_constituents(2)*(prm%N_constituents(3)-1))
|
||||
sizeState = nIntFaceTot &
|
||||
+ size(['avg constitutive work ','average penalty energy'])
|
||||
|
||||
|
@ -197,8 +197,8 @@ module subroutine mech_RGC_init(num_homogMech)
|
|||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! assigning cluster orientations
|
||||
dependentState(homogenization_typeInstance(h))%orientation = spread(eu2om(prm%angles*inRad),3,NofMyHomog)
|
||||
!dst%orientation = spread(eu2om(prm%angles*inRad),3,NofMyHomog) ifort version 18.0.1 crashes (for whatever reason)
|
||||
dependentState(homogenization_typeInstance(h))%orientation = spread(eu2om(prm%a_g*inRad),3,NofMyHomog)
|
||||
!dst%orientation = spread(eu2om(prm%a_g*inRad),3,NofMyHomog) ifort version 18.0.1 crashes (for whatever reason)
|
||||
|
||||
end associate
|
||||
|
||||
|
@ -229,8 +229,8 @@ module subroutine mech_RGC_partitionDeformation(F,avgF,instance,of)
|
|||
!--------------------------------------------------------------------------------------------------
|
||||
! compute the deformation gradient of individual grains due to relaxations
|
||||
F = 0.0_pReal
|
||||
do iGrain = 1,product(prm%Nconstituents)
|
||||
iGrain3 = grain1to3(iGrain,prm%Nconstituents)
|
||||
do iGrain = 1,product(prm%N_constituents)
|
||||
iGrain3 = grain1to3(iGrain,prm%N_constituents)
|
||||
do iFace = 1,6
|
||||
intFace = getInterface(iFace,iGrain3) ! identifying 6 interfaces of each grain
|
||||
aVect = relaxationVector(intFace,instance,of) ! get the relaxation vectors for each interface from global relaxation vector array
|
||||
|
@ -290,7 +290,7 @@ module procedure mech_RGC_updateState
|
|||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! get the dimension of the cluster (grains and interfaces)
|
||||
nGDim = prm%Nconstituents
|
||||
nGDim = prm%N_constituents
|
||||
nGrain = product(nGDim)
|
||||
nIntFaceTot = (nGDim(1)-1)*nGDim(2)*nGDim(3) &
|
||||
+ nGDim(1)*(nGDim(2)-1)*nGDim(3) &
|
||||
|
@ -324,12 +324,12 @@ module procedure mech_RGC_updateState
|
|||
!------------------------------------------------------------------------------------------------
|
||||
! computing the residual stress from the balance of traction at all (interior) interfaces
|
||||
do iNum = 1,nIntFaceTot
|
||||
faceID = interface1to4(iNum,param(instance)%Nconstituents) ! identifying the interface ID in local coordinate system (4-dimensional index)
|
||||
faceID = interface1to4(iNum,param(instance)%N_constituents) ! identifying the interface ID in local coordinate system (4-dimensional index)
|
||||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! identify the left/bottom/back grain (-|N)
|
||||
iGr3N = faceID(2:4) ! identifying the grain ID in local coordinate system (3-dimensional index)
|
||||
iGrN = grain3to1(iGr3N,param(instance)%Nconstituents) ! translate the local grain ID into global coordinate system (1-dimensional index)
|
||||
iGrN = grain3to1(iGr3N,param(instance)%N_constituents) ! translate the local grain ID into global coordinate system (1-dimensional index)
|
||||
intFaceN = getInterface(2*faceID(1),iGr3N)
|
||||
normN = interfaceNormal(intFaceN,instance,of)
|
||||
|
||||
|
@ -337,7 +337,7 @@ module procedure mech_RGC_updateState
|
|||
! identify the right/up/front grain (+|P)
|
||||
iGr3P = iGr3N
|
||||
iGr3P(faceID(1)) = iGr3N(faceID(1))+1 ! identifying the grain ID in local coordinate system (3-dimensional index)
|
||||
iGrP = grain3to1(iGr3P,param(instance)%Nconstituents) ! translate the local grain ID into global coordinate system (1-dimensional index)
|
||||
iGrP = grain3to1(iGr3P,param(instance)%N_constituents) ! translate the local grain ID into global coordinate system (1-dimensional index)
|
||||
intFaceP = getInterface(2*faceID(1)-1,iGr3P)
|
||||
normP = interfaceNormal(intFaceP,instance,of)
|
||||
|
||||
|
@ -393,7 +393,7 @@ module procedure mech_RGC_updateState
|
|||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! compute/update the state for postResult, i.e., all energy densities computed by time-integration
|
||||
do iGrain = 1,product(prm%Nconstituents)
|
||||
do iGrain = 1,product(prm%N_constituents)
|
||||
do i = 1,3;do j = 1,3
|
||||
stt%work(of) = stt%work(of) &
|
||||
+ P(i,j,iGrain)*(F(i,j,iGrain) - F0(i,j,iGrain))/real(nGrain,pReal)
|
||||
|
@ -450,18 +450,18 @@ module procedure mech_RGC_updateState
|
|||
! ... of the constitutive stress tangent, assembled from dPdF or material constitutive model "smatrix"
|
||||
allocate(smatrix(3*nIntFaceTot,3*nIntFaceTot), source=0.0_pReal)
|
||||
do iNum = 1,nIntFaceTot
|
||||
faceID = interface1to4(iNum,param(instance)%Nconstituents) ! assembling of local dPdF into global Jacobian matrix
|
||||
faceID = interface1to4(iNum,param(instance)%N_constituents) ! assembling of local dPdF into global Jacobian matrix
|
||||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! identify the left/bottom/back grain (-|N)
|
||||
iGr3N = faceID(2:4) ! identifying the grain ID in local coordinate sytem
|
||||
iGrN = grain3to1(iGr3N,param(instance)%Nconstituents) ! translate into global grain ID
|
||||
iGrN = grain3to1(iGr3N,param(instance)%N_constituents) ! translate into global grain ID
|
||||
intFaceN = getInterface(2*faceID(1),iGr3N) ! identifying the connecting interface in local coordinate system
|
||||
normN = interfaceNormal(intFaceN,instance,of)
|
||||
do iFace = 1,6
|
||||
intFaceN = getInterface(iFace,iGr3N) ! identifying all interfaces that influence relaxation of the above interface
|
||||
mornN = interfaceNormal(intFaceN,instance,of)
|
||||
iMun = interface4to1(intFaceN,param(instance)%Nconstituents) ! translate the interfaces ID into local 4-dimensional index
|
||||
iMun = interface4to1(intFaceN,param(instance)%N_constituents) ! translate the interfaces ID into local 4-dimensional index
|
||||
if (iMun > 0) then ! get the corresponding tangent
|
||||
do i=1,3; do j=1,3; do k=1,3; do l=1,3
|
||||
smatrix(3*(iNum-1)+i,3*(iMun-1)+j) = smatrix(3*(iNum-1)+i,3*(iMun-1)+j) &
|
||||
|
@ -476,13 +476,13 @@ module procedure mech_RGC_updateState
|
|||
! identify the right/up/front grain (+|P)
|
||||
iGr3P = iGr3N
|
||||
iGr3P(faceID(1)) = iGr3N(faceID(1))+1 ! identifying the grain ID in local coordinate sytem
|
||||
iGrP = grain3to1(iGr3P,param(instance)%Nconstituents) ! translate into global grain ID
|
||||
iGrP = grain3to1(iGr3P,param(instance)%N_constituents) ! translate into global grain ID
|
||||
intFaceP = getInterface(2*faceID(1)-1,iGr3P) ! identifying the connecting interface in local coordinate system
|
||||
normP = interfaceNormal(intFaceP,instance,of)
|
||||
do iFace = 1,6
|
||||
intFaceP = getInterface(iFace,iGr3P) ! identifying all interfaces that influence relaxation of the above interface
|
||||
mornP = interfaceNormal(intFaceP,instance,of)
|
||||
iMun = interface4to1(intFaceP,param(instance)%Nconstituents) ! translate the interfaces ID into local 4-dimensional index
|
||||
iMun = interface4to1(intFaceP,param(instance)%N_constituents) ! translate the interfaces ID into local 4-dimensional index
|
||||
if (iMun > 0) then ! get the corresponding tangent
|
||||
do i=1,3; do j=1,3; do k=1,3; do l=1,3
|
||||
smatrix(3*(iNum-1)+i,3*(iMun-1)+j) = smatrix(3*(iNum-1)+i,3*(iMun-1)+j) &
|
||||
|
@ -522,12 +522,12 @@ module procedure mech_RGC_updateState
|
|||
! computing the global stress residual array from the perturbed state
|
||||
p_resid = 0.0_pReal
|
||||
do iNum = 1,nIntFaceTot
|
||||
faceID = interface1to4(iNum,param(instance)%Nconstituents) ! identifying the interface ID in local coordinate system (4-dimensional index)
|
||||
faceID = interface1to4(iNum,param(instance)%N_constituents) ! identifying the interface ID in local coordinate system (4-dimensional index)
|
||||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! identify the left/bottom/back grain (-|N)
|
||||
iGr3N = faceID(2:4) ! identify the grain ID in local coordinate system (3-dimensional index)
|
||||
iGrN = grain3to1(iGr3N,param(instance)%Nconstituents) ! translate the local grain ID into global coordinate system (1-dimensional index)
|
||||
iGrN = grain3to1(iGr3N,param(instance)%N_constituents) ! translate the local grain ID into global coordinate system (1-dimensional index)
|
||||
intFaceN = getInterface(2*faceID(1),iGr3N) ! identify the interface ID of the grain
|
||||
normN = interfaceNormal(intFaceN,instance,of)
|
||||
|
||||
|
@ -535,7 +535,7 @@ module procedure mech_RGC_updateState
|
|||
! identify the right/up/front grain (+|P)
|
||||
iGr3P = iGr3N
|
||||
iGr3P(faceID(1)) = iGr3N(faceID(1))+1 ! identify the grain ID in local coordinate system (3-dimensional index)
|
||||
iGrP = grain3to1(iGr3P,param(instance)%Nconstituents) ! translate the local grain ID into global coordinate system (1-dimensional index)
|
||||
iGrP = grain3to1(iGr3P,param(instance)%N_constituents) ! translate the local grain ID into global coordinate system (1-dimensional index)
|
||||
intFaceP = getInterface(2*faceID(1)-1,iGr3P) ! identify the interface ID of the grain
|
||||
normP = interfaceNormal(intFaceP,instance,of)
|
||||
|
||||
|
@ -664,7 +664,7 @@ module procedure mech_RGC_updateState
|
|||
real(pReal) :: muGrain,muGNghb,nDefNorm,bgGrain,bgGNghb
|
||||
real(pReal), parameter :: nDefToler = 1.0e-10_pReal
|
||||
|
||||
nGDim = param(instance)%Nconstituents
|
||||
nGDim = param(instance)%N_constituents
|
||||
rPen = 0.0_pReal
|
||||
nMis = 0.0_pReal
|
||||
|
||||
|
@ -685,11 +685,11 @@ module procedure mech_RGC_updateState
|
|||
|
||||
!-----------------------------------------------------------------------------------------------
|
||||
! computing the mismatch and penalty stress tensor of all grains
|
||||
grainLoop: do iGrain = 1,product(prm%Nconstituents)
|
||||
grainLoop: do iGrain = 1,product(prm%N_constituents)
|
||||
Gmoduli = equivalentModuli(iGrain,ip,el)
|
||||
muGrain = Gmoduli(1) ! collecting the equivalent shear modulus of grain
|
||||
bgGrain = Gmoduli(2) ! and the lengthh of Burgers vector
|
||||
iGrain3 = grain1to3(iGrain,prm%Nconstituents) ! get the grain ID in local 3-dimensional index (x,y,z)-position
|
||||
iGrain3 = grain1to3(iGrain,prm%N_constituents) ! get the grain ID in local 3-dimensional index (x,y,z)-position
|
||||
|
||||
interfaceLoop: do iFace = 1,6
|
||||
intFace = getInterface(iFace,iGrain3) ! get the 4-dimensional index of the interface in local numbering system of the grain
|
||||
|
@ -699,7 +699,7 @@ module procedure mech_RGC_updateState
|
|||
+ int(real(intFace(1),pReal)/real(abs(intFace(1)),pReal))
|
||||
where(iGNghb3 < 1) iGNghb3 = nGDim
|
||||
where(iGNghb3 >nGDim) iGNghb3 = 1
|
||||
iGNghb = grain3to1(iGNghb3,prm%Nconstituents) ! get the ID of the neighboring grain
|
||||
iGNghb = grain3to1(iGNghb3,prm%N_constituents) ! get the ID of the neighboring grain
|
||||
Gmoduli = equivalentModuli(iGNghb,ip,el) ! collect the shear modulus and Burgers vector of the neighbor
|
||||
muGNghb = Gmoduli(1)
|
||||
bgGNghb = Gmoduli(2)
|
||||
|
@ -728,9 +728,9 @@ module procedure mech_RGC_updateState
|
|||
!-------------------------------------------------------------------------------------------
|
||||
! compute the stress penalty of all interfaces
|
||||
do i = 1,3; do j = 1,3; do k = 1,3; do l = 1,3
|
||||
rPen(i,j,iGrain) = rPen(i,j,iGrain) + 0.5_pReal*(muGrain*bgGrain + muGNghb*bgGNghb)*prm%xiAlpha &
|
||||
*surfCorr(abs(intFace(1)))/prm%dAlpha(abs(intFace(1))) &
|
||||
*cosh(prm%ciAlpha*nDefNorm) &
|
||||
rPen(i,j,iGrain) = rPen(i,j,iGrain) + 0.5_pReal*(muGrain*bgGrain + muGNghb*bgGNghb)*prm%xi_alpha &
|
||||
*surfCorr(abs(intFace(1)))/prm%D_alpha(abs(intFace(1))) &
|
||||
*cosh(prm%c_alpha*nDefNorm) &
|
||||
*0.5_pReal*nVect(l)*nDef(i,k)/nDefNorm*math_LeviCivita(k,l,j) &
|
||||
*tanh(nDefNorm/num%xSmoo)
|
||||
enddo; enddo;enddo; enddo
|
||||
|
@ -885,8 +885,8 @@ module procedure mech_RGC_updateState
|
|||
associate(prm => param(instance))
|
||||
|
||||
F = 0.0_pReal
|
||||
do iGrain = 1,product(prm%Nconstituents)
|
||||
iGrain3 = grain1to3(iGrain,prm%Nconstituents)
|
||||
do iGrain = 1,product(prm%N_constituents)
|
||||
iGrain3 = grain1to3(iGrain,prm%N_constituents)
|
||||
do iFace = 1,6
|
||||
intFace = getInterface(iFace,iGrain3)
|
||||
aVect = relaxationVector(intFace,instance,of)
|
||||
|
@ -916,8 +916,8 @@ module subroutine mech_RGC_averageStressAndItsTangent(avgP,dAvgPdAvgF,P,dPdF,ins
|
|||
real(pReal), dimension (:,:,:,:,:), intent(in) :: dPdF !< partitioned stiffnesses
|
||||
integer, intent(in) :: instance
|
||||
|
||||
avgP = sum(P,3) /real(product(param(instance)%Nconstituents),pReal)
|
||||
dAvgPdAvgF = sum(dPdF,5)/real(product(param(instance)%Nconstituents),pReal)
|
||||
avgP = sum(P,3) /real(product(param(instance)%N_constituents),pReal)
|
||||
dAvgPdAvgF = sum(dPdF,5)/real(product(param(instance)%N_constituents),pReal)
|
||||
|
||||
end subroutine mech_RGC_averageStressAndItsTangent
|
||||
|
||||
|
@ -975,7 +975,7 @@ pure function relaxationVector(intFace,instance,of)
|
|||
!--------------------------------------------------------------------------------------------------
|
||||
! collect the interface relaxation vector from the global state array
|
||||
|
||||
iNum = interface4to1(intFace,param(instance)%Nconstituents) ! identify the position of the interface in global state array
|
||||
iNum = interface4to1(intFace,param(instance)%N_constituents) ! identify the position of the interface in global state array
|
||||
if (iNum > 0) then
|
||||
relaxationVector = state(instance)%relaxationVector((3*iNum-2):(3*iNum),of)
|
||||
else
|
||||
|
|
|
@ -13,7 +13,7 @@ submodule(homogenization) homogenization_mech_isostrain
|
|||
|
||||
type :: tParameters !< container type for internal constitutive parameters
|
||||
integer :: &
|
||||
Nconstituents
|
||||
N_constituents
|
||||
integer(kind(average_ID)) :: &
|
||||
mapping
|
||||
end type
|
||||
|
@ -51,7 +51,7 @@ module subroutine mech_isostrain_init
|
|||
homogMech => homog%get('mech')
|
||||
associate(prm => param(homogenization_typeInstance(h)))
|
||||
|
||||
prm%Nconstituents = homogMech%get_asInt('N_constituents')
|
||||
prm%N_constituents = homogMech%get_asInt('N_constituents')
|
||||
select case(homogMech%get_asString('mapping',defaultVal = 'sum'))
|
||||
case ('sum')
|
||||
prm%mapping = parallel_ID
|
||||
|
@ -107,8 +107,8 @@ module subroutine mech_isostrain_averageStressAndItsTangent(avgP,dAvgPdAvgF,P,dP
|
|||
avgP = sum(P,3)
|
||||
dAvgPdAvgF = sum(dPdF,5)
|
||||
case (average_ID)
|
||||
avgP = sum(P,3) /real(prm%Nconstituents,pReal)
|
||||
dAvgPdAvgF = sum(dPdF,5)/real(prm%Nconstituents,pReal)
|
||||
avgP = sum(P,3) /real(prm%N_constituents,pReal)
|
||||
dAvgPdAvgF = sum(dPdF,5)/real(prm%N_constituents,pReal)
|
||||
end select
|
||||
|
||||
end associate
|
||||
|
|
|
@ -12,10 +12,10 @@ submodule(constitutive:constitutive_damage) kinematics_cleavage_opening
|
|||
integer :: &
|
||||
sum_N_cl !< total number of cleavage planes
|
||||
real(pReal) :: &
|
||||
sdot0, & !< opening rate of cleavage planes
|
||||
n !< damage rate sensitivity
|
||||
dot_o, & !< opening rate of cleavage planes
|
||||
q !< damage rate sensitivity
|
||||
real(pReal), dimension(:), allocatable :: &
|
||||
critLoad
|
||||
g_crit
|
||||
real(pReal), dimension(:,:,:,:), allocatable :: &
|
||||
cleavage_systems
|
||||
end type tParameters
|
||||
|
@ -70,21 +70,21 @@ module function kinematics_cleavage_opening_init(kinematics_length) result(myKin
|
|||
N_cl = kinematic_type%get_asInts('N_cl')
|
||||
prm%sum_N_cl = sum(abs(N_cl))
|
||||
|
||||
prm%n = kinematic_type%get_asFloat('q')
|
||||
prm%sdot0 = kinematic_type%get_asFloat('dot_o')
|
||||
prm%q = kinematic_type%get_asFloat('q')
|
||||
prm%dot_o = kinematic_type%get_asFloat('dot_o')
|
||||
|
||||
prm%critLoad = kinematic_type%get_asFloats('g_crit',requiredSize=size(N_cl))
|
||||
prm%g_crit = kinematic_type%get_asFloats('g_crit',requiredSize=size(N_cl))
|
||||
|
||||
prm%cleavage_systems = lattice_SchmidMatrix_cleavage(N_cl,phase%get_asString('lattice'),&
|
||||
phase%get_asFloat('c/a',defaultVal=0.0_pReal))
|
||||
|
||||
! expand: family => system
|
||||
prm%critLoad = math_expand(prm%critLoad,N_cl)
|
||||
prm%g_crit = math_expand(prm%g_crit,N_cl)
|
||||
|
||||
! sanity checks
|
||||
if (prm%n <= 0.0_pReal) extmsg = trim(extmsg)//' q'
|
||||
if (prm%sdot0 <= 0.0_pReal) extmsg = trim(extmsg)//' dot_o'
|
||||
if (any(prm%critLoad < 0.0_pReal)) extmsg = trim(extmsg)//' g_crit'
|
||||
if (prm%q <= 0.0_pReal) extmsg = trim(extmsg)//' q'
|
||||
if (prm%dot_o <= 0.0_pReal) extmsg = trim(extmsg)//' dot_o'
|
||||
if (any(prm%g_crit < 0.0_pReal)) extmsg = trim(extmsg)//' g_crit'
|
||||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! exit if any parameter is out of range
|
||||
|
@ -128,13 +128,13 @@ module subroutine kinematics_cleavage_opening_LiAndItsTangent(Ld, dLd_dTstar, S,
|
|||
dLd_dTstar = 0.0_pReal
|
||||
associate(prm => param(kinematics_cleavage_opening_instance(material_phaseAt(ipc,el))))
|
||||
do i = 1,prm%sum_N_cl
|
||||
traction_crit = prm%critLoad(i)* damage(homog)%p(damageOffset)**2.0_pReal
|
||||
traction_crit = prm%g_crit(i)* damage(homog)%p(damageOffset)**2.0_pReal
|
||||
|
||||
traction_d = math_tensordot(S,prm%cleavage_systems(1:3,1:3,1,i))
|
||||
if (abs(traction_d) > traction_crit + tol_math_check) then
|
||||
udotd = sign(1.0_pReal,traction_d)* prm%sdot0 * ((abs(traction_d) - traction_crit)/traction_crit)**prm%n
|
||||
udotd = sign(1.0_pReal,traction_d)* prm%dot_o * ((abs(traction_d) - traction_crit)/traction_crit)**prm%q
|
||||
Ld = Ld + udotd*prm%cleavage_systems(1:3,1:3,1,i)
|
||||
dudotd_dt = sign(1.0_pReal,traction_d)*udotd*prm%n / (abs(traction_d) - traction_crit)
|
||||
dudotd_dt = sign(1.0_pReal,traction_d)*udotd*prm%q / (abs(traction_d) - traction_crit)
|
||||
forall (k=1:3,l=1:3,m=1:3,n=1:3) &
|
||||
dLd_dTstar(k,l,m,n) = dLd_dTstar(k,l,m,n) &
|
||||
+ dudotd_dt*prm%cleavage_systems(k,l,1,i) * prm%cleavage_systems(m,n,1,i)
|
||||
|
@ -142,9 +142,9 @@ module subroutine kinematics_cleavage_opening_LiAndItsTangent(Ld, dLd_dTstar, S,
|
|||
|
||||
traction_t = math_tensordot(S,prm%cleavage_systems(1:3,1:3,2,i))
|
||||
if (abs(traction_t) > traction_crit + tol_math_check) then
|
||||
udott = sign(1.0_pReal,traction_t)* prm%sdot0 * ((abs(traction_t) - traction_crit)/traction_crit)**prm%n
|
||||
udott = sign(1.0_pReal,traction_t)* prm%dot_o * ((abs(traction_t) - traction_crit)/traction_crit)**prm%q
|
||||
Ld = Ld + udott*prm%cleavage_systems(1:3,1:3,2,i)
|
||||
dudott_dt = sign(1.0_pReal,traction_t)*udott*prm%n / (abs(traction_t) - traction_crit)
|
||||
dudott_dt = sign(1.0_pReal,traction_t)*udott*prm%q / (abs(traction_t) - traction_crit)
|
||||
forall (k=1:3,l=1:3,m=1:3,n=1:3) &
|
||||
dLd_dTstar(k,l,m,n) = dLd_dTstar(k,l,m,n) &
|
||||
+ dudott_dt*prm%cleavage_systems(k,l,2,i) * prm%cleavage_systems(m,n,2,i)
|
||||
|
@ -152,9 +152,9 @@ module subroutine kinematics_cleavage_opening_LiAndItsTangent(Ld, dLd_dTstar, S,
|
|||
|
||||
traction_n = math_tensordot(S,prm%cleavage_systems(1:3,1:3,3,i))
|
||||
if (abs(traction_n) > traction_crit + tol_math_check) then
|
||||
udotn = sign(1.0_pReal,traction_n)* prm%sdot0 * ((abs(traction_n) - traction_crit)/traction_crit)**prm%n
|
||||
udotn = sign(1.0_pReal,traction_n)* prm%dot_o * ((abs(traction_n) - traction_crit)/traction_crit)**prm%q
|
||||
Ld = Ld + udotn*prm%cleavage_systems(1:3,1:3,3,i)
|
||||
dudotn_dt = sign(1.0_pReal,traction_n)*udotn*prm%n / (abs(traction_n) - traction_crit)
|
||||
dudotn_dt = sign(1.0_pReal,traction_n)*udotn*prm%q / (abs(traction_n) - traction_crit)
|
||||
forall (k=1:3,l=1:3,m=1:3,n=1:3) &
|
||||
dLd_dTstar(k,l,m,n) = dLd_dTstar(k,l,m,n) &
|
||||
+ dudotn_dt*prm%cleavage_systems(k,l,3,i) * prm%cleavage_systems(m,n,3,i)
|
||||
|
|
|
@ -12,10 +12,10 @@ submodule(constitutive:constitutive_damage) kinematics_slipplane_opening
|
|||
integer :: &
|
||||
sum_N_sl !< total number of cleavage planes
|
||||
real(pReal) :: &
|
||||
sdot0, & !< opening rate of cleavage planes
|
||||
n !< damage rate sensitivity
|
||||
dot_o, & !< opening rate of cleavage planes
|
||||
q !< damage rate sensitivity
|
||||
real(pReal), dimension(:), allocatable :: &
|
||||
critLoad
|
||||
g_crit
|
||||
real(pReal), dimension(:,:,:), allocatable :: &
|
||||
P_d, &
|
||||
P_t, &
|
||||
|
@ -70,8 +70,8 @@ module function kinematics_slipplane_opening_init(kinematics_length) result(myKi
|
|||
associate(prm => param(kinematics_slipplane_opening_instance(p)))
|
||||
kinematic_type => kinematics%get(k)
|
||||
|
||||
prm%sdot0 = kinematic_type%get_asFloat('dot_o')
|
||||
prm%n = kinematic_type%get_asFloat('q')
|
||||
prm%dot_o = kinematic_type%get_asFloat('dot_o')
|
||||
prm%q = kinematic_type%get_asFloat('q')
|
||||
N_sl = pl%get_asInts('N_sl')
|
||||
prm%sum_N_sl = sum(abs(N_sl))
|
||||
|
||||
|
@ -89,15 +89,15 @@ module function kinematics_slipplane_opening_init(kinematics_length) result(myKi
|
|||
prm%P_n(1:3,1:3,i) = math_outer(n(1:3,i), n(1:3,i))
|
||||
enddo
|
||||
|
||||
prm%critLoad = kinematic_type%get_asFloats('g_crit',requiredSize=size(N_sl))
|
||||
prm%g_crit = kinematic_type%get_asFloats('g_crit',requiredSize=size(N_sl))
|
||||
|
||||
! expand: family => system
|
||||
prm%critLoad = math_expand(prm%critLoad,N_sl)
|
||||
prm%g_crit = math_expand(prm%g_crit,N_sl)
|
||||
|
||||
! sanity checks
|
||||
if (prm%n <= 0.0_pReal) extmsg = trim(extmsg)//' anisoDuctile_n'
|
||||
if (prm%sdot0 <= 0.0_pReal) extmsg = trim(extmsg)//' anisoDuctile_sdot0'
|
||||
if (any(prm%critLoad < 0.0_pReal)) extmsg = trim(extmsg)//' anisoDuctile_critLoad'
|
||||
if (prm%q <= 0.0_pReal) extmsg = trim(extmsg)//' anisoDuctile_n'
|
||||
if (prm%dot_o <= 0.0_pReal) extmsg = trim(extmsg)//' anisoDuctile_sdot0'
|
||||
if (any(prm%g_crit < 0.0_pReal)) extmsg = trim(extmsg)//' anisoDuctile_critLoad'
|
||||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! exit if any parameter is out of range
|
||||
|
@ -150,27 +150,27 @@ module subroutine kinematics_slipplane_opening_LiAndItsTangent(Ld, dLd_dTstar, S
|
|||
traction_t = math_tensordot(S,prm%P_t(1:3,1:3,i))
|
||||
traction_n = math_tensordot(S,prm%P_n(1:3,1:3,i))
|
||||
|
||||
traction_crit = prm%critLoad(i)* damage(homog)%p(damageOffset) ! degrading critical load carrying capacity by damage
|
||||
traction_crit = prm%g_crit(i)* damage(homog)%p(damageOffset) ! degrading critical load carrying capacity by damage
|
||||
|
||||
udotd = sign(1.0_pReal,traction_d)* prm%sdot0* ( abs(traction_d)/traction_crit &
|
||||
- abs(traction_d)/prm%critLoad(i))**prm%n
|
||||
udott = sign(1.0_pReal,traction_t)* prm%sdot0* ( abs(traction_t)/traction_crit &
|
||||
- abs(traction_t)/prm%critLoad(i))**prm%n
|
||||
udotn = prm%sdot0* ( max(0.0_pReal,traction_n)/traction_crit &
|
||||
- max(0.0_pReal,traction_n)/prm%critLoad(i))**prm%n
|
||||
udotd = sign(1.0_pReal,traction_d)* prm%dot_o* ( abs(traction_d)/traction_crit &
|
||||
- abs(traction_d)/prm%g_crit(i))**prm%q
|
||||
udott = sign(1.0_pReal,traction_t)* prm%dot_o* ( abs(traction_t)/traction_crit &
|
||||
- abs(traction_t)/prm%g_crit(i))**prm%q
|
||||
udotn = prm%dot_o* ( max(0.0_pReal,traction_n)/traction_crit &
|
||||
- max(0.0_pReal,traction_n)/prm%g_crit(i))**prm%q
|
||||
|
||||
if (dNeq0(traction_d)) then
|
||||
dudotd_dt = udotd*prm%n/traction_d
|
||||
dudotd_dt = udotd*prm%q/traction_d
|
||||
else
|
||||
dudotd_dt = 0.0_pReal
|
||||
endif
|
||||
if (dNeq0(traction_t)) then
|
||||
dudott_dt = udott*prm%n/traction_t
|
||||
dudott_dt = udott*prm%q/traction_t
|
||||
else
|
||||
dudott_dt = 0.0_pReal
|
||||
endif
|
||||
if (dNeq0(traction_n)) then
|
||||
dudotn_dt = udotn*prm%n/traction_n
|
||||
dudotn_dt = udotn*prm%q/traction_n
|
||||
else
|
||||
dudotn_dt = 0.0_pReal
|
||||
endif
|
||||
|
|
|
@ -11,7 +11,7 @@ submodule(constitutive:constitutive_thermal) kinematics_thermal_expansion
|
|||
real(pReal) :: &
|
||||
T_ref
|
||||
real(pReal), dimension(3,3,3) :: &
|
||||
expansion = 0.0_pReal
|
||||
A = 0.0_pReal
|
||||
end type tParameters
|
||||
|
||||
type(tParameters), dimension(:), allocatable :: param
|
||||
|
@ -64,13 +64,13 @@ module function kinematics_thermal_expansion_init(kinematics_length) result(myKi
|
|||
|
||||
! read up to three parameters (constant, linear, quadratic with T)
|
||||
temp = kinematic_type%get_asFloats('A_11')
|
||||
prm%expansion(1,1,1:size(temp)) = temp
|
||||
prm%A(1,1,1:size(temp)) = temp
|
||||
temp = kinematic_type%get_asFloats('A_22',defaultVal=[(0.0_pReal, i=1,size(temp))],requiredSize=size(temp))
|
||||
prm%expansion(2,2,1:size(temp)) = temp
|
||||
prm%A(2,2,1:size(temp)) = temp
|
||||
temp = kinematic_type%get_asFloats('A_33',defaultVal=[(0.0_pReal, i=1,size(temp))],requiredSize=size(temp))
|
||||
prm%expansion(3,3,1:size(temp)) = temp
|
||||
do i=1, size(prm%expansion,3)
|
||||
prm%expansion(1:3,1:3,i) = lattice_applyLatticeSymmetry33(prm%expansion(1:3,1:3,i),&
|
||||
prm%A(3,3,1:size(temp)) = temp
|
||||
do i=1, size(prm%A,3)
|
||||
prm%A(1:3,1:3,i) = lattice_applyLatticeSymmetry33(prm%A(1:3,1:3,i),&
|
||||
phase%get_asString('lattice'))
|
||||
enddo
|
||||
|
||||
|
@ -98,9 +98,9 @@ pure module function kinematics_thermal_expansion_initialStrain(homog,phase,offs
|
|||
|
||||
associate(prm => param(kinematics_thermal_expansion_instance(phase)))
|
||||
initialStrain = &
|
||||
(temperature(homog)%p(offset) - prm%T_ref)**1 / 1. * prm%expansion(1:3,1:3,1) + & ! constant coefficient
|
||||
(temperature(homog)%p(offset) - prm%T_ref)**2 / 2. * prm%expansion(1:3,1:3,2) + & ! linear coefficient
|
||||
(temperature(homog)%p(offset) - prm%T_ref)**3 / 3. * prm%expansion(1:3,1:3,3) ! quadratic coefficient
|
||||
(temperature(homog)%p(offset) - prm%T_ref)**1 / 1. * prm%A(1:3,1:3,1) + & ! constant coefficient
|
||||
(temperature(homog)%p(offset) - prm%T_ref)**2 / 2. * prm%A(1:3,1:3,2) + & ! linear coefficient
|
||||
(temperature(homog)%p(offset) - prm%T_ref)**3 / 3. * prm%A(1:3,1:3,3) ! quadratic coefficient
|
||||
end associate
|
||||
|
||||
end function kinematics_thermal_expansion_initialStrain
|
||||
|
@ -133,14 +133,14 @@ module subroutine kinematics_thermal_expansion_LiAndItsTangent(Li, dLi_dTstar, i
|
|||
|
||||
associate(prm => param(kinematics_thermal_expansion_instance(phase)))
|
||||
Li = TDot * ( &
|
||||
prm%expansion(1:3,1:3,1)*(T - prm%T_ref)**0 & ! constant coefficient
|
||||
+ prm%expansion(1:3,1:3,2)*(T - prm%T_ref)**1 & ! linear coefficient
|
||||
+ prm%expansion(1:3,1:3,3)*(T - prm%T_ref)**2 & ! quadratic coefficient
|
||||
prm%A(1:3,1:3,1)*(T - prm%T_ref)**0 & ! constant coefficient
|
||||
+ prm%A(1:3,1:3,2)*(T - prm%T_ref)**1 & ! linear coefficient
|
||||
+ prm%A(1:3,1:3,3)*(T - prm%T_ref)**2 & ! quadratic coefficient
|
||||
) / &
|
||||
(1.0_pReal &
|
||||
+ prm%expansion(1:3,1:3,1)*(T - prm%T_ref)**1 / 1. &
|
||||
+ prm%expansion(1:3,1:3,2)*(T - prm%T_ref)**2 / 2. &
|
||||
+ prm%expansion(1:3,1:3,3)*(T - prm%T_ref)**3 / 3. &
|
||||
+ prm%A(1:3,1:3,1)*(T - prm%T_ref)**1 / 1. &
|
||||
+ prm%A(1:3,1:3,2)*(T - prm%T_ref)**2 / 2. &
|
||||
+ prm%A(1:3,1:3,3)*(T - prm%T_ref)**3 / 3. &
|
||||
)
|
||||
end associate
|
||||
dLi_dTstar = 0.0_pReal
|
||||
|
|
|
@ -394,13 +394,13 @@ module lattice
|
|||
! SHOULD NOT BE PART OF LATTICE BEGIN
|
||||
real(pReal), dimension(:), allocatable, public, protected :: &
|
||||
lattice_mu, lattice_nu, &
|
||||
lattice_damageMobility, &
|
||||
lattice_massDensity, &
|
||||
lattice_specificHeat
|
||||
lattice_M, &
|
||||
lattice_rho, &
|
||||
lattice_c_p
|
||||
real(pReal), dimension(:,:,:), allocatable, public, protected :: &
|
||||
lattice_C66, &
|
||||
lattice_thermalConductivity, &
|
||||
lattice_damageDiffusion
|
||||
lattice_K, &
|
||||
lattice_D
|
||||
integer(kind(lattice_UNDEFINED_ID)), dimension(:), allocatable, public, protected :: &
|
||||
lattice_structure
|
||||
! SHOULD NOT BE PART OF LATTICE END
|
||||
|
@ -465,11 +465,11 @@ subroutine lattice_init
|
|||
allocate(lattice_structure(Nphases),source = lattice_UNDEFINED_ID)
|
||||
allocate(lattice_C66(6,6,Nphases), source=0.0_pReal)
|
||||
|
||||
allocate(lattice_thermalConductivity (3,3,Nphases), source=0.0_pReal)
|
||||
allocate(lattice_damageDiffusion (3,3,Nphases), source=0.0_pReal)
|
||||
allocate(lattice_K (3,3,Nphases), source=0.0_pReal)
|
||||
allocate(lattice_D (3,3,Nphases), source=0.0_pReal)
|
||||
|
||||
allocate(lattice_damageMobility,&
|
||||
lattice_massDensity,lattice_specificHeat, &
|
||||
allocate(lattice_M,&
|
||||
lattice_rho,lattice_c_p, &
|
||||
lattice_mu, lattice_nu,&
|
||||
source=[(0.0_pReal,i=1,Nphases)])
|
||||
|
||||
|
@ -517,22 +517,22 @@ subroutine lattice_init
|
|||
|
||||
|
||||
! SHOULD NOT BE PART OF LATTICE BEGIN
|
||||
lattice_thermalConductivity(1,1,p) = phase%get_asFloat('K_11',defaultVal=0.0_pReal)
|
||||
lattice_thermalConductivity(2,2,p) = phase%get_asFloat('K_22',defaultVal=0.0_pReal)
|
||||
lattice_thermalConductivity(3,3,p) = phase%get_asFloat('K_33',defaultVal=0.0_pReal)
|
||||
lattice_thermalConductivity(1:3,1:3,p) = lattice_applyLatticeSymmetry33(lattice_thermalConductivity(1:3,1:3,p), &
|
||||
lattice_K(1,1,p) = phase%get_asFloat('K_11',defaultVal=0.0_pReal)
|
||||
lattice_K(2,2,p) = phase%get_asFloat('K_22',defaultVal=0.0_pReal)
|
||||
lattice_K(3,3,p) = phase%get_asFloat('K_33',defaultVal=0.0_pReal)
|
||||
lattice_K(1:3,1:3,p) = lattice_applyLatticeSymmetry33(lattice_K(1:3,1:3,p), &
|
||||
phase%get_asString('lattice'))
|
||||
|
||||
lattice_specificHeat(p) = phase%get_asFloat('c_p',defaultVal=0.0_pReal)
|
||||
lattice_massDensity(p) = phase%get_asFloat('rho', defaultVal=0.0_pReal)
|
||||
lattice_c_p(p) = phase%get_asFloat('c_p', defaultVal=0.0_pReal)
|
||||
lattice_rho(p) = phase%get_asFloat('rho', defaultVal=0.0_pReal)
|
||||
|
||||
lattice_DamageDiffusion(1,1,p) = phase%get_asFloat('D_11',defaultVal=0.0_pReal)
|
||||
lattice_DamageDiffusion(2,2,p) = phase%get_asFloat('D_22',defaultVal=0.0_pReal)
|
||||
lattice_DamageDiffusion(3,3,p) = phase%get_asFloat('D_33',defaultVal=0.0_pReal)
|
||||
lattice_DamageDiffusion(1:3,1:3,p) = lattice_applyLatticeSymmetry33(lattice_DamageDiffusion(1:3,1:3,p), &
|
||||
lattice_D(1,1,p) = phase%get_asFloat('D_11',defaultVal=0.0_pReal)
|
||||
lattice_D(2,2,p) = phase%get_asFloat('D_22',defaultVal=0.0_pReal)
|
||||
lattice_D(3,3,p) = phase%get_asFloat('D_33',defaultVal=0.0_pReal)
|
||||
lattice_D(1:3,1:3,p) = lattice_applyLatticeSymmetry33(lattice_D(1:3,1:3,p), &
|
||||
phase%get_asString('lattice'))
|
||||
|
||||
lattice_DamageMobility(p) = phase%get_asFloat('M',defaultVal=0.0_pReal)
|
||||
lattice_M(p) = phase%get_asFloat('M',defaultVal=0.0_pReal)
|
||||
! SHOULD NOT BE PART OF LATTICE END
|
||||
|
||||
call selfTest
|
||||
|
|
|
@ -52,7 +52,7 @@ subroutine discretization_marc_init
|
|||
type(tElement) :: elem
|
||||
|
||||
integer, dimension(:), allocatable :: &
|
||||
microstructureAt
|
||||
materialAt
|
||||
integer:: &
|
||||
Nnodes, & !< total number of nodes in the mesh
|
||||
Nelems, & !< total number of elements in the mesh
|
||||
|
@ -83,7 +83,7 @@ subroutine discretization_marc_init
|
|||
mesh_unitlength = num_commercialFEM%get_asFloat('unitlength',defaultVal=1.0_pReal) ! set physical extent of a length unit in mesh
|
||||
if (mesh_unitlength <= 0.0_pReal) call IO_error(301,ext_msg='unitlength')
|
||||
|
||||
call inputRead(elem,node0_elem,connectivity_elem,microstructureAt)
|
||||
call inputRead(elem,node0_elem,connectivity_elem,materialAt)
|
||||
nElems = size(connectivity_elem,2)
|
||||
|
||||
if (debug_e < 1 .or. debug_e > nElems) call IO_error(602,ext_msg='element')
|
||||
|
@ -103,7 +103,7 @@ subroutine discretization_marc_init
|
|||
call buildIPcoordinates(IP_reshaped,reshape(connectivity_cell,[elem%NcellNodesPerCell,&
|
||||
elem%nIPs*nElems]),node0_cell)
|
||||
|
||||
call discretization_init(microstructureAt,&
|
||||
call discretization_init(materialAt,&
|
||||
IP_reshaped,&
|
||||
node0_cell)
|
||||
|
||||
|
@ -172,7 +172,7 @@ end subroutine writeGeometry
|
|||
!--------------------------------------------------------------------------------------------------
|
||||
!> @brief Read mesh from marc input file
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
subroutine inputRead(elem,node0_elem,connectivity_elem,microstructureAt)
|
||||
subroutine inputRead(elem,node0_elem,connectivity_elem,materialAt)
|
||||
|
||||
type(tElement), intent(out) :: elem
|
||||
real(pReal), dimension(:,:), allocatable, intent(out) :: &
|
||||
|
@ -180,7 +180,7 @@ subroutine inputRead(elem,node0_elem,connectivity_elem,microstructureAt)
|
|||
integer, dimension(:,:), allocatable, intent(out) :: &
|
||||
connectivity_elem
|
||||
integer, dimension(:), allocatable, intent(out) :: &
|
||||
microstructureAt
|
||||
materialAt
|
||||
|
||||
integer :: &
|
||||
fileFormatVersion, &
|
||||
|
@ -226,7 +226,7 @@ subroutine inputRead(elem,node0_elem,connectivity_elem,microstructureAt)
|
|||
|
||||
connectivity_elem = inputRead_connectivityElem(nElems,elem%nNodes,inputFile)
|
||||
|
||||
call inputRead_microstructure(microstructureAt, &
|
||||
call inputRead_material(materialAt, &
|
||||
nElems,elem%nNodes,nameElemSet,mapElemSet,&
|
||||
initialcondTableStyle,inputFile)
|
||||
end subroutine inputRead
|
||||
|
@ -675,13 +675,13 @@ end function inputRead_connectivityElem
|
|||
|
||||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
!> @brief Store microstructure ID
|
||||
!> @brief Store material ID
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
subroutine inputRead_microstructure(microstructureAt,&
|
||||
subroutine inputRead_material(materialAt,&
|
||||
nElem,nNodes,nameElemSet,mapElemSet,initialcondTableStyle,fileContent)
|
||||
|
||||
integer, dimension(:), allocatable, intent(out) :: &
|
||||
microstructureAt
|
||||
materialAt
|
||||
integer, intent(in) :: &
|
||||
nElem, &
|
||||
nNodes, & !< number of nodes per element
|
||||
|
@ -696,7 +696,7 @@ subroutine inputRead_microstructure(microstructureAt,&
|
|||
integer :: i,j,t,sv,myVal,e,nNodesAlreadyRead,l,k,m
|
||||
|
||||
|
||||
allocate(microstructureAt(nElem),source=0)
|
||||
allocate(materialAt(nElem),source=0)
|
||||
|
||||
do l = 1, size(fileContent)
|
||||
chunkPos = IO_stringPos(fileContent(l))
|
||||
|
@ -715,7 +715,7 @@ subroutine inputRead_microstructure(microstructureAt,&
|
|||
contInts = continuousIntValues(fileContent(l+k+m+1:),nElem,nameElemSet,mapElemSet,size(nameElemSet)) ! get affected elements
|
||||
do i = 1,contInts(1)
|
||||
e = mesh_FEM2DAMASK_elem(contInts(1+i))
|
||||
microstructureAt(e) = myVal
|
||||
materialAt(e) = myVal
|
||||
enddo
|
||||
if (initialcondTableStyle == 0) m = m + 1
|
||||
enddo
|
||||
|
@ -723,9 +723,9 @@ subroutine inputRead_microstructure(microstructureAt,&
|
|||
endif
|
||||
enddo
|
||||
|
||||
if(any(microstructureAt < 1)) call IO_error(180)
|
||||
if(any(materialAt < 1)) call IO_error(180)
|
||||
|
||||
end subroutine inputRead_microstructure
|
||||
end subroutine inputRead_material
|
||||
|
||||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
!> @author Franz Roters, Max-Planck-Institut für Eisenforschung GmbH
|
||||
!> @author Philip Eisenlohr, Max-Planck-Institut für Eisenforschung GmbH
|
||||
!> @author Martin Diehl, Max-Planck-Institut für Eisenforschung GmbH
|
||||
!> @brief Parses material config file, either solverJobName.materialConfig or material.config
|
||||
!> @brief Defines phase and homogenization
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
module material
|
||||
use prec
|
||||
|
@ -97,7 +97,7 @@ module material
|
|||
material_orientation0 !< initial orientation of each grain,IP,element
|
||||
|
||||
integer, dimension(:), allocatable, private :: &
|
||||
microstructure_Nconstituents !< number of constituents in each microstructure
|
||||
material_Nconstituents !< number of constituents in each material
|
||||
|
||||
|
||||
|
||||
|
@ -180,8 +180,8 @@ subroutine material_init(restart)
|
|||
material_name_homogenization(myHomog) = trim(adjustl(sectionName))//material_homogenization%getKey(myHomog)
|
||||
enddo
|
||||
|
||||
call material_parseMicrostructure
|
||||
print*, 'Microstructure parsed'
|
||||
call material_parseMaterial
|
||||
print*, 'Material parsed'
|
||||
|
||||
call material_parseHomogenization
|
||||
print*, 'Homogenization parsed'
|
||||
|
@ -317,16 +317,16 @@ end subroutine material_parseHomogenization
|
|||
|
||||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
!> @brief parses the microstructure part in the material configuration file
|
||||
!> @brief parses the material part in the material configuration file
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
subroutine material_parseMicrostructure
|
||||
subroutine material_parseMaterial
|
||||
|
||||
class(tNode), pointer :: microstructures, & !> list of microstructures
|
||||
microstructure, & !> microstructure definition
|
||||
class(tNode), pointer :: materials, & !> list of materials
|
||||
material, & !> material definition
|
||||
constituents, & !> list of constituents
|
||||
constituent, & !> constituent definition
|
||||
phases, &
|
||||
homogenization
|
||||
homogenizations
|
||||
|
||||
integer, dimension(:), allocatable :: &
|
||||
counterPhase, &
|
||||
|
@ -341,17 +341,17 @@ subroutine material_parseMicrostructure
|
|||
c, &
|
||||
maxNconstituents
|
||||
|
||||
microstructures => config_material%get('microstructure')
|
||||
if(any(discretization_microstructureAt > microstructures%length)) &
|
||||
call IO_error(155,ext_msg='More microstructures requested than found in material.yaml')
|
||||
materials => config_material%get('material')
|
||||
if(any(discretization_materialAt > materials%length)) &
|
||||
call IO_error(155,ext_msg='More materials requested than found in material.yaml')
|
||||
|
||||
allocate(microstructure_Nconstituents(microstructures%length),source=0)
|
||||
do m = 1, microstructures%length
|
||||
microstructure => microstructures%get(m)
|
||||
constituents => microstructure%get('constituents')
|
||||
microstructure_Nconstituents(m) = constituents%length
|
||||
allocate(material_Nconstituents(materials%length),source=0)
|
||||
do m = 1, materials%length
|
||||
material => materials%get(m)
|
||||
constituents => material%get('constituents')
|
||||
material_Nconstituents(m) = constituents%length
|
||||
enddo
|
||||
maxNconstituents = maxval(microstructure_Nconstituents)
|
||||
maxNconstituents = maxval(material_Nconstituents)
|
||||
|
||||
allocate(material_homogenizationAt(discretization_nElem),source=0)
|
||||
allocate(material_homogenizationMemberAt(discretization_nIP,discretization_nElem),source=0)
|
||||
|
@ -362,14 +362,14 @@ subroutine material_parseMicrostructure
|
|||
|
||||
phases => config_material%get('phase')
|
||||
allocate(counterPhase(phases%length),source=0)
|
||||
homogenization => config_material%get('homogenization')
|
||||
allocate(counterHomogenization(homogenization%length),source=0)
|
||||
homogenizations => config_material%get('homogenization')
|
||||
allocate(counterHomogenization(homogenizations%length),source=0)
|
||||
|
||||
do e = 1, discretization_nElem
|
||||
microstructure => microstructures%get(discretization_microstructureAt(e))
|
||||
constituents => microstructure%get('constituents')
|
||||
material => materials%get(discretization_materialAt(e))
|
||||
constituents => material%get('constituents')
|
||||
|
||||
material_homogenizationAt(e) = homogenization%getIndex(microstructure%get_asString('homogenization'))
|
||||
material_homogenizationAt(e) = homogenizations%getIndex(material%get_asString('homogenization'))
|
||||
do i = 1, discretization_nIP
|
||||
counterHomogenization(material_homogenizationAt(e)) = counterHomogenization(material_homogenizationAt(e)) + 1
|
||||
material_homogenizationMemberAt(i,e) = counterHomogenization(material_homogenizationAt(e))
|
||||
|
@ -385,7 +385,7 @@ subroutine material_parseMicrostructure
|
|||
counterPhase(material_phaseAt(c,e)) = counterPhase(material_phaseAt(c,e)) + 1
|
||||
material_phaseMemberAt(c,i,e) = counterPhase(material_phaseAt(c,e))
|
||||
|
||||
call material_orientation0(c,i,e)%fromQuaternion(constituent%get_asFloats('orientation',requiredSize=4))
|
||||
call material_orientation0(c,i,e)%fromQuaternion(constituent%get_asFloats('O',requiredSize=4))
|
||||
enddo
|
||||
|
||||
enddo
|
||||
|
@ -393,7 +393,7 @@ subroutine material_parseMicrostructure
|
|||
|
||||
enddo
|
||||
|
||||
end subroutine material_parseMicrostructure
|
||||
end subroutine material_parseMaterial
|
||||
|
||||
|
||||
end module material
|
||||
|
|
|
@ -160,7 +160,7 @@ subroutine utilities_constitutiveResponse(timeinc,P_av,forwardData)
|
|||
|
||||
print'(/,a)', ' ... evaluating constitutive response ......................................'
|
||||
|
||||
call materialpoint_stressAndItsTangent(.true.,timeinc) ! calculate P field
|
||||
call materialpoint_stressAndItsTangent(timeinc) ! calculate P field
|
||||
|
||||
cutBack = .false. ! reset cutBack status
|
||||
|
||||
|
|
|
@ -78,7 +78,7 @@ subroutine discretization_mesh_init(restart)
|
|||
IS :: faceSetIS
|
||||
PetscErrorCode :: ierr
|
||||
integer, dimension(:), allocatable :: &
|
||||
microstructureAt
|
||||
materialAt
|
||||
class(tNode), pointer :: &
|
||||
num_mesh
|
||||
integer :: integrationOrder !< order of quadrature rule required
|
||||
|
@ -164,9 +164,9 @@ subroutine discretization_mesh_init(restart)
|
|||
call mesh_FEM_build_ipCoordinates(dimPlex,FEM_quadrature_points(dimPlex,integrationOrder)%p)
|
||||
call mesh_FEM_build_ipVolumes(dimPlex)
|
||||
|
||||
allocate(microstructureAt(mesh_NcpElems))
|
||||
allocate(materialAt(mesh_NcpElems))
|
||||
do j = 1, mesh_NcpElems
|
||||
call DMGetLabelValue(geomMesh,'material',j-1,microstructureAt(j),ierr)
|
||||
call DMGetLabelValue(geomMesh,'material',j-1,materialAt(j),ierr)
|
||||
CHKERRQ(ierr)
|
||||
end do
|
||||
|
||||
|
@ -178,7 +178,7 @@ subroutine discretization_mesh_init(restart)
|
|||
|
||||
allocate(mesh_node0(3,mesh_Nnodes),source=0.0_pReal)
|
||||
|
||||
call discretization_init(microstructureAt,&
|
||||
call discretization_init(materialAt,&
|
||||
reshape(mesh_ipCoordinates,[3,mesh_maxNips*mesh_NcpElems]), &
|
||||
mesh_node0)
|
||||
|
||||
|
|
|
@ -57,10 +57,10 @@ subroutine parallelization_init
|
|||
if (err /= 0) error stop 'Could not determine worldrank'
|
||||
|
||||
if (worldrank == 0) print'(/,a)', ' <<<+- parallelization init -+>>>'
|
||||
if (worldrank == 0) print'(a,i3)', ' MPI processes: ',worldsize
|
||||
|
||||
call MPI_Comm_size(PETSC_COMM_WORLD,worldsize,err)
|
||||
if (err /= 0) error stop 'Could not determine worldsize'
|
||||
if (worldrank == 0) print'(a,i3)', ' MPI processes: ',worldsize
|
||||
|
||||
call MPI_Type_size(MPI_INTEGER,typeSize,err)
|
||||
if (err /= 0) error stop 'Could not determine MPI integer size'
|
||||
|
|
|
@ -1452,7 +1452,7 @@ subroutine selfTest
|
|||
|
||||
contains
|
||||
|
||||
function quaternion_equal(qu1,qu2) result(ok)
|
||||
pure recursive function quaternion_equal(qu1,qu2) result(ok)
|
||||
|
||||
real(pReal), intent(in), dimension(4) :: qu1,qu2
|
||||
logical :: ok
|
||||
|
|
|
@ -12,11 +12,11 @@ submodule (constitutive:constitutive_damage) source_damage_anisoBrittle
|
|||
|
||||
type :: tParameters !< container type for internal constitutive parameters
|
||||
real(pReal) :: &
|
||||
sdot_0, & !< opening rate of cleavage planes
|
||||
n !< damage rate sensitivity
|
||||
dot_o, & !< opening rate of cleavage planes
|
||||
q !< damage rate sensitivity
|
||||
real(pReal), dimension(:), allocatable :: &
|
||||
critDisp, & !< critical displacement
|
||||
critLoad !< critical load
|
||||
s_crit, & !< critical displacement
|
||||
g_crit !< critical load
|
||||
real(pReal), dimension(:,:,:,:), allocatable :: &
|
||||
cleavage_systems
|
||||
integer :: &
|
||||
|
@ -75,18 +75,18 @@ module function source_damage_anisoBrittle_init(source_length) result(mySources)
|
|||
N_cl = src%get_asInts('N_cl',defaultVal=emptyIntArray)
|
||||
prm%sum_N_cl = sum(abs(N_cl))
|
||||
|
||||
prm%n = src%get_asFloat('q')
|
||||
prm%sdot_0 = src%get_asFloat('dot_o')
|
||||
prm%q = src%get_asFloat('q')
|
||||
prm%dot_o = src%get_asFloat('dot_o')
|
||||
|
||||
prm%critDisp = src%get_asFloats('s_crit', requiredSize=size(N_cl))
|
||||
prm%critLoad = src%get_asFloats('g_crit', requiredSize=size(N_cl))
|
||||
prm%s_crit = src%get_asFloats('s_crit', requiredSize=size(N_cl))
|
||||
prm%g_crit = src%get_asFloats('g_crit', requiredSize=size(N_cl))
|
||||
|
||||
prm%cleavage_systems = lattice_SchmidMatrix_cleavage(N_cl,phase%get_asString('lattice'),&
|
||||
phase%get_asFloat('c/a',defaultVal=0.0_pReal))
|
||||
|
||||
! expand: family => system
|
||||
prm%critDisp = math_expand(prm%critDisp,N_cl)
|
||||
prm%critLoad = math_expand(prm%critLoad,N_cl)
|
||||
prm%s_crit = math_expand(prm%s_crit,N_cl)
|
||||
prm%g_crit = math_expand(prm%g_crit,N_cl)
|
||||
|
||||
#if defined (__GFORTRAN__)
|
||||
prm%output = output_asStrings(src)
|
||||
|
@ -95,10 +95,10 @@ module function source_damage_anisoBrittle_init(source_length) result(mySources)
|
|||
#endif
|
||||
|
||||
! sanity checks
|
||||
if (prm%n <= 0.0_pReal) extmsg = trim(extmsg)//' q'
|
||||
if (prm%sdot_0 <= 0.0_pReal) extmsg = trim(extmsg)//' dot_o'
|
||||
if (any(prm%critLoad < 0.0_pReal)) extmsg = trim(extmsg)//' g_crit'
|
||||
if (any(prm%critDisp < 0.0_pReal)) extmsg = trim(extmsg)//' s_crit'
|
||||
if (prm%q <= 0.0_pReal) extmsg = trim(extmsg)//' q'
|
||||
if (prm%dot_o <= 0.0_pReal) extmsg = trim(extmsg)//' dot_o'
|
||||
if (any(prm%g_crit < 0.0_pReal)) extmsg = trim(extmsg)//' g_crit'
|
||||
if (any(prm%s_crit < 0.0_pReal)) extmsg = trim(extmsg)//' s_crit'
|
||||
|
||||
NipcMyPhase = count(material_phaseAt==p) * discretization_nIP
|
||||
call constitutive_allocateState(sourceState(p)%p(sourceOffset),NipcMyPhase,1,1,0)
|
||||
|
@ -152,14 +152,14 @@ module subroutine source_damage_anisoBrittle_dotState(S, ipc, ip, el)
|
|||
traction_t = math_tensordot(S,prm%cleavage_systems(1:3,1:3,2,i))
|
||||
traction_n = math_tensordot(S,prm%cleavage_systems(1:3,1:3,3,i))
|
||||
|
||||
traction_crit = prm%critLoad(i)*damage(homog)%p(damageOffset)**2.0_pReal
|
||||
traction_crit = prm%g_crit(i)*damage(homog)%p(damageOffset)**2.0_pReal
|
||||
|
||||
sourceState(phase)%p(sourceOffset)%dotState(1,constituent) &
|
||||
= sourceState(phase)%p(sourceOffset)%dotState(1,constituent) &
|
||||
+ prm%sdot_0 / prm%critDisp(i) &
|
||||
* ((max(0.0_pReal, abs(traction_d) - traction_crit)/traction_crit)**prm%n + &
|
||||
(max(0.0_pReal, abs(traction_t) - traction_crit)/traction_crit)**prm%n + &
|
||||
(max(0.0_pReal, abs(traction_n) - traction_crit)/traction_crit)**prm%n)
|
||||
+ prm%dot_o / prm%s_crit(i) &
|
||||
* ((max(0.0_pReal, abs(traction_d) - traction_crit)/traction_crit)**prm%q + &
|
||||
(max(0.0_pReal, abs(traction_t) - traction_crit)/traction_crit)**prm%q + &
|
||||
(max(0.0_pReal, abs(traction_n) - traction_crit)/traction_crit)**prm%q)
|
||||
enddo
|
||||
end associate
|
||||
|
||||
|
|
|
@ -12,9 +12,9 @@ submodule(constitutive:constitutive_damage) source_damage_anisoDuctile
|
|||
|
||||
type :: tParameters !< container type for internal constitutive parameters
|
||||
real(pReal) :: &
|
||||
n !< damage rate sensitivity
|
||||
q !< damage rate sensitivity
|
||||
real(pReal), dimension(:), allocatable :: &
|
||||
critPlasticStrain !< critical plastic strain per slip system
|
||||
gamma_crit !< critical plastic strain per slip system
|
||||
character(len=pStringLen), allocatable, dimension(:) :: &
|
||||
output
|
||||
end type tParameters
|
||||
|
@ -68,11 +68,11 @@ module function source_damage_anisoDuctile_init(source_length) result(mySources)
|
|||
src => sources%get(sourceOffset)
|
||||
|
||||
N_sl = pl%get_asInts('N_sl',defaultVal=emptyIntArray)
|
||||
prm%n = src%get_asFloat('q')
|
||||
prm%critPlasticStrain = src%get_asFloats('gamma_crit',requiredSize=size(N_sl))
|
||||
prm%q = src%get_asFloat('q')
|
||||
prm%gamma_crit = src%get_asFloats('gamma_crit',requiredSize=size(N_sl))
|
||||
|
||||
! expand: family => system
|
||||
prm%critPlasticStrain = math_expand(prm%critPlasticStrain,N_sl)
|
||||
prm%gamma_crit = math_expand(prm%gamma_crit,N_sl)
|
||||
|
||||
#if defined (__GFORTRAN__)
|
||||
prm%output = output_asStrings(src)
|
||||
|
@ -81,8 +81,8 @@ module function source_damage_anisoDuctile_init(source_length) result(mySources)
|
|||
#endif
|
||||
|
||||
! sanity checks
|
||||
if (prm%n <= 0.0_pReal) extmsg = trim(extmsg)//' q'
|
||||
if (any(prm%critPlasticStrain < 0.0_pReal)) extmsg = trim(extmsg)//' gamma_crit'
|
||||
if (prm%q <= 0.0_pReal) extmsg = trim(extmsg)//' q'
|
||||
if (any(prm%gamma_crit < 0.0_pReal)) extmsg = trim(extmsg)//' gamma_crit'
|
||||
|
||||
NipcMyPhase=count(material_phaseAt==p) * discretization_nIP
|
||||
call constitutive_allocateState(sourceState(p)%p(sourceOffset),NipcMyPhase,1,1,0)
|
||||
|
@ -127,7 +127,7 @@ module subroutine source_damage_anisoDuctile_dotState(ipc, ip, el)
|
|||
|
||||
associate(prm => param(source_damage_anisoDuctile_instance(phase)))
|
||||
sourceState(phase)%p(sourceOffset)%dotState(1,constituent) &
|
||||
= sum(plasticState(phase)%slipRate(:,constituent)/(damage(homog)%p(damageOffset)**prm%n)/prm%critPlasticStrain)
|
||||
= sum(plasticState(phase)%slipRate(:,constituent)/(damage(homog)%p(damageOffset)**prm%q)/prm%gamma_crit)
|
||||
end associate
|
||||
|
||||
end subroutine source_damage_anisoDuctile_dotState
|
||||
|
|
|
@ -12,8 +12,8 @@ submodule (constitutive:constitutive_damage) source_damage_isoDuctile
|
|||
|
||||
type:: tParameters !< container type for internal constitutive parameters
|
||||
real(pReal) :: &
|
||||
critPlasticStrain, & !< critical plastic strain
|
||||
N
|
||||
gamma_crit, & !< critical plastic strain
|
||||
q
|
||||
character(len=pStringLen), allocatable, dimension(:) :: &
|
||||
output
|
||||
end type tParameters
|
||||
|
@ -64,8 +64,8 @@ module function source_damage_isoDuctile_init(source_length) result(mySources)
|
|||
associate(prm => param(source_damage_isoDuctile_instance(p)))
|
||||
src => sources%get(sourceOffset)
|
||||
|
||||
prm%N = src%get_asFloat('q')
|
||||
prm%critPlasticStrain = src%get_asFloat('gamma_crit')
|
||||
prm%q = src%get_asFloat('q')
|
||||
prm%gamma_crit = src%get_asFloat('gamma_crit')
|
||||
|
||||
#if defined (__GFORTRAN__)
|
||||
prm%output = output_asStrings(src)
|
||||
|
@ -74,8 +74,8 @@ module function source_damage_isoDuctile_init(source_length) result(mySources)
|
|||
#endif
|
||||
|
||||
! sanity checks
|
||||
if (prm%N <= 0.0_pReal) extmsg = trim(extmsg)//' q'
|
||||
if (prm%critPlasticStrain <= 0.0_pReal) extmsg = trim(extmsg)//' gamma_crit'
|
||||
if (prm%q <= 0.0_pReal) extmsg = trim(extmsg)//' q'
|
||||
if (prm%gamma_crit <= 0.0_pReal) extmsg = trim(extmsg)//' gamma_crit'
|
||||
|
||||
NipcMyPhase=count(material_phaseAt==p) * discretization_nIP
|
||||
call constitutive_allocateState(sourceState(p)%p(sourceOffset),NipcMyPhase,1,1,0)
|
||||
|
@ -120,7 +120,7 @@ module subroutine source_damage_isoDuctile_dotState(ipc, ip, el)
|
|||
|
||||
associate(prm => param(source_damage_isoDuctile_instance(phase)))
|
||||
sourceState(phase)%p(sourceOffset)%dotState(1,constituent) = &
|
||||
sum(plasticState(phase)%slipRate(:,constituent))/(damage(homog)%p(damageOffset)**prm%N)/prm%critPlasticStrain
|
||||
sum(plasticState(phase)%slipRate(:,constituent))/(damage(homog)%p(damageOffset)**prm%q)/prm%gamma_crit
|
||||
end associate
|
||||
|
||||
end subroutine source_damage_isoDuctile_dotState
|
||||
|
|
|
@ -13,8 +13,8 @@ submodule(constitutive:constitutive_thermal) source_thermal_externalheat
|
|||
|
||||
type :: tParameters !< container type for internal constitutive parameters
|
||||
real(pReal), dimension(:), allocatable :: &
|
||||
time, &
|
||||
heat_rate
|
||||
t_n, &
|
||||
f_T
|
||||
integer :: &
|
||||
nIntervals
|
||||
end type tParameters
|
||||
|
@ -64,10 +64,10 @@ module function source_thermal_externalheat_init(source_length) result(mySources
|
|||
associate(prm => param(source_thermal_externalheat_instance(p)))
|
||||
src => sources%get(sourceOffset)
|
||||
|
||||
prm%time = src%get_asFloats('t_n')
|
||||
prm%nIntervals = size(prm%time) - 1
|
||||
prm%t_n = src%get_asFloats('t_n')
|
||||
prm%nIntervals = size(prm%t_n) - 1
|
||||
|
||||
prm%heat_rate = src%get_asFloats('f_T',requiredSize = size(prm%time))
|
||||
prm%f_T = src%get_asFloats('f_T',requiredSize = size(prm%t_n))
|
||||
|
||||
NipcMyPhase = count(material_phaseAt==p) * discretization_nIP
|
||||
call constitutive_allocateState(sourceState(p)%p(sourceOffset),NipcMyPhase,1,1,0)
|
||||
|
@ -121,13 +121,13 @@ module subroutine source_thermal_externalheat_getRateAndItsTangent(TDot, dTDot_d
|
|||
|
||||
associate(prm => param(source_thermal_externalheat_instance(phase)))
|
||||
do interval = 1, prm%nIntervals ! scan through all rate segments
|
||||
frac_time = (sourceState(phase)%p(sourceOffset)%state(1,of) - prm%time(interval)) &
|
||||
/ (prm%time(interval+1) - prm%time(interval)) ! fractional time within segment
|
||||
frac_time = (sourceState(phase)%p(sourceOffset)%state(1,of) - prm%t_n(interval)) &
|
||||
/ (prm%t_n(interval+1) - prm%t_n(interval)) ! fractional time within segment
|
||||
if ( (frac_time < 0.0_pReal .and. interval == 1) &
|
||||
.or. (frac_time >= 1.0_pReal .and. interval == prm%nIntervals) &
|
||||
.or. (frac_time >= 0.0_pReal .and. frac_time < 1.0_pReal) ) &
|
||||
TDot = prm%heat_rate(interval ) * (1.0_pReal - frac_time) + &
|
||||
prm%heat_rate(interval+1) * frac_time ! interpolate heat rate between segment boundaries...
|
||||
TDot = prm%f_T(interval ) * (1.0_pReal - frac_time) + &
|
||||
prm%f_T(interval+1) * frac_time ! interpolate heat rate between segment boundaries...
|
||||
! ...or extrapolate if outside of bounds
|
||||
enddo
|
||||
dTDot_dT = 0.0
|
||||
|
|
|
@ -169,7 +169,7 @@ function thermal_adiabatic_getSpecificHeat(ip,el)
|
|||
|
||||
do grain = 1, homogenization_Ngrains(material_homogenizationAt(el))
|
||||
thermal_adiabatic_getSpecificHeat = thermal_adiabatic_getSpecificHeat &
|
||||
+ lattice_specificHeat(material_phaseAt(grain,el))
|
||||
+ lattice_c_p(material_phaseAt(grain,el))
|
||||
enddo
|
||||
|
||||
thermal_adiabatic_getSpecificHeat = thermal_adiabatic_getSpecificHeat &
|
||||
|
@ -195,7 +195,7 @@ function thermal_adiabatic_getMassDensity(ip,el)
|
|||
|
||||
do grain = 1, homogenization_Ngrains(material_homogenizationAt(el))
|
||||
thermal_adiabatic_getMassDensity = thermal_adiabatic_getMassDensity &
|
||||
+ lattice_massDensity(material_phaseAt(grain,el))
|
||||
+ lattice_rho(material_phaseAt(grain,el))
|
||||
enddo
|
||||
|
||||
thermal_adiabatic_getMassDensity = thermal_adiabatic_getMassDensity &
|
||||
|
|
|
@ -127,7 +127,7 @@ function thermal_conduction_getConductivity(ip,el)
|
|||
thermal_conduction_getConductivity = 0.0_pReal
|
||||
do grain = 1, homogenization_Ngrains(material_homogenizationAt(el))
|
||||
thermal_conduction_getConductivity = thermal_conduction_getConductivity + &
|
||||
crystallite_push33ToRef(grain,ip,el,lattice_thermalConductivity(:,:,material_phaseAt(grain,el)))
|
||||
crystallite_push33ToRef(grain,ip,el,lattice_K(:,:,material_phaseAt(grain,el)))
|
||||
enddo
|
||||
|
||||
thermal_conduction_getConductivity = thermal_conduction_getConductivity &
|
||||
|
@ -153,7 +153,7 @@ function thermal_conduction_getSpecificHeat(ip,el)
|
|||
|
||||
do grain = 1, homogenization_Ngrains(material_homogenizationAt(el))
|
||||
thermal_conduction_getSpecificHeat = thermal_conduction_getSpecificHeat &
|
||||
+ lattice_specificHeat(material_phaseAt(grain,el))
|
||||
+ lattice_c_p(material_phaseAt(grain,el))
|
||||
enddo
|
||||
|
||||
thermal_conduction_getSpecificHeat = thermal_conduction_getSpecificHeat &
|
||||
|
@ -180,7 +180,7 @@ function thermal_conduction_getMassDensity(ip,el)
|
|||
|
||||
do grain = 1, homogenization_Ngrains(material_homogenizationAt(el))
|
||||
thermal_conduction_getMassDensity = thermal_conduction_getMassDensity &
|
||||
+ lattice_massDensity(material_phaseAt(grain,el))
|
||||
+ lattice_rho(material_phaseAt(grain,el))
|
||||
enddo
|
||||
|
||||
thermal_conduction_getMassDensity = thermal_conduction_getMassDensity &
|
||||
|
|
Loading…
Reference in New Issue