Merge branch 'development' into fix_homogenization_restart

This commit is contained in:
Vitesh Shah 2021-02-22 10:41:01 +01:00
commit 68d8aecb2b
73 changed files with 2546 additions and 2759 deletions

View File

@ -1 +1 @@
v3.0.0-alpha2-407-g47f52b909 v3.0.0-alpha2-478-gc9e4dc21f

View File

@ -1,9 +0,0 @@
step:
- mechanics:
dot_F: [0, 0, 0,
1e-3, 0, 0,
0, 0, 0]
discretization:
t: 60
N: 120
f_out: 20

View File

@ -1,10 +0,0 @@
---
step:
- mechanics:
dot_F: [0, 0, 1e-3,
0, 0, 0,
0, 0, 0]
discretization:
t: 60
N: 120
f_out: 20

View File

@ -1,25 +0,0 @@
---
step:
- mechanics:
dot_F: [1.0e-3, 0, 0,
0, x, 0,
0, 0, x]
P: [x, x, x,
x, 0, x,
x, x, 0]
discretization:
t: 10
N: 40
f_out: 4
- mechanics:
dot_F: [1.0e-3, 0, 0,
0, x, 0,
0, 0, x]
P: [x, x, x,
x, 0, x,
x, x, 0]
discretization:
t: 60
N: 60
f_out: 4

View File

@ -2,108 +2,108 @@
homogenization: homogenization:
SX: SX:
N_constituents: 1 N_constituents: 1
mechanics: {type: none} mechanics: {type: pass}
material: material:
- homogenization: SX - homogenization: SX
constituents: constituents:
- phase: Aluminum - phase: Aluminum
fraction: 1.0 v: 1.0
O: [1.0, 0.0, 0.0, 0.0] O: [1.0, 0.0, 0.0, 0.0]
- homogenization: SX - homogenization: SX
constituents: constituents:
- phase: Aluminum - phase: Aluminum
fraction: 1.0 v: 1.0
O: [0.7936696712125002, -0.28765777461664166, -0.3436487135089419, 0.4113964260949434] O: [0.7936696712125002, -0.28765777461664166, -0.3436487135089419, 0.4113964260949434]
- homogenization: SX - homogenization: SX
constituents: constituents:
- phase: Aluminum - phase: Aluminum
fraction: 1.0 v: 1.0
O: [0.3986143167493579, -0.7014883552495493, 0.2154871765709027, 0.5500781677772945] O: [0.3986143167493579, -0.7014883552495493, 0.2154871765709027, 0.5500781677772945]
- homogenization: SX - homogenization: SX
constituents: constituents:
- phase: Aluminum - phase: Aluminum
fraction: 1.0 v: 1.0
O: [0.28645844315788244, -0.022571491243423537, -0.467933059311115, -0.8357456192708106] O: [0.28645844315788244, -0.022571491243423537, -0.467933059311115, -0.8357456192708106]
- homogenization: SX - homogenization: SX
constituents: constituents:
- phase: Aluminum - phase: Aluminum
fraction: 1.0 v: 1.0
O: [0.33012772942625784, -0.6781865350268957, 0.6494525351030648, 0.09638521992649676] O: [0.33012772942625784, -0.6781865350268957, 0.6494525351030648, 0.09638521992649676]
- homogenization: SX - homogenization: SX
constituents: constituents:
- phase: Aluminum - phase: Aluminum
fraction: 1.0 v: 1.0
O: [0.43596817439583935, -0.5982537129781701, 0.046599032277502436, 0.6707106499919265] O: [0.43596817439583935, -0.5982537129781701, 0.046599032277502436, 0.6707106499919265]
- homogenization: SX - homogenization: SX
constituents: constituents:
- phase: Aluminum - phase: Aluminum
fraction: 1.0 v: 1.0
O: [0.169734823419553, -0.699615227367322, -0.6059581215838098, -0.33844257746495854] O: [0.169734823419553, -0.699615227367322, -0.6059581215838098, -0.33844257746495854]
- homogenization: SX - homogenization: SX
constituents: constituents:
- phase: Aluminum - phase: Aluminum
fraction: 1.0 v: 1.0
O: [0.9698864809294915, 0.1729052643205874, -0.15948307917616958, 0.06315956884687175] O: [0.9698864809294915, 0.1729052643205874, -0.15948307917616958, 0.06315956884687175]
- homogenization: SX - homogenization: SX
constituents: constituents:
- phase: Aluminum - phase: Aluminum
fraction: 1.0 v: 1.0
O: [0.46205660912967883, 0.3105054068891252, -0.617849551030653, 0.555294529545738] O: [0.46205660912967883, 0.3105054068891252, -0.617849551030653, 0.555294529545738]
- homogenization: SX - homogenization: SX
constituents: constituents:
- phase: Aluminum - phase: Aluminum
fraction: 1.0 v: 1.0
O: [0.4512443497461787, -0.7636045534540555, -0.04739348426715133, -0.45939142396805815] O: [0.4512443497461787, -0.7636045534540555, -0.04739348426715133, -0.45939142396805815]
- homogenization: SX - homogenization: SX
constituents: constituents:
- phase: Aluminum - phase: Aluminum
fraction: 1.0 v: 1.0
O: [0.2161856212656443, -0.6581450184826598, -0.5498086209601588, 0.4667112513346289] O: [0.2161856212656443, -0.6581450184826598, -0.5498086209601588, 0.4667112513346289]
- homogenization: SX - homogenization: SX
constituents: constituents:
- phase: Aluminum - phase: Aluminum
fraction: 1.0 v: 1.0
O: [0.8753220715350803, -0.4561599367657419, -0.13298279533852678, -0.08969369719975541] O: [0.8753220715350803, -0.4561599367657419, -0.13298279533852678, -0.08969369719975541]
- homogenization: SX - homogenization: SX
constituents: constituents:
- phase: Aluminum - phase: Aluminum
fraction: 1.0 v: 1.0
O: [0.11908260752431069, 0.18266024809834172, -0.7144822594012615, -0.664807992845101] O: [0.11908260752431069, 0.18266024809834172, -0.7144822594012615, -0.664807992845101]
- homogenization: SX - homogenization: SX
constituents: constituents:
- phase: Aluminum - phase: Aluminum
fraction: 1.0 v: 1.0
O: [0.751104669484278, 0.5585633382623958, -0.34579336397009175, 0.06538900566860861] O: [0.751104669484278, 0.5585633382623958, -0.34579336397009175, 0.06538900566860861]
- homogenization: SX - homogenization: SX
constituents: constituents:
- phase: Aluminum - phase: Aluminum
fraction: 1.0 v: 1.0
O: [0.08740438971703973, 0.8991264096610437, -0.4156704205935976, 0.10559485570696363] O: [0.08740438971703973, 0.8991264096610437, -0.4156704205935976, 0.10559485570696363]
- homogenization: SX - homogenization: SX
constituents: constituents:
- phase: Aluminum - phase: Aluminum
fraction: 1.0 v: 1.0
O: [0.5584325870096193, 0.6016408353068798, -0.14280340445801173, 0.5529814994483859] O: [0.5584325870096193, 0.6016408353068798, -0.14280340445801173, 0.5529814994483859]
- homogenization: SX - homogenization: SX
constituents: constituents:
- phase: Aluminum - phase: Aluminum
fraction: 1.0 v: 1.0
O: [0.4052725440888093, 0.25253073423599154, 0.5693263597910454, -0.669215876471182] O: [0.4052725440888093, 0.25253073423599154, 0.5693263597910454, -0.669215876471182]
- homogenization: SX - homogenization: SX
constituents: constituents:
- phase: Aluminum - phase: Aluminum
fraction: 1.0 v: 1.0
O: [0.7570164606888676, 0.15265448024694664, -0.5998021466848317, 0.20942796551297105] O: [0.7570164606888676, 0.15265448024694664, -0.5998021466848317, 0.20942796551297105]
- homogenization: SX - homogenization: SX
constituents: constituents:
- phase: Aluminum - phase: Aluminum
fraction: 1.0 v: 1.0
O: [0.6987659297138081, -0.132172211261028, -0.19693254724422338, 0.6748883269678543] O: [0.6987659297138081, -0.132172211261028, -0.19693254724422338, 0.6748883269678543]
- homogenization: SX - homogenization: SX
constituents: constituents:
- phase: Aluminum - phase: Aluminum
fraction: 1.0 v: 1.0
O: [0.7729330445886478, 0.21682179052722322, -0.5207379472917645, 0.2905078484066341] O: [0.7729330445886478, 0.21682179052722322, -0.5207379472917645, 0.2905078484066341]
phase: phase:

View File

@ -0,0 +1,15 @@
---
solver:
mechanical: spectral_basic
loadstep:
- boundary_conditions:
mechanical:
dot_F: [0, 0, 0,
1e-3, 0, 0,
0, 0, 0]
discretization:
t: 60
N: 120
f_out: 20

View File

@ -0,0 +1,15 @@
---
solver:
mechanical: spectral_basic
loadstep:
- boundary_conditions:
mechanical:
dot_F: [0, 0, 1e-3,
0, 0, 0,
0, 0, 0]
discretization:
t: 60
N: 120
f_out: 20

View File

@ -0,0 +1,30 @@
---
solver:
mechanical: spectral_basic
loadstep:
- boundary_conditions:
mechanical:
dot_F: [1.0e-3, 0, 0,
0, x, 0,
0, 0, x]
P: [x, x, x,
x, 0, x,
x, x, 0]
discretization:
t: 10
N: 40
f_out: 4
- boundary_conditions:
mechanical:
dot_F: [1.0e-3, 0, 0,
0, x, 0,
0, 0, x]
P: [x, x, x,
x, 0, x,
x, x, 0]
discretization:
t: 60
N: 60
f_out: 4

View File

@ -223,25 +223,46 @@ class Colormap(mpl.colors.ListedColormap):
return Colormap(np.array(rev.colors),rev.name[:-4] if rev.name.endswith('_r_r') else rev.name) return Colormap(np.array(rev.colors),rev.name[:-4] if rev.name.endswith('_r_r') else rev.name)
def _get_file_handle(self,fname,extension):
"""
Provide file handle.
Parameters
----------
fname : file, str, pathlib.Path, or None
Filename or filehandle, will be name of the colormap+extension if None.
extension: str
Extension of the filename.
Returns
-------
f
File handle
"""
if fname is None:
fhandle = open(self.name.replace(' ','_')+'.'+extension,'w',newline='\n')
else:
try:
fhandle = open(fname,'w',newline='\n')
except TypeError:
fhandle = fname
return fhandle
def save_paraview(self,fname=None): def save_paraview(self,fname=None):
""" """
Save as JSON file for use in Paraview. Save as JSON file for use in Paraview.
Parameters Parameters
---------- ----------
fname : file, str, or pathlib.Path, optional. fname : file, str, or pathlib.Path, optional
Filename to store results. If not given, the filename will Filename to store results. If not given, the filename will
consist of the name of the colormap and extension '.json'. consist of the name of the colormap and extension '.json'.
""" """
if fname is None:
fhandle = None
else:
try:
fhandle = open(fname,'w')
except TypeError:
fhandle = fname
colors = [] colors = []
for i,c in enumerate(np.round(self.colors,6).tolist()): for i,c in enumerate(np.round(self.colors,6).tolist()):
colors+=[i]+c colors+=[i]+c
@ -254,8 +275,7 @@ class Colormap(mpl.colors.ListedColormap):
'RGBPoints':colors 'RGBPoints':colors
}] }]
with open(self.name.replace(' ','_')+'.json', 'w') if fhandle is None else fhandle as f: json.dump(out,self._get_file_handle(fname,'json'),indent=4)
json.dump(out, f,indent=4)
def save_ASCII(self,fname=None): def save_ASCII(self,fname=None):
@ -264,24 +284,14 @@ class Colormap(mpl.colors.ListedColormap):
Parameters Parameters
---------- ----------
fname : file, str, or pathlib.Path, optional. fname : file, str, or pathlib.Path, optional
Filename to store results. If not given, the filename will Filename to store results. If not given, the filename will
consist of the name of the colormap and extension '.txt'. consist of the name of the colormap and extension '.txt'.
""" """
if fname is None:
fhandle = None
else:
try:
fhandle = open(fname,'w')
except TypeError:
fhandle = fname
labels = {'RGBA':4} if self.colors.shape[1] == 4 else {'RGB': 3} labels = {'RGBA':4} if self.colors.shape[1] == 4 else {'RGB': 3}
t = Table(self.colors,labels,f'Creator: {util.execution_stamp("Colormap")}') t = Table(self.colors,labels,f'Creator: {util.execution_stamp("Colormap")}')
t.save(self._get_file_handle(fname,'txt'))
with open(self.name.replace(' ','_')+'.txt', 'w') if fhandle is None else fhandle as f:
t.save(f)
def save_GOM(self,fname=None): def save_GOM(self,fname=None):
@ -290,26 +300,19 @@ class Colormap(mpl.colors.ListedColormap):
Parameters Parameters
---------- ----------
fname : file, str, or pathlib.Path, optional. fname : file, str, or pathlib.Path, optional
Filename to store results. If not given, the filename will Filename to store results. If not given, the filename will
consist of the name of the colormap and extension '.legend'. consist of the name of the colormap and extension '.legend'.
""" """
if fname is None:
fhandle = None
else:
try:
fhandle = open(fname,'w')
except TypeError:
fhandle = fname
# ToDo: test in GOM # ToDo: test in GOM
GOM_str = '1 1 {name} 9 {name} '.format(name=self.name.replace(" ","_")) \ GOM_str = '1 1 {name} 9 {name} '.format(name=self.name.replace(" ","_")) \
+ '0 1 0 3 0 0 -1 9 \\ 0 0 0 255 255 255 0 0 255 ' \ + '0 1 0 3 0 0 -1 9 \\ 0 0 0 255 255 255 0 0 255 ' \
+ f'30 NO_UNIT 1 1 64 64 64 255 1 0 0 0 0 0 0 3 0 {len(self.colors)}' \ + f'30 NO_UNIT 1 1 64 64 64 255 1 0 0 0 0 0 0 3 0 {len(self.colors)}' \
+ ' '.join([f' 0 {c[0]} {c[1]} {c[2]} 255 1' for c in reversed((self.colors*255).astype(int))]) \ + ' '.join([f' 0 {c[0]} {c[1]} {c[2]} 255 1' for c in reversed((self.colors*255).astype(int))]) \
+ '\n' + '\n'
with open(self.name.replace(' ','_')+'.legend', 'w') if fhandle is None else fhandle as f:
f.write(GOM_str) self._get_file_handle(fname,'legend').write(GOM_str)
def save_gmsh(self,fname=None): def save_gmsh(self,fname=None):
@ -318,24 +321,16 @@ class Colormap(mpl.colors.ListedColormap):
Parameters Parameters
---------- ----------
fname : file, str, or pathlib.Path, optional. fname : file, str, or pathlib.Path, optional
Filename to store results. If not given, the filename will Filename to store results. If not given, the filename will
consist of the name of the colormap and extension '.msh'. consist of the name of the colormap and extension '.msh'.
""" """
if fname is None:
fhandle = None
else:
try:
fhandle = open(fname,'w')
except TypeError:
fhandle = fname
# ToDo: test in gmsh # ToDo: test in gmsh
gmsh_str = 'View.ColorTable = {\n' \ gmsh_str = 'View.ColorTable = {\n' \
+'\n'.join([f'{c[0]},{c[1]},{c[2]},' for c in self.colors[:,:3]*255]) \ +'\n'.join([f'{c[0]},{c[1]},{c[2]},' for c in self.colors[:,:3]*255]) \
+'\n}\n' +'\n}\n'
with open(self.name.replace(' ','_')+'.msh', 'w') if fhandle is None else fhandle as f: self._get_file_handle(fname,'msh').write(gmsh_str)
f.write(gmsh_str)
@staticmethod @staticmethod

View File

@ -75,7 +75,7 @@ class Config(dict):
""" """
try: try:
fhandle = open(fname,'w') fhandle = open(fname,'w',newline='\n')
except TypeError: except TypeError:
fhandle = fname fhandle = fname

View File

@ -74,12 +74,12 @@ class ConfigMaterial(Config):
material: material:
- constituents: - constituents:
- O: [0.19, 0.8, 0.24, -0.51] - O: [0.19, 0.8, 0.24, -0.51]
fraction: 1.0 v: 1.0
phase: Aluminum phase: Aluminum
homogenization: SX homogenization: SX
- constituents: - constituents:
- O: [0.8, 0.19, 0.24, -0.51] - O: [0.8, 0.19, 0.24, -0.51]
fraction: 1.0 v: 1.0
phase: Steel phase: Steel
homogenization: SX homogenization: SX
homogenization: {} homogenization: {}
@ -168,11 +168,11 @@ class ConfigMaterial(Config):
ok = False ok = False
if 'material' in self: if 'material' in self:
for i,v in enumerate(self['material']): for i,m in enumerate(self['material']):
if 'constituents' in v: if 'constituents' in m:
f = 0.0 v = 0.0
for c in v['constituents']: for c in m['constituents']:
f+= float(c['fraction']) v+= float(c['v'])
if 'O' in c: if 'O' in c:
try: try:
Rotation.from_quaternion(c['O']) Rotation.from_quaternion(c['O'])
@ -180,8 +180,8 @@ class ConfigMaterial(Config):
o = c['O'] o = c['O']
print(f"Invalid orientation: '{o}' in material '{i}'") print(f"Invalid orientation: '{o}' in material '{i}'")
ok = False ok = False
if not np.isclose(f,1.0): if not np.isclose(v,1.0):
print(f"Invalid total fraction '{f}' in material '{i}'") print(f"Invalid total fraction (v) '{v}' in material '{i}'")
ok = False ok = False
return ok return ok
@ -257,17 +257,17 @@ class ConfigMaterial(Config):
material: material:
- constituents: - constituents:
- O: [0.577764, -0.146299, -0.617669, 0.513010] - O: [0.577764, -0.146299, -0.617669, 0.513010]
fraction: 1.0 v: 1.0
phase: Aluminum phase: Aluminum
homogenization: SX homogenization: SX
- constituents: - constituents:
- O: [0.184176, 0.340305, 0.737247, 0.553840] - O: [0.184176, 0.340305, 0.737247, 0.553840]
fraction: 1.0 v: 1.0
phase: Steel phase: Steel
homogenization: SX homogenization: SX
- constituents: - constituents:
- O: [0.0886257, -0.144848, 0.615674, -0.769487] - O: [0.0886257, -0.144848, 0.615674, -0.769487]
fraction: 1.0 v: 1.0
phase: Aluminum phase: Aluminum
homogenization: SX homogenization: SX
homogenization: {} homogenization: {}
@ -312,7 +312,7 @@ class ConfigMaterial(Config):
if hasattr(v,'__len__') and not isinstance(v,str): N_material = len(v) if hasattr(v,'__len__') and not isinstance(v,str): N_material = len(v)
if N == 1: if N == 1:
m = [[{'fraction':1.0}] for _ in range(N_material)] m = [[{'v':1.0}] for _ in range(N_material)]
for k,v in kwargs.items(): for k,v in kwargs.items():
if hasattr(v,'__len__') and not isinstance(v,str): if hasattr(v,'__len__') and not isinstance(v,str):
if len(v) != N_material: if len(v) != N_material:

View File

@ -1,3 +1,5 @@
import inspect
import numpy as np import numpy as np
from . import Rotation from . import Rotation
@ -7,7 +9,7 @@ from . import tensor
_parameter_doc = \ _parameter_doc = \
"""lattice : str """lattice : str
Either a crystal family out of [triclinic, monoclinic, orthorhombic, tetragonal, hexagonal, cubic] Either a crystal family out of [triclinic, monoclinic, orthorhombic, tetragonal, hexagonal, cubic]
or a Bravais lattice out of [aP, mP, mS, oP, oS, oI, oF, tP, tI, hP, cP, cI, cF]. or a Bravais lattice out of [aP, mP, mS, oP, oS, oI, oF, tP, tI, hP, cP, cI, cF].
When specifying a Bravais lattice, additional lattice parameters might be required: When specifying a Bravais lattice, additional lattice parameters might be required:
a : float, optional a : float, optional
Length of lattice parameter "a". Length of lattice parameter "a".
@ -107,8 +109,7 @@ class Orientation(Rotation):
lattice = None, lattice = None,
a = None,b = None,c = None, a = None,b = None,c = None,
alpha = None,beta = None,gamma = None, alpha = None,beta = None,gamma = None,
degrees = False, degrees = False):
**kwargs):
""" """
Initialize orientation object. Initialize orientation object.
@ -263,70 +264,112 @@ class Orientation(Rotation):
raise TypeError('Use "O@b", i.e. matmul, to apply Orientation "O" to object "b"') raise TypeError('Use "O@b", i.e. matmul, to apply Orientation "O" to object "b"')
@staticmethod
def _split_kwargs(kwargs,target):
"""
Separate keyword arguments in 'kwargs' targeted at 'target' from general keyword arguments of Orientation objects.
Parameters
----------
kwargs : dictionary
Contains all **kwargs.
target: method
Function to scan for kwarg signature.
Returns
-------
rot_kwargs: dictionary
Valid keyword arguments of 'target' function of Rotation class.
ori_kwargs: dictionary
Valid keyword arguments of Orientation object.
"""
kws = ()
for t in (target,Orientation.__init__):
kws += ({key: kwargs[key] for key in set(inspect.signature(t).parameters) & set(kwargs)},)
invalid_keys = set(kwargs)-(set(kws[0])|set(kws[1]))
if invalid_keys:
raise TypeError(f"{inspect.stack()[1][3]}() got an unexpected keyword argument '{invalid_keys.pop()}'")
return kws
@classmethod @classmethod
@util.extended_docstring(Rotation.from_random,_parameter_doc) @util.extended_docstring(Rotation.from_random,_parameter_doc)
def from_random(cls,**kwargs): def from_random(cls,**kwargs):
return cls(rotation=Rotation.from_random(**kwargs),**kwargs) kwargs_rot,kwargs_ori = Orientation._split_kwargs(kwargs,Rotation.from_random)
return cls(rotation=Rotation.from_random(**kwargs_rot),**kwargs_ori)
@classmethod @classmethod
@util.extended_docstring(Rotation.from_quaternion,_parameter_doc) @util.extended_docstring(Rotation.from_quaternion,_parameter_doc)
def from_quaternion(cls,**kwargs): def from_quaternion(cls,**kwargs):
return cls(rotation=Rotation.from_quaternion(**kwargs),**kwargs) kwargs_rot,kwargs_ori = Orientation._split_kwargs(kwargs,Rotation.from_quaternion)
return cls(rotation=Rotation.from_quaternion(**kwargs_rot),**kwargs_ori)
@classmethod @classmethod
@util.extended_docstring(Rotation.from_Euler_angles,_parameter_doc) @util.extended_docstring(Rotation.from_Euler_angles,_parameter_doc)
def from_Euler_angles(cls,**kwargs): def from_Euler_angles(cls,**kwargs):
return cls(rotation=Rotation.from_Euler_angles(**kwargs),**kwargs) kwargs_rot,kwargs_ori = Orientation._split_kwargs(kwargs,Rotation.from_Euler_angles)
return cls(rotation=Rotation.from_Euler_angles(**kwargs_rot),**kwargs_ori)
@classmethod @classmethod
@util.extended_docstring(Rotation.from_axis_angle,_parameter_doc) @util.extended_docstring(Rotation.from_axis_angle,_parameter_doc)
def from_axis_angle(cls,**kwargs): def from_axis_angle(cls,**kwargs):
return cls(rotation=Rotation.from_axis_angle(**kwargs),**kwargs) kwargs_rot,kwargs_ori = Orientation._split_kwargs(kwargs,Rotation.from_axis_angle)
return cls(rotation=Rotation.from_axis_angle(**kwargs_rot),**kwargs_ori)
@classmethod @classmethod
@util.extended_docstring(Rotation.from_basis,_parameter_doc) @util.extended_docstring(Rotation.from_basis,_parameter_doc)
def from_basis(cls,**kwargs): def from_basis(cls,**kwargs):
return cls(rotation=Rotation.from_basis(**kwargs),**kwargs) kwargs_rot,kwargs_ori = Orientation._split_kwargs(kwargs,Rotation.from_basis)
return cls(rotation=Rotation.from_basis(**kwargs_rot),**kwargs_ori)
@classmethod @classmethod
@util.extended_docstring(Rotation.from_matrix,_parameter_doc) @util.extended_docstring(Rotation.from_matrix,_parameter_doc)
def from_matrix(cls,**kwargs): def from_matrix(cls,**kwargs):
return cls(rotation=Rotation.from_matrix(**kwargs),**kwargs) kwargs_rot,kwargs_ori = Orientation._split_kwargs(kwargs,Rotation.from_matrix)
return cls(rotation=Rotation.from_matrix(**kwargs_rot),**kwargs_ori)
@classmethod @classmethod
@util.extended_docstring(Rotation.from_Rodrigues_vector,_parameter_doc) @util.extended_docstring(Rotation.from_Rodrigues_vector,_parameter_doc)
def from_Rodrigues_vector(cls,**kwargs): def from_Rodrigues_vector(cls,**kwargs):
return cls(rotation=Rotation.from_Rodrigues_vector(**kwargs),**kwargs) kwargs_rot,kwargs_ori = Orientation._split_kwargs(kwargs,Rotation.from_Rodrigues_vector)
return cls(rotation=Rotation.from_Rodrigues_vector(**kwargs_rot),**kwargs_ori)
@classmethod @classmethod
@util.extended_docstring(Rotation.from_homochoric,_parameter_doc) @util.extended_docstring(Rotation.from_homochoric,_parameter_doc)
def from_homochoric(cls,**kwargs): def from_homochoric(cls,**kwargs):
return cls(rotation=Rotation.from_homochoric(**kwargs),**kwargs) kwargs_rot,kwargs_ori = Orientation._split_kwargs(kwargs,Rotation.from_homochoric)
return cls(rotation=Rotation.from_homochoric(**kwargs_rot),**kwargs_ori)
@classmethod @classmethod
@util.extended_docstring(Rotation.from_cubochoric,_parameter_doc) @util.extended_docstring(Rotation.from_cubochoric,_parameter_doc)
def from_cubochoric(cls,**kwargs): def from_cubochoric(cls,**kwargs):
return cls(rotation=Rotation.from_cubochoric(**kwargs),**kwargs) kwargs_rot,kwargs_ori = Orientation._split_kwargs(kwargs,Rotation.from_cubochoric)
return cls(rotation=Rotation.from_cubochoric(**kwargs_rot),**kwargs_ori)
@classmethod @classmethod
@util.extended_docstring(Rotation.from_spherical_component,_parameter_doc) @util.extended_docstring(Rotation.from_spherical_component,_parameter_doc)
def from_spherical_component(cls,**kwargs): def from_spherical_component(cls,**kwargs):
return cls(rotation=Rotation.from_spherical_component(**kwargs),**kwargs) kwargs_rot,kwargs_ori = Orientation._split_kwargs(kwargs,Rotation.from_spherical_component)
return cls(rotation=Rotation.from_spherical_component(**kwargs_rot),**kwargs_ori)
@classmethod @classmethod
@util.extended_docstring(Rotation.from_fiber_component,_parameter_doc) @util.extended_docstring(Rotation.from_fiber_component,_parameter_doc)
def from_fiber_component(cls,**kwargs): def from_fiber_component(cls,**kwargs):
return cls(rotation=Rotation.from_fiber_component(**kwargs),**kwargs) kwargs_rot,kwargs_ori = Orientation._split_kwargs(kwargs,Rotation.from_fiber_component)
return cls(rotation=Rotation.from_fiber_component(**kwargs_rot),**kwargs_ori)
@classmethod @classmethod
@ -481,26 +524,26 @@ class Orientation(Rotation):
if self.family is None: if self.family is None:
raise ValueError('Missing crystal symmetry') raise ValueError('Missing crystal symmetry')
rho_abs = np.abs(self.as_Rodrigues_vector(compact=True)) rho_abs = np.abs(self.as_Rodrigues_vector(compact=True))*(1.-1.e-9)
with np.errstate(invalid='ignore'): with np.errstate(invalid='ignore'):
# using '*'/prod for 'and' # using '*'/prod for 'and'
if self.family == 'cubic': if self.family == 'cubic':
return (np.prod(np.sqrt(2)-1. >= rho_abs,axis=-1) * return (np.prod(np.sqrt(2)-1. >= rho_abs,axis=-1) *
(1. >= np.sum(rho_abs,axis=-1))).astype(np.bool) (1. >= np.sum(rho_abs,axis=-1))).astype(bool)
elif self.family == 'hexagonal': elif self.family == 'hexagonal':
return (np.prod(1. >= rho_abs,axis=-1) * return (np.prod(1. >= rho_abs,axis=-1) *
(2. >= np.sqrt(3)*rho_abs[...,0] + rho_abs[...,1]) * (2. >= np.sqrt(3)*rho_abs[...,0] + rho_abs[...,1]) *
(2. >= np.sqrt(3)*rho_abs[...,1] + rho_abs[...,0]) * (2. >= np.sqrt(3)*rho_abs[...,1] + rho_abs[...,0]) *
(2. >= np.sqrt(3) + rho_abs[...,2])).astype(np.bool) (2. >= np.sqrt(3) + rho_abs[...,2])).astype(bool)
elif self.family == 'tetragonal': elif self.family == 'tetragonal':
return (np.prod(1. >= rho_abs[...,:2],axis=-1) * return (np.prod(1. >= rho_abs[...,:2],axis=-1) *
(np.sqrt(2) >= rho_abs[...,0] + rho_abs[...,1]) * (np.sqrt(2) >= rho_abs[...,0] + rho_abs[...,1]) *
(np.sqrt(2) >= rho_abs[...,2] + 1.)).astype(np.bool) (np.sqrt(2) >= rho_abs[...,2] + 1.)).astype(bool)
elif self.family == 'orthorhombic': elif self.family == 'orthorhombic':
return (np.prod(1. >= rho_abs,axis=-1)).astype(np.bool) return (np.prod(1. >= rho_abs,axis=-1)).astype(bool)
elif self.family == 'monoclinic': elif self.family == 'monoclinic':
return (1. >= rho_abs[...,1]).astype(np.bool) return (1. >= rho_abs[...,1]).astype(bool)
else: else:
return np.all(np.isfinite(rho_abs),axis=-1) return np.all(np.isfinite(rho_abs),axis=-1)
@ -524,28 +567,28 @@ class Orientation(Rotation):
if self.family is None: if self.family is None:
raise ValueError('Missing crystal symmetry') raise ValueError('Missing crystal symmetry')
rho = self.as_Rodrigues_vector(compact=True) rho = self.as_Rodrigues_vector(compact=True)*(1.0-1.0e-9)
with np.errstate(invalid='ignore'): with np.errstate(invalid='ignore'):
if self.family == 'cubic': if self.family == 'cubic':
return ((rho[...,0] >= rho[...,1]) & return ((rho[...,0] >= rho[...,1]) &
(rho[...,1] >= rho[...,2]) & (rho[...,1] >= rho[...,2]) &
(rho[...,2] >= 0)).astype(np.bool) (rho[...,2] >= 0)).astype(bool)
elif self.family == 'hexagonal': elif self.family == 'hexagonal':
return ((rho[...,0] >= rho[...,1]*np.sqrt(3)) & return ((rho[...,0] >= rho[...,1]*np.sqrt(3)) &
(rho[...,1] >= 0) & (rho[...,1] >= 0) &
(rho[...,2] >= 0)).astype(np.bool) (rho[...,2] >= 0)).astype(bool)
elif self.family == 'tetragonal': elif self.family == 'tetragonal':
return ((rho[...,0] >= rho[...,1]) & return ((rho[...,0] >= rho[...,1]) &
(rho[...,1] >= 0) & (rho[...,1] >= 0) &
(rho[...,2] >= 0)).astype(np.bool) (rho[...,2] >= 0)).astype(bool)
elif self.family == 'orthorhombic': elif self.family == 'orthorhombic':
return ((rho[...,0] >= 0) & return ((rho[...,0] >= 0) &
(rho[...,1] >= 0) & (rho[...,1] >= 0) &
(rho[...,2] >= 0)).astype(np.bool) (rho[...,2] >= 0)).astype(bool)
elif self.family == 'monoclinic': elif self.family == 'monoclinic':
return ((rho[...,1] >= 0) & return ((rho[...,1] >= 0) &
(rho[...,2] >= 0)).astype(np.bool) (rho[...,2] >= 0)).astype(bool)
else: else:
return np.ones_like(rho[...,0],dtype=bool) return np.ones_like(rho[...,0],dtype=bool)

View File

@ -1287,7 +1287,7 @@ class Result:
np.prod(shape))} np.prod(shape))}
data_items[-1].text=f'{os.path.split(self.fname)[1]}:{name}' data_items[-1].text=f'{os.path.split(self.fname)[1]}:{name}'
with open(self.fname.with_suffix('.xdmf').name,'w') as f: with open(self.fname.with_suffix('.xdmf').name,'w',newline='\n') as f:
f.write(xml.dom.minidom.parseString(ET.tostring(xdmf).decode()).toprettyxml()) f.write(xml.dom.minidom.parseString(ET.tostring(xdmf).decode()).toprettyxml())

View File

@ -502,8 +502,8 @@ class Rotation:
Returns Returns
------- -------
c : numpy.ndarray of shape (...,3) x : numpy.ndarray of shape (...,3)
Cubochoric vector: (c_1, c_2, c_3), max(c_i) < 1/2*π^(2/3). Cubochoric vector: (x_1, x_2, x_3), max(x_i) < 1/2*π^(2/3).
""" """
return Rotation._qu2cu(self.quaternion) return Rotation._qu2cu(self.quaternion)
@ -514,8 +514,7 @@ class Rotation:
@staticmethod @staticmethod
def from_quaternion(q, def from_quaternion(q,
accept_homomorph = False, accept_homomorph = False,
P = -1, P = -1):
**kwargs):
""" """
Initialize from quaternion. Initialize from quaternion.
@ -550,8 +549,7 @@ class Rotation:
@staticmethod @staticmethod
def from_Euler_angles(phi, def from_Euler_angles(phi,
degrees = False, degrees = False):
**kwargs):
""" """
Initialize from Bunge-Euler angles. Initialize from Bunge-Euler angles.
@ -578,8 +576,7 @@ class Rotation:
def from_axis_angle(axis_angle, def from_axis_angle(axis_angle,
degrees = False, degrees = False,
normalize = False, normalize = False,
P = -1, P = -1):
**kwargs):
""" """
Initialize from Axis angle pair. Initialize from Axis angle pair.
@ -616,8 +613,7 @@ class Rotation:
@staticmethod @staticmethod
def from_basis(basis, def from_basis(basis,
orthonormal = True, orthonormal = True,
reciprocal = False, reciprocal = False):
**kwargs):
""" """
Initialize from lattice basis vectors. Initialize from lattice basis vectors.
@ -651,7 +647,7 @@ class Rotation:
return Rotation(Rotation._om2qu(om)) return Rotation(Rotation._om2qu(om))
@staticmethod @staticmethod
def from_matrix(R,**kwargs): def from_matrix(R):
""" """
Initialize from rotation matrix. Initialize from rotation matrix.
@ -695,8 +691,7 @@ class Rotation:
@staticmethod @staticmethod
def from_Rodrigues_vector(rho, def from_Rodrigues_vector(rho,
normalize = False, normalize = False,
P = -1, P = -1):
**kwargs):
""" """
Initialize from Rodrigues-Frank vector (angle separated from axis). Initialize from Rodrigues-Frank vector (angle separated from axis).
@ -727,8 +722,7 @@ class Rotation:
@staticmethod @staticmethod
def from_homochoric(h, def from_homochoric(h,
P = -1, P = -1):
**kwargs):
""" """
Initialize from homochoric vector. Initialize from homochoric vector.
@ -754,21 +748,20 @@ class Rotation:
return Rotation(Rotation._ho2qu(ho)) return Rotation(Rotation._ho2qu(ho))
@staticmethod @staticmethod
def from_cubochoric(c, def from_cubochoric(x,
P = -1, P = -1):
**kwargs):
""" """
Initialize from cubochoric vector. Initialize from cubochoric vector.
Parameters Parameters
---------- ----------
c : numpy.ndarray of shape (...,3) x : numpy.ndarray of shape (...,3)
Cubochoric vector: (c_1, c_2, c_3), max(c_i) < 1/2*π^(2/3). Cubochoric vector: (x_1, x_2, x_3), max(x_i) < 1/2*π^(2/3).
P : int {-1,1}, optional P : int {-1,1}, optional
Convention used. Defaults to -1. Convention used. Defaults to -1.
""" """
cu = np.array(c,dtype=float) cu = np.array(x,dtype=float)
if cu.shape[:-2:-1] != (3,): if cu.shape[:-2:-1] != (3,):
raise ValueError('Invalid shape.') raise ValueError('Invalid shape.')
if abs(P) != 1: if abs(P) != 1:
@ -784,8 +777,7 @@ class Rotation:
@staticmethod @staticmethod
def from_random(shape = None, def from_random(shape = None,
rng_seed = None, rng_seed = None):
**kwargs):
""" """
Draw random rotation. Draw random rotation.
@ -878,8 +870,7 @@ class Rotation:
sigma, sigma,
N = 500, N = 500,
degrees = True, degrees = True,
rng_seed = None, rng_seed = None):
**kwargs):
""" """
Calculate set of rotations with Gaussian distribution around center. Calculate set of rotations with Gaussian distribution around center.
@ -915,8 +906,7 @@ class Rotation:
sigma = 0.0, sigma = 0.0,
N = 500, N = 500,
degrees = True, degrees = True,
rng_seed = None, rng_seed = None):
**kwargs):
""" """
Calculate set of rotations with Gaussian distribution around direction. Calculate set of rotations with Gaussian distribution around direction.

View File

@ -26,7 +26,7 @@ class Table:
comments_ = [comments] if isinstance(comments,str) else comments comments_ = [comments] if isinstance(comments,str) else comments
self.comments = [] if comments_ is None else [c for c in comments_] self.comments = [] if comments_ is None else [c for c in comments_]
self.data = pd.DataFrame(data=data) self.data = pd.DataFrame(data=data)
self.shapes = { k:(v,) if isinstance(v,(np.int,int)) else v for k,v in shapes.items() } self.shapes = { k:(v,) if isinstance(v,(np.int64,np.int32,int)) else v for k,v in shapes.items() }
self._label_uniform() self._label_uniform()
def __repr__(self): def __repr__(self):
@ -380,7 +380,7 @@ class Table:
[f'# {comment}' for comment in self.comments] [f'# {comment}' for comment in self.comments]
try: try:
fhandle = open(fname,'w') fhandle = open(fname,'w',newline='\n')
except TypeError: except TypeError:
fhandle = fname fhandle = fname

View File

@ -347,23 +347,21 @@ class VTK:
See http://compilatrix.com/article/vtk-1 for further ideas. See http://compilatrix.com/article/vtk-1 for further ideas.
""" """
def screen_size(): try:
import wx
_ = wx.App(False) # noqa
width, height = wx.GetDisplaySize()
except ImportError:
try: try:
import wx import tkinter
_ = wx.App(False) # noqa tk = tkinter.Tk()
width, height = wx.GetDisplaySize() width = tk.winfo_screenwidth()
except ImportError: height = tk.winfo_screenheight()
try: tk.destroy()
import tkinter except Exception as e:
tk = tkinter.Tk() width = 1024
width = tk.winfo_screenwidth() height = 768
height = tk.winfo_screenheight()
tk.destroy()
except Exception as e:
width = 1024
height = 768
return (width,height)
mapper = vtk.vtkDataSetMapper() mapper = vtk.vtkDataSetMapper()
mapper.SetInputData(self.vtk_data) mapper.SetInputData(self.vtk_data)
actor = vtk.vtkActor() actor = vtk.vtkActor()
@ -377,7 +375,7 @@ class VTK:
ren.AddActor(actor) ren.AddActor(actor)
ren.SetBackground(0.2,0.2,0.2) ren.SetBackground(0.2,0.2,0.2)
window.SetSize(screen_size[0],screen_size[1]) window.SetSize(width,height)
iren = vtk.vtkRenderWindowInteractor() iren = vtk.vtkRenderWindowInteractor()
iren.SetRenderWindow(window) iren.SetRenderWindow(window)

View File

@ -66,7 +66,7 @@ class Marc:
if logfile is not None: if logfile is not None:
try: try:
f = open(logfile,'w+') f = open(logfile,'w+',newline='\n')
except TypeError: except TypeError:
f = logfile f = logfile
else: else:

View File

@ -1,32 +1,32 @@
homogenization: homogenization:
SX: SX:
N_constituents: 1 N_constituents: 1
mechanics: {type: none} mechanics: {type: pass}
Taylor: Taylor:
N_constituents: 2 N_constituents: 2
mechanics: {type: isostrain} mechanics: {type: isostrain}
material: material:
- constituents: - constituents:
- fraction: 1.0 - v: 1.0
O: [1.0, 0.0, 0.0, 0.0] O: [1.0, 0.0, 0.0, 0.0]
phase: Aluminum phase: Aluminum
homogenization: SX homogenization: SX
- constituents: - constituents:
- fraction: 1.0 - v: 1.0
O: [0.7936696712125002, -0.28765777461664166, -0.3436487135089419, 0.4113964260949434] O: [0.7936696712125002, -0.28765777461664166, -0.3436487135089419, 0.4113964260949434]
phase: Aluminum phase: Aluminum
homogenization: SX homogenization: SX
- constituents: - constituents:
- fraction: 1.0 - v: 1.0
O: [0.3986143167493579, -0.7014883552495493, 0.2154871765709027, 0.5500781677772945] O: [0.3986143167493579, -0.7014883552495493, 0.2154871765709027, 0.5500781677772945]
phase: Aluminum phase: Aluminum
homogenization: SX homogenization: SX
- constituents: - constituents:
- fraction: 0.5 - v: 0.5
O: [0.28645844315788244, -0.022571491243423537, -0.467933059311115, -0.8357456192708106] O: [0.28645844315788244, -0.022571491243423537, -0.467933059311115, -0.8357456192708106]
phase: Aluminum phase: Aluminum
- fraction: 0.5 - v: 0.5
O: [0.3986143167493579, -0.7014883552495493, 0.2154871765709027, 0.5500781677772945] O: [0.3986143167493579, -0.7014883552495493, 0.2154871765709027, 0.5500781677772945]
phase: Steel phase: Steel
homogenization: Taylor homogenization: Taylor

View File

@ -42,7 +42,7 @@ class TestConfigMaterial:
def test_invalid_fraction(self,ref_path): def test_invalid_fraction(self,ref_path):
material_config = ConfigMaterial.load(ref_path/'material.yaml') material_config = ConfigMaterial.load(ref_path/'material.yaml')
material_config['material'][0]['constituents'][0]['fraction']=.9 material_config['material'][0]['constituents'][0]['v']=.9
assert not material_config.is_valid assert not material_config.is_valid
@pytest.mark.parametrize('item',['homogenization','phase','material']) @pytest.mark.parametrize('item',['homogenization','phase','material'])

View File

@ -7,6 +7,7 @@ from damask import Orientation
from damask import Table from damask import Table
from damask import lattice from damask import lattice
from damask import util from damask import util
from damask import grid_filters
@pytest.fixture @pytest.fixture
@ -118,7 +119,7 @@ class TestOrientation:
== np.eye(3)) == np.eye(3))
def test_from_cubochoric(self): def test_from_cubochoric(self):
assert np.all(Orientation.from_cubochoric(c=np.zeros(3),lattice='triclinic').as_matrix() assert np.all(Orientation.from_cubochoric(x=np.zeros(3),lattice='triclinic').as_matrix()
== np.eye(3)) == np.eye(3))
def test_from_spherical_component(self): def test_from_spherical_component(self):
@ -141,7 +142,7 @@ class TestOrientation:
dict(lattice='hP',a=1.0 ), dict(lattice='hP',a=1.0 ),
dict(lattice='cI',a=1.0, ), dict(lattice='cI',a=1.0, ),
]) ])
def test_from_direction(self,kwargs): def test_from_directions(self,kwargs):
for a,b in np.random.random((10,2,3)): for a,b in np.random.random((10,2,3)):
c = np.cross(b,a) c = np.cross(b,a)
if np.all(np.isclose(c,0)): continue if np.all(np.isclose(c,0)): continue
@ -151,6 +152,21 @@ class TestOrientation:
assert np.isclose(np.dot(x/np.linalg.norm(x),np.array([1,0,0])),1) \ assert np.isclose(np.dot(x/np.linalg.norm(x),np.array([1,0,0])),1) \
and np.isclose(np.dot(z/np.linalg.norm(z),np.array([0,0,1])),1) and np.isclose(np.dot(z/np.linalg.norm(z),np.array([0,0,1])),1)
@pytest.mark.parametrize('function',[Orientation.from_random,
Orientation.from_quaternion,
Orientation.from_Euler_angles,
Orientation.from_axis_angle,
Orientation.from_basis,
Orientation.from_matrix,
Orientation.from_Rodrigues_vector,
Orientation.from_homochoric,
Orientation.from_cubochoric,
Orientation.from_spherical_component,
Orientation.from_fiber_component,
Orientation.from_directions])
def test_invalid_from(self,function):
with pytest.raises(TypeError):
function(c=.1,degrees=True,invalid=66)
def test_negative_angle(self): def test_negative_angle(self):
with pytest.raises(ValueError): with pytest.raises(ValueError):
@ -221,6 +237,16 @@ class TestOrientation:
for r, theO in zip(o.reduced.flatten(),o.flatten()): for r, theO in zip(o.reduced.flatten(),o.flatten()):
assert r == theO.reduced assert r == theO.reduced
@pytest.mark.parametrize('lattice',Orientation.crystal_families)
def test_reduced_corner_cases(self,lattice):
# test whether there is always a sym-eq rotation that falls into the FZ
N = np.random.randint(10,40)
size = np.ones(3)*np.pi**(2./3.)
grid = grid_filters.coordinates0_node([N+1,N+1,N+1],size,-size*.5)
evenly_distributed = Orientation.from_cubochoric(x=grid[:-2,:-2,:-2],lattice=lattice)
assert evenly_distributed.shape == evenly_distributed.reduced.shape
@pytest.mark.parametrize('lattice',Orientation.crystal_families) @pytest.mark.parametrize('lattice',Orientation.crystal_families)
@pytest.mark.parametrize('shape',[(1),(2,3),(4,3,2)]) @pytest.mark.parametrize('shape',[(1),(2,3),(4,3,2)])
@pytest.mark.parametrize('vector',np.array([[1,0,0],[1,2,3],[-1,1,-1]])) @pytest.mark.parametrize('vector',np.array([[1,0,0],[1,2,3],[-1,1,-1]]))

View File

@ -85,7 +85,7 @@ subroutine CPFEM_initAll
call discretization_marc_init call discretization_marc_init
call lattice_init call lattice_init
call material_init(.false.) call material_init(.false.)
call constitutive_init call phase_init
call homogenization_init call homogenization_init
call crystallite_init call crystallite_init
call CPFEM_init call CPFEM_init
@ -257,7 +257,7 @@ end subroutine CPFEM_general
subroutine CPFEM_forward subroutine CPFEM_forward
call homogenization_forward call homogenization_forward
call constitutive_forward call phase_forward
end subroutine CPFEM_forward end subroutine CPFEM_forward
@ -272,7 +272,7 @@ subroutine CPFEM_results(inc,time)
call results_openJobFile call results_openJobFile
call results_addIncrement(inc,time) call results_addIncrement(inc,time)
call constitutive_results call phase_results
call homogenization_results call homogenization_results
call discretization_results call discretization_results
call results_finalizeIncrement call results_finalizeIncrement

View File

@ -60,7 +60,7 @@ subroutine CPFEM_initAll
call discretization_grid_init(restart=interface_restartInc>0) call discretization_grid_init(restart=interface_restartInc>0)
#endif #endif
call material_init(restart=interface_restartInc>0) call material_init(restart=interface_restartInc>0)
call constitutive_init call phase_init
call homogenization_init call homogenization_init
call crystallite_init call crystallite_init
call CPFEM_init call CPFEM_init
@ -87,7 +87,7 @@ subroutine CPFEM_init
fileHandle = HDF5_openFile(fileName) fileHandle = HDF5_openFile(fileName)
call homogenization_restartRead(fileHandle) call homogenization_restartRead(fileHandle)
call constitutive_restartRead(fileHandle) call phase_restartRead(fileHandle)
call HDF5_closeFile(fileHandle) call HDF5_closeFile(fileHandle)
endif endif
@ -110,7 +110,7 @@ subroutine CPFEM_restartWrite
fileHandle = HDF5_openFile(fileName,'a') fileHandle = HDF5_openFile(fileName,'a')
call homogenization_restartWrite(fileHandle) call homogenization_restartWrite(fileHandle)
call constitutive_restartWrite(fileHandle) call phase_restartWrite(fileHandle)
call HDF5_closeFile(fileHandle) call HDF5_closeFile(fileHandle)
@ -123,7 +123,7 @@ end subroutine CPFEM_restartWrite
subroutine CPFEM_forward subroutine CPFEM_forward
call homogenization_forward call homogenization_forward
call constitutive_forward call phase_forward
end subroutine CPFEM_forward end subroutine CPFEM_forward
@ -138,7 +138,7 @@ subroutine CPFEM_results(inc,time)
call results_openJobFile call results_openJobFile
call results_addIncrement(inc,time) call results_addIncrement(inc,time)
call constitutive_results call phase_results
call homogenization_results call homogenization_results
call discretization_results call discretization_results
call results_finalizeIncrement call results_finalizeIncrement

View File

@ -65,8 +65,8 @@ end subroutine IO_init
function IO_readlines(fileName) result(fileContent) function IO_readlines(fileName) result(fileContent)
character(len=*), intent(in) :: fileName character(len=*), intent(in) :: fileName
character(len=pStringLen), dimension(:), allocatable :: fileContent !< file content, separated per lines character(len=pStringLen), dimension(:), allocatable :: fileContent !< file content, separated per lines
character(len=pStringLen) :: line character(len=pStringLen) :: line
character(len=:), allocatable :: rawData character(len=:), allocatable :: rawData
integer :: & integer :: &
@ -75,6 +75,7 @@ function IO_readlines(fileName) result(fileContent)
l l
logical :: warned logical :: warned
rawData = IO_read(fileName) rawData = IO_read(fileName)
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
@ -112,16 +113,21 @@ end function IO_readlines
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief Read whole file. !> @brief Read whole file.
!> @details ensures that the string ends with a new line (expected UNIX behavior) !> @details ensures that the string ends with a new line (expected UNIX behavior) and rejects
! windows (CRLF) line endings
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
function IO_read(fileName) result(fileContent) function IO_read(fileName) result(fileContent)
character(len=*), intent(in) :: fileName character(len=*), intent(in) :: fileName
character(len=:), allocatable :: fileContent character(len=:), allocatable :: fileContent
integer :: & integer :: &
fileLength, & fileLength, &
fileUnit, & fileUnit, &
myStat myStat, &
firstEOL
character, parameter :: CR = achar(13)
inquire(file = fileName, size=fileLength) inquire(file = fileName, size=fileLength)
open(newunit=fileUnit, file=fileName, access='stream',& open(newunit=fileUnit, file=fileName, access='stream',&
@ -137,8 +143,12 @@ function IO_read(fileName) result(fileContent)
if(myStat /= 0) call IO_error(102,ext_msg=trim(fileName)) if(myStat /= 0) call IO_error(102,ext_msg=trim(fileName))
close(fileUnit) close(fileUnit)
if(fileContent(fileLength:fileLength) /= IO_EOL) fileContent = fileContent//IO_EOL ! ensure EOL@EOF if(fileContent(fileLength:fileLength) /= IO_EOL) fileContent = fileContent//IO_EOL ! ensure EOL@EOF
firstEOL = index(fileContent,IO_EOL)
if(scan(fileContent(firstEOL:firstEOL),CR) /= 0) call IO_error(115)
end function IO_read end function IO_read
@ -151,6 +161,7 @@ logical pure function IO_isBlank(string)
integer :: posNonBlank integer :: posNonBlank
posNonBlank = verify(string,IO_WHITESPACE) posNonBlank = verify(string,IO_WHITESPACE)
IO_isBlank = posNonBlank == 0 .or. posNonBlank == scan(string,IO_COMMENT) IO_isBlank = posNonBlank == 0 .or. posNonBlank == scan(string,IO_COMMENT)
@ -170,6 +181,7 @@ pure function IO_stringPos(string)
integer :: left, right integer :: left, right
allocate(IO_stringPos(1), source=0) allocate(IO_stringPos(1), source=0)
right = 0 right = 0
@ -249,6 +261,7 @@ pure function IO_lc(string)
integer :: i,n integer :: i,n
do i=1,len(string) do i=1,len(string)
n = index(UPPER,string(i:i)) n = index(UPPER,string(i:i))
if(n/=0) then if(n/=0) then
@ -271,6 +284,7 @@ function IO_rmComment(line)
character(len=:), allocatable :: IO_rmComment character(len=:), allocatable :: IO_rmComment
integer :: split integer :: split
split = index(line,IO_COMMENT) split = index(line,IO_COMMENT)
if (split == 0) then if (split == 0) then
@ -292,6 +306,7 @@ integer function IO_stringAsInt(string)
integer :: readStatus integer :: readStatus
character(len=*), parameter :: VALIDCHARS = '0123456789+- ' character(len=*), parameter :: VALIDCHARS = '0123456789+- '
valid: if (verify(string,VALIDCHARS) == 0) then valid: if (verify(string,VALIDCHARS) == 0) then
read(string,*,iostat=readStatus) IO_stringAsInt read(string,*,iostat=readStatus) IO_stringAsInt
if (readStatus /= 0) call IO_error(111,ext_msg=string) if (readStatus /= 0) call IO_error(111,ext_msg=string)
@ -313,6 +328,7 @@ real(pReal) function IO_stringAsFloat(string)
integer :: readStatus integer :: readStatus
character(len=*), parameter :: VALIDCHARS = '0123456789eE.+- ' character(len=*), parameter :: VALIDCHARS = '0123456789eE.+- '
valid: if (verify(string,VALIDCHARS) == 0) then valid: if (verify(string,VALIDCHARS) == 0) then
read(string,*,iostat=readStatus) IO_stringAsFloat read(string,*,iostat=readStatus) IO_stringAsFloat
if (readStatus /= 0) call IO_error(112,ext_msg=string) if (readStatus /= 0) call IO_error(112,ext_msg=string)
@ -331,6 +347,7 @@ logical function IO_stringAsBool(string)
character(len=*), intent(in) :: string !< string for conversion to int value character(len=*), intent(in) :: string !< string for conversion to int value
if (trim(adjustl(string)) == 'True' .or. trim(adjustl(string)) == 'true') then if (trim(adjustl(string)) == 'True' .or. trim(adjustl(string)) == 'true') then
IO_stringAsBool = .true. IO_stringAsBool = .true.
elseif (trim(adjustl(string)) == 'False' .or. trim(adjustl(string)) == 'false') then elseif (trim(adjustl(string)) == 'False' .or. trim(adjustl(string)) == 'false') then
@ -356,6 +373,7 @@ subroutine IO_error(error_ID,el,ip,g,instance,ext_msg)
character(len=:), allocatable :: msg character(len=:), allocatable :: msg
character(len=pStringLen) :: formatString character(len=pStringLen) :: formatString
select case (error_ID) select case (error_ID)
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
@ -382,6 +400,9 @@ subroutine IO_error(error_ID,el,ip,g,instance,ext_msg)
msg = 'invalid character for logical:' msg = 'invalid character for logical:'
case (114) case (114)
msg = 'cannot decode base64 string:' msg = 'cannot decode base64 string:'
case (115)
msg = 'found CR. Windows file endings (CRLF) are not supported.'
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
! lattice error messages ! lattice error messages

View File

@ -20,19 +20,19 @@
#include "material.f90" #include "material.f90"
#include "lattice.f90" #include "lattice.f90"
#include "phase.f90" #include "phase.f90"
#include "phase_mechanics.f90" #include "phase_mechanical.f90"
#include "phase_mechanics_plastic.f90" #include "phase_mechanical_plastic.f90"
#include "phase_mechanics_plastic_none.f90" #include "phase_mechanical_plastic_none.f90"
#include "phase_mechanics_plastic_isotropic.f90" #include "phase_mechanical_plastic_isotropic.f90"
#include "phase_mechanics_plastic_phenopowerlaw.f90" #include "phase_mechanical_plastic_phenopowerlaw.f90"
#include "phase_mechanics_plastic_kinehardening.f90" #include "phase_mechanical_plastic_kinehardening.f90"
#include "phase_mechanics_plastic_dislotwin.f90" #include "phase_mechanical_plastic_dislotwin.f90"
#include "phase_mechanics_plastic_dislotungsten.f90" #include "phase_mechanical_plastic_dislotungsten.f90"
#include "phase_mechanics_plastic_nonlocal.f90" #include "phase_mechanical_plastic_nonlocal.f90"
#include "phase_mechanics_eigendeformation.f90" #include "phase_mechanical_eigen.f90"
#include "phase_mechanics_eigendeformation_cleavageopening.f90" #include "phase_mechanical_eigen_cleavageopening.f90"
#include "phase_mechanics_eigendeformation_slipplaneopening.f90" #include "phase_mechanical_eigen_slipplaneopening.f90"
#include "phase_mechanics_eigendeformation_thermalexpansion.f90" #include "phase_mechanical_eigen_thermalexpansion.f90"
#include "phase_thermal.f90" #include "phase_thermal.f90"
#include "phase_thermal_dissipation.f90" #include "phase_thermal_dissipation.f90"
#include "phase_thermal_externalheat.f90" #include "phase_thermal_externalheat.f90"
@ -41,13 +41,11 @@
#include "phase_damage_isoductile.f90" #include "phase_damage_isoductile.f90"
#include "phase_damage_anisobrittle.f90" #include "phase_damage_anisobrittle.f90"
#include "phase_damage_anisoductile.f90" #include "phase_damage_anisoductile.f90"
#include "damage_none.f90"
#include "damage_nonlocal.f90"
#include "homogenization.f90" #include "homogenization.f90"
#include "homogenization_mechanics.f90" #include "homogenization_mechanical.f90"
#include "homogenization_mechanics_none.f90" #include "homogenization_mechanical_pass.f90"
#include "homogenization_mechanics_isostrain.f90" #include "homogenization_mechanical_isostrain.f90"
#include "homogenization_mechanics_RGC.f90" #include "homogenization_mechanical_RGC.f90"
#include "homogenization_thermal.f90" #include "homogenization_thermal.f90"
#include "homogenization_damage.f90" #include "homogenization_damage.f90"
#include "CPFEM.f90" #include "CPFEM.f90"

View File

@ -5,16 +5,10 @@
!! precedence over material.yaml. !! precedence over material.yaml.
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
module config module config
use prec
use DAMASK_interface
use IO use IO
use YAML_parse use YAML_parse
use YAML_types use YAML_types
#ifdef PETSc
#include <petsc/finclude/petscsys.h>
use petscsys
#endif
implicit none implicit none
private private
@ -50,17 +44,12 @@ end subroutine config_init
subroutine parse_material subroutine parse_material
logical :: fileExists logical :: fileExists
character(len=:), allocatable :: fname
fname = getSolverJobName()//'.yaml'
inquire(file=fname,exist=fileExists) inquire(file='material.yaml',exist=fileExists)
if(.not. fileExists) then if(.not. fileExists) call IO_error(100,ext_msg='material.yaml')
fname = 'material.yaml' print*, 'reading material.yaml'; flush(IO_STDOUT)
inquire(file=fname,exist=fileExists) config_material => YAML_parse_file('material.yaml')
if(.not. fileExists) call IO_error(100,ext_msg=fname)
endif
print*, 'reading '//fname; flush(IO_STDOUT)
config_material => YAML_parse_file(fname)
end subroutine parse_material end subroutine parse_material
@ -72,6 +61,7 @@ subroutine parse_numerics
logical :: fexist logical :: fexist
config_numerics => emptyDict config_numerics => emptyDict
inquire(file='numerics.yaml', exist=fexist) inquire(file='numerics.yaml', exist=fexist)
if (fexist) then if (fexist) then
@ -89,6 +79,7 @@ subroutine parse_debug
logical :: fexist logical :: fexist
config_debug => emptyDict config_debug => emptyDict
inquire(file='debug.yaml', exist=fexist) inquire(file='debug.yaml', exist=fexist)
fileExists: if (fexist) then fileExists: if (fexist) then

View File

@ -1,38 +0,0 @@
!--------------------------------------------------------------------------------------------------
!> @author Pratheek Shanthraj, Max-Planck-Institut für Eisenforschung GmbH
!> @brief material subroutine for constant damage field
!--------------------------------------------------------------------------------------------------
module damage_none
use prec
use config
use material
implicit none
public
contains
!--------------------------------------------------------------------------------------------------
!> @brief allocates all neccessary fields, reads information from material configuration file
!--------------------------------------------------------------------------------------------------
subroutine damage_none_init
integer :: h,Nmaterialpoints
print'(/,a)', ' <<<+- damage_none init -+>>>'; flush(6)
do h = 1, size(material_name_homogenization)
if (damage_type(h) /= DAMAGE_NONE_ID) cycle
Nmaterialpoints = count(material_homogenizationAt == h)
damageState_h(h)%sizeState = 0
allocate(damageState_h(h)%state0 (0,Nmaterialpoints))
allocate(damageState_h(h)%state (0,Nmaterialpoints))
allocate (damage(h)%p(Nmaterialpoints), source=1.0_pReal)
enddo
end subroutine damage_none_init
end module damage_none

View File

@ -1,94 +0,0 @@
!--------------------------------------------------------------------------------------------------
!> @author Pratheek Shanthraj, Max-Planck-Institut für Eisenforschung GmbH
!> @brief material subroutine for non-locally evolving damage field
!--------------------------------------------------------------------------------------------------
module damage_nonlocal
use prec
use material
use config
use YAML_types
use lattice
use phase
use results
implicit none
private
type, private :: tNumerics
real(pReal) :: &
charLength !< characteristic length scale for gradient problems
end type tNumerics
type(tNumerics), private :: &
num
public :: &
damage_nonlocal_init, &
damage_nonlocal_getDiffusion
contains
!--------------------------------------------------------------------------------------------------
!> @brief module initialization
!> @details reads in material parameters, allocates arrays, and does sanity checks
!--------------------------------------------------------------------------------------------------
subroutine damage_nonlocal_init
integer :: Ninstances,Nmaterialpoints,h
class(tNode), pointer :: &
num_generic, &
material_homogenization
print'(/,a)', ' <<<+- damage_nonlocal init -+>>>'; flush(6)
!------------------------------------------------------------------------------------
! read numerics parameter
num_generic => config_numerics%get('generic',defaultVal= emptyDict)
num%charLength = num_generic%get_asFloat('charLength',defaultVal=1.0_pReal)
Ninstances = count(damage_type == DAMAGE_nonlocal_ID)
material_homogenization => config_material%get('homogenization')
do h = 1, material_homogenization%length
if (damage_type(h) /= DAMAGE_NONLOCAL_ID) cycle
Nmaterialpoints = count(material_homogenizationAt == h)
damageState_h(h)%sizeState = 1
allocate(damageState_h(h)%state0 (1,Nmaterialpoints), source=1.0_pReal)
allocate(damageState_h(h)%state (1,Nmaterialpoints), source=1.0_pReal)
damage(h)%p => damageState_h(h)%state(1,:)
enddo
end subroutine damage_nonlocal_init
!--------------------------------------------------------------------------------------------------
!> @brief returns homogenized non local damage diffusion tensor in reference configuration
!--------------------------------------------------------------------------------------------------
function damage_nonlocal_getDiffusion(ip,el)
integer, intent(in) :: &
ip, & !< integration point number
el !< element number
real(pReal), dimension(3,3) :: &
damage_nonlocal_getDiffusion
integer :: &
homog, &
grain
homog = material_homogenizationAt(el)
damage_nonlocal_getDiffusion = 0.0_pReal
do grain = 1, homogenization_Nconstituents(homog)
damage_nonlocal_getDiffusion = damage_nonlocal_getDiffusion + &
crystallite_push33ToRef(grain,ip,el,lattice_D(1:3,1:3,material_phaseAt(grain,el)))
enddo
damage_nonlocal_getDiffusion = &
num%charLength**2*damage_nonlocal_getDiffusion/real(homogenization_Nconstituents(homog),pReal)
end function damage_nonlocal_getDiffusion
end module damage_nonlocal

View File

@ -18,9 +18,9 @@ program DAMASK_grid
use CPFEM2 use CPFEM2
use material use material
use spectral_utilities use spectral_utilities
use grid_mech_spectral_basic use grid_mechanical_spectral_basic
use grid_mech_spectral_polarisation use grid_mechanical_spectral_polarisation
use grid_mech_FEM use grid_mechanical_FEM
use grid_damage_spectral use grid_damage_spectral
use grid_thermal_spectral use grid_thermal_spectral
use results use results
@ -36,7 +36,7 @@ program DAMASK_grid
integer :: N, & !< number of increments integer :: N, & !< number of increments
f_out, & !< frequency of result writes f_out, & !< frequency of result writes
f_restart !< frequency of restart writes f_restart !< frequency of restart writes
logical :: drop_guessing !< do not follow trajectory of former loadcase logical :: estimate_rate !< follow trajectory of former loadcase
integer(kind(FIELD_UNDEFINED_ID)), allocatable :: ID(:) integer(kind(FIELD_UNDEFINED_ID)), allocatable :: ID(:)
end type tLoadCase end type tLoadCase
@ -83,16 +83,16 @@ program DAMASK_grid
type(tLoadCase), allocatable, dimension(:) :: loadCases !< array of all load cases type(tLoadCase), allocatable, dimension(:) :: loadCases !< array of all load cases
type(tSolutionState), allocatable, dimension(:) :: solres type(tSolutionState), allocatable, dimension(:) :: solres
procedure(grid_mech_spectral_basic_init), pointer :: & procedure(grid_mechanical_spectral_basic_init), pointer :: &
mech_init mechanical_init
procedure(grid_mech_spectral_basic_forward), pointer :: & procedure(grid_mechanical_spectral_basic_forward), pointer :: &
mech_forward mechanical_forward
procedure(grid_mech_spectral_basic_solution), pointer :: & procedure(grid_mechanical_spectral_basic_solution), pointer :: &
mech_solution mechanical_solution
procedure(grid_mech_spectral_basic_updateCoords), pointer :: & procedure(grid_mechanical_spectral_basic_updateCoords), pointer :: &
mech_updateCoords mechanical_updateCoords
procedure(grid_mech_spectral_basic_restartWrite), pointer :: & procedure(grid_mechanical_spectral_basic_restartWrite), pointer :: &
mech_restartWrite mechanical_restartWrite
external :: & external :: &
quit quit
@ -102,6 +102,7 @@ program DAMASK_grid
config_load, & config_load, &
load_steps, & load_steps, &
load_step, & load_step, &
step_bc, &
step_mech, & step_mech, &
step_discretization, & step_discretization, &
step_deformation, & step_deformation, &
@ -138,25 +139,25 @@ program DAMASK_grid
debug_grid => config_debug%get('grid',defaultVal=emptyList) debug_grid => config_debug%get('grid',defaultVal=emptyList)
select case (trim(num_grid%get_asString('solver', defaultVal = 'Basic'))) select case (trim(num_grid%get_asString('solver', defaultVal = 'Basic')))
case ('Basic') case ('Basic')
mech_init => grid_mech_spectral_basic_init mechanical_init => grid_mechanical_spectral_basic_init
mech_forward => grid_mech_spectral_basic_forward mechanical_forward => grid_mechanical_spectral_basic_forward
mech_solution => grid_mech_spectral_basic_solution mechanical_solution => grid_mechanical_spectral_basic_solution
mech_updateCoords => grid_mech_spectral_basic_updateCoords mechanical_updateCoords => grid_mechanical_spectral_basic_updateCoords
mech_restartWrite => grid_mech_spectral_basic_restartWrite mechanical_restartWrite => grid_mechanical_spectral_basic_restartWrite
case ('Polarisation') case ('Polarisation')
mech_init => grid_mech_spectral_polarisation_init mechanical_init => grid_mechanical_spectral_polarisation_init
mech_forward => grid_mech_spectral_polarisation_forward mechanical_forward => grid_mechanical_spectral_polarisation_forward
mech_solution => grid_mech_spectral_polarisation_solution mechanical_solution => grid_mechanical_spectral_polarisation_solution
mech_updateCoords => grid_mech_spectral_polarisation_updateCoords mechanical_updateCoords => grid_mechanical_spectral_polarisation_updateCoords
mech_restartWrite => grid_mech_spectral_polarisation_restartWrite mechanical_restartWrite => grid_mechanical_spectral_polarisation_restartWrite
case ('FEM') case ('FEM')
mech_init => grid_mech_FEM_init mechanical_init => grid_mechanical_FEM_init
mech_forward => grid_mech_FEM_forward mechanical_forward => grid_mechanical_FEM_forward
mech_solution => grid_mech_FEM_solution mechanical_solution => grid_mechanical_FEM_solution
mech_updateCoords => grid_mech_FEM_updateCoords mechanical_updateCoords => grid_mechanical_FEM_updateCoords
mech_restartWrite => grid_mech_FEM_restartWrite mechanical_restartWrite => grid_mechanical_FEM_restartWrite
case default case default
call IO_error(error_ID = 891, ext_msg = trim(num_grid%get_asString('solver'))) call IO_error(error_ID = 891, ext_msg = trim(num_grid%get_asString('solver')))
@ -168,7 +169,7 @@ program DAMASK_grid
! reading information from load case file and to sanity checks ! reading information from load case file and to sanity checks
config_load => YAML_parse_file(trim(interface_loadFile)) config_load => YAML_parse_file(trim(interface_loadFile))
load_steps => config_load%get('step') load_steps => config_load%get('loadstep')
allocate(loadCases(load_steps%length)) ! array of load cases allocate(loadCases(load_steps%length)) ! array of load cases
do l = 1, load_steps%length do l = 1, load_steps%length
@ -186,8 +187,8 @@ program DAMASK_grid
endif damageActive endif damageActive
load_step => load_steps%get(l) load_step => load_steps%get(l)
step_bc => load_step%get('boundary_conditions')
step_mech => load_step%get('mechanics') step_mech => step_bc%get('mechanical')
loadCases(l)%stress%myType='' loadCases(l)%stress%myType=''
readMech: do m = 1, step_mech%length readMech: do m = 1, step_mech%length
select case (step_mech%getKey(m)) select case (step_mech%getKey(m))
@ -224,16 +225,16 @@ program DAMASK_grid
loadCases(l)%t = step_discretization%get_asFloat('t') loadCases(l)%t = step_discretization%get_asFloat('t')
loadCases(l)%N = step_discretization%get_asInt ('N') loadCases(l)%N = step_discretization%get_asInt ('N')
loadCases(l)%r = step_discretization%get_asFloat('r', defaultVal= 1.0_pReal) loadCases(l)%r = step_discretization%get_asFloat('r', defaultVal= 1.0_pReal)
loadCases(l)%f_out = step_discretization%get_asInt ('f_out', defaultVal=1)
loadCases(l)%f_restart = step_discretization%get_asInt ('f_restart', defaultVal=huge(0)) loadCases(l)%f_restart = step_discretization%get_asInt ('f_restart', defaultVal=huge(0))
loadCases(l)%drop_guessing = (load_step%get_asBool('drop_guessing',defaultVal=.false.) .or. & loadCases(l)%f_out = load_step%get_asInt('f_out', defaultVal=1)
merge(.false.,.true.,l > 1)) loadCases(l)%estimate_rate = (load_step%get_asBool('estimate_rate',defaultVal=.true.) .and. &
merge(.true.,.false.,l > 1))
reportAndCheck: if (worldrank == 0) then reportAndCheck: if (worldrank == 0) then
write (loadcase_string, '(i0)' ) l write (loadcase_string, '(i0)' ) l
print'(/,a,i0)', ' load case: ', l print'(/,a,i0)', ' load case: ', l
print*, ' drop_guessing:', loadCases(l)%drop_guessing print*, ' estimate_rate:', loadCases(l)%estimate_rate
if (loadCases(l)%deformation%myType == 'L') then if (loadCases(l)%deformation%myType == 'L') then
do j = 1, 3 do j = 1, 3
if (any(loadCases(l)%deformation%mask(j,1:3) .eqv. .true.) .and. & if (any(loadCases(l)%deformation%mask(j,1:3) .eqv. .true.) .and. &
@ -302,7 +303,7 @@ program DAMASK_grid
do field = 1, nActiveFields do field = 1, nActiveFields
select case (loadCases(1)%ID(field)) select case (loadCases(1)%ID(field))
case(FIELD_MECH_ID) case(FIELD_MECH_ID)
call mech_init call mechanical_init
case(FIELD_THERMAL_ID) case(FIELD_THERMAL_ID)
call grid_thermal_spectral_init call grid_thermal_spectral_init
@ -333,7 +334,7 @@ program DAMASK_grid
loadCaseLooping: do l = 1, size(loadCases) loadCaseLooping: do l = 1, size(loadCases)
time0 = time ! load case start time time0 = time ! load case start time
guess = .not. loadCases(l)%drop_guessing ! change of load case? homogeneous guess for the first inc guess = loadCases(l)%estimate_rate ! change of load case? homogeneous guess for the first inc
incLooping: do inc = 1, loadCases(l)%N incLooping: do inc = 1, loadCases(l)%N
totalIncsCounter = totalIncsCounter + 1 totalIncsCounter = totalIncsCounter + 1
@ -378,7 +379,7 @@ program DAMASK_grid
do field = 1, nActiveFields do field = 1, nActiveFields
select case(loadCases(l)%ID(field)) select case(loadCases(l)%ID(field))
case(FIELD_MECH_ID) case(FIELD_MECH_ID)
call mech_forward (& call mechanical_forward (&
cutBack,guess,timeinc,timeIncOld,remainingLoadCaseTime, & cutBack,guess,timeinc,timeIncOld,remainingLoadCaseTime, &
deformation_BC = loadCases(l)%deformation, & deformation_BC = loadCases(l)%deformation, &
stress_BC = loadCases(l)%stress, & stress_BC = loadCases(l)%stress, &
@ -398,7 +399,7 @@ program DAMASK_grid
do field = 1, nActiveFields do field = 1, nActiveFields
select case(loadCases(l)%ID(field)) select case(loadCases(l)%ID(field))
case(FIELD_MECH_ID) case(FIELD_MECH_ID)
solres(field) = mech_solution(incInfo) solres(field) = mechanical_solution(incInfo)
case(FIELD_THERMAL_ID) case(FIELD_THERMAL_ID)
solres(field) = grid_thermal_spectral_solution(timeinc) solres(field) = grid_thermal_spectral_solution(timeinc)
case(FIELD_DAMAGE_ID) case(FIELD_DAMAGE_ID)
@ -419,7 +420,7 @@ program DAMASK_grid
if ( (all(solres(:)%converged .and. solres(:)%stagConverged)) & ! converged if ( (all(solres(:)%converged .and. solres(:)%stagConverged)) & ! converged
.and. .not. solres(1)%termIll) then ! and acceptable solution found .and. .not. solres(1)%termIll) then ! and acceptable solution found
call mech_updateCoords call mechanical_updateCoords
timeIncOld = timeinc timeIncOld = timeinc
cutBack = .false. cutBack = .false.
guess = .true. ! start guessing after first converged (sub)inc guess = .true. ! start guessing after first converged (sub)inc
@ -462,7 +463,7 @@ program DAMASK_grid
call MPI_Allreduce(interface_SIGUSR2,signal,1,MPI_LOGICAL,MPI_LOR,PETSC_COMM_WORLD,ierr) call MPI_Allreduce(interface_SIGUSR2,signal,1,MPI_LOGICAL,MPI_LOR,PETSC_COMM_WORLD,ierr)
if (ierr /= 0) error stop 'MPI error' if (ierr /= 0) error stop 'MPI error'
if (mod(inc,loadCases(l)%f_restart) == 0 .or. signal) then if (mod(inc,loadCases(l)%f_restart) == 0 .or. signal) then
call mech_restartWrite call mechanical_restartWrite
call CPFEM_restartWrite call CPFEM_restartWrite
endif endif
if(signal) call interface_setSIGUSR2(.false.) if(signal) call interface_setSIGUSR2(.false.)

View File

@ -15,7 +15,6 @@ module grid_damage_spectral
use IO use IO
use spectral_utilities use spectral_utilities
use discretization_grid use discretization_grid
use damage_nonlocal
use YAML_types use YAML_types
use homogenization use homogenization
use config use config

View File

@ -4,7 +4,7 @@
!> @author Pratheek Shanthraj, Max-Planck-Institut für Eisenforschung GmbH !> @author Pratheek Shanthraj, Max-Planck-Institut für Eisenforschung GmbH
!> @brief Grid solver for mechanics: FEM !> @brief Grid solver for mechanics: FEM
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
module grid_mech_FEM module grid_mechanical_FEM
#include <petsc/finclude/petscsnes.h> #include <petsc/finclude/petscsnes.h>
#include <petsc/finclude/petscdmda.h> #include <petsc/finclude/petscdmda.h>
use PETScdmda use PETScdmda
@ -45,8 +45,8 @@ module grid_mech_FEM
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
! PETSc data ! PETSc data
DM :: mech_grid DM :: mechanical_grid
SNES :: mech_snes SNES :: mechanical_snes
Vec :: solution_current, solution_lastInc, solution_rate Vec :: solution_current, solution_lastInc, solution_rate
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
@ -79,18 +79,18 @@ module grid_mech_FEM
totalIter = 0 !< total iteration in current increment totalIter = 0 !< total iteration in current increment
public :: & public :: &
grid_mech_FEM_init, & grid_mechanical_FEM_init, &
grid_mech_FEM_solution, & grid_mechanical_FEM_solution, &
grid_mech_FEM_forward, & grid_mechanical_FEM_forward, &
grid_mech_FEM_updateCoords, & grid_mechanical_FEM_updateCoords, &
grid_mech_FEM_restartWrite grid_mechanical_FEM_restartWrite
contains contains
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief allocates all necessary fields and fills them with data, potentially from restart info !> @brief allocates all necessary fields and fills them with data, potentially from restart info
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
subroutine grid_mech_FEM_init subroutine grid_mechanical_FEM_init
real(pReal), parameter :: HGCoeff = 0.0e-2_pReal real(pReal), parameter :: HGCoeff = 0.0e-2_pReal
real(pReal), parameter, dimension(4,8) :: & real(pReal), parameter, dimension(4,8) :: &
@ -114,7 +114,7 @@ subroutine grid_mech_FEM_init
num_grid, & num_grid, &
debug_grid debug_grid
print'(/,a)', ' <<<+- grid_mech_FEM init -+>>>'; flush(IO_STDOUT) print'(/,a)', ' <<<+- grid_mechanical_FEM init -+>>>'; flush(IO_STDOUT)
!------------------------------------------------------------------------------------------------- !-------------------------------------------------------------------------------------------------
! debugging options ! debugging options
@ -141,8 +141,11 @@ subroutine grid_mech_FEM_init
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
! set default and user defined options for PETSc ! set default and user defined options for PETSc
call PetscOptionsInsertString(PETSC_NULL_OPTIONS,'-mech_snes_type newtonls -mech_ksp_type fgmres & call PetscOptionsInsertString(PETSC_NULL_OPTIONS, &
&-mech_ksp_max_it 25 -mech_pc_type ml -mech_mg_levels_ksp_type chebyshev',ierr) '-mechanical_snes_type newtonls -mechanical_ksp_type fgmres &
&-mechanical_ksp_max_it 25 -mechanical_pc_type ml &
&-mechanical_mg_levels_ksp_type chebyshev', &
ierr)
CHKERRQ(ierr) CHKERRQ(ierr)
call PetscOptionsInsertString(PETSC_NULL_OPTIONS,num_grid%get_asString('petsc_options',defaultVal=''),ierr) call PetscOptionsInsertString(PETSC_NULL_OPTIONS,num_grid%get_asString('petsc_options',defaultVal=''),ierr)
CHKERRQ(ierr) CHKERRQ(ierr)
@ -155,8 +158,10 @@ subroutine grid_mech_FEM_init
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
! initialize solver specific parts of PETSc ! initialize solver specific parts of PETSc
call SNESCreate(PETSC_COMM_WORLD,mech_snes,ierr); CHKERRQ(ierr) call SNESCreate(PETSC_COMM_WORLD,mechanical_snes,ierr)
call SNESSetOptionsPrefix(mech_snes,'mech_',ierr);CHKERRQ(ierr) CHKERRQ(ierr)
call SNESSetOptionsPrefix(mechanical_snes,'mechanical_',ierr)
CHKERRQ(ierr)
localK = 0 localK = 0
localK(worldrank) = grid3 localK(worldrank) = grid3
call MPI_Allreduce(MPI_IN_PLACE,localK,worldsize,MPI_INTEGER,MPI_SUM,PETSC_COMM_WORLD,ierr) call MPI_Allreduce(MPI_IN_PLACE,localK,worldsize,MPI_INTEGER,MPI_SUM,PETSC_COMM_WORLD,ierr)
@ -167,34 +172,44 @@ subroutine grid_mech_FEM_init
1, 1, worldsize, & 1, 1, worldsize, &
3, 1, & 3, 1, &
[grid(1)],[grid(2)],localK, & [grid(1)],[grid(2)],localK, &
mech_grid,ierr) mechanical_grid,ierr)
CHKERRQ(ierr) CHKERRQ(ierr)
call SNESSetDM(mech_snes,mech_grid,ierr); CHKERRQ(ierr) call SNESSetDM(mechanical_snes,mechanical_grid,ierr)
call DMsetFromOptions(mech_grid,ierr); CHKERRQ(ierr)
call DMsetUp(mech_grid,ierr); CHKERRQ(ierr)
call DMDASetUniformCoordinates(mech_grid,0.0_pReal,geomSize(1),0.0_pReal,geomSize(2),0.0_pReal,geomSize(3),ierr)
CHKERRQ(ierr) CHKERRQ(ierr)
call DMCreateGlobalVector(mech_grid,solution_current,ierr); CHKERRQ(ierr) call DMsetFromOptions(mechanical_grid,ierr)
call DMCreateGlobalVector(mech_grid,solution_lastInc,ierr); CHKERRQ(ierr)
call DMCreateGlobalVector(mech_grid,solution_rate ,ierr); CHKERRQ(ierr)
call DMSNESSetFunctionLocal(mech_grid,formResidual,PETSC_NULL_SNES,ierr)
CHKERRQ(ierr) CHKERRQ(ierr)
call DMSNESSetJacobianLocal(mech_grid,formJacobian,PETSC_NULL_SNES,ierr) call DMsetUp(mechanical_grid,ierr)
CHKERRQ(ierr) CHKERRQ(ierr)
call SNESSetConvergenceTest(mech_snes,converged,PETSC_NULL_SNES,PETSC_NULL_FUNCTION,ierr) ! specify custom convergence check function "_converged" call DMDASetUniformCoordinates(mechanical_grid,0.0_pReal,geomSize(1),0.0_pReal,geomSize(2),0.0_pReal,geomSize(3),ierr)
CHKERRQ(ierr)
call DMCreateGlobalVector(mechanical_grid,solution_current,ierr)
CHKERRQ(ierr)
call DMCreateGlobalVector(mechanical_grid,solution_lastInc,ierr)
CHKERRQ(ierr)
call DMCreateGlobalVector(mechanical_grid,solution_rate ,ierr)
CHKERRQ(ierr)
call DMSNESSetFunctionLocal(mechanical_grid,formResidual,PETSC_NULL_SNES,ierr)
CHKERRQ(ierr)
call DMSNESSetJacobianLocal(mechanical_grid,formJacobian,PETSC_NULL_SNES,ierr)
CHKERRQ(ierr)
call SNESSetConvergenceTest(mechanical_snes,converged,PETSC_NULL_SNES,PETSC_NULL_FUNCTION,ierr) ! specify custom convergence check function "_converged"
CHKERRQ(ierr)
call SNESSetMaxLinearSolveFailures(mechanical_snes, huge(1), ierr) ! ignore linear solve failures
CHKERRQ(ierr)
call SNESSetFromOptions(mechanical_snes,ierr) ! pull it all together with additional cli arguments
CHKERRQ(ierr) CHKERRQ(ierr)
call SNESSetMaxLinearSolveFailures(mech_snes, huge(1), ierr); CHKERRQ(ierr) ! ignore linear solve failures
call SNESSetFromOptions(mech_snes,ierr); CHKERRQ(ierr) ! pull it all together with additional cli arguments
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
! init fields ! init fields
call VecSet(solution_current,0.0_pReal,ierr);CHKERRQ(ierr) call VecSet(solution_current,0.0_pReal,ierr);CHKERRQ(ierr)
call VecSet(solution_lastInc,0.0_pReal,ierr);CHKERRQ(ierr) call VecSet(solution_lastInc,0.0_pReal,ierr);CHKERRQ(ierr)
call VecSet(solution_rate ,0.0_pReal,ierr);CHKERRQ(ierr) call VecSet(solution_rate ,0.0_pReal,ierr);CHKERRQ(ierr)
call DMDAVecGetArrayF90(mech_grid,solution_current,u_current,ierr); CHKERRQ(ierr) call DMDAVecGetArrayF90(mechanical_grid,solution_current,u_current,ierr)
call DMDAVecGetArrayF90(mech_grid,solution_lastInc,u_lastInc,ierr); CHKERRQ(ierr) CHKERRQ(ierr)
call DMDAVecGetArrayF90(mechanical_grid,solution_lastInc,u_lastInc,ierr)
CHKERRQ(ierr)
call DMDAGetCorners(mech_grid,xstart,ystart,zstart,xend,yend,zend,ierr) ! local grid extent call DMDAGetCorners(mechanical_grid,xstart,ystart,zstart,xend,yend,zend,ierr) ! local grid extent
CHKERRQ(ierr) CHKERRQ(ierr)
xend = xstart+xend-1 xend = xstart+xend-1
yend = ystart+yend-1 yend = ystart+yend-1
@ -242,9 +257,9 @@ subroutine grid_mech_FEM_init
call utilities_constitutiveResponse(P_current,P_av,C_volAvg,devNull, & ! stress field, stress avg, global average of stiffness and (min+max)/2 call utilities_constitutiveResponse(P_current,P_av,C_volAvg,devNull, & ! stress field, stress avg, global average of stiffness and (min+max)/2
F, & ! target F F, & ! target F
0.0_pReal) ! time increment 0.0_pReal) ! time increment
call DMDAVecRestoreArrayF90(mech_grid,solution_current,u_current,ierr) call DMDAVecRestoreArrayF90(mechanical_grid,solution_current,u_current,ierr)
CHKERRQ(ierr) CHKERRQ(ierr)
call DMDAVecRestoreArrayF90(mech_grid,solution_lastInc,u_lastInc,ierr) call DMDAVecRestoreArrayF90(mechanical_grid,solution_lastInc,u_lastInc,ierr)
CHKERRQ(ierr) CHKERRQ(ierr)
restartRead2: if (interface_restartInc > 0) then restartRead2: if (interface_restartInc > 0) then
@ -257,13 +272,13 @@ subroutine grid_mech_FEM_init
endif restartRead2 endif restartRead2
end subroutine grid_mech_FEM_init end subroutine grid_mechanical_FEM_init
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief solution for the FEM scheme with internal iterations !> @brief solution for the FEM scheme with internal iterations
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
function grid_mech_FEM_solution(incInfoIn) result(solution) function grid_mechanical_FEM_solution(incInfoIn) result(solution)
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
! input data for solution ! input data for solution
@ -284,11 +299,13 @@ function grid_mech_FEM_solution(incInfoIn) result(solution)
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
! solve BVP ! solve BVP
call SNESsolve(mech_snes,PETSC_NULL_VEC,solution_current,ierr); CHKERRQ(ierr) call SNESsolve(mechanical_snes,PETSC_NULL_VEC,solution_current,ierr)
CHKERRQ(ierr)
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
! check convergence ! check convergence
call SNESGetConvergedReason(mech_snes,reason,ierr); CHKERRQ(ierr) call SNESGetConvergedReason(mechanical_snes,reason,ierr)
CHKERRQ(ierr)
solution%converged = reason > 0 solution%converged = reason > 0
solution%iterationsNeeded = totalIter solution%iterationsNeeded = totalIter
@ -296,14 +313,14 @@ function grid_mech_FEM_solution(incInfoIn) result(solution)
terminallyIll = .false. terminallyIll = .false.
P_aim = merge(P_aim,P_av,params%stress_mask) P_aim = merge(P_aim,P_av,params%stress_mask)
end function grid_mech_FEM_solution end function grid_mechanical_FEM_solution
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief forwarding routine !> @brief forwarding routine
!> @details find new boundary conditions and best F estimate for end of current timestep !> @details find new boundary conditions and best F estimate for end of current timestep
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
subroutine grid_mech_FEM_forward(cutBack,guess,Delta_t,Delta_t_old,t_remaining,& subroutine grid_mechanical_FEM_forward(cutBack,guess,Delta_t,Delta_t_old,t_remaining,&
deformation_BC,stress_BC,rotation_BC) deformation_BC,stress_BC,rotation_BC)
logical, intent(in) :: & logical, intent(in) :: &
@ -323,8 +340,10 @@ subroutine grid_mech_FEM_forward(cutBack,guess,Delta_t,Delta_t_old,t_remaining,&
u_current,u_lastInc u_current,u_lastInc
call DMDAVecGetArrayF90(mech_grid,solution_current,u_current,ierr); CHKERRQ(ierr) call DMDAVecGetArrayF90(mechanical_grid,solution_current,u_current,ierr)
call DMDAVecGetArrayF90(mech_grid,solution_lastInc,u_lastInc,ierr); CHKERRQ(ierr) CHKERRQ(ierr)
call DMDAVecGetArrayF90(mechanical_grid,solution_lastInc,u_lastInc,ierr)
CHKERRQ(ierr)
if (cutBack) then if (cutBack) then
C_volAvg = C_volAvgLastInc C_volAvg = C_volAvgLastInc
@ -371,8 +390,10 @@ subroutine grid_mech_FEM_forward(cutBack,guess,Delta_t,Delta_t_old,t_remaining,&
call VecAXPY(solution_current,Delta_t,solution_rate,ierr); CHKERRQ(ierr) call VecAXPY(solution_current,Delta_t,solution_rate,ierr); CHKERRQ(ierr)
call DMDAVecRestoreArrayF90(mech_grid,solution_current,u_current,ierr); CHKERRQ(ierr) call DMDAVecRestoreArrayF90(mechanical_grid,solution_current,u_current,ierr)
call DMDAVecRestoreArrayF90(mech_grid,solution_lastInc,u_lastInc,ierr); CHKERRQ(ierr) CHKERRQ(ierr)
call DMDAVecRestoreArrayF90(mechanical_grid,solution_lastInc,u_lastInc,ierr)
CHKERRQ(ierr)
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
! set module wide available data ! set module wide available data
@ -380,31 +401,33 @@ subroutine grid_mech_FEM_forward(cutBack,guess,Delta_t,Delta_t_old,t_remaining,&
params%rotation_BC = rotation_BC params%rotation_BC = rotation_BC
params%timeinc = Delta_t params%timeinc = Delta_t
end subroutine grid_mech_FEM_forward end subroutine grid_mechanical_FEM_forward
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief Update coordinates !> @brief Update coordinates
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
subroutine grid_mech_FEM_updateCoords subroutine grid_mechanical_FEM_updateCoords
call utilities_updateCoords(F) call utilities_updateCoords(F)
end subroutine grid_mech_FEM_updateCoords end subroutine grid_mechanical_FEM_updateCoords
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief Write current solver and constitutive data for restart to file !> @brief Write current solver and constitutive data for restart to file
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
subroutine grid_mech_FEM_restartWrite subroutine grid_mechanical_FEM_restartWrite
PetscErrorCode :: ierr PetscErrorCode :: ierr
integer(HID_T) :: fileHandle, groupHandle integer(HID_T) :: fileHandle, groupHandle
PetscScalar, dimension(:,:,:,:), pointer :: u_current,u_lastInc PetscScalar, dimension(:,:,:,:), pointer :: u_current,u_lastInc
character(len=pStringLen) :: fileName character(len=pStringLen) :: fileName
call DMDAVecGetArrayF90(mech_grid,solution_current,u_current,ierr); CHKERRQ(ierr) call DMDAVecGetArrayF90(mechanical_grid,solution_current,u_current,ierr)
call DMDAVecGetArrayF90(mech_grid,solution_lastInc,u_lastInc,ierr); CHKERRQ(ierr) CHKERRQ(ierr)
call DMDAVecGetArrayF90(mechanical_grid,solution_lastInc,u_lastInc,ierr)
CHKERRQ(ierr)
print*, 'writing solver data required for restart to file'; flush(IO_STDOUT) print*, 'writing solver data required for restart to file'; flush(IO_STDOUT)
@ -427,10 +450,12 @@ subroutine grid_mech_FEM_restartWrite
call HDF5_closeGroup(groupHandle) call HDF5_closeGroup(groupHandle)
call HDF5_closeFile(fileHandle) call HDF5_closeFile(fileHandle)
call DMDAVecRestoreArrayF90(mech_grid,solution_current,u_current,ierr);CHKERRQ(ierr) call DMDAVecRestoreArrayF90(mechanical_grid,solution_current,u_current,ierr)
call DMDAVecRestoreArrayF90(mech_grid,solution_lastInc,u_lastInc,ierr);CHKERRQ(ierr) CHKERRQ(ierr)
call DMDAVecRestoreArrayF90(mechanical_grid,solution_lastInc,u_lastInc,ierr)
CHKERRQ(ierr)
end subroutine grid_mech_FEM_restartWrite end subroutine grid_mechanical_FEM_restartWrite
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
@ -498,8 +523,10 @@ subroutine formResidual(da_local,x_local, &
PetscErrorCode :: ierr PetscErrorCode :: ierr
real(pReal), dimension(3,3,3,3) :: devNull real(pReal), dimension(3,3,3,3) :: devNull
call SNESGetNumberFunctionEvals(mech_snes,nfuncs,ierr); CHKERRQ(ierr) call SNESGetNumberFunctionEvals(mechanical_snes,nfuncs,ierr)
call SNESGetIterationNumber(mech_snes,PETScIter,ierr); CHKERRQ(ierr) CHKERRQ(ierr)
call SNESGetIterationNumber(mechanical_snes,PETScIter,ierr)
CHKERRQ(ierr)
if (nfuncs == 0 .and. PETScIter == 0) totalIter = -1 ! new increment if (nfuncs == 0 .and. PETScIter == 0) totalIter = -1 ! new increment
@ -679,4 +706,4 @@ subroutine formJacobian(da_local,x_local,Jac_pre,Jac,dummy,ierr)
end subroutine formJacobian end subroutine formJacobian
end module grid_mech_FEM end module grid_mechanical_FEM

View File

@ -4,7 +4,7 @@
!> @author Philip Eisenlohr, Max-Planck-Institut für Eisenforschung GmbH !> @author Philip Eisenlohr, Max-Planck-Institut für Eisenforschung GmbH
!> @brief Grid solver for mechanics: Spectral basic !> @brief Grid solver for mechanics: Spectral basic
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
module grid_mech_spectral_basic module grid_mechanical_spectral_basic
#include <petsc/finclude/petscsnes.h> #include <petsc/finclude/petscsnes.h>
#include <petsc/finclude/petscdmda.h> #include <petsc/finclude/petscdmda.h>
use PETScdmda use PETScdmda
@ -79,18 +79,18 @@ module grid_mech_spectral_basic
totalIter = 0 !< total iteration in current increment totalIter = 0 !< total iteration in current increment
public :: & public :: &
grid_mech_spectral_basic_init, & grid_mechanical_spectral_basic_init, &
grid_mech_spectral_basic_solution, & grid_mechanical_spectral_basic_solution, &
grid_mech_spectral_basic_forward, & grid_mechanical_spectral_basic_forward, &
grid_mech_spectral_basic_updateCoords, & grid_mechanical_spectral_basic_updateCoords, &
grid_mech_spectral_basic_restartWrite grid_mechanical_spectral_basic_restartWrite
contains contains
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief allocates all necessary fields and fills them with data, potentially from restart info !> @brief allocates all necessary fields and fills them with data, potentially from restart info
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
subroutine grid_mech_spectral_basic_init subroutine grid_mechanical_spectral_basic_init
real(pReal), dimension(3,3,grid(1),grid(2),grid3) :: P real(pReal), dimension(3,3,grid(1),grid(2),grid3) :: P
PetscErrorCode :: ierr PetscErrorCode :: ierr
@ -105,7 +105,7 @@ subroutine grid_mech_spectral_basic_init
num_grid, & num_grid, &
debug_grid debug_grid
print'(/,a)', ' <<<+- grid_mech_spectral_basic init -+>>>'; flush(IO_STDOUT) print'(/,a)', ' <<<+- grid_mechanical_spectral_basic init -+>>>'; flush(IO_STDOUT)
print*, 'Eisenlohr et al., International Journal of Plasticity 46:3753, 2013' print*, 'Eisenlohr et al., International Journal of Plasticity 46:3753, 2013'
print*, 'https://doi.org/10.1016/j.ijplas.2012.09.012'//IO_EOL print*, 'https://doi.org/10.1016/j.ijplas.2012.09.012'//IO_EOL
@ -139,7 +139,7 @@ subroutine grid_mech_spectral_basic_init
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
! set default and user defined options for PETSc ! set default and user defined options for PETSc
call PetscOptionsInsertString(PETSC_NULL_OPTIONS,'-mech_snes_type ngmres',ierr) call PetscOptionsInsertString(PETSC_NULL_OPTIONS,'-mechanical_snes_type ngmres',ierr)
CHKERRQ(ierr) CHKERRQ(ierr)
call PetscOptionsInsertString(PETSC_NULL_OPTIONS,num_grid%get_asString('petsc_options',defaultVal=''),ierr) call PetscOptionsInsertString(PETSC_NULL_OPTIONS,num_grid%get_asString('petsc_options',defaultVal=''),ierr)
CHKERRQ(ierr) CHKERRQ(ierr)
@ -152,7 +152,7 @@ subroutine grid_mech_spectral_basic_init
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
! initialize solver specific parts of PETSc ! initialize solver specific parts of PETSc
call SNESCreate(PETSC_COMM_WORLD,snes,ierr); CHKERRQ(ierr) call SNESCreate(PETSC_COMM_WORLD,snes,ierr); CHKERRQ(ierr)
call SNESSetOptionsPrefix(snes,'mech_',ierr);CHKERRQ(ierr) call SNESSetOptionsPrefix(snes,'mechanical_',ierr);CHKERRQ(ierr)
localK = 0 localK = 0
localK(worldrank) = grid3 localK(worldrank) = grid3
call MPI_Allreduce(MPI_IN_PLACE,localK,worldsize,MPI_INTEGER,MPI_SUM,PETSC_COMM_WORLD,ierr) call MPI_Allreduce(MPI_IN_PLACE,localK,worldsize,MPI_INTEGER,MPI_SUM,PETSC_COMM_WORLD,ierr)
@ -222,13 +222,13 @@ subroutine grid_mech_spectral_basic_init
call utilities_updateGamma(C_minMaxAvg) call utilities_updateGamma(C_minMaxAvg)
call utilities_saveReferenceStiffness call utilities_saveReferenceStiffness
end subroutine grid_mech_spectral_basic_init end subroutine grid_mechanical_spectral_basic_init
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief solution for the basic scheme with internal iterations !> @brief solution for the basic scheme with internal iterations
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
function grid_mech_spectral_basic_solution(incInfoIn) result(solution) function grid_mechanical_spectral_basic_solution(incInfoIn) result(solution)
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
! input data for solution ! input data for solution
@ -262,14 +262,14 @@ function grid_mech_spectral_basic_solution(incInfoIn) result(solution)
terminallyIll = .false. terminallyIll = .false.
P_aim = merge(P_aim,P_av,params%stress_mask) P_aim = merge(P_aim,P_av,params%stress_mask)
end function grid_mech_spectral_basic_solution end function grid_mechanical_spectral_basic_solution
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief forwarding routine !> @brief forwarding routine
!> @details find new boundary conditions and best F estimate for end of current timestep !> @details find new boundary conditions and best F estimate for end of current timestep
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
subroutine grid_mech_spectral_basic_forward(cutBack,guess,Delta_t,Delta_t_old,t_remaining,& subroutine grid_mechanical_spectral_basic_forward(cutBack,guess,Delta_t,Delta_t_old,t_remaining,&
deformation_BC,stress_BC,rotation_BC) deformation_BC,stress_BC,rotation_BC)
logical, intent(in) :: & logical, intent(in) :: &
@ -339,13 +339,13 @@ subroutine grid_mech_spectral_basic_forward(cutBack,guess,Delta_t,Delta_t_old,t_
params%rotation_BC = rotation_BC params%rotation_BC = rotation_BC
params%timeinc = Delta_t params%timeinc = Delta_t
end subroutine grid_mech_spectral_basic_forward end subroutine grid_mechanical_spectral_basic_forward
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief Update coordinates !> @brief Update coordinates
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
subroutine grid_mech_spectral_basic_updateCoords subroutine grid_mechanical_spectral_basic_updateCoords
PetscErrorCode :: ierr PetscErrorCode :: ierr
PetscScalar, dimension(:,:,:,:), pointer :: F PetscScalar, dimension(:,:,:,:), pointer :: F
@ -354,13 +354,13 @@ subroutine grid_mech_spectral_basic_updateCoords
call utilities_updateCoords(F) call utilities_updateCoords(F)
call DMDAVecRestoreArrayF90(da,solution_vec,F,ierr); CHKERRQ(ierr) call DMDAVecRestoreArrayF90(da,solution_vec,F,ierr); CHKERRQ(ierr)
end subroutine grid_mech_spectral_basic_updateCoords end subroutine grid_mechanical_spectral_basic_updateCoords
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief Write current solver and constitutive data for restart to file !> @brief Write current solver and constitutive data for restart to file
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
subroutine grid_mech_spectral_basic_restartWrite subroutine grid_mechanical_spectral_basic_restartWrite
PetscErrorCode :: ierr PetscErrorCode :: ierr
integer(HID_T) :: fileHandle, groupHandle integer(HID_T) :: fileHandle, groupHandle
@ -393,7 +393,7 @@ subroutine grid_mech_spectral_basic_restartWrite
call DMDAVecRestoreArrayF90(da,solution_vec,F,ierr); CHKERRQ(ierr) call DMDAVecRestoreArrayF90(da,solution_vec,F,ierr); CHKERRQ(ierr)
end subroutine grid_mech_spectral_basic_restartWrite end subroutine grid_mechanical_spectral_basic_restartWrite
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
@ -506,4 +506,4 @@ subroutine formResidual(in, F, &
end subroutine formResidual end subroutine formResidual
end module grid_mech_spectral_basic end module grid_mechanical_spectral_basic

View File

@ -4,7 +4,7 @@
!> @author Philip Eisenlohr, Max-Planck-Institut für Eisenforschung GmbH !> @author Philip Eisenlohr, Max-Planck-Institut für Eisenforschung GmbH
!> @brief Grid solver for mechanics: Spectral Polarisation !> @brief Grid solver for mechanics: Spectral Polarisation
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
module grid_mech_spectral_polarisation module grid_mechanical_spectral_polarisation
#include <petsc/finclude/petscsnes.h> #include <petsc/finclude/petscsnes.h>
#include <petsc/finclude/petscdmda.h> #include <petsc/finclude/petscdmda.h>
use PETScdmda use PETScdmda
@ -90,18 +90,18 @@ module grid_mech_spectral_polarisation
totalIter = 0 !< total iteration in current increment totalIter = 0 !< total iteration in current increment
public :: & public :: &
grid_mech_spectral_polarisation_init, & grid_mechanical_spectral_polarisation_init, &
grid_mech_spectral_polarisation_solution, & grid_mechanical_spectral_polarisation_solution, &
grid_mech_spectral_polarisation_forward, & grid_mechanical_spectral_polarisation_forward, &
grid_mech_spectral_polarisation_updateCoords, & grid_mechanical_spectral_polarisation_updateCoords, &
grid_mech_spectral_polarisation_restartWrite grid_mechanical_spectral_polarisation_restartWrite
contains contains
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief allocates all necessary fields and fills them with data, potentially from restart info !> @brief allocates all necessary fields and fills them with data, potentially from restart info
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
subroutine grid_mech_spectral_polarisation_init subroutine grid_mechanical_spectral_polarisation_init
real(pReal), dimension(3,3,grid(1),grid(2),grid3) :: P real(pReal), dimension(3,3,grid(1),grid(2),grid3) :: P
PetscErrorCode :: ierr PetscErrorCode :: ierr
@ -118,7 +118,7 @@ subroutine grid_mech_spectral_polarisation_init
num_grid, & num_grid, &
debug_grid debug_grid
print'(/,a)', ' <<<+- grid_mech_spectral_polarisation init -+>>>'; flush(IO_STDOUT) print'(/,a)', ' <<<+- grid_mechanical_spectral_polarisation init -+>>>'; flush(IO_STDOUT)
print*, 'Shanthraj et al., International Journal of Plasticity 66:3145, 2015' print*, 'Shanthraj et al., International Journal of Plasticity 66:3145, 2015'
print*, 'https://doi.org/10.1016/j.ijplas.2014.02.006' print*, 'https://doi.org/10.1016/j.ijplas.2014.02.006'
@ -157,7 +157,7 @@ subroutine grid_mech_spectral_polarisation_init
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
! set default and user defined options for PETSc ! set default and user defined options for PETSc
call PetscOptionsInsertString(PETSC_NULL_OPTIONS,'-mech_snes_type ngmres',ierr) call PetscOptionsInsertString(PETSC_NULL_OPTIONS,'-mechanical_snes_type ngmres',ierr)
CHKERRQ(ierr) CHKERRQ(ierr)
call PetscOptionsInsertString(PETSC_NULL_OPTIONS,num_grid%get_asString('petsc_options',defaultVal=''),ierr) call PetscOptionsInsertString(PETSC_NULL_OPTIONS,num_grid%get_asString('petsc_options',defaultVal=''),ierr)
CHKERRQ(ierr) CHKERRQ(ierr)
@ -172,7 +172,7 @@ subroutine grid_mech_spectral_polarisation_init
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
! initialize solver specific parts of PETSc ! initialize solver specific parts of PETSc
call SNESCreate(PETSC_COMM_WORLD,snes,ierr); CHKERRQ(ierr) call SNESCreate(PETSC_COMM_WORLD,snes,ierr); CHKERRQ(ierr)
call SNESSetOptionsPrefix(snes,'mech_',ierr);CHKERRQ(ierr) call SNESSetOptionsPrefix(snes,'mechanical_',ierr);CHKERRQ(ierr)
localK = 0 localK = 0
localK(worldrank) = grid3 localK(worldrank) = grid3
call MPI_Allreduce(MPI_IN_PLACE,localK,worldsize,MPI_INTEGER,MPI_SUM,PETSC_COMM_WORLD,ierr) call MPI_Allreduce(MPI_IN_PLACE,localK,worldsize,MPI_INTEGER,MPI_SUM,PETSC_COMM_WORLD,ierr)
@ -250,13 +250,13 @@ subroutine grid_mech_spectral_polarisation_init
C_scale = C_minMaxAvg C_scale = C_minMaxAvg
S_scale = math_invSym3333(C_minMaxAvg) S_scale = math_invSym3333(C_minMaxAvg)
end subroutine grid_mech_spectral_polarisation_init end subroutine grid_mechanical_spectral_polarisation_init
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief solution for the Polarisation scheme with internal iterations !> @brief solution for the Polarisation scheme with internal iterations
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
function grid_mech_spectral_polarisation_solution(incInfoIn) result(solution) function grid_mechanical_spectral_polarisation_solution(incInfoIn) result(solution)
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
! input data for solution ! input data for solution
@ -294,14 +294,14 @@ function grid_mech_spectral_polarisation_solution(incInfoIn) result(solution)
terminallyIll = .false. terminallyIll = .false.
P_aim = merge(P_aim,P_av,params%stress_mask) P_aim = merge(P_aim,P_av,params%stress_mask)
end function grid_mech_spectral_polarisation_solution end function grid_mechanical_spectral_polarisation_solution
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief forwarding routine !> @brief forwarding routine
!> @details find new boundary conditions and best F estimate for end of current timestep !> @details find new boundary conditions and best F estimate for end of current timestep
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
subroutine grid_mech_spectral_polarisation_forward(cutBack,guess,Delta_t,Delta_t_old,t_remaining,& subroutine grid_mechanical_spectral_polarisation_forward(cutBack,guess,Delta_t,Delta_t_old,t_remaining,&
deformation_BC,stress_BC,rotation_BC) deformation_BC,stress_BC,rotation_BC)
logical, intent(in) :: & logical, intent(in) :: &
@ -393,13 +393,13 @@ subroutine grid_mech_spectral_polarisation_forward(cutBack,guess,Delta_t,Delta_t
params%rotation_BC = rotation_BC params%rotation_BC = rotation_BC
params%timeinc = Delta_t params%timeinc = Delta_t
end subroutine grid_mech_spectral_polarisation_forward end subroutine grid_mechanical_spectral_polarisation_forward
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief Update coordinates !> @brief Update coordinates
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
subroutine grid_mech_spectral_polarisation_updateCoords subroutine grid_mechanical_spectral_polarisation_updateCoords
PetscErrorCode :: ierr PetscErrorCode :: ierr
PetscScalar, dimension(:,:,:,:), pointer :: FandF_tau PetscScalar, dimension(:,:,:,:), pointer :: FandF_tau
@ -408,13 +408,13 @@ subroutine grid_mech_spectral_polarisation_updateCoords
call utilities_updateCoords(FandF_tau(0:8,:,:,:)) call utilities_updateCoords(FandF_tau(0:8,:,:,:))
call DMDAVecRestoreArrayF90(da,solution_vec,FandF_tau,ierr); CHKERRQ(ierr) call DMDAVecRestoreArrayF90(da,solution_vec,FandF_tau,ierr); CHKERRQ(ierr)
end subroutine grid_mech_spectral_polarisation_updateCoords end subroutine grid_mechanical_spectral_polarisation_updateCoords
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief Write current solver and constitutive data for restart to file !> @brief Write current solver and constitutive data for restart to file
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
subroutine grid_mech_spectral_polarisation_restartWrite subroutine grid_mechanical_spectral_polarisation_restartWrite
PetscErrorCode :: ierr PetscErrorCode :: ierr
integer(HID_T) :: fileHandle, groupHandle integer(HID_T) :: fileHandle, groupHandle
@ -450,7 +450,7 @@ subroutine grid_mech_spectral_polarisation_restartWrite
call DMDAVecRestoreArrayF90(da,solution_vec,FandF_tau,ierr); CHKERRQ(ierr) call DMDAVecRestoreArrayF90(da,solution_vec,FandF_tau,ierr); CHKERRQ(ierr)
end subroutine grid_mech_spectral_polarisation_restartWrite end subroutine grid_mechanical_spectral_polarisation_restartWrite
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
@ -618,4 +618,4 @@ subroutine formResidual(in, FandF_tau, &
end subroutine formResidual end subroutine formResidual
end module grid_mech_spectral_polarisation end module grid_mechanical_spectral_polarisation

View File

@ -12,14 +12,53 @@ module homogenization
use material use material
use phase use phase
use discretization use discretization
use damage_none
use damage_nonlocal
use HDF5_utilities use HDF5_utilities
use results use results
use lattice
implicit none implicit none
private private
enum, bind(c); enumerator :: &
THERMAL_ISOTHERMAL_ID, &
THERMAL_CONDUCTION_ID, &
DAMAGE_NONE_ID, &
DAMAGE_NONLOCAL_ID, &
HOMOGENIZATION_UNDEFINED_ID, &
HOMOGENIZATION_NONE_ID, &
HOMOGENIZATION_ISOSTRAIN_ID, &
HOMOGENIZATION_RGC_ID
end enum
type(tState), allocatable, dimension(:), public :: &
homogState, &
damageState_h
integer, dimension(:), allocatable, public, protected :: &
homogenization_typeInstance, & !< instance of particular type of each homogenization
thermal_typeInstance, & !< instance of particular type of each thermal transport
damage_typeInstance !< instance of particular type of each nonlocal damage
real(pReal), dimension(:), allocatable, public, protected :: &
thermal_initialT
integer(kind(THERMAL_isothermal_ID)), dimension(:), allocatable, public, protected :: &
thermal_type !< thermal transport model
integer(kind(DAMAGE_none_ID)), dimension(:), allocatable, public, protected :: &
damage_type !< nonlocal damage model
integer(kind(HOMOGENIZATION_undefined_ID)), dimension(:), allocatable, public, protected :: &
homogenization_type !< type of each homogenization
type, private :: tNumerics_damage
real(pReal) :: &
charLength !< characteristic length scale for gradient problems
end type tNumerics_damage
type(tNumerics_damage), private :: &
num_damage
logical, public :: & logical, public :: &
terminallyIll = .false. !< at least one material point is terminally ill terminallyIll = .false. !< at least one material point is terminally ill
@ -45,10 +84,10 @@ module homogenization
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
interface interface
module subroutine mech_init(num_homog) module subroutine mechanical_init(num_homog)
class(tNode), pointer, intent(in) :: & class(tNode), pointer, intent(in) :: &
num_homog !< pointer to mechanical homogenization numerics data num_homog !< pointer to mechanical homogenization numerics data
end subroutine mech_init end subroutine mechanical_init
module subroutine thermal_init module subroutine thermal_init
end subroutine thermal_init end subroutine thermal_init
@ -56,13 +95,13 @@ module homogenization
module subroutine damage_init module subroutine damage_init
end subroutine damage_init end subroutine damage_init
module subroutine mech_partition(subF,ip,el) module subroutine mechanical_partition(subF,ip,el)
real(pReal), intent(in), dimension(3,3) :: & real(pReal), intent(in), dimension(3,3) :: &
subF subF
integer, intent(in) :: & integer, intent(in) :: &
ip, & !< integration point ip, & !< integration point
el !< element number el !< element number
end subroutine mech_partition end subroutine mechanical_partition
module subroutine thermal_partition(ce) module subroutine thermal_partition(ce)
integer, intent(in) :: ce integer, intent(in) :: ce
@ -76,19 +115,19 @@ module homogenization
integer, intent(in) :: ip,el integer, intent(in) :: ip,el
end subroutine thermal_homogenize end subroutine thermal_homogenize
module subroutine mech_homogenize(dt,ip,el) module subroutine mechanical_homogenize(dt,ip,el)
real(pReal), intent(in) :: dt real(pReal), intent(in) :: dt
integer, intent(in) :: & integer, intent(in) :: &
ip, & !< integration point ip, & !< integration point
el !< element number el !< element number
end subroutine mech_homogenize end subroutine mechanical_homogenize
module subroutine mech_results(group_base,h) module subroutine mechanical_results(group_base,h)
character(len=*), intent(in) :: group_base character(len=*), intent(in) :: group_base
integer, intent(in) :: h integer, intent(in) :: h
end subroutine mech_results end subroutine mechanical_results
module function mech_updateState(subdt,subF,ip,el) result(doneAndHappy) module function mechanical_updateState(subdt,subF,ip,el) result(doneAndHappy)
real(pReal), intent(in) :: & real(pReal), intent(in) :: &
subdt !< current time step subdt !< current time step
real(pReal), intent(in), dimension(3,3) :: & real(pReal), intent(in), dimension(3,3) :: &
@ -97,7 +136,7 @@ module homogenization
ip, & !< integration point ip, & !< integration point
el !< element number el !< element number
logical, dimension(2) :: doneAndHappy logical, dimension(2) :: doneAndHappy
end function mech_updateState end function mechanical_updateState
module function thermal_conduction_getConductivity(ip,el) result(K) module function thermal_conduction_getConductivity(ip,el) result(K)
@ -193,7 +232,13 @@ module homogenization
homogenization_forward, & homogenization_forward, &
homogenization_results, & homogenization_results, &
homogenization_restartRead, & homogenization_restartRead, &
homogenization_restartWrite homogenization_restartWrite, &
THERMAL_CONDUCTION_ID, &
DAMAGE_NONLOCAL_ID
public :: &
damage_nonlocal_init, &
damage_nonlocal_getDiffusion
contains contains
@ -209,6 +254,12 @@ subroutine homogenization_init()
print'(/,a)', ' <<<+- homogenization init -+>>>'; flush(IO_STDOUT) print'(/,a)', ' <<<+- homogenization init -+>>>'; flush(IO_STDOUT)
allocate(homogState (size(material_name_homogenization)))
allocate(damageState_h (size(material_name_homogenization)))
call material_parseHomogenization
num_homog => config_numerics%get('homogenization',defaultVal=emptyDict) num_homog => config_numerics%get('homogenization',defaultVal=emptyDict)
num_homogGeneric => num_homog%get('generic',defaultVal=emptyDict) num_homogGeneric => num_homog%get('generic',defaultVal=emptyDict)
@ -216,12 +267,11 @@ subroutine homogenization_init()
if (num%nMPstate < 1) call IO_error(301,ext_msg='nMPstate') if (num%nMPstate < 1) call IO_error(301,ext_msg='nMPstate')
call mech_init(num_homog) call mechanical_init(num_homog)
call thermal_init() call thermal_init()
call damage_init() call damage_init()
if (any(damage_type == DAMAGE_none_ID)) call damage_none_init call damage_nonlocal_init
if (any(damage_type == DAMAGE_nonlocal_ID)) call damage_nonlocal_init
end subroutine homogenization_init end subroutine homogenization_init
@ -253,10 +303,11 @@ subroutine materialpoint_stressAndItsTangent(dt,FEsolving_execIP,FEsolving_execE
ce = (el-1)*discretization_nIPs + ip ce = (el-1)*discretization_nIPs + ip
me = material_homogenizationMemberAt2(ce) me = material_homogenizationMemberAt2(ce)
call constitutive_restore(ce,.false.) ! wrong name (is more a forward function) call phase_restore(ce,.false.) ! wrong name (is more a forward function)
if(homogState(ho)%sizeState > 0) homogState(ho)%State(:,me) = homogState(ho)%State0(:,me) if(homogState(ho)%sizeState > 0) homogState(ho)%State(:,me) = homogState(ho)%State0(:,me)
if(damageState_h(ho)%sizeState > 0) damageState_h(ho)%State(:,me) = damageState_h(ho)%State0(:,me) if(damageState_h(ho)%sizeState > 0) damageState_h(ho)%State(:,me) = damageState_h(ho)%State0(:,me)
call damage_partition(ce)
doneAndHappy = [.false.,.true.] doneAndHappy = [.false.,.true.]
@ -267,7 +318,7 @@ subroutine materialpoint_stressAndItsTangent(dt,FEsolving_execIP,FEsolving_execE
if (.not. doneAndHappy(1)) then if (.not. doneAndHappy(1)) then
call mech_partition(homogenization_F(1:3,1:3,ce),ip,el) call mechanical_partition(homogenization_F(1:3,1:3,ce),ip,el)
converged = .true. converged = .true.
do co = 1, myNgrains do co = 1, myNgrains
converged = converged .and. crystallite_stress(dt,co,ip,el) converged = converged .and. crystallite_stress(dt,co,ip,el)
@ -276,7 +327,7 @@ subroutine materialpoint_stressAndItsTangent(dt,FEsolving_execIP,FEsolving_execE
if (.not. converged) then if (.not. converged) then
doneAndHappy = [.true.,.false.] doneAndHappy = [.true.,.false.]
else else
doneAndHappy = mech_updateState(dt,homogenization_F(1:3,1:3,ce),ip,el) doneAndHappy = mechanical_updateState(dt,homogenization_F(1:3,1:3,ce),ip,el)
converged = all(doneAndHappy) converged = all(doneAndHappy)
endif endif
endif endif
@ -311,26 +362,6 @@ subroutine materialpoint_stressAndItsTangent(dt,FEsolving_execIP,FEsolving_execE
enddo enddo
!$OMP END DO !$OMP END DO
! !$OMP DO PRIVATE(ho,ph,ce)
! do el = FEsolving_execElem(1),FEsolving_execElem(2)
! if (terminallyIll) continue
! ho = material_homogenizationAt(el)
! do ip = FEsolving_execIP(1),FEsolving_execIP(2)
! ce = (el-1)*discretization_nIPs + ip
! call damage_partition(ce)
! do co = 1, homogenization_Nconstituents(ho)
! ph = material_phaseAt(co,el)
! if (.not. thermal_stress(dt,ph,material_phaseMemberAt(co,ip,el))) then
! if (.not. terminallyIll) & ! so first signals terminally ill...
! print*, ' Integration point ', ip,' at element ', el, ' terminally ill'
! terminallyIll = .true. ! ...and kills all others
! endif
! call thermal_homogenize(ip,el)
! enddo
! enddo
! enddo
! !$OMP END DO
!$OMP DO PRIVATE(ho) !$OMP DO PRIVATE(ho)
elementLooping3: do el = FEsolving_execElem(1),FEsolving_execElem(2) elementLooping3: do el = FEsolving_execElem(1),FEsolving_execElem(2)
ho = material_homogenizationAt(el) ho = material_homogenizationAt(el)
@ -338,7 +369,7 @@ subroutine materialpoint_stressAndItsTangent(dt,FEsolving_execIP,FEsolving_execE
do co = 1, homogenization_Nconstituents(ho) do co = 1, homogenization_Nconstituents(ho)
call crystallite_orientations(co,ip,el) call crystallite_orientations(co,ip,el)
enddo enddo
call mech_homogenize(dt,ip,el) call mechanical_homogenize(dt,ip,el)
enddo IpLooping3 enddo IpLooping3
enddo elementLooping3 enddo elementLooping3
!$OMP END DO !$OMP END DO
@ -365,7 +396,7 @@ subroutine homogenization_results
group_base = 'current/homogenization/'//trim(material_name_homogenization(ho)) group_base = 'current/homogenization/'//trim(material_name_homogenization(ho))
call results_closeGroup(results_addGroup(group_base)) call results_closeGroup(results_addGroup(group_base))
call mech_results(group_base,ho) call mechanical_results(group_base,ho)
group = trim(group_base)//'/damage' group = trim(group_base)//'/damage'
call results_closeGroup(results_addGroup(group)) call results_closeGroup(results_addGroup(group))
@ -397,7 +428,8 @@ subroutine homogenization_forward
do ho = 1, size(material_name_homogenization) do ho = 1, size(material_name_homogenization)
homogState (ho)%state0 = homogState (ho)%state homogState (ho)%state0 = homogState (ho)%state
damageState_h(ho)%state0 = damageState_h(ho)%state if(damageState_h(ho)%sizeState > 0) &
damageState_h(ho)%state0 = damageState_h(ho)%state
enddo enddo
end subroutine homogenization_forward end subroutine homogenization_forward
@ -457,4 +489,143 @@ subroutine homogenization_restartRead(fileHandle)
end subroutine homogenization_restartRead end subroutine homogenization_restartRead
!--------------------------------------------------------------------------------------------------
!> @brief module initialization
!> @details reads in material parameters, allocates arrays, and does sanity checks
!--------------------------------------------------------------------------------------------------
subroutine damage_nonlocal_init
integer :: Ninstances,Nmaterialpoints,h
class(tNode), pointer :: &
num_generic, &
material_homogenization
print'(/,a)', ' <<<+- damage_nonlocal init -+>>>'; flush(6)
!------------------------------------------------------------------------------------
! read numerics parameter
num_generic => config_numerics%get('generic',defaultVal= emptyDict)
num_damage%charLength = num_generic%get_asFloat('charLength',defaultVal=1.0_pReal)
Ninstances = count(damage_type == DAMAGE_nonlocal_ID)
material_homogenization => config_material%get('homogenization')
do h = 1, material_homogenization%length
if (damage_type(h) /= DAMAGE_NONLOCAL_ID) cycle
Nmaterialpoints = count(material_homogenizationAt == h)
damageState_h(h)%sizeState = 1
allocate(damageState_h(h)%state0 (1,Nmaterialpoints), source=1.0_pReal)
allocate(damageState_h(h)%state (1,Nmaterialpoints), source=1.0_pReal)
enddo
end subroutine damage_nonlocal_init
!--------------------------------------------------------------------------------------------------
!> @brief returns homogenized non local damage diffusion tensor in reference configuration
!--------------------------------------------------------------------------------------------------
function damage_nonlocal_getDiffusion(ip,el)
integer, intent(in) :: &
ip, & !< integration point number
el !< element number
real(pReal), dimension(3,3) :: &
damage_nonlocal_getDiffusion
integer :: &
homog, &
grain
homog = material_homogenizationAt(el)
damage_nonlocal_getDiffusion = 0.0_pReal
do grain = 1, homogenization_Nconstituents(homog)
damage_nonlocal_getDiffusion = damage_nonlocal_getDiffusion + &
crystallite_push33ToRef(grain,ip,el,lattice_D(1:3,1:3,material_phaseAt(grain,el)))
enddo
damage_nonlocal_getDiffusion = &
num_damage%charLength**2*damage_nonlocal_getDiffusion/real(homogenization_Nconstituents(homog),pReal)
end function damage_nonlocal_getDiffusion
!--------------------------------------------------------------------------------------------------
!> @brief parses the homogenization part from the material configuration
! ToDo: This should be done in homogenization
!--------------------------------------------------------------------------------------------------
subroutine material_parseHomogenization
class(tNode), pointer :: &
material_homogenization, &
homog, &
homogMech, &
homogThermal, &
homogDamage
integer :: h
material_homogenization => config_material%get('homogenization')
allocate(homogenization_type(size(material_name_homogenization)), source=HOMOGENIZATION_undefined_ID)
allocate(thermal_type(size(material_name_homogenization)), source=THERMAL_isothermal_ID)
allocate(damage_type (size(material_name_homogenization)), source=DAMAGE_none_ID)
allocate(homogenization_typeInstance(size(material_name_homogenization)), source=0)
allocate(thermal_typeInstance(size(material_name_homogenization)), source=0)
allocate(damage_typeInstance(size(material_name_homogenization)), source=0)
allocate(thermal_initialT(size(material_name_homogenization)), source=300.0_pReal)
do h=1, size(material_name_homogenization)
homog => material_homogenization%get(h)
homogMech => homog%get('mechanics')
select case (homogMech%get_asString('type'))
case('pass')
homogenization_type(h) = HOMOGENIZATION_NONE_ID
case('isostrain')
homogenization_type(h) = HOMOGENIZATION_ISOSTRAIN_ID
case('RGC')
homogenization_type(h) = HOMOGENIZATION_RGC_ID
case default
call IO_error(500,ext_msg=homogMech%get_asString('type'))
end select
homogenization_typeInstance(h) = count(homogenization_type==homogenization_type(h))
if(homog%contains('thermal')) then
homogThermal => homog%get('thermal')
thermal_initialT(h) = homogThermal%get_asFloat('T_0',defaultVal=300.0_pReal)
select case (homogThermal%get_asString('type'))
case('isothermal')
thermal_type(h) = THERMAL_isothermal_ID
case('conduction')
thermal_type(h) = THERMAL_conduction_ID
case default
call IO_error(500,ext_msg=homogThermal%get_asString('type'))
end select
endif
if(homog%contains('damage')) then
homogDamage => homog%get('damage')
select case (homogDamage%get_asString('type'))
case('none')
damage_type(h) = DAMAGE_none_ID
case('nonlocal')
damage_type(h) = DAMAGE_nonlocal_ID
case default
call IO_error(500,ext_msg=homogDamage%get_asString('type'))
end select
endif
enddo
do h=1, size(material_name_homogenization)
homogenization_typeInstance(h) = count(homogenization_type(1:h) == homogenization_type(h))
thermal_typeInstance(h) = count(thermal_type (1:h) == thermal_type (h))
damage_typeInstance(h) = count(damage_type (1:h) == damage_type (h))
enddo
end subroutine material_parseHomogenization
end module homogenization end module homogenization

View File

@ -72,9 +72,10 @@ module subroutine damage_partition(ce)
integer :: co integer :: co
phi = current(material_homogenizationAt2(ce))%phi(material_homogenizationMemberAt2(ce)) if(damageState_h(material_homogenizationAt2(ce))%sizeState < 1) return
phi = damagestate_h(material_homogenizationAt2(ce))%state(1,material_homogenizationMemberAt2(ce))
do co = 1, homogenization_Nconstituents(material_homogenizationAt2(ce)) do co = 1, homogenization_Nconstituents(material_homogenizationAt2(ce))
call constitutive_damage_set_phi(phi,co,ce) call phase_damage_set_phi(phi,co,ce)
enddo enddo
end subroutine damage_partition end subroutine damage_partition
@ -120,7 +121,7 @@ module subroutine damage_nonlocal_getSourceAndItsTangent(phiDot, dPhiDot_dPhi, p
phiDot = 0.0_pReal phiDot = 0.0_pReal
dPhiDot_dPhi = 0.0_pReal dPhiDot_dPhi = 0.0_pReal
call constitutive_damage_getRateAndItsTangents(phiDot, dPhiDot_dPhi, phi, ip, el) call phase_damage_getRateAndItsTangents(phiDot, dPhiDot_dPhi, phi, ip, el)
phiDot = phiDot/real(homogenization_Nconstituents(material_homogenizationAt(el)),pReal) phiDot = phiDot/real(homogenization_Nconstituents(material_homogenizationAt(el)),pReal)
dPhiDot_dPhi = dPhiDot_dPhi/real(homogenization_Nconstituents(material_homogenizationAt(el)),pReal) dPhiDot_dPhi = dPhiDot_dPhi/real(homogenization_Nconstituents(material_homogenizationAt(el)),pReal)
@ -143,7 +144,7 @@ module subroutine damage_nonlocal_putNonLocalDamage(phi,ip,el)
homog = material_homogenizationAt(el) homog = material_homogenizationAt(el)
offset = material_homogenizationMemberAt(ip,el) offset = material_homogenizationMemberAt(ip,el)
damage(homog)%p(offset) = phi damagestate_h(homog)%state(1,offset) = phi
end subroutine damage_nonlocal_putNonLocalDamage end subroutine damage_nonlocal_putNonLocalDamage
@ -162,7 +163,7 @@ module subroutine damage_nonlocal_results(homog,group)
outputsLoop: do o = 1,size(prm%output) outputsLoop: do o = 1,size(prm%output)
select case(prm%output(o)) select case(prm%output(o))
case ('phi') case ('phi')
call results_writeDataset(group,damage(homog)%p,prm%output(o),& call results_writeDataset(group,damagestate_h(homog)%state(1,:),prm%output(o),&
'damage indicator','-') 'damage indicator','-')
end select end select
enddo outputsLoop enddo outputsLoop

View File

@ -2,57 +2,57 @@
!> @author Martin Diehl, KU Leuven !> @author Martin Diehl, KU Leuven
!> @brief Partition F and homogenize P/dPdF !> @brief Partition F and homogenize P/dPdF
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
submodule(homogenization) mechanics submodule(homogenization) mechanical
interface interface
module subroutine mech_none_init module subroutine mechanical_pass_init
end subroutine mech_none_init end subroutine mechanical_pass_init
module subroutine mech_isostrain_init module subroutine mechanical_isostrain_init
end subroutine mech_isostrain_init end subroutine mechanical_isostrain_init
module subroutine mech_RGC_init(num_homogMech) module subroutine mechanical_RGC_init(num_homogMech)
class(tNode), pointer, intent(in) :: & class(tNode), pointer, intent(in) :: &
num_homogMech !< pointer to mechanical homogenization numerics data num_homogMech !< pointer to mechanical homogenization numerics data
end subroutine mech_RGC_init end subroutine mechanical_RGC_init
module subroutine mech_isostrain_partitionDeformation(F,avgF) module subroutine mechanical_isostrain_partitionDeformation(F,avgF)
real(pReal), dimension (:,:,:), intent(out) :: F !< partitioned deformation gradient real(pReal), dimension (:,:,:), intent(out) :: F !< partitioned deformation gradient
real(pReal), dimension (3,3), intent(in) :: avgF !< average deformation gradient at material point real(pReal), dimension (3,3), intent(in) :: avgF !< average deformation gradient at material point
end subroutine mech_isostrain_partitionDeformation end subroutine mechanical_isostrain_partitionDeformation
module subroutine mech_RGC_partitionDeformation(F,avgF,instance,of) module subroutine mechanical_RGC_partitionDeformation(F,avgF,instance,of)
real(pReal), dimension (:,:,:), intent(out) :: F !< partitioned deformation gradient real(pReal), dimension (:,:,:), intent(out) :: F !< partitioned deformation gradient
real(pReal), dimension (3,3), intent(in) :: avgF !< average deformation gradient at material point real(pReal), dimension (3,3), intent(in) :: avgF !< average deformation gradient at material point
integer, intent(in) :: & integer, intent(in) :: &
instance, & instance, &
of of
end subroutine mech_RGC_partitionDeformation end subroutine mechanical_RGC_partitionDeformation
module subroutine mech_isostrain_averageStressAndItsTangent(avgP,dAvgPdAvgF,P,dPdF,instance) module subroutine mechanical_isostrain_averageStressAndItsTangent(avgP,dAvgPdAvgF,P,dPdF,instance)
real(pReal), dimension (3,3), intent(out) :: avgP !< average stress at material point real(pReal), dimension (3,3), intent(out) :: avgP !< average stress at material point
real(pReal), dimension (3,3,3,3), intent(out) :: dAvgPdAvgF !< average stiffness at material point real(pReal), dimension (3,3,3,3), intent(out) :: dAvgPdAvgF !< average stiffness at material point
real(pReal), dimension (:,:,:), intent(in) :: P !< partitioned stresses real(pReal), dimension (:,:,:), intent(in) :: P !< partitioned stresses
real(pReal), dimension (:,:,:,:,:), intent(in) :: dPdF !< partitioned stiffnesses real(pReal), dimension (:,:,:,:,:), intent(in) :: dPdF !< partitioned stiffnesses
integer, intent(in) :: instance integer, intent(in) :: instance
end subroutine mech_isostrain_averageStressAndItsTangent end subroutine mechanical_isostrain_averageStressAndItsTangent
module subroutine mech_RGC_averageStressAndItsTangent(avgP,dAvgPdAvgF,P,dPdF,instance) module subroutine mechanical_RGC_averageStressAndItsTangent(avgP,dAvgPdAvgF,P,dPdF,instance)
real(pReal), dimension (3,3), intent(out) :: avgP !< average stress at material point real(pReal), dimension (3,3), intent(out) :: avgP !< average stress at material point
real(pReal), dimension (3,3,3,3), intent(out) :: dAvgPdAvgF !< average stiffness at material point real(pReal), dimension (3,3,3,3), intent(out) :: dAvgPdAvgF !< average stiffness at material point
real(pReal), dimension (:,:,:), intent(in) :: P !< partitioned stresses real(pReal), dimension (:,:,:), intent(in) :: P !< partitioned stresses
real(pReal), dimension (:,:,:,:,:), intent(in) :: dPdF !< partitioned stiffnesses real(pReal), dimension (:,:,:,:,:), intent(in) :: dPdF !< partitioned stiffnesses
integer, intent(in) :: instance integer, intent(in) :: instance
end subroutine mech_RGC_averageStressAndItsTangent end subroutine mechanical_RGC_averageStressAndItsTangent
module function mech_RGC_updateState(P,F,avgF,dt,dPdF,ip,el) result(doneAndHappy) module function mechanical_RGC_updateState(P,F,avgF,dt,dPdF,ip,el) result(doneAndHappy)
logical, dimension(2) :: doneAndHappy logical, dimension(2) :: doneAndHappy
real(pReal), dimension(:,:,:), intent(in) :: & real(pReal), dimension(:,:,:), intent(in) :: &
P,& !< partitioned stresses P,& !< partitioned stresses
@ -63,13 +63,13 @@ submodule(homogenization) mechanics
integer, intent(in) :: & integer, intent(in) :: &
ip, & !< integration point number ip, & !< integration point number
el !< element number el !< element number
end function mech_RGC_updateState end function mechanical_RGC_updateState
module subroutine mech_RGC_results(instance,group) module subroutine mechanical_RGC_results(instance,group)
integer, intent(in) :: instance !< homogenization instance integer, intent(in) :: instance !< homogenization instance
character(len=*), intent(in) :: group !< group name in HDF5 file character(len=*), intent(in) :: group !< group name in HDF5 file
end subroutine mech_RGC_results end subroutine mechanical_RGC_results
end interface end interface
@ -78,7 +78,7 @@ contains
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief Allocate variables and set parameters. !> @brief Allocate variables and set parameters.
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
module subroutine mech_init(num_homog) module subroutine mechanical_init(num_homog)
class(tNode), pointer, intent(in) :: & class(tNode), pointer, intent(in) :: &
num_homog num_homog
@ -86,7 +86,7 @@ module subroutine mech_init(num_homog)
class(tNode), pointer :: & class(tNode), pointer :: &
num_homogMech num_homogMech
print'(/,a)', ' <<<+- homogenization:mechanics init -+>>>' print'(/,a)', ' <<<+- homogenization:mechanical init -+>>>'
allocate(homogenization_dPdF(3,3,3,3,discretization_nIPs*discretization_Nelems), source=0.0_pReal) allocate(homogenization_dPdF(3,3,3,3,discretization_nIPs*discretization_Nelems), source=0.0_pReal)
homogenization_F0 = spread(math_I3,3,discretization_nIPs*discretization_Nelems) ! initialize to identity homogenization_F0 = spread(math_I3,3,discretization_nIPs*discretization_Nelems) ! initialize to identity
@ -94,17 +94,17 @@ module subroutine mech_init(num_homog)
allocate(homogenization_P(3,3,discretization_nIPs*discretization_Nelems), source=0.0_pReal) allocate(homogenization_P(3,3,discretization_nIPs*discretization_Nelems), source=0.0_pReal)
num_homogMech => num_homog%get('mech',defaultVal=emptyDict) num_homogMech => num_homog%get('mech',defaultVal=emptyDict)
if (any(homogenization_type == HOMOGENIZATION_NONE_ID)) call mech_none_init if (any(homogenization_type == HOMOGENIZATION_NONE_ID)) call mechanical_pass_init
if (any(homogenization_type == HOMOGENIZATION_ISOSTRAIN_ID)) call mech_isostrain_init if (any(homogenization_type == HOMOGENIZATION_ISOSTRAIN_ID)) call mechanical_isostrain_init
if (any(homogenization_type == HOMOGENIZATION_RGC_ID)) call mech_RGC_init(num_homogMech) if (any(homogenization_type == HOMOGENIZATION_RGC_ID)) call mechanical_RGC_init(num_homogMech)
end subroutine mech_init end subroutine mechanical_init
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief Partition F onto the individual constituents. !> @brief Partition F onto the individual constituents.
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
module subroutine mech_partition(subF,ip,el) module subroutine mechanical_partition(subF,ip,el)
real(pReal), intent(in), dimension(3,3) :: & real(pReal), intent(in), dimension(3,3) :: &
subF subF
@ -122,25 +122,25 @@ module subroutine mech_partition(subF,ip,el)
Fs(1:3,1:3,1) = subF Fs(1:3,1:3,1) = subF
case (HOMOGENIZATION_ISOSTRAIN_ID) chosenHomogenization case (HOMOGENIZATION_ISOSTRAIN_ID) chosenHomogenization
call mech_isostrain_partitionDeformation(Fs,subF) call mechanical_isostrain_partitionDeformation(Fs,subF)
case (HOMOGENIZATION_RGC_ID) chosenHomogenization case (HOMOGENIZATION_RGC_ID) chosenHomogenization
call mech_RGC_partitionDeformation(Fs,subF,ip,el) call mechanical_RGC_partitionDeformation(Fs,subF,ip,el)
end select chosenHomogenization end select chosenHomogenization
do co = 1,homogenization_Nconstituents(material_homogenizationAt(el)) do co = 1,homogenization_Nconstituents(material_homogenizationAt(el))
call constitutive_mech_setF(Fs(1:3,1:3,co),co,ip,el) call phase_mechanical_setF(Fs(1:3,1:3,co),co,ip,el)
enddo enddo
end subroutine mech_partition end subroutine mechanical_partition
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief Average P and dPdF from the individual constituents. !> @brief Average P and dPdF from the individual constituents.
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
module subroutine mech_homogenize(dt,ip,el) module subroutine mechanical_homogenize(dt,ip,el)
real(pReal), intent(in) :: dt real(pReal), intent(in) :: dt
integer, intent(in) :: & integer, intent(in) :: &
@ -156,15 +156,15 @@ module subroutine mech_homogenize(dt,ip,el)
chosenHomogenization: select case(homogenization_type(material_homogenizationAt(el))) chosenHomogenization: select case(homogenization_type(material_homogenizationAt(el)))
case (HOMOGENIZATION_NONE_ID) chosenHomogenization case (HOMOGENIZATION_NONE_ID) chosenHomogenization
homogenization_P(1:3,1:3,ce) = constitutive_mech_getP(1,ip,el) homogenization_P(1:3,1:3,ce) = phase_mechanical_getP(1,ip,el)
homogenization_dPdF(1:3,1:3,1:3,1:3,ce) = constitutive_mech_dPdF(dt,1,ip,el) homogenization_dPdF(1:3,1:3,1:3,1:3,ce) = phase_mechanical_dPdF(dt,1,ip,el)
case (HOMOGENIZATION_ISOSTRAIN_ID) chosenHomogenization case (HOMOGENIZATION_ISOSTRAIN_ID) chosenHomogenization
do co = 1, homogenization_Nconstituents(material_homogenizationAt(el)) do co = 1, homogenization_Nconstituents(material_homogenizationAt(el))
dPdFs(:,:,:,:,co) = constitutive_mech_dPdF(dt,co,ip,el) dPdFs(:,:,:,:,co) = phase_mechanical_dPdF(dt,co,ip,el)
Ps(:,:,co) = constitutive_mech_getP(co,ip,el) Ps(:,:,co) = phase_mechanical_getP(co,ip,el)
enddo enddo
call mech_isostrain_averageStressAndItsTangent(& call mechanical_isostrain_averageStressAndItsTangent(&
homogenization_P(1:3,1:3,ce), & homogenization_P(1:3,1:3,ce), &
homogenization_dPdF(1:3,1:3,1:3,1:3,ce),& homogenization_dPdF(1:3,1:3,1:3,1:3,ce),&
Ps,dPdFs, & Ps,dPdFs, &
@ -172,10 +172,10 @@ module subroutine mech_homogenize(dt,ip,el)
case (HOMOGENIZATION_RGC_ID) chosenHomogenization case (HOMOGENIZATION_RGC_ID) chosenHomogenization
do co = 1, homogenization_Nconstituents(material_homogenizationAt(el)) do co = 1, homogenization_Nconstituents(material_homogenizationAt(el))
dPdFs(:,:,:,:,co) = constitutive_mech_dPdF(dt,co,ip,el) dPdFs(:,:,:,:,co) = phase_mechanical_dPdF(dt,co,ip,el)
Ps(:,:,co) = constitutive_mech_getP(co,ip,el) Ps(:,:,co) = phase_mechanical_getP(co,ip,el)
enddo enddo
call mech_RGC_averageStressAndItsTangent(& call mechanical_RGC_averageStressAndItsTangent(&
homogenization_P(1:3,1:3,ce), & homogenization_P(1:3,1:3,ce), &
homogenization_dPdF(1:3,1:3,1:3,1:3,ce),& homogenization_dPdF(1:3,1:3,1:3,1:3,ce),&
Ps,dPdFs, & Ps,dPdFs, &
@ -183,14 +183,14 @@ module subroutine mech_homogenize(dt,ip,el)
end select chosenHomogenization end select chosenHomogenization
end subroutine mech_homogenize end subroutine mechanical_homogenize
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief update the internal state of the homogenization scheme and tell whether "done" and !> @brief update the internal state of the homogenization scheme and tell whether "done" and
!> "happy" with result !> "happy" with result
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
module function mech_updateState(subdt,subF,ip,el) result(doneAndHappy) module function mechanical_updateState(subdt,subF,ip,el) result(doneAndHappy)
real(pReal), intent(in) :: & real(pReal), intent(in) :: &
subdt !< current time step subdt !< current time step
@ -209,24 +209,22 @@ module function mech_updateState(subdt,subF,ip,el) result(doneAndHappy)
if (homogenization_type(material_homogenizationAt(el)) == HOMOGENIZATION_RGC_ID) then if (homogenization_type(material_homogenizationAt(el)) == HOMOGENIZATION_RGC_ID) then
do co = 1, homogenization_Nconstituents(material_homogenizationAt(el)) do co = 1, homogenization_Nconstituents(material_homogenizationAt(el))
dPdFs(:,:,:,:,co) = constitutive_mech_dPdF(subdt,co,ip,el) dPdFs(:,:,:,:,co) = phase_mechanical_dPdF(subdt,co,ip,el)
Fs(:,:,co) = constitutive_mech_getF(co,ip,el) Fs(:,:,co) = phase_mechanical_getF(co,ip,el)
Ps(:,:,co) = constitutive_mech_getP(co,ip,el) Ps(:,:,co) = phase_mechanical_getP(co,ip,el)
enddo enddo
doneAndHappy = mech_RGC_updateState(Ps,Fs,subF,subdt,dPdFs,ip,el) doneAndHappy = mechanical_RGC_updateState(Ps,Fs,subF,subdt,dPdFs,ip,el)
else else
doneAndHappy = .true. doneAndHappy = .true.
endif endif
end function mech_updateState end function mechanical_updateState
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief Write results to file. !> @brief Write results to file.
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
module subroutine mech_results(group_base,h) module subroutine mechanical_results(group_base,h)
use material, only: &
material_homogenization_type => homogenization_type
character(len=*), intent(in) :: group_base character(len=*), intent(in) :: group_base
integer, intent(in) :: h integer, intent(in) :: h
@ -236,10 +234,10 @@ module subroutine mech_results(group_base,h)
group = trim(group_base)//'/mech' group = trim(group_base)//'/mech'
call results_closeGroup(results_addGroup(group)) call results_closeGroup(results_addGroup(group))
select case(material_homogenization_type(h)) select case(homogenization_type(h))
case(HOMOGENIZATION_rgc_ID) case(HOMOGENIZATION_rgc_ID)
call mech_RGC_results(homogenization_typeInstance(h),group) call mechanical_RGC_results(homogenization_typeInstance(h),group)
end select end select
@ -250,7 +248,7 @@ module subroutine mech_results(group_base,h)
!call results_writeDataset(group,temp,'P',& !call results_writeDataset(group,temp,'P',&
! '1st Piola-Kirchhoff stress','Pa') ! '1st Piola-Kirchhoff stress','Pa')
end subroutine mech_results end subroutine mechanical_results
end submodule mechanics end submodule mechanical

View File

@ -6,7 +6,7 @@
!> @brief Relaxed grain cluster (RGC) homogenization scheme !> @brief Relaxed grain cluster (RGC) homogenization scheme
!> N_constituents is defined as p x q x r (cluster) !> N_constituents is defined as p x q x r (cluster)
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
submodule(homogenization:mechanics) RGC submodule(homogenization:mechanical) RGC
use rotations use rotations
use lattice use lattice
@ -71,7 +71,7 @@ contains
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief allocates all necessary fields, reads information from material configuration file !> @brief allocates all necessary fields, reads information from material configuration file
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
module subroutine mech_RGC_init(num_homogMech) module subroutine mechanical_RGC_init(num_homogMech)
class(tNode), pointer, intent(in) :: & class(tNode), pointer, intent(in) :: &
num_homogMech !< pointer to mechanical homogenization numerics data num_homogMech !< pointer to mechanical homogenization numerics data
@ -88,7 +88,7 @@ module subroutine mech_RGC_init(num_homogMech)
homog, & homog, &
homogMech homogMech
print'(/,a)', ' <<<+- homogenization:mechanics:RGC init -+>>>' print'(/,a)', ' <<<+- homogenization:mechanical:RGC init -+>>>'
Ninstances = count(homogenization_type == HOMOGENIZATION_RGC_ID) Ninstances = count(homogenization_type == HOMOGENIZATION_RGC_ID)
print'(a,i2)', ' # instances: ',Ninstances; flush(IO_STDOUT) print'(a,i2)', ' # instances: ',Ninstances; flush(IO_STDOUT)
@ -155,7 +155,7 @@ module subroutine mech_RGC_init(num_homogMech)
prm%N_constituents = homogMech%get_asInts('cluster_size',requiredSize=3) prm%N_constituents = homogMech%get_asInts('cluster_size',requiredSize=3)
if (homogenization_Nconstituents(h) /= product(prm%N_constituents)) & if (homogenization_Nconstituents(h) /= product(prm%N_constituents)) &
call IO_error(211,ext_msg='N_constituents (mech_RGC)') call IO_error(211,ext_msg='N_constituents (mechanical_RGC)')
prm%xi_alpha = homogMech%get_asFloat('xi_alpha') prm%xi_alpha = homogMech%get_asFloat('xi_alpha')
prm%c_alpha = homogMech%get_asFloat('c_alpha') prm%c_alpha = homogMech%get_asFloat('c_alpha')
@ -190,13 +190,13 @@ module subroutine mech_RGC_init(num_homogMech)
enddo enddo
end subroutine mech_RGC_init end subroutine mechanical_RGC_init
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief partitions the deformation gradient onto the constituents !> @brief partitions the deformation gradient onto the constituents
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
module subroutine mech_RGC_partitionDeformation(F,avgF,instance,of) module subroutine mechanical_RGC_partitionDeformation(F,avgF,instance,of)
real(pReal), dimension (:,:,:), intent(out) :: F !< partitioned F per grain real(pReal), dimension (:,:,:), intent(out) :: F !< partitioned F per grain
@ -229,14 +229,14 @@ module subroutine mech_RGC_partitionDeformation(F,avgF,instance,of)
end associate end associate
end subroutine mech_RGC_partitionDeformation end subroutine mechanical_RGC_partitionDeformation
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief update the internal state of the homogenization scheme and tell whether "done" and !> @brief update the internal state of the homogenization scheme and tell whether "done" and
! "happy" with result ! "happy" with result
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
module function mech_RGC_updateState(P,F,avgF,dt,dPdF,ip,el) result(doneAndHappy) module function mechanical_RGC_updateState(P,F,avgF,dt,dPdF,ip,el) result(doneAndHappy)
logical, dimension(2) :: doneAndHappy logical, dimension(2) :: doneAndHappy
real(pReal), dimension(:,:,:), intent(in) :: & real(pReal), dimension(:,:,:), intent(in) :: &
P,& !< partitioned stresses P,& !< partitioned stresses
@ -658,7 +658,7 @@ module function mech_RGC_updateState(P,F,avgF,dt,dPdF,ip,el) result(doneAndHappy
real(pReal), dimension(6,6) :: C real(pReal), dimension(6,6) :: C
C = constitutive_homogenizedC(material_phaseAt(grainID,el),material_phaseMemberAt(grainID,ip,el)) C = phase_homogenizedC(material_phaseAt(grainID,el),material_phaseMemberAt(grainID,ip,el))
equivalentMu = lattice_equivalent_mu(C,'voigt') equivalentMu = lattice_equivalent_mu(C,'voigt')
end function equivalentMu end function equivalentMu
@ -704,13 +704,13 @@ module function mech_RGC_updateState(P,F,avgF,dt,dPdF,ip,el) result(doneAndHappy
end subroutine grainDeformation end subroutine grainDeformation
end function mech_RGC_updateState end function mechanical_RGC_updateState
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief derive average stress and stiffness from constituent quantities !> @brief derive average stress and stiffness from constituent quantities
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
module subroutine mech_RGC_averageStressAndItsTangent(avgP,dAvgPdAvgF,P,dPdF,instance) module subroutine mechanical_RGC_averageStressAndItsTangent(avgP,dAvgPdAvgF,P,dPdF,instance)
real(pReal), dimension (3,3), intent(out) :: avgP !< average stress at material point real(pReal), dimension (3,3), intent(out) :: avgP !< average stress at material point
real(pReal), dimension (3,3,3,3), intent(out) :: dAvgPdAvgF !< average stiffness at material point real(pReal), dimension (3,3,3,3), intent(out) :: dAvgPdAvgF !< average stiffness at material point
@ -722,13 +722,13 @@ module subroutine mech_RGC_averageStressAndItsTangent(avgP,dAvgPdAvgF,P,dPdF,ins
avgP = sum(P,3) /real(product(param(instance)%N_constituents),pReal) avgP = sum(P,3) /real(product(param(instance)%N_constituents),pReal)
dAvgPdAvgF = sum(dPdF,5)/real(product(param(instance)%N_constituents),pReal) dAvgPdAvgF = sum(dPdF,5)/real(product(param(instance)%N_constituents),pReal)
end subroutine mech_RGC_averageStressAndItsTangent end subroutine mechanical_RGC_averageStressAndItsTangent
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief writes results to HDF5 output file !> @brief writes results to HDF5 output file
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
module subroutine mech_RGC_results(instance,group) module subroutine mechanical_RGC_results(instance,group)
integer, intent(in) :: instance integer, intent(in) :: instance
character(len=*), intent(in) :: group character(len=*), intent(in) :: group
@ -754,7 +754,7 @@ module subroutine mech_RGC_results(instance,group)
enddo outputsLoop enddo outputsLoop
end associate end associate
end subroutine mech_RGC_results end subroutine mechanical_RGC_results
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------

View File

@ -4,7 +4,7 @@
!> @author Philip Eisenlohr, Max-Planck-Institut für Eisenforschung GmbH !> @author Philip Eisenlohr, Max-Planck-Institut für Eisenforschung GmbH
!> @brief Isostrain (full constraint Taylor assuption) homogenization scheme !> @brief Isostrain (full constraint Taylor assuption) homogenization scheme
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
submodule(homogenization:mechanics) isostrain submodule(homogenization:mechanical) isostrain
enum, bind(c); enumerator :: & enum, bind(c); enumerator :: &
parallel_ID, & parallel_ID, &
@ -26,7 +26,7 @@ contains
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief allocates all neccessary fields, reads information from material configuration file !> @brief allocates all neccessary fields, reads information from material configuration file
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
module subroutine mech_isostrain_init module subroutine mechanical_isostrain_init
integer :: & integer :: &
Ninstances, & Ninstances, &
@ -37,7 +37,7 @@ module subroutine mech_isostrain_init
homog, & homog, &
homogMech homogMech
print'(/,a)', ' <<<+- homogenization:mechanics:isostrain init -+>>>' print'(/,a)', ' <<<+- homogenization:mechanical:isostrain init -+>>>'
Ninstances = count(homogenization_type == HOMOGENIZATION_ISOSTRAIN_ID) Ninstances = count(homogenization_type == HOMOGENIZATION_ISOSTRAIN_ID)
print'(a,i2)', ' # instances: ',Ninstances; flush(IO_STDOUT) print'(a,i2)', ' # instances: ',Ninstances; flush(IO_STDOUT)
@ -58,7 +58,7 @@ module subroutine mech_isostrain_init
case ('avg') case ('avg')
prm%mapping = average_ID prm%mapping = average_ID
case default case default
call IO_error(211,ext_msg='sum'//' (mech_isostrain)') call IO_error(211,ext_msg='sum'//' (mechanical_isostrain)')
end select end select
Nmaterialpoints = count(material_homogenizationAt == h) Nmaterialpoints = count(material_homogenizationAt == h)
@ -70,13 +70,13 @@ module subroutine mech_isostrain_init
enddo enddo
end subroutine mech_isostrain_init end subroutine mechanical_isostrain_init
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief partitions the deformation gradient onto the constituents !> @brief partitions the deformation gradient onto the constituents
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
module subroutine mech_isostrain_partitionDeformation(F,avgF) module subroutine mechanical_isostrain_partitionDeformation(F,avgF)
real(pReal), dimension (:,:,:), intent(out) :: F !< partitioned deformation gradient real(pReal), dimension (:,:,:), intent(out) :: F !< partitioned deformation gradient
@ -84,13 +84,13 @@ module subroutine mech_isostrain_partitionDeformation(F,avgF)
F = spread(avgF,3,size(F,3)) F = spread(avgF,3,size(F,3))
end subroutine mech_isostrain_partitionDeformation end subroutine mechanical_isostrain_partitionDeformation
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief derive average stress and stiffness from constituent quantities !> @brief derive average stress and stiffness from constituent quantities
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
module subroutine mech_isostrain_averageStressAndItsTangent(avgP,dAvgPdAvgF,P,dPdF,instance) module subroutine mechanical_isostrain_averageStressAndItsTangent(avgP,dAvgPdAvgF,P,dPdF,instance)
real(pReal), dimension (3,3), intent(out) :: avgP !< average stress at material point real(pReal), dimension (3,3), intent(out) :: avgP !< average stress at material point
real(pReal), dimension (3,3,3,3), intent(out) :: dAvgPdAvgF !< average stiffness at material point real(pReal), dimension (3,3,3,3), intent(out) :: dAvgPdAvgF !< average stiffness at material point
@ -112,6 +112,6 @@ module subroutine mech_isostrain_averageStressAndItsTangent(avgP,dAvgPdAvgF,P,dP
end associate end associate
end subroutine mech_isostrain_averageStressAndItsTangent end subroutine mechanical_isostrain_averageStressAndItsTangent
end submodule isostrain end submodule isostrain

View File

@ -4,21 +4,21 @@
!> @author Martin Diehl, Max-Planck-Institut für Eisenforschung GmbH !> @author Martin Diehl, Max-Planck-Institut für Eisenforschung GmbH
!> @brief dummy homogenization homogenization scheme for 1 constituent per material point !> @brief dummy homogenization homogenization scheme for 1 constituent per material point
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
submodule(homogenization:mechanics) none submodule(homogenization:mechanical) none
contains contains
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief allocates all necessary fields, reads information from material configuration file !> @brief allocates all necessary fields, reads information from material configuration file
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
module subroutine mech_none_init module subroutine mechanical_pass_init
integer :: & integer :: &
Ninstances, & Ninstances, &
h, & h, &
Nmaterialpoints Nmaterialpoints
print'(/,a)', ' <<<+- homogenization:mechanics:none init -+>>>' print'(/,a)', ' <<<+- homogenization:mechanical:pass init -+>>>'
Ninstances = count(homogenization_type == HOMOGENIZATION_NONE_ID) Ninstances = count(homogenization_type == HOMOGENIZATION_NONE_ID)
print'(a,i2)', ' # instances: ',Ninstances; flush(IO_STDOUT) print'(a,i2)', ' # instances: ',Ninstances; flush(IO_STDOUT)
@ -27,7 +27,7 @@ module subroutine mech_none_init
if(homogenization_type(h) /= HOMOGENIZATION_NONE_ID) cycle if(homogenization_type(h) /= HOMOGENIZATION_NONE_ID) cycle
if(homogenization_Nconstituents(h) /= 1) & if(homogenization_Nconstituents(h) /= 1) &
call IO_error(211,ext_msg='N_constituents (mech_none)') call IO_error(211,ext_msg='N_constituents (mechanical_pass)')
Nmaterialpoints = count(material_homogenizationAt == h) Nmaterialpoints = count(material_homogenizationAt == h)
homogState(h)%sizeState = 0 homogState(h)%sizeState = 0
@ -36,6 +36,6 @@ module subroutine mech_none_init
enddo enddo
end subroutine mech_none_init end subroutine mechanical_pass_init
end submodule none end submodule none

View File

@ -78,7 +78,7 @@ module subroutine thermal_partition(ce)
T = current(material_homogenizationAt2(ce))%T(material_homogenizationMemberAt2(ce)) T = current(material_homogenizationAt2(ce))%T(material_homogenizationMemberAt2(ce))
dot_T = current(material_homogenizationAt2(ce))%dot_T(material_homogenizationMemberAt2(ce)) dot_T = current(material_homogenizationAt2(ce))%dot_T(material_homogenizationMemberAt2(ce))
do co = 1, homogenization_Nconstituents(material_homogenizationAt2(ce)) do co = 1, homogenization_Nconstituents(material_homogenizationAt2(ce))
call constitutive_thermal_setField(T,dot_T,co,ce) call phase_thermal_setField(T,dot_T,co,ce)
enddo enddo
end subroutine thermal_partition end subroutine thermal_partition
@ -91,7 +91,7 @@ module subroutine thermal_homogenize(ip,el)
integer, intent(in) :: ip,el integer, intent(in) :: ip,el
!call constitutive_thermal_getRate(homogenization_dot_T((el-1)*discretization_nIPs+ip), ip,el) !call phase_thermal_getRate(homogenization_dot_T((el-1)*discretization_nIPs+ip), ip,el)
end subroutine thermal_homogenize end subroutine thermal_homogenize
@ -235,7 +235,7 @@ module subroutine thermal_conduction_getSource(Tdot, ip,el)
do co = 1, homogenization_Nconstituents(ho) do co = 1, homogenization_Nconstituents(ho)
ph = material_phaseAt(co,el) ph = material_phaseAt(co,el)
me = material_phasememberAt(co,ip,el) me = material_phasememberAt(co,ip,el)
call constitutive_thermal_getRate(dot_T_temp, ph,me) call phase_thermal_getRate(dot_T_temp, ph,me)
Tdot = Tdot + dot_T_temp Tdot = Tdot + dot_T_temp
enddo enddo

View File

@ -459,7 +459,8 @@ subroutine lattice_init
phase, & phase, &
mech, & mech, &
elasticity, & elasticity, &
thermal thermal, &
damage
print'(/,a)', ' <<<+- lattice init -+>>>'; flush(IO_STDOUT) print'(/,a)', ' <<<+- lattice init -+>>>'; flush(IO_STDOUT)
@ -535,13 +536,17 @@ subroutine lattice_init
endif endif
lattice_D(1,1,ph) = phase%get_asFloat('D_11',defaultVal=0.0_pReal) if (phase%contains('damage')) then
lattice_D(2,2,ph) = phase%get_asFloat('D_22',defaultVal=0.0_pReal) damage => phase%get('damage')
lattice_D(3,3,ph) = phase%get_asFloat('D_33',defaultVal=0.0_pReal) damage => damage%get(1)
lattice_D(1:3,1:3,ph) = lattice_applyLatticeSymmetry33(lattice_D(1:3,1:3,ph), & lattice_D(1,1,ph) = damage%get_asFloat('D_11',defaultVal=0.0_pReal)
lattice_D(2,2,ph) = damage%get_asFloat('D_22',defaultVal=0.0_pReal)
lattice_D(3,3,ph) = damage%get_asFloat('D_33',defaultVal=0.0_pReal)
lattice_D(1:3,1:3,ph) = lattice_applyLatticeSymmetry33(lattice_D(1:3,1:3,ph), &
phase%get_asString('lattice')) phase%get_asString('lattice'))
lattice_M(ph) = phase%get_asFloat('M',defaultVal=0.0_pReal) lattice_M(ph) = damage%get_asFloat('M',defaultVal=0.0_pReal)
endif
! SHOULD NOT BE PART OF LATTICE END ! SHOULD NOT BE PART OF LATTICE END
call selfTest call selfTest

View File

@ -6,50 +6,26 @@
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
module material module material
use prec use prec
use math
use config use config
use results use results
use IO use IO
use rotations use rotations
use discretization use discretization
use YAML_types
implicit none implicit none
private private
enum, bind(c); enumerator :: & integer, dimension(:), allocatable, public, protected :: &
THERMAL_ISOTHERMAL_ID, & homogenization_Nconstituents !< number of grains in each homogenization
THERMAL_CONDUCTION_ID, &
DAMAGE_NONE_ID, &
DAMAGE_NONLOCAL_ID, &
HOMOGENIZATION_UNDEFINED_ID, &
HOMOGENIZATION_NONE_ID, &
HOMOGENIZATION_ISOSTRAIN_ID, &
HOMOGENIZATION_RGC_ID
end enum
character(len=:), public, protected, allocatable, dimension(:) :: & character(len=:), public, protected, allocatable, dimension(:) :: &
material_name_phase, & !< name of each phase material_name_phase, & !< name of each phase
material_name_homogenization !< name of each homogenization material_name_homogenization !< name of each homogenization
integer(kind(THERMAL_isothermal_ID)), dimension(:), allocatable, public, protected :: &
thermal_type !< thermal transport model
integer(kind(DAMAGE_none_ID)), dimension(:), allocatable, public, protected :: &
damage_type !< nonlocal damage model
integer(kind(HOMOGENIZATION_undefined_ID)), dimension(:), allocatable, public, protected :: &
homogenization_type !< type of each homogenization
integer, public, protected :: & integer, public, protected :: &
homogenization_maxNconstituents !< max number of grains in any USED homogenization homogenization_maxNconstituents !< max number of grains in any USED homogenization
integer, dimension(:), allocatable, public, protected :: &
homogenization_Nconstituents, & !< number of grains in each homogenization
homogenization_typeInstance, & !< instance of particular type of each homogenization
thermal_typeInstance, & !< instance of particular type of each thermal transport
damage_typeInstance !< instance of particular type of each nonlocal damage
real(pReal), dimension(:), allocatable, public, protected :: &
thermal_initialT !< initial temperature per each homogenization
integer, dimension(:), allocatable, public, protected :: & ! (elem) integer, dimension(:), allocatable, public, protected :: & ! (elem)
material_homogenizationAt, & !< homogenization ID of each element material_homogenizationAt, & !< homogenization ID of each element
material_homogenizationAt2, & !< per cell material_homogenizationAt2, & !< per cell
@ -63,50 +39,28 @@ module material
integer, dimension(:,:,:), allocatable, public, protected :: & ! (constituent,IP,elem) integer, dimension(:,:,:), allocatable, public, protected :: & ! (constituent,IP,elem)
material_phaseMemberAt !< position of the element within its phase instance material_phaseMemberAt !< position of the element within its phase instance
type(tState), allocatable, dimension(:), public :: &
homogState, &
damageState_h
type(Rotation), dimension(:,:,:), allocatable, public, protected :: & type(Rotation), dimension(:,:,:), allocatable, public, protected :: &
material_orientation0 !< initial orientation of each grain,IP,element material_orientation0 !< initial orientation of each grain,IP,element
type(group_float), allocatable, dimension(:), public :: &
damage !< damage field
public :: & public :: &
material_init, & material_init
THERMAL_ISOTHERMAL_ID, &
THERMAL_CONDUCTION_ID, &
DAMAGE_NONE_ID, &
DAMAGE_NONLOCAL_ID, &
HOMOGENIZATION_NONE_ID, &
HOMOGENIZATION_ISOSTRAIN_ID, &
HOMOGENIZATION_RGC_ID
contains contains
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief parses material configuration file !> @brief Parse material configuration file (material.yaml).
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
subroutine material_init(restart) subroutine material_init(restart)
logical, intent(in) :: restart logical, intent(in) :: restart
print'(/,a)', ' <<<+- material init -+>>>'; flush(IO_STDOUT) print'(/,a)', ' <<<+- material init -+>>>'; flush(IO_STDOUT)
call material_parseMaterial call material_parseMaterial
print*, 'Material parsed' print*, 'Material parsed'
call material_parseHomogenization
print*, 'Homogenization parsed'
allocate(homogState (size(material_name_homogenization)))
allocate(damageState_h (size(material_name_homogenization)))
allocate(damage (size(material_name_homogenization)))
if (.not. restart) then if (.not. restart) then
call results_openJobFile call results_openJobFile
@ -118,82 +72,6 @@ subroutine material_init(restart)
end subroutine material_init end subroutine material_init
!--------------------------------------------------------------------------------------------------
!> @brief parses the homogenization part from the material configuration
! ToDo: This should be done in homogenization
!--------------------------------------------------------------------------------------------------
subroutine material_parseHomogenization
class(tNode), pointer :: &
material_homogenization, &
homog, &
homogMech, &
homogThermal, &
homogDamage
integer :: h
material_homogenization => config_material%get('homogenization')
allocate(homogenization_type(size(material_name_homogenization)), source=HOMOGENIZATION_undefined_ID)
allocate(thermal_type(size(material_name_homogenization)), source=THERMAL_isothermal_ID)
allocate(damage_type (size(material_name_homogenization)), source=DAMAGE_none_ID)
allocate(homogenization_typeInstance(size(material_name_homogenization)), source=0)
allocate(thermal_typeInstance(size(material_name_homogenization)), source=0)
allocate(damage_typeInstance(size(material_name_homogenization)), source=0)
allocate(thermal_initialT(size(material_name_homogenization)), source=300.0_pReal)
do h=1, size(material_name_homogenization)
homog => material_homogenization%get(h)
homogMech => homog%get('mechanics')
select case (homogMech%get_asString('type'))
case('none')
homogenization_type(h) = HOMOGENIZATION_NONE_ID
case('isostrain')
homogenization_type(h) = HOMOGENIZATION_ISOSTRAIN_ID
case('RGC')
homogenization_type(h) = HOMOGENIZATION_RGC_ID
case default
call IO_error(500,ext_msg=homogMech%get_asString('type'))
end select
homogenization_typeInstance(h) = count(homogenization_type==homogenization_type(h))
if(homog%contains('thermal')) then
homogThermal => homog%get('thermal')
thermal_initialT(h) = homogThermal%get_asFloat('T_0',defaultVal=300.0_pReal)
select case (homogThermal%get_asString('type'))
case('isothermal')
thermal_type(h) = THERMAL_isothermal_ID
case('conduction')
thermal_type(h) = THERMAL_conduction_ID
case default
call IO_error(500,ext_msg=homogThermal%get_asString('type'))
end select
endif
if(homog%contains('damage')) then
homogDamage => homog%get('damage')
select case (homogDamage%get_asString('type'))
case('none')
damage_type(h) = DAMAGE_none_ID
case('nonlocal')
damage_type(h) = DAMAGE_nonlocal_ID
case default
call IO_error(500,ext_msg=homogDamage%get_asString('type'))
end select
endif
enddo
do h=1, size(material_name_homogenization)
homogenization_typeInstance(h) = count(homogenization_type(1:h) == homogenization_type(h))
thermal_typeInstance(h) = count(thermal_type (1:h) == thermal_type (h))
damage_typeInstance(h) = count(damage_type (1:h) == damage_type (h))
enddo
end subroutine material_parseHomogenization
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief parses the material part in the material configuration file !> @brief parses the material part in the material configuration file
@ -265,7 +143,7 @@ subroutine material_parseMaterial
frac = 0.0_pReal frac = 0.0_pReal
do co = 1, constituents%length do co = 1, constituents%length
constituent => constituents%get(co) constituent => constituents%get(co)
frac = frac + constituent%get_asFloat('fraction') frac = frac + constituent%get_asFloat('v')
material_phaseAt(co,el) = phases%getIndex(constituent%get_asString('phase')) material_phaseAt(co,el) = phases%getIndex(constituent%get_asString('phase'))
do ip = 1, discretization_nIPs do ip = 1, discretization_nIPs

View File

@ -18,7 +18,7 @@ program DAMASK_mesh
use config use config
use discretization_mesh use discretization_mesh
use FEM_Utilities use FEM_Utilities
use mesh_mech_FEM use mesh_mechanical_FEM
implicit none implicit none
@ -242,7 +242,7 @@ program DAMASK_mesh
do field = 1, nActiveFields do field = 1, nActiveFields
select case (loadCases(1)%fieldBC(field)%ID) select case (loadCases(1)%fieldBC(field)%ID)
case(FIELD_MECH_ID) case(FIELD_MECH_ID)
call FEM_mech_init(loadCases(1)%fieldBC(field)) call FEM_mechanical_init(loadCases(1)%fieldBC(field))
end select end select
enddo enddo
@ -306,7 +306,7 @@ program DAMASK_mesh
do field = 1, nActiveFields do field = 1, nActiveFields
select case (loadCases(currentLoadCase)%fieldBC(field)%ID) select case (loadCases(currentLoadCase)%fieldBC(field)%ID)
case(FIELD_MECH_ID) case(FIELD_MECH_ID)
call FEM_mech_forward (& call FEM_mechanical_forward (&
guess,timeinc,timeIncOld,loadCases(currentLoadCase)%fieldBC(field)) guess,timeinc,timeIncOld,loadCases(currentLoadCase)%fieldBC(field))
end select end select
@ -320,7 +320,7 @@ program DAMASK_mesh
do field = 1, nActiveFields do field = 1, nActiveFields
select case (loadCases(currentLoadCase)%fieldBC(field)%ID) select case (loadCases(currentLoadCase)%fieldBC(field)%ID)
case(FIELD_MECH_ID) case(FIELD_MECH_ID)
solres(field) = FEM_mech_solution (& solres(field) = FEM_mechanical_solution (&
incInfo,timeinc,timeIncOld,loadCases(currentLoadCase)%fieldBC(field)) incInfo,timeinc,timeIncOld,loadCases(currentLoadCase)%fieldBC(field))
end select end select

View File

@ -127,12 +127,12 @@ subroutine FEM_utilities_init
CHKERRQ(ierr) CHKERRQ(ierr)
if(debugPETSc) call PetscOptionsInsertString(PETSC_NULL_OPTIONS,trim(PETSCDEBUG),ierr) if(debugPETSc) call PetscOptionsInsertString(PETSC_NULL_OPTIONS,trim(PETSCDEBUG),ierr)
CHKERRQ(ierr) CHKERRQ(ierr)
call PetscOptionsInsertString(PETSC_NULL_OPTIONS,'-mech_snes_type newtonls & call PetscOptionsInsertString(PETSC_NULL_OPTIONS,'-mechanical_snes_type newtonls &
&-mech_snes_linesearch_type cp -mech_snes_ksp_ew & &-mechanical_snes_linesearch_type cp -mechanical_snes_ksp_ew &
&-mech_snes_ksp_ew_rtol0 0.01 -mech_snes_ksp_ew_rtolmax 0.01 & &-mechanical_snes_ksp_ew_rtol0 0.01 -mechanical_snes_ksp_ew_rtolmax 0.01 &
&-mech_ksp_type fgmres -mech_ksp_max_it 25 & &-mechanical_ksp_type fgmres -mechanical_ksp_max_it 25 &
&-mech_pc_type ml -mech_mg_levels_ksp_type chebyshev & &-mechanical_pc_type ml -mechanical_mg_levels_ksp_type chebyshev &
&-mech_mg_levels_pc_type sor -mech_pc_ml_nullspace user',ierr) &-mechanical_mg_levels_pc_type sor -mechanical_pc_ml_nullspace user',ierr)
CHKERRQ(ierr) CHKERRQ(ierr)
call PetscOptionsInsertString(PETSC_NULL_OPTIONS,num_mesh%get_asString('petsc_options',defaultVal=''),ierr) call PetscOptionsInsertString(PETSC_NULL_OPTIONS,num_mesh%get_asString('petsc_options',defaultVal=''),ierr)
CHKERRQ(ierr) CHKERRQ(ierr)

View File

@ -4,7 +4,7 @@
!> @author Philip Eisenlohr, Max-Planck-Institut für Eisenforschung GmbH !> @author Philip Eisenlohr, Max-Planck-Institut für Eisenforschung GmbH
!> @brief FEM PETSc solver !> @brief FEM PETSc solver
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
module mesh_mech_FEM module mesh_mechanical_FEM
#include <petsc/finclude/petscdmplex.h> #include <petsc/finclude/petscdmplex.h>
#include <petsc/finclude/petscdm.h> #include <petsc/finclude/petscdm.h>
#include <petsc/finclude/petsc.h> #include <petsc/finclude/petsc.h>
@ -50,7 +50,7 @@ module mesh_mech_FEM
type(tNumerics), private :: num type(tNumerics), private :: num
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
! PETSc data ! PETSc data
SNES :: mech_snes SNES :: mechanical_snes
Vec :: solution, solution_rate, solution_local Vec :: solution, solution_rate, solution_local
PetscInt :: dimPlex, cellDof, nQuadrature, nBasis PetscInt :: dimPlex, cellDof, nQuadrature, nBasis
PetscReal, allocatable, target :: qPoints(:), qWeights(:) PetscReal, allocatable, target :: qPoints(:), qWeights(:)
@ -65,20 +65,20 @@ module mesh_mech_FEM
real(pReal), parameter :: eps = 1.0e-18_pReal real(pReal), parameter :: eps = 1.0e-18_pReal
public :: & public :: &
FEM_mech_init, & FEM_mechanical_init, &
FEM_mech_solution, & FEM_mechanical_solution, &
FEM_mech_forward FEM_mechanical_forward
contains contains
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief allocates all neccessary fields and fills them with data !> @brief allocates all neccessary fields and fills them with data
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
subroutine FEM_mech_init(fieldBC) subroutine FEM_mechanical_init(fieldBC)
type(tFieldBC), intent(in) :: fieldBC type(tFieldBC), intent(in) :: fieldBC
DM :: mech_mesh DM :: mechanical_mesh
PetscFE :: mechFE PetscFE :: mechFE
PetscQuadrature :: mechQuad, functional PetscQuadrature :: mechQuad, functional
PetscDS :: mechDS PetscDS :: mechDS
@ -126,8 +126,8 @@ subroutine FEM_mech_init(fieldBC)
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
! Setup FEM mech mesh ! Setup FEM mech mesh
call DMClone(geomMesh,mech_mesh,ierr); CHKERRQ(ierr) call DMClone(geomMesh,mechanical_mesh,ierr); CHKERRQ(ierr)
call DMGetDimension(mech_mesh,dimPlex,ierr); CHKERRQ(ierr) call DMGetDimension(mechanical_mesh,dimPlex,ierr); CHKERRQ(ierr)
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
! Setup FEM mech discretization ! Setup FEM mech discretization
@ -146,22 +146,22 @@ subroutine FEM_mech_init(fieldBC)
call PetscFESetQuadrature(mechFE,mechQuad,ierr); CHKERRQ(ierr) call PetscFESetQuadrature(mechFE,mechQuad,ierr); CHKERRQ(ierr)
call PetscFEGetDimension(mechFE,nBasis,ierr); CHKERRQ(ierr) call PetscFEGetDimension(mechFE,nBasis,ierr); CHKERRQ(ierr)
nBasis = nBasis/nc nBasis = nBasis/nc
call DMAddField(mech_mesh,PETSC_NULL_DMLABEL,mechFE,ierr); CHKERRQ(ierr) call DMAddField(mechanical_mesh,PETSC_NULL_DMLABEL,mechFE,ierr); CHKERRQ(ierr)
call DMCreateDS(mech_mesh,ierr); CHKERRQ(ierr) call DMCreateDS(mechanical_mesh,ierr); CHKERRQ(ierr)
call DMGetDS(mech_mesh,mechDS,ierr); CHKERRQ(ierr) call DMGetDS(mechanical_mesh,mechDS,ierr); CHKERRQ(ierr)
call PetscDSGetTotalDimension(mechDS,cellDof,ierr); CHKERRQ(ierr) call PetscDSGetTotalDimension(mechDS,cellDof,ierr); CHKERRQ(ierr)
call PetscFEDestroy(mechFE,ierr); CHKERRQ(ierr) call PetscFEDestroy(mechFE,ierr); CHKERRQ(ierr)
call PetscQuadratureDestroy(mechQuad,ierr); CHKERRQ(ierr) call PetscQuadratureDestroy(mechQuad,ierr); CHKERRQ(ierr)
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
! Setup FEM mech boundary conditions ! Setup FEM mech boundary conditions
call DMGetLabel(mech_mesh,'Face Sets',BCLabel,ierr); CHKERRQ(ierr) call DMGetLabel(mechanical_mesh,'Face Sets',BCLabel,ierr); CHKERRQ(ierr)
call DMPlexLabelComplete(mech_mesh,BCLabel,ierr); CHKERRQ(ierr) call DMPlexLabelComplete(mechanical_mesh,BCLabel,ierr); CHKERRQ(ierr)
call DMGetLocalSection(mech_mesh,section,ierr); CHKERRQ(ierr) call DMGetLocalSection(mechanical_mesh,section,ierr); CHKERRQ(ierr)
allocate(pnumComp(1), source=dimPlex) allocate(pnumComp(1), source=dimPlex)
allocate(pnumDof(0:dimPlex), source = 0) allocate(pnumDof(0:dimPlex), source = 0)
do topologDim = 0, dimPlex do topologDim = 0, dimPlex
call DMPlexGetDepthStratum(mech_mesh,topologDim,cellStart,cellEnd,ierr) call DMPlexGetDepthStratum(mechanical_mesh,topologDim,cellStart,cellEnd,ierr)
CHKERRQ(ierr) CHKERRQ(ierr)
call PetscSectionGetDof(section,cellStart,pnumDof(topologDim),ierr) call PetscSectionGetDof(section,cellStart,pnumDof(topologDim),ierr)
CHKERRQ(ierr) CHKERRQ(ierr)
@ -179,10 +179,10 @@ subroutine FEM_mech_init(fieldBC)
numBC = numBC + 1 numBC = numBC + 1
call ISCreateGeneral(PETSC_COMM_WORLD,1,[field-1],PETSC_COPY_VALUES,pbcComps(numBC),ierr) call ISCreateGeneral(PETSC_COMM_WORLD,1,[field-1],PETSC_COPY_VALUES,pbcComps(numBC),ierr)
CHKERRQ(ierr) CHKERRQ(ierr)
call DMGetStratumSize(mech_mesh,'Face Sets',mesh_boundaries(faceSet),bcSize,ierr) call DMGetStratumSize(mechanical_mesh,'Face Sets',mesh_boundaries(faceSet),bcSize,ierr)
CHKERRQ(ierr) CHKERRQ(ierr)
if (bcSize > 0) then if (bcSize > 0) then
call DMGetStratumIS(mech_mesh,'Face Sets',mesh_boundaries(faceSet),bcPoint,ierr) call DMGetStratumIS(mechanical_mesh,'Face Sets',mesh_boundaries(faceSet),bcPoint,ierr)
CHKERRQ(ierr) CHKERRQ(ierr)
call ISGetIndicesF90(bcPoint,pBcPoint,ierr); CHKERRQ(ierr) call ISGetIndicesF90(bcPoint,pBcPoint,ierr); CHKERRQ(ierr)
call ISCreateGeneral(PETSC_COMM_WORLD,bcSize,pBcPoint,PETSC_COPY_VALUES,pbcPoints(numBC),ierr) call ISCreateGeneral(PETSC_COMM_WORLD,bcSize,pBcPoint,PETSC_COPY_VALUES,pbcPoints(numBC),ierr)
@ -195,32 +195,32 @@ subroutine FEM_mech_init(fieldBC)
endif endif
endif endif
enddo; enddo enddo; enddo
call DMPlexCreateSection(mech_mesh,nolabel,pNumComp,pNumDof, & call DMPlexCreateSection(mechanical_mesh,nolabel,pNumComp,pNumDof, &
numBC,pBcField,pBcComps,pBcPoints,PETSC_NULL_IS,section,ierr) numBC,pBcField,pBcComps,pBcPoints,PETSC_NULL_IS,section,ierr)
CHKERRQ(ierr) CHKERRQ(ierr)
call DMSetSection(mech_mesh,section,ierr); CHKERRQ(ierr) call DMSetSection(mechanical_mesh,section,ierr); CHKERRQ(ierr)
do faceSet = 1, numBC do faceSet = 1, numBC
call ISDestroy(pbcPoints(faceSet),ierr); CHKERRQ(ierr) call ISDestroy(pbcPoints(faceSet),ierr); CHKERRQ(ierr)
enddo enddo
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
! initialize solver specific parts of PETSc ! initialize solver specific parts of PETSc
call SNESCreate(PETSC_COMM_WORLD,mech_snes,ierr);CHKERRQ(ierr) call SNESCreate(PETSC_COMM_WORLD,mechanical_snes,ierr);CHKERRQ(ierr)
call SNESSetOptionsPrefix(mech_snes,'mech_',ierr);CHKERRQ(ierr) call SNESSetOptionsPrefix(mechanical_snes,'mechanical_',ierr);CHKERRQ(ierr)
call SNESSetDM(mech_snes,mech_mesh,ierr); CHKERRQ(ierr) !< set the mesh for non-linear solver call SNESSetDM(mechanical_snes,mechanical_mesh,ierr); CHKERRQ(ierr) !< set the mesh for non-linear solver
call DMCreateGlobalVector(mech_mesh,solution ,ierr); CHKERRQ(ierr) !< locally owned displacement Dofs call DMCreateGlobalVector(mechanical_mesh,solution ,ierr); CHKERRQ(ierr) !< locally owned displacement Dofs
call DMCreateGlobalVector(mech_mesh,solution_rate ,ierr); CHKERRQ(ierr) !< locally owned velocity Dofs to guess solution at next load step call DMCreateGlobalVector(mechanical_mesh,solution_rate ,ierr); CHKERRQ(ierr) !< locally owned velocity Dofs to guess solution at next load step
call DMCreateLocalVector (mech_mesh,solution_local ,ierr); CHKERRQ(ierr) !< locally owned velocity Dofs to guess solution at next load step call DMCreateLocalVector (mechanical_mesh,solution_local ,ierr); CHKERRQ(ierr) !< locally owned velocity Dofs to guess solution at next load step
call DMSNESSetFunctionLocal(mech_mesh,FEM_mech_formResidual,PETSC_NULL_VEC,ierr) !< function to evaluate residual forces call DMSNESSetFunctionLocal(mechanical_mesh,FEM_mechanical_formResidual,PETSC_NULL_VEC,ierr) !< function to evaluate residual forces
CHKERRQ(ierr) CHKERRQ(ierr)
call DMSNESSetJacobianLocal(mech_mesh,FEM_mech_formJacobian,PETSC_NULL_VEC,ierr) !< function to evaluate stiffness matrix call DMSNESSetJacobianLocal(mechanical_mesh,FEM_mechanical_formJacobian,PETSC_NULL_VEC,ierr) !< function to evaluate stiffness matrix
CHKERRQ(ierr) CHKERRQ(ierr)
call SNESSetMaxLinearSolveFailures(mech_snes, huge(1), ierr); CHKERRQ(ierr) !< ignore linear solve failures call SNESSetMaxLinearSolveFailures(mechanical_snes, huge(1), ierr); CHKERRQ(ierr) !< ignore linear solve failures
call SNESSetConvergenceTest(mech_snes,FEM_mech_converged,PETSC_NULL_VEC,PETSC_NULL_FUNCTION,ierr) call SNESSetConvergenceTest(mechanical_snes,FEM_mechanical_converged,PETSC_NULL_VEC,PETSC_NULL_FUNCTION,ierr)
CHKERRQ(ierr) CHKERRQ(ierr)
call SNESSetTolerances(mech_snes,1.0,0.0,0.0,num%itmax,num%itmax,ierr) call SNESSetTolerances(mechanical_snes,1.0,0.0,0.0,num%itmax,num%itmax,ierr)
CHKERRQ(ierr) CHKERRQ(ierr)
call SNESSetFromOptions(mech_snes,ierr); CHKERRQ(ierr) call SNESSetFromOptions(mechanical_snes,ierr); CHKERRQ(ierr)
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
! init fields ! init fields
@ -236,11 +236,11 @@ subroutine FEM_mech_init(fieldBC)
call PetscDSGetDiscretization(mechDS,0,mechFE,ierr) call PetscDSGetDiscretization(mechDS,0,mechFE,ierr)
CHKERRQ(ierr) CHKERRQ(ierr)
call PetscFEGetDualSpace(mechFE,mechDualSpace,ierr); CHKERRQ(ierr) call PetscFEGetDualSpace(mechFE,mechDualSpace,ierr); CHKERRQ(ierr)
call DMPlexGetHeightStratum(mech_mesh,0,cellStart,cellEnd,ierr) call DMPlexGetHeightStratum(mechanical_mesh,0,cellStart,cellEnd,ierr)
CHKERRQ(ierr) CHKERRQ(ierr)
do cell = cellStart, cellEnd-1 !< loop over all elements do cell = cellStart, cellEnd-1 !< loop over all elements
x_scal = 0.0_pReal x_scal = 0.0_pReal
call DMPlexComputeCellGeometryAffineFEM(mech_mesh,cell,pV0,pCellJ,pInvcellJ,detJ,ierr) call DMPlexComputeCellGeometryAffineFEM(mechanical_mesh,cell,pV0,pCellJ,pInvcellJ,detJ,ierr)
CHKERRQ(ierr) CHKERRQ(ierr)
cellJMat = reshape(pCellJ,shape=[dimPlex,dimPlex]) cellJMat = reshape(pCellJ,shape=[dimPlex,dimPlex])
do basis = 0, nBasis*dimPlex-1, dimPlex do basis = 0, nBasis*dimPlex-1, dimPlex
@ -251,17 +251,17 @@ subroutine FEM_mech_init(fieldBC)
x_scal(basis+1:basis+dimPlex) = pV0 + matmul(transpose(cellJMat),nodalPointsP + 1.0_pReal) x_scal(basis+1:basis+dimPlex) = pV0 + matmul(transpose(cellJMat),nodalPointsP + 1.0_pReal)
enddo enddo
px_scal => x_scal px_scal => x_scal
call DMPlexVecSetClosure(mech_mesh,section,solution_local,cell,px_scal,5,ierr) call DMPlexVecSetClosure(mechanical_mesh,section,solution_local,cell,px_scal,5,ierr)
CHKERRQ(ierr) CHKERRQ(ierr)
enddo enddo
end subroutine FEM_mech_init end subroutine FEM_mechanical_init
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief solution for the FEM load step !> @brief solution for the FEM load step
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
type(tSolutionState) function FEM_mech_solution( & type(tSolutionState) function FEM_mechanical_solution( &
incInfoIn,timeinc,timeinc_old,fieldBC) incInfoIn,timeinc,timeinc_old,fieldBC)
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
@ -278,35 +278,35 @@ type(tSolutionState) function FEM_mech_solution( &
SNESConvergedReason :: reason SNESConvergedReason :: reason
incInfo = incInfoIn incInfo = incInfoIn
FEM_mech_solution%converged =.false. FEM_mechanical_solution%converged =.false.
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
! set module wide availabe data ! set module wide availabe data
params%timeinc = timeinc params%timeinc = timeinc
params%fieldBC = fieldBC params%fieldBC = fieldBC
call SNESSolve(mech_snes,PETSC_NULL_VEC,solution,ierr); CHKERRQ(ierr) ! solve mech_snes based on solution guess (result in solution) call SNESSolve(mechanical_snes,PETSC_NULL_VEC,solution,ierr); CHKERRQ(ierr) ! solve mechanical_snes based on solution guess (result in solution)
call SNESGetConvergedReason(mech_snes,reason,ierr); CHKERRQ(ierr) ! solution converged? call SNESGetConvergedReason(mechanical_snes,reason,ierr); CHKERRQ(ierr) ! solution converged?
terminallyIll = .false. terminallyIll = .false.
if (reason < 1) then ! 0: still iterating (will not occur), negative -> convergence error if (reason < 1) then ! 0: still iterating (will not occur), negative -> convergence error
FEM_mech_solution%converged = .false. FEM_mechanical_solution%converged = .false.
FEM_mech_solution%iterationsNeeded = num%itmax FEM_mechanical_solution%iterationsNeeded = num%itmax
else ! >= 1 proper convergence (or terminally ill) else ! >= 1 proper convergence (or terminally ill)
FEM_mech_solution%converged = .true. FEM_mechanical_solution%converged = .true.
call SNESGetIterationNumber(mech_snes,FEM_mech_solution%iterationsNeeded,ierr) call SNESGetIterationNumber(mechanical_snes,FEM_mechanical_solution%iterationsNeeded,ierr)
CHKERRQ(ierr) CHKERRQ(ierr)
endif endif
print'(/,a)', ' ===========================================================================' print'(/,a)', ' ==========================================================================='
flush(IO_STDOUT) flush(IO_STDOUT)
end function FEM_mech_solution end function FEM_mechanical_solution
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief forms the FEM residual vector !> @brief forms the FEM residual vector
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
subroutine FEM_mech_formResidual(dm_local,xx_local,f_local,dummy,ierr) subroutine FEM_mechanical_formResidual(dm_local,xx_local,f_local,dummy,ierr)
DM :: dm_local DM :: dm_local
PetscObject,intent(in) :: dummy PetscObject,intent(in) :: dummy
@ -431,13 +431,13 @@ subroutine FEM_mech_formResidual(dm_local,xx_local,f_local,dummy,ierr)
enddo enddo
call DMRestoreLocalVector(dm_local,x_local,ierr); CHKERRQ(ierr) call DMRestoreLocalVector(dm_local,x_local,ierr); CHKERRQ(ierr)
end subroutine FEM_mech_formResidual end subroutine FEM_mechanical_formResidual
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief forms the FEM stiffness matrix !> @brief forms the FEM stiffness matrix
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
subroutine FEM_mech_formJacobian(dm_local,xx_local,Jac_pre,Jac,dummy,ierr) subroutine FEM_mechanical_formJacobian(dm_local,xx_local,Jac_pre,Jac,dummy,ierr)
DM :: dm_local DM :: dm_local
@ -575,13 +575,13 @@ subroutine FEM_mech_formJacobian(dm_local,xx_local,Jac_pre,Jac,dummy,ierr)
call MatSetNearNullSpace(Jac,matnull,ierr); CHKERRQ(ierr) call MatSetNearNullSpace(Jac,matnull,ierr); CHKERRQ(ierr)
call MatNullSpaceDestroy(matnull,ierr); CHKERRQ(ierr) call MatNullSpaceDestroy(matnull,ierr); CHKERRQ(ierr)
end subroutine FEM_mech_formJacobian end subroutine FEM_mechanical_formJacobian
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief forwarding routine !> @brief forwarding routine
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
subroutine FEM_mech_forward(guess,timeinc,timeinc_old,fieldBC) subroutine FEM_mechanical_forward(guess,timeinc,timeinc_old,fieldBC)
type(tFieldBC), intent(in) :: & type(tFieldBC), intent(in) :: &
fieldBC fieldBC
@ -603,7 +603,7 @@ subroutine FEM_mech_forward(guess,timeinc,timeinc_old,fieldBC)
if (guess .and. .not. cutBack) then if (guess .and. .not. cutBack) then
ForwardData = .True. ForwardData = .True.
homogenization_F0 = homogenization_F homogenization_F0 = homogenization_F
call SNESGetDM(mech_snes,dm_local,ierr); CHKERRQ(ierr) !< retrieve mesh info from mech_snes into dm_local call SNESGetDM(mechanical_snes,dm_local,ierr); CHKERRQ(ierr) !< retrieve mesh info from mechanical_snes into dm_local
call DMGetSection(dm_local,section,ierr); CHKERRQ(ierr) call DMGetSection(dm_local,section,ierr); CHKERRQ(ierr)
call DMGetLocalVector(dm_local,x_local,ierr); CHKERRQ(ierr) call DMGetLocalVector(dm_local,x_local,ierr); CHKERRQ(ierr)
call VecSet(x_local,0.0_pReal,ierr); CHKERRQ(ierr) call VecSet(x_local,0.0_pReal,ierr); CHKERRQ(ierr)
@ -634,13 +634,13 @@ subroutine FEM_mech_forward(guess,timeinc,timeinc_old,fieldBC)
call VecCopy(solution_rate,solution,ierr); CHKERRQ(ierr) call VecCopy(solution_rate,solution,ierr); CHKERRQ(ierr)
call VecScale(solution,timeinc,ierr); CHKERRQ(ierr) call VecScale(solution,timeinc,ierr); CHKERRQ(ierr)
end subroutine FEM_mech_forward end subroutine FEM_mechanical_forward
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief reporting !> @brief reporting
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
subroutine FEM_mech_converged(snes_local,PETScIter,xnorm,snorm,fnorm,reason,dummy,ierr) subroutine FEM_mechanical_converged(snes_local,PETScIter,xnorm,snorm,fnorm,reason,dummy,ierr)
SNES :: snes_local SNES :: snes_local
PetscInt :: PETScIter PetscInt :: PETScIter
@ -662,6 +662,6 @@ subroutine FEM_mech_converged(snes_local,PETScIter,xnorm,snorm,fnorm,reason,dumm
' Piola--Kirchhoff stress / MPa =',transpose(P_av)*1.e-6_pReal ' Piola--Kirchhoff stress / MPa =',transpose(P_av)*1.e-6_pReal
flush(IO_STDOUT) flush(IO_STDOUT)
end subroutine FEM_mech_converged end subroutine FEM_mechanical_converged
end module mesh_mech_FEM end module mesh_mechanical_FEM

View File

@ -58,32 +58,28 @@ module phase
type(tDebugOptions) :: debugCrystallite type(tDebugOptions) :: debugCrystallite
integer, dimension(:), allocatable, public :: & !< ToDo: should be protected (bug in Intel compiler) integer, dimension(:), allocatable, public :: & !< ToDo: should be protected (bug in Intel compiler)
thermal_Nsources, & phase_elasticityInstance, &
phase_Nsources, & !< number of source mechanisms active in each phase phase_NstiffnessDegradations
phase_Nkinematics, & !< number of kinematic mechanisms active in each phase
phase_NstiffnessDegradations, & !< number of stiffness degradation mechanisms active in each phase
phase_plasticityInstance, & !< instance of particular plasticity of each phase
phase_elasticityInstance !< instance of particular elasticity of each phase
logical, dimension(:), allocatable, public :: & ! ToDo: should be protected (bug in Intel Compiler) logical, dimension(:), allocatable, public :: & ! ToDo: should be protected (bug in Intel Compiler)
phase_localPlasticity !< flags phases with local constitutive law phase_localPlasticity !< flags phases with local constitutive law
type(tPlasticState), allocatable, dimension(:), public :: & type(tPlasticState), allocatable, dimension(:), public :: &
plasticState plasticState
type(tSourceState), allocatable, dimension(:), public :: & type(tState), allocatable, dimension(:), public :: &
damageState, thermalState damageState
integer, public, protected :: & integer, public, protected :: &
constitutive_plasticity_maxSizeDotState, & phase_plasticity_maxSizeDotState, &
constitutive_source_maxSizeDotState phase_source_maxSizeDotState
interface interface
! == cleaned:begin ================================================================================= ! == cleaned:begin =================================================================================
module subroutine mech_init(phases) module subroutine mechanical_init(phases)
class(tNode), pointer :: phases class(tNode), pointer :: phases
end subroutine mech_init end subroutine mechanical_init
module subroutine damage_init module subroutine damage_init
end subroutine damage_init end subroutine damage_init
@ -93,83 +89,83 @@ module phase
end subroutine thermal_init end subroutine thermal_init
module subroutine mech_results(group,ph) module subroutine mechanical_results(group,ph)
character(len=*), intent(in) :: group character(len=*), intent(in) :: group
integer, intent(in) :: ph integer, intent(in) :: ph
end subroutine mech_results end subroutine mechanical_results
module subroutine damage_results(group,ph) module subroutine damage_results(group,ph)
character(len=*), intent(in) :: group character(len=*), intent(in) :: group
integer, intent(in) :: ph integer, intent(in) :: ph
end subroutine damage_results end subroutine damage_results
module subroutine mech_windForward(ph,me) module subroutine mechanical_windForward(ph,me)
integer, intent(in) :: ph, me integer, intent(in) :: ph, me
end subroutine mech_windForward end subroutine mechanical_windForward
module subroutine mech_forward() module subroutine mechanical_forward()
end subroutine mech_forward end subroutine mechanical_forward
module subroutine thermal_forward() module subroutine thermal_forward()
end subroutine thermal_forward end subroutine thermal_forward
module subroutine mech_restore(ce,includeL) module subroutine mechanical_restore(ce,includeL)
integer, intent(in) :: ce integer, intent(in) :: ce
logical, intent(in) :: includeL logical, intent(in) :: includeL
end subroutine mech_restore end subroutine mechanical_restore
module function constitutive_mech_dPdF(dt,co,ip,el) result(dPdF) module function phase_mechanical_dPdF(dt,co,ip,el) result(dPdF)
real(pReal), intent(in) :: dt real(pReal), intent(in) :: dt
integer, intent(in) :: & integer, intent(in) :: &
co, & !< counter in constituent loop co, & !< counter in constituent loop
ip, & !< counter in integration point loop ip, & !< counter in integration point loop
el !< counter in element loop el !< counter in element loop
real(pReal), dimension(3,3,3,3) :: dPdF real(pReal), dimension(3,3,3,3) :: dPdF
end function constitutive_mech_dPdF end function phase_mechanical_dPdF
module subroutine mech_restartWrite(groupHandle,ph) module subroutine mechanical_restartWrite(groupHandle,ph)
integer(HID_T), intent(in) :: groupHandle integer(HID_T), intent(in) :: groupHandle
integer, intent(in) :: ph integer, intent(in) :: ph
end subroutine mech_restartWrite end subroutine mechanical_restartWrite
module subroutine mech_restartRead(groupHandle,ph) module subroutine mechanical_restartRead(groupHandle,ph)
integer(HID_T), intent(in) :: groupHandle integer(HID_T), intent(in) :: groupHandle
integer, intent(in) :: ph integer, intent(in) :: ph
end subroutine mech_restartRead end subroutine mechanical_restartRead
module function mech_S(ph,me) result(S) module function mechanical_S(ph,me) result(S)
integer, intent(in) :: ph,me integer, intent(in) :: ph,me
real(pReal), dimension(3,3) :: S real(pReal), dimension(3,3) :: S
end function mech_S end function mechanical_S
module function mech_L_p(ph,me) result(L_p) module function mechanical_L_p(ph,me) result(L_p)
integer, intent(in) :: ph,me integer, intent(in) :: ph,me
real(pReal), dimension(3,3) :: L_p real(pReal), dimension(3,3) :: L_p
end function mech_L_p end function mechanical_L_p
module function constitutive_mech_getF(co,ip,el) result(F) module function phase_mechanical_getF(co,ip,el) result(F)
integer, intent(in) :: co, ip, el integer, intent(in) :: co, ip, el
real(pReal), dimension(3,3) :: F real(pReal), dimension(3,3) :: F
end function constitutive_mech_getF end function phase_mechanical_getF
module function mech_F_e(ph,me) result(F_e) module function mechanical_F_e(ph,me) result(F_e)
integer, intent(in) :: ph,me integer, intent(in) :: ph,me
real(pReal), dimension(3,3) :: F_e real(pReal), dimension(3,3) :: F_e
end function mech_F_e end function mechanical_F_e
module function constitutive_mech_getP(co,ip,el) result(P) module function phase_mechanical_getP(co,ip,el) result(P)
integer, intent(in) :: co, ip, el integer, intent(in) :: co, ip, el
real(pReal), dimension(3,3) :: P real(pReal), dimension(3,3) :: P
end function constitutive_mech_getP end function phase_mechanical_getP
module function constitutive_damage_get_phi(co,ip,el) result(phi) module function phase_damage_get_phi(co,ip,el) result(phi)
integer, intent(in) :: co, ip, el integer, intent(in) :: co, ip, el
real(pReal) :: phi real(pReal) :: phi
end function constitutive_damage_get_phi end function phase_damage_get_phi
module function thermal_T(ph,me) result(T) module function thermal_T(ph,me) result(T)
integer, intent(in) :: ph,me integer, intent(in) :: ph,me
@ -181,21 +177,26 @@ module phase
real(pReal) :: dot_T real(pReal) :: dot_T
end function thermal_dot_T end function thermal_dot_T
module function damage_phi(ph,me) result(phi)
integer, intent(in) :: ph,me
real(pReal) :: phi
end function damage_phi
module subroutine constitutive_mech_setF(F,co,ip,el)
module subroutine phase_mechanical_setF(F,co,ip,el)
real(pReal), dimension(3,3), intent(in) :: F real(pReal), dimension(3,3), intent(in) :: F
integer, intent(in) :: co, ip, el integer, intent(in) :: co, ip, el
end subroutine constitutive_mech_setF end subroutine phase_mechanical_setF
module subroutine constitutive_thermal_setField(T,dot_T, co,ce) module subroutine phase_thermal_setField(T,dot_T, co,ce)
real(pReal), intent(in) :: T, dot_T real(pReal), intent(in) :: T, dot_T
integer, intent(in) :: ce, co integer, intent(in) :: ce, co
end subroutine constitutive_thermal_setField end subroutine phase_thermal_setField
module subroutine constitutive_damage_set_phi(phi,co,ce) module subroutine phase_damage_set_phi(phi,co,ce)
real(pReal), intent(in) :: phi real(pReal), intent(in) :: phi
integer, intent(in) :: co, ce integer, intent(in) :: co, ce
end subroutine constitutive_damage_set_phi end subroutine phase_damage_set_phi
! == cleaned:end =================================================================================== ! == cleaned:end ===================================================================================
@ -222,13 +223,13 @@ module phase
logical :: converged_ logical :: converged_
end function crystallite_stress end function crystallite_stress
module function constitutive_homogenizedC(ph,me) result(C) module function phase_homogenizedC(ph,me) result(C)
integer, intent(in) :: ph, me integer, intent(in) :: ph, me
real(pReal), dimension(6,6) :: C real(pReal), dimension(6,6) :: C
end function constitutive_homogenizedC end function phase_homogenizedC
module subroutine constitutive_damage_getRateAndItsTangents(phiDot, dPhiDot_dPhi, phi, ip, el) module subroutine phase_damage_getRateAndItsTangents(phiDot, dPhiDot_dPhi, phi, ip, el)
integer, intent(in) :: & integer, intent(in) :: &
ip, & !< integration point number ip, & !< integration point number
el !< element number el !< element number
@ -237,17 +238,17 @@ module phase
real(pReal), intent(inout) :: & real(pReal), intent(inout) :: &
phiDot, & phiDot, &
dPhiDot_dPhi dPhiDot_dPhi
end subroutine constitutive_damage_getRateAndItsTangents end subroutine phase_damage_getRateAndItsTangents
module subroutine constitutive_thermal_getRate(TDot, ph,me) module subroutine phase_thermal_getRate(TDot, ph,me)
integer, intent(in) :: ph, me integer, intent(in) :: ph, me
real(pReal), intent(out) :: & real(pReal), intent(out) :: &
TDot TDot
end subroutine constitutive_thermal_getRate end subroutine phase_thermal_getRate
module subroutine plastic_nonlocal_updateCompatibility(orientation,instance,i,e) module subroutine plastic_nonlocal_updateCompatibility(orientation,ph,i,e)
integer, intent(in) :: & integer, intent(in) :: &
instance, & ph, &
i, & i, &
e e
type(rotation), dimension(1,discretization_nIPs,discretization_Nelems), intent(in) :: & type(rotation), dimension(1,discretization_nIPs,discretization_Nelems), intent(in) :: &
@ -261,6 +262,27 @@ module phase
el !< element el !< element
end subroutine plastic_dependentState end subroutine plastic_dependentState
module subroutine kinematics_cleavage_opening_LiAndItsTangent(Ld, dLd_dTstar, S, ph,me)
integer, intent(in) :: ph, me
real(pReal), intent(in), dimension(3,3) :: &
S
real(pReal), intent(out), dimension(3,3) :: &
Ld !< damage velocity gradient
real(pReal), intent(out), dimension(3,3,3,3) :: &
dLd_dTstar !< derivative of Ld with respect to Tstar (4th-order tensor)
end subroutine kinematics_cleavage_opening_LiAndItsTangent
module subroutine kinematics_slipplane_opening_LiAndItsTangent(Ld, dLd_dTstar, S, ph,me)
integer, intent(in) :: ph, me
real(pReal), intent(in), dimension(3,3) :: &
S
real(pReal), intent(out), dimension(3,3) :: &
Ld !< damage velocity gradient
real(pReal), intent(out), dimension(3,3,3,3) :: &
dLd_dTstar !< derivative of Ld with respect to Tstar (4th-order tensor)
end subroutine kinematics_slipplane_opening_LiAndItsTangent
end interface end interface
@ -281,39 +303,39 @@ module phase
#endif #endif
public :: & public :: &
constitutive_init, & phase_init, &
constitutive_homogenizedC, & phase_homogenizedC, &
constitutive_damage_getRateAndItsTangents, & phase_damage_getRateAndItsTangents, &
constitutive_thermal_getRate, & phase_thermal_getRate, &
constitutive_results, & phase_results, &
constitutive_allocateState, & phase_allocateState, &
constitutive_forward, & phase_forward, &
constitutive_restore, & phase_restore, &
plastic_nonlocal_updateCompatibility, & plastic_nonlocal_updateCompatibility, &
converged, & converged, &
crystallite_init, & crystallite_init, &
crystallite_stress, & crystallite_stress, &
thermal_stress, & thermal_stress, &
constitutive_mech_dPdF, & phase_mechanical_dPdF, &
crystallite_orientations, & crystallite_orientations, &
crystallite_push33ToRef, & crystallite_push33ToRef, &
constitutive_restartWrite, & phase_restartWrite, &
constitutive_restartRead, & phase_restartRead, &
integrateDamageState, & integrateDamageState, &
constitutive_thermal_setField, & phase_thermal_setField, &
constitutive_damage_set_phi, & phase_damage_set_phi, &
constitutive_damage_get_phi, & phase_damage_get_phi, &
constitutive_mech_getP, & phase_mechanical_getP, &
constitutive_mech_setF, & phase_mechanical_setF, &
constitutive_mech_getF, & phase_mechanical_getF, &
constitutive_windForward phase_windForward
contains contains
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief Initialze constitutive models for individual physics !> @brief Initialze constitutive models for individual physics
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
subroutine constitutive_init subroutine phase_init
integer :: & integer :: &
ph, & !< counter in phase loop ph, & !< counter in phase loop
@ -336,33 +358,31 @@ subroutine constitutive_init
phases => config_material%get('phase') phases => config_material%get('phase')
call mech_init(phases) call mechanical_init(phases)
call damage_init call damage_init
call thermal_init(phases) call thermal_init(phases)
constitutive_source_maxSizeDotState = 0 phase_source_maxSizeDotState = 0
PhaseLoop2:do ph = 1,phases%length PhaseLoop2:do ph = 1,phases%length
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
! partition and initialize state ! partition and initialize state
plasticState(ph)%state = plasticState(ph)%state0 plasticState(ph)%state = plasticState(ph)%state0
forall(so = 1:phase_Nsources(ph)) if(damageState(ph)%sizeState > 0) &
damageState(ph)%p(so)%state = damageState(ph)%p(so)%state0 damageState(ph)%state = damageState(ph)%state0
end forall
constitutive_source_maxSizeDotState = max(constitutive_source_maxSizeDotState, &
maxval(damageState(ph)%p%sizeDotState))
enddo PhaseLoop2 enddo PhaseLoop2
constitutive_plasticity_maxSizeDotState = maxval(plasticState%sizeDotState)
end subroutine constitutive_init phase_source_maxSizeDotState = maxval(damageState%sizeDotState)
phase_plasticity_maxSizeDotState = maxval(plasticState%sizeDotState)
end subroutine phase_init
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief Allocate the components of the state structure for a given phase !> @brief Allocate the components of the state structure for a given phase
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
subroutine constitutive_allocateState(state, & subroutine phase_allocateState(state, &
Nconstituents,sizeState,sizeDotState,sizeDeltaState) Nconstituents,sizeState,sizeDotState,sizeDeltaState)
class(tState), intent(out) :: & class(tState), intent(out) :: &
state state
@ -387,58 +407,56 @@ subroutine constitutive_allocateState(state, &
allocate(state%deltaState (sizeDeltaState,Nconstituents), source=0.0_pReal) allocate(state%deltaState (sizeDeltaState,Nconstituents), source=0.0_pReal)
end subroutine constitutive_allocateState end subroutine phase_allocateState
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief Restore data after homog cutback. !> @brief Restore data after homog cutback.
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
subroutine constitutive_restore(ce,includeL) subroutine phase_restore(ce,includeL)
logical, intent(in) :: includeL logical, intent(in) :: includeL
integer, intent(in) :: ce integer, intent(in) :: ce
integer :: & integer :: &
co, & !< constituent number co
so
do co = 1,homogenization_Nconstituents(material_homogenizationAt2(ce)) do co = 1,homogenization_Nconstituents(material_homogenizationAt2(ce))
do so = 1, phase_Nsources(material_phaseAt2(co,ce)) if (damageState(material_phaseAt2(co,ce))%sizeState > 0) &
damageState(material_phaseAt2(co,ce))%p(so)%state( :,material_phasememberAt2(co,ce)) = & damageState(material_phaseAt2(co,ce))%state( :,material_phasememberAt2(co,ce)) = &
damageState(material_phaseAt2(co,ce))%p(so)%state0(:,material_phasememberAt2(co,ce)) damageState(material_phaseAt2(co,ce))%state0(:,material_phasememberAt2(co,ce))
enddo
enddo enddo
call mech_restore(ce,includeL) call mechanical_restore(ce,includeL)
end subroutine constitutive_restore end subroutine phase_restore
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief Forward data after successful increment. !> @brief Forward data after successful increment.
! ToDo: Any guessing for the current states possible? ! ToDo: Any guessing for the current states possible?
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
subroutine constitutive_forward() subroutine phase_forward()
integer :: ph, so integer :: ph
call mech_forward() call mechanical_forward()
call thermal_forward() call thermal_forward()
do ph = 1, size(damageState) do ph = 1, size(damageState)
do so = 1,phase_Nsources(ph) if (damageState(ph)%sizeState > 0) &
damageState(ph)%p(so)%state0 = damageState(ph)%p(so)%state damageState(ph)%state0 = damageState(ph)%state
enddo; enddo enddo
end subroutine constitutive_forward end subroutine phase_forward
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief writes constitutive results to HDF5 output file !> @brief writes constitutive results to HDF5 output file
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
subroutine constitutive_results() subroutine phase_results()
integer :: ph integer :: ph
character(len=:), allocatable :: group character(len=:), allocatable :: group
@ -451,12 +469,12 @@ subroutine constitutive_results()
group = '/current/phase/'//trim(material_name_phase(ph))//'/' group = '/current/phase/'//trim(material_name_phase(ph))//'/'
call results_closeGroup(results_addGroup(group)) call results_closeGroup(results_addGroup(group))
call mech_results(group,ph) call mechanical_results(group,ph)
call damage_results(group,ph) call damage_results(group,ph)
enddo enddo
end subroutine constitutive_results end subroutine phase_results
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
@ -526,9 +544,8 @@ subroutine crystallite_init()
phases => config_material%get('phase') phases => config_material%get('phase')
do ph = 1, phases%length do ph = 1, phases%length
do so = 1, phase_Nsources(ph) if (damageState(ph)%sizeState > 0) &
allocate(damageState(ph)%p(so)%subState0,source=damageState(ph)%p(so)%state0) ! ToDo: hack allocate(damageState(ph)%subState0,source=damageState(ph)%state0) ! ToDo: hack
enddo
enddo enddo
print'(a42,1x,i10)', ' # of elements: ', eMax print'(a42,1x,i10)', ' # of elements: ', eMax
@ -557,7 +574,7 @@ end subroutine crystallite_init
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief Wind homog inc forward. !> @brief Wind homog inc forward.
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
subroutine constitutive_windForward(ip,el) subroutine phase_windForward(ip,el)
integer, intent(in) :: & integer, intent(in) :: &
ip, & !< integration point number ip, & !< integration point number
@ -572,15 +589,14 @@ subroutine constitutive_windForward(ip,el)
ph = material_phaseAt(co,el) ph = material_phaseAt(co,el)
me = material_phaseMemberAt(co,ip,el) me = material_phaseMemberAt(co,ip,el)
call mech_windForward(ph,me) call mechanical_windForward(ph,me)
if(damageState(ph)%sizeState > 0) damageState(ph)%state0(:,me) = damageState(ph)%state(:,me)
do so = 1, phase_Nsources(material_phaseAt(co,el))
damageState(ph)%p(so)%state0(:,me) = damageState(ph)%p(so)%state(:,me)
enddo
enddo enddo
end subroutine constitutive_windForward end subroutine phase_windForward
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
@ -595,11 +611,11 @@ subroutine crystallite_orientations(co,ip,el)
call crystallite_orientation(co,ip,el)%fromMatrix(transpose(math_rotationalPart(& call crystallite_orientation(co,ip,el)%fromMatrix(transpose(math_rotationalPart(&
mech_F_e(material_phaseAt(co,el),material_phaseMemberAt(co,ip,el))))) mechanical_F_e(material_phaseAt(co,el),material_phaseMemberAt(co,ip,el)))))
if (plasticState(material_phaseAt(1,el))%nonlocal) & if (plasticState(material_phaseAt(1,el))%nonlocal) &
call plastic_nonlocal_updateCompatibility(crystallite_orientation, & call plastic_nonlocal_updateCompatibility(crystallite_orientation, &
phase_plasticityInstance(material_phaseAt(1,el)),ip,el) material_phaseAt(1,el),ip,el)
end subroutine crystallite_orientations end subroutine crystallite_orientations
@ -620,7 +636,7 @@ function crystallite_push33ToRef(co,ip,el, tensor33)
real(pReal), dimension(3,3) :: T real(pReal), dimension(3,3) :: T
T = matmul(material_orientation0(co,ip,el)%asMatrix(),transpose(math_inv33(constitutive_mech_getF(co,ip,el)))) ! ToDo: initial orientation correct? T = matmul(material_orientation0(co,ip,el)%asMatrix(),transpose(math_inv33(phase_mechanical_getF(co,ip,el)))) ! ToDo: initial orientation correct?
crystallite_push33ToRef = matmul(transpose(T),matmul(tensor33,T)) crystallite_push33ToRef = matmul(transpose(T),matmul(tensor33,T))
@ -648,7 +664,7 @@ end function converged
!> @brief Write current restart information (Field and constitutive data) to file. !> @brief Write current restart information (Field and constitutive data) to file.
! ToDo: Merge data into one file for MPI ! ToDo: Merge data into one file for MPI
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
subroutine constitutive_restartWrite(fileHandle) subroutine phase_restartWrite(fileHandle)
integer(HID_T), intent(in) :: fileHandle integer(HID_T), intent(in) :: fileHandle
@ -662,7 +678,7 @@ subroutine constitutive_restartWrite(fileHandle)
groupHandle(2) = HDF5_addGroup(groupHandle(1),material_name_phase(ph)) groupHandle(2) = HDF5_addGroup(groupHandle(1),material_name_phase(ph))
call mech_restartWrite(groupHandle(2),ph) call mechanical_restartWrite(groupHandle(2),ph)
call HDF5_closeGroup(groupHandle(2)) call HDF5_closeGroup(groupHandle(2))
@ -670,14 +686,14 @@ subroutine constitutive_restartWrite(fileHandle)
call HDF5_closeGroup(groupHandle(1)) call HDF5_closeGroup(groupHandle(1))
end subroutine constitutive_restartWrite end subroutine phase_restartWrite
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief Read data for restart !> @brief Read data for restart
! ToDo: Merge data into one file for MPI ! ToDo: Merge data into one file for MPI
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
subroutine constitutive_restartRead(fileHandle) subroutine phase_restartRead(fileHandle)
integer(HID_T), intent(in) :: fileHandle integer(HID_T), intent(in) :: fileHandle
@ -691,7 +707,7 @@ subroutine constitutive_restartRead(fileHandle)
groupHandle(2) = HDF5_openGroup(groupHandle(1),material_name_phase(ph)) groupHandle(2) = HDF5_openGroup(groupHandle(1),material_name_phase(ph))
call mech_restartRead(groupHandle(2),ph) call mechanical_restartRead(groupHandle(2),ph)
call HDF5_closeGroup(groupHandle(2)) call HDF5_closeGroup(groupHandle(2))
@ -699,7 +715,7 @@ subroutine constitutive_restartRead(fileHandle)
call HDF5_closeGroup(groupHandle(1)) call HDF5_closeGroup(groupHandle(1))
end subroutine constitutive_restartRead end subroutine phase_restartRead
end module phase end module phase

View File

@ -15,110 +15,92 @@ submodule(phase) damagee
real(pReal), dimension(:), allocatable :: phi, d_phi_d_dot_phi real(pReal), dimension(:), allocatable :: phi, d_phi_d_dot_phi
end type tDataContainer end type tDataContainer
integer(kind(DAMAGE_UNDEFINED_ID)), dimension(:,:), allocatable :: & integer(kind(DAMAGE_UNDEFINED_ID)), dimension(:), allocatable :: &
phase_source !< active sources mechanisms of each phase phase_source !< active sources mechanisms of each phase
integer, dimension(:), allocatable :: &
phase_Nsources
type(tDataContainer), dimension(:), allocatable :: current type(tDataContainer), dimension(:), allocatable :: current
interface interface
module function anisobrittle_init(source_length) result(mySources) module function anisobrittle_init() result(mySources)
integer, intent(in) :: source_length logical, dimension(:), allocatable :: mySources
logical, dimension(:,:), allocatable :: mySources
end function anisobrittle_init end function anisobrittle_init
module function anisoductile_init(source_length) result(mySources) module function anisoductile_init() result(mySources)
integer, intent(in) :: source_length logical, dimension(:), allocatable :: mySources
logical, dimension(:,:), allocatable :: mySources
end function anisoductile_init end function anisoductile_init
module function isobrittle_init(source_length) result(mySources) module function isobrittle_init() result(mySources)
integer, intent(in) :: source_length logical, dimension(:), allocatable :: mySources
logical, dimension(:,:), allocatable :: mySources
end function isobrittle_init end function isobrittle_init
module function isoductile_init(source_length) result(mySources) module function isoductile_init() result(mySources)
integer, intent(in) :: source_length logical, dimension(:), allocatable :: mySources
logical, dimension(:,:), allocatable :: mySources
end function isoductile_init end function isoductile_init
module subroutine source_damage_isoBrittle_deltaState(C, Fe, ph, me) module subroutine isobrittle_deltaState(C, Fe, ph, me)
integer, intent(in) :: ph,me integer, intent(in) :: ph,me
real(pReal), intent(in), dimension(3,3) :: & real(pReal), intent(in), dimension(3,3) :: &
Fe Fe
real(pReal), intent(in), dimension(6,6) :: & real(pReal), intent(in), dimension(6,6) :: &
C C
end subroutine source_damage_isoBrittle_deltaState end subroutine isobrittle_deltaState
module subroutine anisobrittle_dotState(S, co, ip, el) module subroutine anisobrittle_dotState(S, ph, me)
integer, intent(in) :: & integer, intent(in) :: ph,me
co, & !< component-ID of integration point
ip, & !< integration point
el !< element
real(pReal), intent(in), dimension(3,3) :: & real(pReal), intent(in), dimension(3,3) :: &
S S
end subroutine anisobrittle_dotState end subroutine anisobrittle_dotState
module subroutine anisoductile_dotState(co, ip, el) module subroutine anisoductile_dotState(ph,me)
integer, intent(in) :: & integer, intent(in) :: ph,me
co, & !< component-ID of integration point
ip, & !< integration point
el !< element
end subroutine anisoductile_dotState end subroutine anisoductile_dotState
module subroutine isoductile_dotState(co, ip, el) module subroutine isoductile_dotState(ph,me)
integer, intent(in) :: & integer, intent(in) :: ph,me
co, & !< component-ID of integration point
ip, & !< integration point
el !< element
end subroutine isoductile_dotState end subroutine isoductile_dotState
module subroutine source_damage_anisobrittle_getRateAndItsTangent(localphiDot, dLocalphiDot_dPhi, phi, phase, constituent) module subroutine anisobrittle_getRateAndItsTangent(localphiDot, dLocalphiDot_dPhi, phi, ph, me)
integer, intent(in) :: & integer, intent(in) :: ph,me
phase, & !< phase ID of element
constituent !< position of element within its phase instance
real(pReal), intent(in) :: & real(pReal), intent(in) :: &
phi !< damage parameter phi !< damage parameter
real(pReal), intent(out) :: & real(pReal), intent(out) :: &
localphiDot, & localphiDot, &
dLocalphiDot_dPhi dLocalphiDot_dPhi
end subroutine source_damage_anisoBrittle_getRateAndItsTangent end subroutine anisobrittle_getRateAndItsTangent
module subroutine source_damage_anisoDuctile_getRateAndItsTangent(localphiDot, dLocalphiDot_dPhi, phi, phase, constituent) module subroutine anisoductile_getRateAndItsTangent(localphiDot, dLocalphiDot_dPhi, phi, ph,me)
integer, intent(in) :: & integer, intent(in) :: ph,me
phase, & !< phase ID of element
constituent !< position of element within its phase instance
real(pReal), intent(in) :: & real(pReal), intent(in) :: &
phi !< damage parameter phi !< damage parameter
real(pReal), intent(out) :: & real(pReal), intent(out) :: &
localphiDot, & localphiDot, &
dLocalphiDot_dPhi dLocalphiDot_dPhi
end subroutine source_damage_anisoDuctile_getRateAndItsTangent end subroutine anisoductile_getRateAndItsTangent
module subroutine source_damage_isoBrittle_getRateAndItsTangent(localphiDot, dLocalphiDot_dPhi, phi, phase, constituent) module subroutine isobrittle_getRateAndItsTangent(localphiDot, dLocalphiDot_dPhi, phi, ph,me)
integer, intent(in) :: & integer, intent(in) :: ph,me
phase, & !< phase ID of element
constituent !< position of element within its phase instance
real(pReal), intent(in) :: & real(pReal), intent(in) :: &
phi !< damage parameter phi !< damage parameter
real(pReal), intent(out) :: & real(pReal), intent(out) :: &
localphiDot, & localphiDot, &
dLocalphiDot_dPhi dLocalphiDot_dPhi
end subroutine source_damage_isoBrittle_getRateAndItsTangent end subroutine isobrittle_getRateAndItsTangent
module subroutine source_damage_isoDuctile_getRateAndItsTangent(localphiDot, dLocalphiDot_dPhi, phi, phase, constituent) module subroutine isoductile_getRateAndItsTangent(localphiDot, dLocalphiDot_dPhi, phi, ph,me)
integer, intent(in) :: & integer, intent(in) :: ph,me
phase, & !< phase ID of element
constituent !< position of element within its phase instance
real(pReal), intent(in) :: & real(pReal), intent(in) :: &
phi !< damage parameter phi !< damage parameter
real(pReal), intent(out) :: & real(pReal), intent(out) :: &
localphiDot, & localphiDot, &
dLocalphiDot_dPhi dLocalphiDot_dPhi
end subroutine source_damage_isoDuctile_getRateAndItsTangent end subroutine isoductile_getRateAndItsTangent
module subroutine anisobrittle_results(phase,group) module subroutine anisobrittle_results(phase,group)
integer, intent(in) :: phase integer, intent(in) :: phase
@ -175,19 +157,20 @@ module subroutine damage_init
allocate(current(ph)%d_phi_d_dot_phi(Nconstituents),source=0.0_pReal) allocate(current(ph)%d_phi_d_dot_phi(Nconstituents),source=0.0_pReal)
phase => phases%get(ph) phase => phases%get(ph)
sources => phase%get('source',defaultVal=emptyList) sources => phase%get('damage',defaultVal=emptyList)
if (sources%length > 1) error stop
phase_Nsources(ph) = sources%length phase_Nsources(ph) = sources%length
allocate(damageState(ph)%p(phase_Nsources(ph)))
enddo enddo
allocate(phase_source(maxval(phase_Nsources),phases%length), source = DAMAGE_UNDEFINED_ID) allocate(phase_source(phases%length), source = DAMAGE_UNDEFINED_ID)
! initialize source mechanisms ! initialize source mechanisms
if(maxval(phase_Nsources) /= 0) then if(maxval(phase_Nsources) /= 0) then
where(isobrittle_init (maxval(phase_Nsources))) phase_source = DAMAGE_ISOBRITTLE_ID where(isobrittle_init() ) phase_source = DAMAGE_ISOBRITTLE_ID
where(isoductile_init (maxval(phase_Nsources))) phase_source = DAMAGE_ISODUCTILE_ID where(isoductile_init() ) phase_source = DAMAGE_ISODUCTILE_ID
where(anisobrittle_init (maxval(phase_Nsources))) phase_source = DAMAGE_ANISOBRITTLE_ID where(anisobrittle_init()) phase_source = DAMAGE_ANISOBRITTLE_ID
where(anisoductile_init (maxval(phase_Nsources))) phase_source = DAMAGE_ANISODUCTILE_ID where(anisoductile_init()) phase_source = DAMAGE_ANISODUCTILE_ID
endif endif
end subroutine damage_init end subroutine damage_init
@ -196,7 +179,7 @@ end subroutine damage_init
!---------------------------------------------------------------------------------------------- !----------------------------------------------------------------------------------------------
!< @brief returns local part of nonlocal damage driving force !< @brief returns local part of nonlocal damage driving force
!---------------------------------------------------------------------------------------------- !----------------------------------------------------------------------------------------------
module subroutine constitutive_damage_getRateAndItsTangents(phiDot, dPhiDot_dPhi, phi, ip, el) module subroutine phase_damage_getRateAndItsTangents(phiDot, dPhiDot_dPhi, phi, ip, el)
integer, intent(in) :: & integer, intent(in) :: &
ip, & !< integration point number ip, & !< integration point number
@ -213,7 +196,6 @@ module subroutine constitutive_damage_getRateAndItsTangents(phiDot, dPhiDot_dPhi
integer :: & integer :: &
ph, & ph, &
co, & co, &
so, &
me me
phiDot = 0.0_pReal phiDot = 0.0_pReal
@ -222,19 +204,19 @@ module subroutine constitutive_damage_getRateAndItsTangents(phiDot, dPhiDot_dPhi
do co = 1, homogenization_Nconstituents(material_homogenizationAt(el)) do co = 1, homogenization_Nconstituents(material_homogenizationAt(el))
ph = material_phaseAt(co,el) ph = material_phaseAt(co,el)
me = material_phasememberAt(co,ip,el) me = material_phasememberAt(co,ip,el)
do so = 1, phase_Nsources(ph)
select case(phase_source(so,ph)) select case(phase_source(ph))
case (DAMAGE_ISOBRITTLE_ID) case (DAMAGE_ISOBRITTLE_ID)
call source_damage_isobrittle_getRateAndItsTangent (localphiDot, dLocalphiDot_dPhi, phi, ph, me) call isobrittle_getRateAndItsTangent (localphiDot, dLocalphiDot_dPhi, phi, ph, me)
case (DAMAGE_ISODUCTILE_ID) case (DAMAGE_ISODUCTILE_ID)
call source_damage_isoductile_getRateAndItsTangent (localphiDot, dLocalphiDot_dPhi, phi, ph, me) call isoductile_getRateAndItsTangent (localphiDot, dLocalphiDot_dPhi, phi, ph, me)
case (DAMAGE_ANISOBRITTLE_ID) case (DAMAGE_ANISOBRITTLE_ID)
call source_damage_anisobrittle_getRateAndItsTangent(localphiDot, dLocalphiDot_dPhi, phi, ph, me) call anisobrittle_getRateAndItsTangent(localphiDot, dLocalphiDot_dPhi, phi, ph, me)
case (DAMAGE_ANISODUCTILE_ID) case (DAMAGE_ANISODUCTILE_ID)
call source_damage_anisoductile_getRateAndItsTangent(localphiDot, dLocalphiDot_dPhi, phi, ph, me) call anisoductile_getRateAndItsTangent(localphiDot, dLocalphiDot_dPhi, phi, ph, me)
case default case default
localphiDot = 0.0_pReal localphiDot = 0.0_pReal
@ -243,10 +225,9 @@ module subroutine constitutive_damage_getRateAndItsTangents(phiDot, dPhiDot_dPhi
end select end select
phiDot = phiDot + localphiDot phiDot = phiDot + localphiDot
dPhiDot_dPhi = dPhiDot_dPhi + dLocalphiDot_dPhi dPhiDot_dPhi = dPhiDot_dPhi + dLocalphiDot_dPhi
enddo
enddo enddo
end subroutine constitutive_damage_getRateAndItsTangents end subroutine phase_damage_getRateAndItsTangents
@ -267,60 +248,55 @@ module function integrateDamageState(dt,co,ip,el) result(broken)
NiterationState, & !< number of iterations in state loop NiterationState, & !< number of iterations in state loop
ph, & ph, &
me, & me, &
so
integer, dimension(maxval(phase_Nsources)) :: &
size_so size_so
real(pReal) :: & real(pReal) :: &
zeta zeta
real(pReal), dimension(constitutive_source_maxSizeDotState) :: & real(pReal), dimension(phase_source_maxSizeDotState) :: &
r ! state residuum r ! state residuum
real(pReal), dimension(constitutive_source_maxSizeDotState,2,maxval(phase_Nsources)) :: source_dotState real(pReal), dimension(phase_source_maxSizeDotState,2) :: source_dotState
logical :: & logical :: &
converged_ converged_
ph = material_phaseAt(co,el) ph = material_phaseAt(co,el)
me = material_phaseMemberAt(co,ip,el) me = material_phaseMemberAt(co,ip,el)
if (damageState(ph)%sizeState == 0) then
broken = .false.
return
endif
converged_ = .true. converged_ = .true.
broken = constitutive_damage_collectDotState(co,ip,el,ph,me) broken = phase_damage_collectDotState(ph,me)
if(broken) return if(broken) return
do so = 1, phase_Nsources(ph) size_so = damageState(ph)%sizeDotState
size_so(so) = damageState(ph)%p(so)%sizeDotState damageState(ph)%state(1:size_so,me) = damageState(ph)%subState0(1:size_so,me) &
damageState(ph)%p(so)%state(1:size_so(so),me) = damageState(ph)%p(so)%subState0(1:size_so(so),me) & + damageState(ph)%dotState (1:size_so,me) * dt
+ damageState(ph)%p(so)%dotState (1:size_so(so),me) * dt source_dotState(1:size_so,2) = 0.0_pReal
source_dotState(1:size_so(so),2,so) = 0.0_pReal
enddo
iteration: do NiterationState = 1, num%nState iteration: do NiterationState = 1, num%nState
do so = 1, phase_Nsources(ph) if(nIterationState > 1) source_dotState(1:size_so,2) = source_dotState(1:size_so,1)
if(nIterationState > 1) source_dotState(1:size_so(so),2,so) = source_dotState(1:size_so(so),1,so) source_dotState(1:size_so,1) = damageState(ph)%dotState(:,me)
source_dotState(1:size_so(so),1,so) = damageState(ph)%p(so)%dotState(:,me)
enddo
broken = constitutive_damage_collectDotState(co,ip,el,ph,me) broken = phase_damage_collectDotState(ph,me)
if(broken) exit iteration if(broken) exit iteration
do so = 1, phase_Nsources(ph)
zeta = damper(damageState(ph)%p(so)%dotState(:,me), & zeta = damper(damageState(ph)%dotState(:,me),source_dotState(1:size_so,1),source_dotState(1:size_so,2))
source_dotState(1:size_so(so),1,so),& damageState(ph)%dotState(:,me) = damageState(ph)%dotState(:,me) * zeta &
source_dotState(1:size_so(so),2,so)) + source_dotState(1:size_so,1)* (1.0_pReal - zeta)
damageState(ph)%p(so)%dotState(:,me) = damageState(ph)%p(so)%dotState(:,me) * zeta & r(1:size_so) = damageState(ph)%state (1:size_so,me) &
+ source_dotState(1:size_so(so),1,so)* (1.0_pReal - zeta) - damageState(ph)%subState0(1:size_so,me) &
r(1:size_so(so)) = damageState(ph)%p(so)%state (1:size_so(so),me) & - damageState(ph)%dotState (1:size_so,me) * dt
- damageState(ph)%p(so)%subState0(1:size_so(so),me) & damageState(ph)%state(1:size_so,me) = damageState(ph)%state(1:size_so,me) - r(1:size_so)
- damageState(ph)%p(so)%dotState (1:size_so(so),me) * dt converged_ = converged_ .and. converged(r(1:size_so), &
damageState(ph)%p(so)%state(1:size_so(so),me) = damageState(ph)%p(so)%state(1:size_so(so),me) & damageState(ph)%state(1:size_so,me), &
- r(1:size_so(so)) damageState(ph)%atol(1:size_so))
converged_ = converged_ .and. converged(r(1:size_so(so)), &
damageState(ph)%p(so)%state(1:size_so(so),me), &
damageState(ph)%p(so)%atol(1:size_so(so)))
enddo
if(converged_) then if(converged_) then
broken = constitutive_damage_deltaState(mech_F_e(ph,me),ph,me) broken = phase_damage_deltaState(mechanical_F_e(ph,me),ph,me)
exit iteration exit iteration
endif endif
@ -366,10 +342,10 @@ module subroutine damage_results(group,ph)
sourceLoop: do so = 1, phase_Nsources(ph) sourceLoop: do so = 1, phase_Nsources(ph)
if (phase_source(so,ph) /= DAMAGE_UNDEFINED_ID) & if (phase_source(ph) /= DAMAGE_UNDEFINED_ID) &
call results_closeGroup(results_addGroup(group//'sources/')) ! should be 'damage' call results_closeGroup(results_addGroup(group//'sources/')) ! should be 'damage'
sourceType: select case (phase_source(so,ph)) sourceType: select case (phase_source(ph))
case (DAMAGE_ISOBRITTLE_ID) sourceType case (DAMAGE_ISOBRITTLE_ID) sourceType
call isobrittle_results(ph,group//'sources/') call isobrittle_results(ph,group//'sources/')
@ -393,41 +369,36 @@ end subroutine damage_results
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief contains the constitutive equation for calculating the rate of change of microstructure !> @brief contains the constitutive equation for calculating the rate of change of microstructure
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
function constitutive_damage_collectDotState(co,ip,el,ph,me) result(broken) function phase_damage_collectDotState(ph,me) result(broken)
integer, intent(in) :: & integer, intent(in) :: &
co, & !< component-ID me integration point
ip, & !< integration point
el, & !< element
ph, & ph, &
me me !< counter in source loop
integer :: &
so !< counter in source loop
logical :: broken logical :: broken
broken = .false. broken = .false.
SourceLoop: do so = 1, phase_Nsources(ph) if (damageState(ph)%sizeState > 0) then
sourceType: select case (phase_source(so,ph)) sourceType: select case (phase_source(ph))
case (DAMAGE_ISODUCTILE_ID) sourceType case (DAMAGE_ISODUCTILE_ID) sourceType
call isoductile_dotState(co, ip, el) call isoductile_dotState(ph,me)
case (DAMAGE_ANISODUCTILE_ID) sourceType case (DAMAGE_ANISODUCTILE_ID) sourceType
call anisoductile_dotState(co, ip, el) call anisoductile_dotState(ph,me)
case (DAMAGE_ANISOBRITTLE_ID) sourceType case (DAMAGE_ANISOBRITTLE_ID) sourceType
call anisobrittle_dotState(mech_S(ph,me),co, ip, el) ! correct stress? call anisobrittle_dotState(mechanical_S(ph,me), ph,me) ! correct stress?
end select sourceType end select sourceType
broken = broken .or. any(IEEE_is_NaN(damageState(ph)%p(so)%dotState(:,me))) broken = broken .or. any(IEEE_is_NaN(damageState(ph)%dotState(:,me)))
enddo SourceLoop endif
end function constitutive_damage_collectDotState end function phase_damage_collectDotState
@ -435,7 +406,7 @@ end function constitutive_damage_collectDotState
!> @brief for constitutive models having an instantaneous change of state !> @brief for constitutive models having an instantaneous change of state
!> will return false if delta state is not needed/supported by the constitutive model !> will return false if delta state is not needed/supported by the constitutive model
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
function constitutive_damage_deltaState(Fe, ph, me) result(broken) function phase_damage_deltaState(Fe, ph, me) result(broken)
integer, intent(in) :: & integer, intent(in) :: &
ph, & ph, &
@ -443,7 +414,6 @@ function constitutive_damage_deltaState(Fe, ph, me) result(broken)
real(pReal), intent(in), dimension(3,3) :: & real(pReal), intent(in), dimension(3,3) :: &
Fe !< elastic deformation gradient Fe !< elastic deformation gradient
integer :: & integer :: &
so, &
myOffset, & myOffset, &
mySize mySize
logical :: & logical :: &
@ -452,52 +422,48 @@ function constitutive_damage_deltaState(Fe, ph, me) result(broken)
broken = .false. broken = .false.
sourceLoop: do so = 1, phase_Nsources(ph) if (damageState(ph)%sizeState == 0) return
sourceType: select case (phase_source(so,ph)) sourceType: select case (phase_source(ph))
case (DAMAGE_ISOBRITTLE_ID) sourceType case (DAMAGE_ISOBRITTLE_ID) sourceType
call source_damage_isoBrittle_deltaState(constitutive_homogenizedC(ph,me), Fe, ph,me) call isobrittle_deltaState(phase_homogenizedC(ph,me), Fe, ph,me)
broken = any(IEEE_is_NaN(damageState(ph)%p(so)%deltaState(:,me))) broken = any(IEEE_is_NaN(damageState(ph)%deltaState(:,me)))
if(.not. broken) then if(.not. broken) then
myOffset = damageState(ph)%p(so)%offsetDeltaState myOffset = damageState(ph)%offsetDeltaState
mySize = damageState(ph)%p(so)%sizeDeltaState mySize = damageState(ph)%sizeDeltaState
damageState(ph)%p(so)%state(myOffset + 1: myOffset + mySize,me) = & damageState(ph)%state(myOffset + 1: myOffset + mySize,me) = &
damageState(ph)%p(so)%state(myOffset + 1: myOffset + mySize,me) + damageState(ph)%p(so)%deltaState(1:mySize,me) damageState(ph)%state(myOffset + 1: myOffset + mySize,me) + damageState(ph)%deltaState(1:mySize,me)
endif endif
end select sourceType end select sourceType
enddo SourceLoop
end function constitutive_damage_deltaState end function phase_damage_deltaState
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief checks if a source mechanism is active or not !> @brief checks if a source mechanism is active or not
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
function source_active(source_label,src_length) result(active_source) function source_active(source_label) result(active_source)
character(len=*), intent(in) :: source_label !< name of source mechanism character(len=*), intent(in) :: source_label !< name of source mechanism
integer, intent(in) :: src_length !< max. number of sources in system logical, dimension(:), allocatable :: active_source
logical, dimension(:,:), allocatable :: active_source
class(tNode), pointer :: & class(tNode), pointer :: &
phases, & phases, &
phase, & phase, &
sources, & sources, &
src src
integer :: p,s integer :: ph
phases => config_material%get('phase') phases => config_material%get('phase')
allocate(active_source(src_length,phases%length), source = .false. ) allocate(active_source(phases%length))
do p = 1, phases%length do ph = 1, phases%length
phase => phases%get(p) phase => phases%get(ph)
sources => phase%get('source',defaultVal=emptyList) sources => phase%get('damage',defaultVal=emptyList)
do s = 1, sources%length src => sources%get(1)
src => sources%get(s) active_source(ph) = src%get_asString('type',defaultVal = 'x') == source_label
if(src%get_asString('type') == source_label) active_source(s,p) = .true.
enddo
enddo enddo
@ -507,7 +473,7 @@ end function source_active
!---------------------------------------------------------------------------------------------- !----------------------------------------------------------------------------------------------
!< @brief Set damage parameter !< @brief Set damage parameter
!---------------------------------------------------------------------------------------------- !----------------------------------------------------------------------------------------------
module subroutine constitutive_damage_set_phi(phi,co,ce) module subroutine phase_damage_set_phi(phi,co,ce)
real(pReal), intent(in) :: phi real(pReal), intent(in) :: phi
integer, intent(in) :: ce, co integer, intent(in) :: ce, co
@ -515,17 +481,28 @@ module subroutine constitutive_damage_set_phi(phi,co,ce)
current(material_phaseAt2(co,ce))%phi(material_phaseMemberAt2(co,ce)) = phi current(material_phaseAt2(co,ce))%phi(material_phaseMemberAt2(co,ce)) = phi
end subroutine constitutive_damage_set_phi end subroutine phase_damage_set_phi
module function constitutive_damage_get_phi(co,ip,el) result(phi) module function phase_damage_get_phi(co,ip,el) result(phi)
integer, intent(in) :: co, ip, el integer, intent(in) :: co, ip, el
real(pReal) :: phi real(pReal) :: phi
phi = current(material_phaseAt(co,el))%phi(material_phaseMemberAt(co,ip,el)) phi = current(material_phaseAt(co,el))%phi(material_phaseMemberAt(co,ip,el))
end function constitutive_damage_get_phi end function phase_damage_get_phi
module function damage_phi(ph,me) result(phi)
integer, intent(in) :: ph, me
real(pReal) :: phi
phi = current(ph)%phi(me)
end function damage_phi
end submodule damagee end submodule damagee

View File

@ -6,10 +6,6 @@
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
submodule (phase:damagee) anisobrittle submodule (phase:damagee) anisobrittle
integer, dimension(:), allocatable :: &
source_damage_anisoBrittle_offset, & !< which source is my current source mechanism?
source_damage_anisoBrittle_instance !< instance of source mechanism
type :: tParameters !< container type for internal constitutive parameters type :: tParameters !< container type for internal constitutive parameters
real(pReal) :: & real(pReal) :: &
dot_o, & !< opening rate of cleavage planes dot_o, & !< opening rate of cleavage planes
@ -35,42 +31,38 @@ contains
!> @brief module initialization !> @brief module initialization
!> @details reads in material parameters, allocates arrays, and does sanity checks !> @details reads in material parameters, allocates arrays, and does sanity checks
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
module function anisobrittle_init(source_length) result(mySources) module function anisobrittle_init() result(mySources)
integer, intent(in) :: source_length logical, dimension(:), allocatable :: mySources
logical, dimension(:,:), allocatable :: mySources
class(tNode), pointer :: & class(tNode), pointer :: &
phases, & phases, &
phase, & phase, &
sources, & sources, &
src src
integer :: Ninstances,sourceOffset,Nconstituents,p integer :: Nconstituents,p
integer, dimension(:), allocatable :: N_cl integer, dimension(:), allocatable :: N_cl
character(len=pStringLen) :: extmsg = '' character(len=pStringLen) :: extmsg = ''
print'(/,a)', ' <<<+- phase:damage:anisobrittle init -+>>>'
mySources = source_active('damage_anisoBrittle',source_length) mySources = source_active('anisobrittle')
Ninstances = count(mySources) if(count(mySources) == 0) return
print'(a,i2)', ' # instances: ',Ninstances; flush(IO_STDOUT)
if(Ninstances == 0) return print'(/,a)', ' <<<+- phase:damage:anisobrittle init -+>>>'
print'(a,i0)', ' # phases: ',count(mySources); flush(IO_STDOUT)
phases => config_material%get('phase') phases => config_material%get('phase')
allocate(param(Ninstances)) allocate(param(phases%length))
allocate(source_damage_anisoBrittle_offset (phases%length), source=0)
allocate(source_damage_anisoBrittle_instance(phases%length), source=0)
do p = 1, phases%length do p = 1, phases%length
if(mySources(p)) then
phase => phases%get(p) phase => phases%get(p)
if(any(mySources(:,p))) source_damage_anisoBrittle_instance(p) = count(mySources(:,1:p)) sources => phase%get('damage')
if(count(mySources(:,p)) == 0) cycle
sources => phase%get('source') associate(prm => param(p))
do sourceOffset = 1, sources%length src => sources%get(1)
if(mySources(sourceOffset,p)) then
source_damage_anisoBrittle_offset(p) = sourceOffset
associate(prm => param(source_damage_anisoBrittle_instance(p)))
src => sources%get(sourceOffset)
N_cl = src%get_asInts('N_cl',defaultVal=emptyIntArray) N_cl = src%get_asInts('N_cl',defaultVal=emptyIntArray)
prm%sum_N_cl = sum(abs(N_cl)) prm%sum_N_cl = sum(abs(N_cl))
@ -101,9 +93,9 @@ module function anisobrittle_init(source_length) result(mySources)
if (any(prm%s_crit < 0.0_pReal)) extmsg = trim(extmsg)//' s_crit' if (any(prm%s_crit < 0.0_pReal)) extmsg = trim(extmsg)//' s_crit'
Nconstituents = count(material_phaseAt==p) * discretization_nIPs Nconstituents = count(material_phaseAt==p) * discretization_nIPs
call constitutive_allocateState(damageState(p)%p(sourceOffset),Nconstituents,1,1,0) call phase_allocateState(damageState(p),Nconstituents,1,1,0)
damageState(p)%p(sourceOffset)%atol = src%get_asFloat('anisobrittle_atol',defaultVal=1.0e-3_pReal) damageState(p)%atol = src%get_asFloat('anisobrittle_atol',defaultVal=1.0e-3_pReal)
if(any(damageState(p)%p(sourceOffset)%atol < 0.0_pReal)) extmsg = trim(extmsg)//' anisobrittle_atol' if(any(damageState(p)%atol < 0.0_pReal)) extmsg = trim(extmsg)//' anisobrittle_atol'
end associate end associate
@ -111,7 +103,7 @@ module function anisobrittle_init(source_length) result(mySources)
! exit if any parameter is out of range ! exit if any parameter is out of range
if (extmsg /= '') call IO_error(211,ext_msg=trim(extmsg)//'(damage_anisoBrittle)') if (extmsg /= '') call IO_error(211,ext_msg=trim(extmsg)//'(damage_anisoBrittle)')
endif endif
enddo
enddo enddo
end function anisobrittle_init end function anisobrittle_init
@ -120,18 +112,14 @@ end function anisobrittle_init
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief calculates derived quantities from state !> @brief calculates derived quantities from state
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
module subroutine anisobrittle_dotState(S, co, ip, el) module subroutine anisobrittle_dotState(S, ph,me)
integer, intent(in) :: & integer, intent(in) :: &
co, & !< component-ID of integration point ph,me
ip, & !< integration point
el !< element
real(pReal), intent(in), dimension(3,3) :: & real(pReal), intent(in), dimension(3,3) :: &
S S
integer :: & integer :: &
ph, &
me, &
sourceOffset, & sourceOffset, &
damageOffset, & damageOffset, &
homog, & homog, &
@ -139,28 +127,22 @@ module subroutine anisobrittle_dotState(S, co, ip, el)
real(pReal) :: & real(pReal) :: &
traction_d, traction_t, traction_n, traction_crit traction_d, traction_t, traction_n, traction_crit
ph = material_phaseAt(co,el)
me = material_phasememberAt(co,ip,el)
sourceOffset = source_damage_anisoBrittle_offset(ph)
homog = material_homogenizationAt(el)
damageOffset = material_homogenizationMemberAt(ip,el)
associate(prm => param(source_damage_anisoBrittle_instance(ph))) associate(prm => param(ph))
damageState(ph)%p(sourceOffset)%dotState(1,me) = 0.0_pReal damageState(ph)%dotState(1,me) = 0.0_pReal
do i = 1, prm%sum_N_cl do i = 1, prm%sum_N_cl
traction_d = math_tensordot(S,prm%cleavage_systems(1:3,1:3,1,i)) traction_d = math_tensordot(S,prm%cleavage_systems(1:3,1:3,1,i))
traction_t = math_tensordot(S,prm%cleavage_systems(1:3,1:3,2,i)) 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_n = math_tensordot(S,prm%cleavage_systems(1:3,1:3,3,i))
traction_crit = prm%g_crit(i)*damage(homog)%p(damageOffset)**2.0_pReal traction_crit = prm%g_crit(i)*damage_phi(ph,me)**2.0_pReal
damageState(ph)%p(sourceOffset)%dotState(1,me) & damageState(ph)%dotState(1,me) = damageState(ph)%dotState(1,me) &
= damageState(ph)%p(sourceOffset)%dotState(1,me) & + prm%dot_o / prm%s_crit(i) &
+ 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_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_t) - traction_crit)/traction_crit)**prm%q + & (max(0.0_pReal, abs(traction_n) - traction_crit)/traction_crit)**prm%q)
(max(0.0_pReal, abs(traction_n) - traction_crit)/traction_crit)**prm%q) enddo
enddo
end associate end associate
end subroutine anisobrittle_dotState end subroutine anisobrittle_dotState
@ -169,28 +151,24 @@ end subroutine anisobrittle_dotState
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief returns local part of nonlocal damage driving force !> @brief returns local part of nonlocal damage driving force
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
module subroutine source_damage_anisobrittle_getRateAndItsTangent(localphiDot, dLocalphiDot_dPhi, phi, phase, constituent) module subroutine anisobrittle_getRateAndItsTangent(localphiDot, dLocalphiDot_dPhi, phi, ph, me)
integer, intent(in) :: & integer, intent(in) :: &
phase, & ph, &
constituent me
real(pReal), intent(in) :: & real(pReal), intent(in) :: &
phi phi
real(pReal), intent(out) :: & real(pReal), intent(out) :: &
localphiDot, & localphiDot, &
dLocalphiDot_dPhi dLocalphiDot_dPhi
integer :: &
sourceOffset
sourceOffset = source_damage_anisoBrittle_offset(phase) dLocalphiDot_dPhi = -damageState(ph)%state(1,me)
dLocalphiDot_dPhi = -damageState(phase)%p(sourceOffset)%state(1,constituent)
localphiDot = 1.0_pReal & localphiDot = 1.0_pReal &
+ dLocalphiDot_dPhi*phi + dLocalphiDot_dPhi*phi
end subroutine source_damage_anisoBrittle_getRateAndItsTangent end subroutine anisobrittle_getRateAndItsTangent
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
@ -203,16 +181,78 @@ module subroutine anisobrittle_results(phase,group)
integer :: o integer :: o
associate(prm => param(source_damage_anisoBrittle_instance(phase)), &
stt => damageState(phase)%p(source_damage_anisoBrittle_offset(phase))%state) associate(prm => param(phase), stt => damageState(phase)%state)
outputsLoop: do o = 1,size(prm%output) outputsLoop: do o = 1,size(prm%output)
select case(trim(prm%output(o))) select case(trim(prm%output(o)))
case ('f_phi') case ('f_phi')
call results_writeDataset(group,stt,trim(prm%output(o)),'driving force','J/m³') call results_writeDataset(group,stt,trim(prm%output(o)),'driving force','J/m³')
end select end select
enddo outputsLoop enddo outputsLoop
end associate end associate
end subroutine anisobrittle_results end subroutine anisobrittle_results
!--------------------------------------------------------------------------------------------------
!> @brief contains the constitutive equation for calculating the velocity gradient
!--------------------------------------------------------------------------------------------------
module subroutine kinematics_cleavage_opening_LiAndItsTangent(Ld, dLd_dTstar, S, ph,me)
integer, intent(in) :: &
ph,me
real(pReal), intent(in), dimension(3,3) :: &
S
real(pReal), intent(out), dimension(3,3) :: &
Ld !< damage velocity gradient
real(pReal), intent(out), dimension(3,3,3,3) :: &
dLd_dTstar !< derivative of Ld with respect to Tstar (4th-order tensor)
integer :: &
i, k, l, m, n
real(pReal) :: &
traction_d, traction_t, traction_n, traction_crit, &
udotd, dudotd_dt, udott, dudott_dt, udotn, dudotn_dt
Ld = 0.0_pReal
dLd_dTstar = 0.0_pReal
associate(prm => param(ph))
do i = 1,prm%sum_N_cl
traction_crit = prm%g_crit(i)*damage_phi(ph,me)**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%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%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)
endif
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%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%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)
endif
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%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%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)
endif
enddo
end associate
end subroutine kinematics_cleavage_opening_LiAndItsTangent
end submodule anisobrittle end submodule anisobrittle

View File

@ -6,10 +6,6 @@
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
submodule(phase:damagee) anisoductile submodule(phase:damagee) anisoductile
integer, dimension(:), allocatable :: &
source_damage_anisoDuctile_offset, & !< which source is my current damage mechanism?
source_damage_anisoDuctile_instance !< instance of damage source mechanism
type :: tParameters !< container type for internal constitutive parameters type :: tParameters !< container type for internal constitutive parameters
real(pReal) :: & real(pReal) :: &
q !< damage rate sensitivity q !< damage rate sensitivity
@ -19,7 +15,7 @@ submodule(phase:damagee) anisoductile
output output
end type tParameters end type tParameters
type(tParameters), dimension(:), allocatable :: param !< containers of constitutive parameters (len Ninstances) type(tParameters), dimension(:), allocatable :: param !< containers of constitutive parameters
contains contains
@ -28,10 +24,9 @@ contains
!> @brief module initialization !> @brief module initialization
!> @details reads in material parameters, allocates arrays, and does sanity checks !> @details reads in material parameters, allocates arrays, and does sanity checks
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
module function anisoductile_init(source_length) result(mySources) module function anisoductile_init() result(mySources)
integer, intent(in) :: source_length logical, dimension(:), allocatable :: mySources
logical, dimension(:,:), allocatable :: mySources
class(tNode), pointer :: & class(tNode), pointer :: &
phases, & phases, &
@ -40,34 +35,31 @@ module function anisoductile_init(source_length) result(mySources)
pl, & pl, &
sources, & sources, &
src src
integer :: Ninstances,sourceOffset,Nconstituents,p integer :: Ninstances,Nconstituents,p
integer, dimension(:), allocatable :: N_sl integer, dimension(:), allocatable :: N_sl
character(len=pStringLen) :: extmsg = '' character(len=pStringLen) :: extmsg = ''
print'(/,a)', ' <<<+- phase:damage:anisoductile init -+>>>'
mySources = source_active('damage_anisoDuctile',source_length) mySources = source_active('anisoductile')
Ninstances = count(mySources) if(count(mySources) == 0) return
print'(a,i2)', ' # instances: ',Ninstances; flush(IO_STDOUT)
if(Ninstances == 0) return print'(/,a)', ' <<<+- phase:damage:anisoductile init -+>>>'
print'(a,i0)', ' # phases: ',count(mySources); flush(IO_STDOUT)
phases => config_material%get('phase') phases => config_material%get('phase')
allocate(param(Ninstances)) allocate(param(phases%length))
allocate(source_damage_anisoDuctile_offset (phases%length), source=0)
allocate(source_damage_anisoDuctile_instance(phases%length), source=0)
do p = 1, phases%length do p = 1, phases%length
phase => phases%get(p) if(mySources(p)) then
if(any(mySources(:,p))) source_damage_anisoDuctile_instance(p) = count(mySources(:,1:p)) phase => phases%get(p)
if(count(mySources(:,p)) == 0) cycle mech => phase%get('mechanics')
mech => phase%get('mechanics') pl => mech%get('plasticity')
pl => mech%get('plasticity') sources => phase%get('damage')
sources => phase%get('source')
do sourceOffset = 1, sources%length
if(mySources(sourceOffset,p)) then associate(prm => param(p))
source_damage_anisoDuctile_offset(p) = sourceOffset src => sources%get(1)
associate(prm => param(source_damage_anisoDuctile_instance(p)))
src => sources%get(sourceOffset)
N_sl = pl%get_asInts('N_sl',defaultVal=emptyIntArray) N_sl = pl%get_asInts('N_sl',defaultVal=emptyIntArray)
prm%q = src%get_asFloat('q') prm%q = src%get_asFloat('q')
@ -86,10 +78,10 @@ module function anisoductile_init(source_length) result(mySources)
if (prm%q <= 0.0_pReal) extmsg = trim(extmsg)//' q' if (prm%q <= 0.0_pReal) extmsg = trim(extmsg)//' q'
if (any(prm%gamma_crit < 0.0_pReal)) extmsg = trim(extmsg)//' gamma_crit' if (any(prm%gamma_crit < 0.0_pReal)) extmsg = trim(extmsg)//' gamma_crit'
Nconstituents=count(material_phaseAt==p) * discretization_nIPs Nconstituents=count(material_phaseAt2==p)
call constitutive_allocateState(damageState(p)%p(sourceOffset),Nconstituents,1,1,0) call phase_allocateState(damageState(p),Nconstituents,1,1,0)
damageState(p)%p(sourceOffset)%atol = src%get_asFloat('anisoDuctile_atol',defaultVal=1.0e-3_pReal) damageState(p)%atol = src%get_asFloat('anisoDuctile_atol',defaultVal=1.0e-3_pReal)
if(any(damageState(p)%p(sourceOffset)%atol < 0.0_pReal)) extmsg = trim(extmsg)//' anisoductile_atol' if(any(damageState(p)%atol < 0.0_pReal)) extmsg = trim(extmsg)//' anisoductile_atol'
end associate end associate
@ -97,7 +89,7 @@ module function anisoductile_init(source_length) result(mySources)
! exit if any parameter is out of range ! exit if any parameter is out of range
if (extmsg /= '') call IO_error(211,ext_msg=trim(extmsg)//'(damage_anisoDuctile)') if (extmsg /= '') call IO_error(211,ext_msg=trim(extmsg)//'(damage_anisoDuctile)')
endif endif
enddo
enddo enddo
@ -107,29 +99,15 @@ end function anisoductile_init
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief calculates derived quantities from state !> @brief calculates derived quantities from state
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
module subroutine anisoductile_dotState(co, ip, el) module subroutine anisoductile_dotState(ph,me)
integer, intent(in) :: & integer, intent(in) :: &
co, & !< component-ID of integration point
ip, & !< integration point
el !< element
integer :: &
ph, & ph, &
me, & me
sourceOffset, &
damageOffset, &
homog
ph = material_phaseAt(co,el)
me = material_phasememberAt(co,ip,el)
sourceOffset = source_damage_anisoDuctile_offset(ph)
homog = material_homogenizationAt(el)
damageOffset = material_homogenizationMemberAt(ip,el)
associate(prm => param(source_damage_anisoDuctile_instance(ph))) associate(prm => param(ph))
damageState(ph)%p(sourceOffset)%dotState(1,me) & damageState(ph)%dotState(1,me) = sum(plasticState(ph)%slipRate(:,me)/(damage_phi(ph,me)**prm%q)/prm%gamma_crit)
= sum(plasticState(ph)%slipRate(:,me)/(damage(homog)%p(damageOffset)**prm%q)/prm%gamma_crit)
end associate end associate
end subroutine anisoductile_dotState end subroutine anisoductile_dotState
@ -138,28 +116,24 @@ end subroutine anisoductile_dotState
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief returns local part of nonlocal damage driving force !> @brief returns local part of nonlocal damage driving force
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
module subroutine source_damage_anisoDuctile_getRateAndItsTangent(localphiDot, dLocalphiDot_dPhi, phi, phase, constituent) module subroutine anisoductile_getRateAndItsTangent(localphiDot, dLocalphiDot_dPhi, phi, ph,me)
integer, intent(in) :: & integer, intent(in) :: &
phase, & ph, &
constituent me
real(pReal), intent(in) :: & real(pReal), intent(in) :: &
phi phi
real(pReal), intent(out) :: & real(pReal), intent(out) :: &
localphiDot, & localphiDot, &
dLocalphiDot_dPhi dLocalphiDot_dPhi
integer :: &
sourceOffset
sourceOffset = source_damage_anisoDuctile_offset(phase) dLocalphiDot_dPhi = -damageState(ph)%state(1,me)
dLocalphiDot_dPhi = -damageState(phase)%p(sourceOffset)%state(1,constituent)
localphiDot = 1.0_pReal & localphiDot = 1.0_pReal &
+ dLocalphiDot_dPhi*phi + dLocalphiDot_dPhi*phi
end subroutine source_damage_anisoDuctile_getRateAndItsTangent end subroutine anisoductile_getRateAndItsTangent
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
@ -172,14 +146,14 @@ module subroutine anisoductile_results(phase,group)
integer :: o integer :: o
associate(prm => param(source_damage_anisoDuctile_instance(phase)), &
stt => damageState(phase)%p(source_damage_anisoDuctile_offset(phase))%state) associate(prm => param(phase), stt => damageState(phase)%state)
outputsLoop: do o = 1,size(prm%output) outputsLoop: do o = 1,size(prm%output)
select case(trim(prm%output(o))) select case(trim(prm%output(o)))
case ('f_phi') case ('f_phi')
call results_writeDataset(group,stt,trim(prm%output(o)),'driving force','J/m³') call results_writeDataset(group,stt,trim(prm%output(o)),'driving force','J/m³')
end select end select
enddo outputsLoop enddo outputsLoop
end associate end associate
end subroutine anisoductile_results end subroutine anisoductile_results

View File

@ -6,10 +6,6 @@
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
submodule(phase:damagee) isobrittle submodule(phase:damagee) isobrittle
integer, dimension(:), allocatable :: &
source_damage_isoBrittle_offset, &
source_damage_isoBrittle_instance
type :: tParameters !< container type for internal constitutive parameters type :: tParameters !< container type for internal constitutive parameters
real(pReal) :: & real(pReal) :: &
W_crit !< critical elastic strain energy W_crit !< critical elastic strain energy
@ -26,41 +22,36 @@ contains
!> @brief module initialization !> @brief module initialization
!> @details reads in material parameters, allocates arrays, and does sanity checks !> @details reads in material parameters, allocates arrays, and does sanity checks
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
module function isobrittle_init(source_length) result(mySources) module function isobrittle_init() result(mySources)
integer, intent(in) :: source_length logical, dimension(:), allocatable :: mySources
logical, dimension(:,:), allocatable :: mySources
class(tNode), pointer :: & class(tNode), pointer :: &
phases, & phases, &
phase, & phase, &
sources, & sources, &
src src
integer :: Ninstances,sourceOffset,Nconstituents,p integer :: Nconstituents,p
character(len=pStringLen) :: extmsg = '' character(len=pStringLen) :: extmsg = ''
print'(/,a)', ' <<<+- phase:damage:isobrittle init -+>>>'
mySources = source_active('damage_isoBrittle',source_length) mySources = source_active('isobrittle')
Ninstances = count(mySources) if(count(mySources) == 0) return
print'(a,i2)', ' # instances: ',Ninstances; flush(IO_STDOUT)
if(Ninstances == 0) return print'(/,a)', ' <<<+- phase:damage:isobrittle init -+>>>'
print'(a,i0)', ' # phases: ',count(mySources); flush(IO_STDOUT)
phases => config_material%get('phase') phases => config_material%get('phase')
allocate(param(Ninstances)) allocate(param(phases%length))
allocate(source_damage_isoBrittle_offset (phases%length), source=0)
allocate(source_damage_isoBrittle_instance(phases%length), source=0)
do p = 1, phases%length do p = 1, phases%length
if(mySources(p)) then
phase => phases%get(p) phase => phases%get(p)
if(any(mySources(:,p))) source_damage_isoBrittle_instance(p) = count(mySources(:,1:p)) sources => phase%get('damage')
if(count(mySources(:,p)) == 0) cycle
sources => phase%get('source') associate(prm => param(p))
do sourceOffset = 1, sources%length src => sources%get(1)
if(mySources(sourceOffset,p)) then
source_damage_isoBrittle_offset(p) = sourceOffset
associate(prm => param(source_damage_isoBrittle_instance(p)))
src => sources%get(sourceOffset)
prm%W_crit = src%get_asFloat('W_crit') prm%W_crit = src%get_asFloat('W_crit')
@ -73,10 +64,10 @@ module function isobrittle_init(source_length) result(mySources)
! sanity checks ! sanity checks
if (prm%W_crit <= 0.0_pReal) extmsg = trim(extmsg)//' W_crit' if (prm%W_crit <= 0.0_pReal) extmsg = trim(extmsg)//' W_crit'
Nconstituents = count(material_phaseAt==p) * discretization_nIPs Nconstituents = count(material_phaseAt2==p)
call constitutive_allocateState(damageState(p)%p(sourceOffset),Nconstituents,1,1,1) call phase_allocateState(damageState(p),Nconstituents,1,1,1)
damageState(p)%p(sourceOffset)%atol = src%get_asFloat('isoBrittle_atol',defaultVal=1.0e-3_pReal) damageState(p)%atol = src%get_asFloat('isoBrittle_atol',defaultVal=1.0e-3_pReal)
if(any(damageState(p)%p(sourceOffset)%atol < 0.0_pReal)) extmsg = trim(extmsg)//' isobrittle_atol' if(any(damageState(p)%atol < 0.0_pReal)) extmsg = trim(extmsg)//' isobrittle_atol'
end associate end associate
@ -84,7 +75,7 @@ module function isobrittle_init(source_length) result(mySources)
! exit if any parameter is out of range ! exit if any parameter is out of range
if (extmsg /= '') call IO_error(211,ext_msg=trim(extmsg)//'(damage_isoBrittle)') if (extmsg /= '') call IO_error(211,ext_msg=trim(extmsg)//'(damage_isoBrittle)')
endif endif
enddo
enddo enddo
@ -94,7 +85,7 @@ end function isobrittle_init
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief calculates derived quantities from state !> @brief calculates derived quantities from state
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
module subroutine source_damage_isoBrittle_deltaState(C, Fe, ph,me) module subroutine isobrittle_deltaState(C, Fe, ph,me)
integer, intent(in) :: ph,me integer, intent(in) :: ph,me
real(pReal), intent(in), dimension(3,3) :: & real(pReal), intent(in), dimension(3,3) :: &
@ -102,60 +93,47 @@ module subroutine source_damage_isoBrittle_deltaState(C, Fe, ph,me)
real(pReal), intent(in), dimension(6,6) :: & real(pReal), intent(in), dimension(6,6) :: &
C C
integer :: &
sourceOffset
real(pReal), dimension(6) :: & real(pReal), dimension(6) :: &
strain strain
real(pReal) :: & real(pReal) :: &
strainenergy strainenergy
sourceOffset = source_damage_isoBrittle_offset(ph)
strain = 0.5_pReal*math_sym33to6(matmul(transpose(Fe),Fe)-math_I3) strain = 0.5_pReal*math_sym33to6(matmul(transpose(Fe),Fe)-math_I3)
associate(prm => param(source_damage_isoBrittle_instance(ph))) associate(prm => param(ph))
strainenergy = 2.0_pReal*sum(strain*matmul(C,strain))/prm%W_crit strainenergy = 2.0_pReal*sum(strain*matmul(C,strain))/prm%W_crit
! ToDo: check strainenergy = 2.0_pReal*dot_product(strain,matmul(C,strain))/prm%W_crit ! ToDo: check strainenergy = 2.0_pReal*dot_product(strain,matmul(C,strain))/prm%W_crit
if (strainenergy > damageState(ph)%p(sourceOffset)%subState0(1,me)) then damageState(ph)%deltaState(1,me) = merge(strainenergy - damageState(ph)%state(1,me), &
damageState(ph)%p(sourceOffset)%deltaState(1,me) = & damageState(ph)%subState0(1,me) - damageState(ph)%state(1,me), &
strainenergy - damageState(ph)%p(sourceOffset)%state(1,me) strainenergy > damageState(ph)%subState0(1,me))
else
damageState(ph)%p(sourceOffset)%deltaState(1,me) = &
damageState(ph)%p(sourceOffset)%subState0(1,me) - &
damageState(ph)%p(sourceOffset)%state(1,me)
endif
end associate end associate
end subroutine source_damage_isoBrittle_deltaState end subroutine isobrittle_deltaState
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief returns local part of nonlocal damage driving force !> @brief returns local part of nonlocal damage driving force
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
module subroutine source_damage_isoBrittle_getRateAndItsTangent(localphiDot, dLocalphiDot_dPhi, phi, phase, constituent) module subroutine isobrittle_getRateAndItsTangent(localphiDot, dLocalphiDot_dPhi, phi, ph, me)
integer, intent(in) :: & integer, intent(in) :: &
phase, & ph, me
constituent
real(pReal), intent(in) :: & real(pReal), intent(in) :: &
phi phi
real(pReal), intent(out) :: & real(pReal), intent(out) :: &
localphiDot, & localphiDot, &
dLocalphiDot_dPhi dLocalphiDot_dPhi
integer :: &
sourceOffset
sourceOffset = source_damage_isoBrittle_offset(phase) associate(prm => param(ph))
localphiDot = 1.0_pReal &
associate(prm => param(source_damage_isoBrittle_instance(phase))) - phi*damageState(ph)%state(1,me)
localphiDot = 1.0_pReal & dLocalphiDot_dPhi = - damageState(ph)%state(1,me)
- phi*damageState(phase)%p(sourceOffset)%state(1,constituent)
dLocalphiDot_dPhi = - damageState(phase)%p(sourceOffset)%state(1,constituent)
end associate end associate
end subroutine source_damage_isoBrittle_getRateAndItsTangent end subroutine isobrittle_getRateAndItsTangent
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
@ -168,14 +146,15 @@ module subroutine isobrittle_results(phase,group)
integer :: o integer :: o
associate(prm => param(source_damage_isoBrittle_instance(phase)), &
stt => damageState(phase)%p(source_damage_isoBrittle_offset(phase))%state) associate(prm => param(phase), &
outputsLoop: do o = 1,size(prm%output) stt => damageState(phase)%state)
select case(trim(prm%output(o))) outputsLoop: do o = 1,size(prm%output)
case ('f_phi') select case(trim(prm%output(o)))
call results_writeDataset(group,stt,trim(prm%output(o)),'driving force','J/m³') case ('f_phi')
end select call results_writeDataset(group,stt,trim(prm%output(o)),'driving force','J/m³')
enddo outputsLoop end select
enddo outputsLoop
end associate end associate
end subroutine isobrittle_results end subroutine isobrittle_results

View File

@ -6,10 +6,6 @@
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
submodule(phase:damagee) isoductile submodule(phase:damagee) isoductile
integer, dimension(:), allocatable :: &
source_damage_isoDuctile_offset, & !< which source is my current damage mechanism?
source_damage_isoDuctile_instance !< instance of damage source mechanism
type:: tParameters !< container type for internal constitutive parameters type:: tParameters !< container type for internal constitutive parameters
real(pReal) :: & real(pReal) :: &
gamma_crit, & !< critical plastic strain gamma_crit, & !< critical plastic strain
@ -28,41 +24,36 @@ contains
!> @brief module initialization !> @brief module initialization
!> @details reads in material parameters, allocates arrays, and does sanity checks !> @details reads in material parameters, allocates arrays, and does sanity checks
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
module function isoductile_init(source_length) result(mySources) module function isoductile_init() result(mySources)
integer, intent(in) :: source_length logical, dimension(:), allocatable :: mySources
logical, dimension(:,:), allocatable :: mySources
class(tNode), pointer :: & class(tNode), pointer :: &
phases, & phases, &
phase, & phase, &
sources, & sources, &
src src
integer :: Ninstances,sourceOffset,Nconstituents,p integer :: Ninstances,Nconstituents,p
character(len=pStringLen) :: extmsg = '' character(len=pStringLen) :: extmsg = ''
print'(/,a)', ' <<<+- phase:damage:isoductile init -+>>>'
mySources = source_active('damage_isoDuctile',source_length) mySources = source_active('isoductile')
Ninstances = count(mySources) if(count(mySources) == 0) return
print'(a,i2)', ' # instances: ',Ninstances; flush(IO_STDOUT)
if(Ninstances == 0) return print'(/,a)', ' <<<+- phase:damage:isoductile init -+>>>'
print'(a,i0)', ' # phases: ',count(mySources); flush(IO_STDOUT)
phases => config_material%get('phase') phases => config_material%get('phase')
allocate(param(Ninstances)) allocate(param(phases%length))
allocate(source_damage_isoDuctile_offset (phases%length), source=0)
allocate(source_damage_isoDuctile_instance(phases%length), source=0)
do p = 1, phases%length do p = 1, phases%length
phase => phases%get(p) if(mySources(p)) then
if(count(mySources(:,p)) == 0) cycle phase => phases%get(p)
if(any(mySources(:,p))) source_damage_isoDuctile_instance(p) = count(mySources(:,1:p)) sources => phase%get('damage')
sources => phase%get('source')
do sourceOffset = 1, sources%length associate(prm => param(p))
if(mySources(sourceOffset,p)) then src => sources%get(1)
source_damage_isoDuctile_offset(p) = sourceOffset
associate(prm => param(source_damage_isoDuctile_instance(p)))
src => sources%get(sourceOffset)
prm%q = src%get_asFloat('q') prm%q = src%get_asFloat('q')
prm%gamma_crit = src%get_asFloat('gamma_crit') prm%gamma_crit = src%get_asFloat('gamma_crit')
@ -77,10 +68,10 @@ module function isoductile_init(source_length) result(mySources)
if (prm%q <= 0.0_pReal) extmsg = trim(extmsg)//' q' if (prm%q <= 0.0_pReal) extmsg = trim(extmsg)//' q'
if (prm%gamma_crit <= 0.0_pReal) extmsg = trim(extmsg)//' gamma_crit' if (prm%gamma_crit <= 0.0_pReal) extmsg = trim(extmsg)//' gamma_crit'
Nconstituents=count(material_phaseAt==p) * discretization_nIPs Nconstituents=count(material_phaseAt2==p)
call constitutive_allocateState(damageState(p)%p(sourceOffset),Nconstituents,1,1,0) call phase_allocateState(damageState(p),Nconstituents,1,1,0)
damageState(p)%p(sourceOffset)%atol = src%get_asFloat('isoDuctile_atol',defaultVal=1.0e-3_pReal) damageState(p)%atol = src%get_asFloat('isoDuctile_atol',defaultVal=1.0e-3_pReal)
if(any(damageState(p)%p(sourceOffset)%atol < 0.0_pReal)) extmsg = trim(extmsg)//' isoductile_atol' if(any(damageState(p)%atol < 0.0_pReal)) extmsg = trim(extmsg)//' isoductile_atol'
end associate end associate
@ -88,7 +79,6 @@ module function isoductile_init(source_length) result(mySources)
! exit if any parameter is out of range ! exit if any parameter is out of range
if (extmsg /= '') call IO_error(211,ext_msg=trim(extmsg)//'(damage_isoDuctile)') if (extmsg /= '') call IO_error(211,ext_msg=trim(extmsg)//'(damage_isoDuctile)')
endif endif
enddo
enddo enddo
@ -98,29 +88,16 @@ end function isoductile_init
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief calculates derived quantities from state !> @brief calculates derived quantities from state
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
module subroutine isoductile_dotState(co, ip, el) module subroutine isoductile_dotState(ph, me)
integer, intent(in) :: & integer, intent(in) :: &
co, & !< component-ID of integration point
ip, & !< integration point
el !< element
integer :: &
ph, & ph, &
me, & me
sourceOffset, &
damageOffset, &
homog
ph = material_phaseAt(co,el)
me = material_phasememberAt(co,ip,el)
sourceOffset = source_damage_isoDuctile_offset(ph)
homog = material_homogenizationAt(el)
damageOffset = material_homogenizationMemberAt(ip,el)
associate(prm => param(source_damage_isoDuctile_instance(ph))) associate(prm => param(ph))
damageState(ph)%p(sourceOffset)%dotState(1,me) = & damageState(ph)%dotState(1,me) = sum(plasticState(ph)%slipRate(:,me)) &
sum(plasticState(ph)%slipRate(:,me))/(damage(homog)%p(damageOffset)**prm%q)/prm%gamma_crit / (prm%gamma_crit*damage_phi(ph,me)**prm%q)
end associate end associate
end subroutine isoductile_dotState end subroutine isoductile_dotState
@ -129,28 +106,24 @@ end subroutine isoductile_dotState
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief returns local part of nonlocal damage driving force !> @brief returns local part of nonlocal damage driving force
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
module subroutine source_damage_isoDuctile_getRateAndItsTangent(localphiDot, dLocalphiDot_dPhi, phi, phase, constituent) module subroutine isoductile_getRateAndItsTangent(localphiDot, dLocalphiDot_dPhi, phi, ph, me)
integer, intent(in) :: & integer, intent(in) :: &
phase, & ph, &
constituent me
real(pReal), intent(in) :: & real(pReal), intent(in) :: &
phi phi
real(pReal), intent(out) :: & real(pReal), intent(out) :: &
localphiDot, & localphiDot, &
dLocalphiDot_dPhi dLocalphiDot_dPhi
integer :: &
sourceOffset
sourceOffset = source_damage_isoDuctile_offset(phase) dLocalphiDot_dPhi = -damageState(ph)%state(1,me)
dLocalphiDot_dPhi = -damageState(phase)%p(sourceOffset)%state(1,constituent)
localphiDot = 1.0_pReal & localphiDot = 1.0_pReal &
+ dLocalphiDot_dPhi*phi + dLocalphiDot_dPhi*phi
end subroutine source_damage_isoDuctile_getRateAndItsTangent end subroutine isoductile_getRateAndItsTangent
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
@ -163,14 +136,13 @@ module subroutine isoductile_results(phase,group)
integer :: o integer :: o
associate(prm => param(source_damage_isoDuctile_instance(phase)), & associate(prm => param(phase), stt => damageState(phase)%state)
stt => damageState(phase)%p(source_damage_isoDuctile_offset(phase))%state) outputsLoop: do o = 1,size(prm%output)
outputsLoop: do o = 1,size(prm%output) select case(trim(prm%output(o)))
select case(trim(prm%output(o))) case ('f_phi')
case ('f_phi') call results_writeDataset(group,stt,trim(prm%output(o)),'driving force','J/m³')
call results_writeDataset(group,stt,trim(prm%output(o)),'driving force','J/m³') end select
end select enddo outputsLoop
enddo outputsLoop
end associate end associate
end subroutine isoductile_results end subroutine isoductile_results

View File

@ -1,7 +1,8 @@
!---------------------------------------------------------------------------------------------------- !----------------------------------------------------------------------------------------------------
!> @brief internal microstructure state for all plasticity constitutive models !> @brief internal microstructure state for all plasticity constitutive models
!---------------------------------------------------------------------------------------------------- !----------------------------------------------------------------------------------------------------
submodule(phase) mechanics submodule(phase) mechanical
enum, bind(c); enumerator :: & enum, bind(c); enumerator :: &
ELASTICITY_UNDEFINED_ID, & ELASTICITY_UNDEFINED_ID, &
@ -22,8 +23,6 @@ submodule(phase) mechanics
KINEMATICS_THERMAL_EXPANSION_ID KINEMATICS_THERMAL_EXPANSION_ID
end enum end enum
integer(kind(KINEMATICS_UNDEFINED_ID)), dimension(:,:), allocatable :: &
phase_kinematics
integer(kind(ELASTICITY_UNDEFINED_ID)), dimension(:), allocatable :: & integer(kind(ELASTICITY_UNDEFINED_ID)), dimension(:), allocatable :: &
phase_elasticity !< elasticity of each phase phase_elasticity !< elasticity of each phase
integer(kind(STIFFNESS_DEGRADATION_UNDEFINED_ID)), dimension(:,:), allocatable :: & integer(kind(STIFFNESS_DEGRADATION_UNDEFINED_ID)), dimension(:,:), allocatable :: &
@ -31,21 +30,21 @@ submodule(phase) mechanics
type(tTensorContainer), dimension(:), allocatable :: & type(tTensorContainer), dimension(:), allocatable :: &
! current value ! current value
constitutive_mech_Fe, & phase_mechanical_Fe, &
constitutive_mech_Fi, & phase_mechanical_Fi, &
constitutive_mech_Fp, & phase_mechanical_Fp, &
constitutive_mech_F, & phase_mechanical_F, &
constitutive_mech_Li, & phase_mechanical_Li, &
constitutive_mech_Lp, & phase_mechanical_Lp, &
constitutive_mech_S, & phase_mechanical_S, &
constitutive_mech_P, & phase_mechanical_P, &
! converged value at end of last solver increment ! converged value at end of last solver increment
constitutive_mech_Fi0, & phase_mechanical_Fi0, &
constitutive_mech_Fp0, & phase_mechanical_Fp0, &
constitutive_mech_F0, & phase_mechanical_F0, &
constitutive_mech_Li0, & phase_mechanical_Li0, &
constitutive_mech_Lp0, & phase_mechanical_Lp0, &
constitutive_mech_S0 phase_mechanical_S0
integer(kind(PLASTICITY_undefined_ID)), dimension(:), allocatable :: & integer(kind(PLASTICITY_undefined_ID)), dimension(:), allocatable :: &
@ -61,7 +60,7 @@ submodule(phase) mechanics
module subroutine plastic_init module subroutine plastic_init
end subroutine plastic_init end subroutine plastic_init
module subroutine plastic_isotropic_LiAndItsTangent(Li,dLi_dMi,Mi,instance,me) module subroutine plastic_isotropic_LiAndItsTangent(Li,dLi_dMi,Mi,ph,me)
real(pReal), dimension(3,3), intent(out) :: & real(pReal), dimension(3,3), intent(out) :: &
Li !< inleastic velocity gradient Li !< inleastic velocity gradient
real(pReal), dimension(3,3,3,3), intent(out) :: & real(pReal), dimension(3,3,3,3), intent(out) :: &
@ -69,7 +68,7 @@ submodule(phase) mechanics
real(pReal), dimension(3,3), intent(in) :: & real(pReal), dimension(3,3), intent(in) :: &
Mi !< Mandel stress Mi !< Mandel stress
integer, intent(in) :: & integer, intent(in) :: &
instance, & ph, &
me me
end subroutine plastic_isotropic_LiAndItsTangent end subroutine plastic_isotropic_LiAndItsTangent
@ -86,24 +85,18 @@ submodule(phase) mechanics
logical :: broken logical :: broken
end function plastic_dotState end function plastic_dotState
module function plastic_deltaState(co, ip, el, ph, me) result(broken) module function plastic_deltaState(ph, me) result(broken)
integer, intent(in) :: & integer, intent(in) :: &
co, & !< component-ID of integration point
ip, & !< integration point
el, & !< element
ph, & ph, &
me me
logical :: & logical :: &
broken broken
end function plastic_deltaState end function plastic_deltaState
module subroutine constitutive_LiAndItsTangents(Li, dLi_dS, dLi_dFi, & module subroutine phase_LiAndItsTangents(Li, dLi_dS, dLi_dFi, &
S, Fi, co, ip, el) S, Fi, ph,me)
integer, intent(in) :: & integer, intent(in) :: &
co, & !< component-ID of integration point ph,me
ip, & !< integration point
el !< element
real(pReal), intent(in), dimension(3,3) :: & real(pReal), intent(in), dimension(3,3) :: &
S !< 2nd Piola-Kirchhoff stress S !< 2nd Piola-Kirchhoff stress
real(pReal), intent(in), dimension(3,3) :: & real(pReal), intent(in), dimension(3,3) :: &
@ -114,15 +107,13 @@ submodule(phase) mechanics
dLi_dS, & !< derivative of Li with respect to S dLi_dS, & !< derivative of Li with respect to S
dLi_dFi dLi_dFi
end subroutine constitutive_LiAndItsTangents end subroutine phase_LiAndItsTangents
module subroutine plastic_LpAndItsTangents(Lp, dLp_dS, dLp_dFi, & module subroutine plastic_LpAndItsTangents(Lp, dLp_dS, dLp_dFi, &
S, Fi, co, ip, el) S, Fi, ph,me)
integer, intent(in) :: & integer, intent(in) :: &
co, & !< component-ID of integration point ph,me
ip, & !< integration point
el !< element
real(pReal), intent(in), dimension(3,3) :: & real(pReal), intent(in), dimension(3,3) :: &
S, & !< 2nd Piola-Kirchhoff stress S, & !< 2nd Piola-Kirchhoff stress
Fi !< intermediate deformation gradient Fi !< intermediate deformation gradient
@ -134,33 +125,33 @@ submodule(phase) mechanics
end subroutine plastic_LpAndItsTangents end subroutine plastic_LpAndItsTangents
module subroutine plastic_isotropic_results(instance,group) module subroutine plastic_isotropic_results(ph,group)
integer, intent(in) :: instance integer, intent(in) :: ph
character(len=*), intent(in) :: group character(len=*), intent(in) :: group
end subroutine plastic_isotropic_results end subroutine plastic_isotropic_results
module subroutine plastic_phenopowerlaw_results(instance,group) module subroutine plastic_phenopowerlaw_results(ph,group)
integer, intent(in) :: instance integer, intent(in) :: ph
character(len=*), intent(in) :: group character(len=*), intent(in) :: group
end subroutine plastic_phenopowerlaw_results end subroutine plastic_phenopowerlaw_results
module subroutine plastic_kinehardening_results(instance,group) module subroutine plastic_kinehardening_results(ph,group)
integer, intent(in) :: instance integer, intent(in) :: ph
character(len=*), intent(in) :: group character(len=*), intent(in) :: group
end subroutine plastic_kinehardening_results end subroutine plastic_kinehardening_results
module subroutine plastic_dislotwin_results(instance,group) module subroutine plastic_dislotwin_results(ph,group)
integer, intent(in) :: instance integer, intent(in) :: ph
character(len=*), intent(in) :: group character(len=*), intent(in) :: group
end subroutine plastic_dislotwin_results end subroutine plastic_dislotwin_results
module subroutine plastic_dislotungsten_results(instance,group) module subroutine plastic_dislotungsten_results(ph,group)
integer, intent(in) :: instance integer, intent(in) :: ph
character(len=*), intent(in) :: group character(len=*), intent(in) :: group
end subroutine plastic_dislotungsten_results end subroutine plastic_dislotungsten_results
module subroutine plastic_nonlocal_results(instance,group) module subroutine plastic_nonlocal_results(ph,group)
integer, intent(in) :: instance integer, intent(in) :: ph
character(len=*), intent(in) :: group character(len=*), intent(in) :: group
end subroutine plastic_nonlocal_results end subroutine plastic_nonlocal_results
@ -186,7 +177,7 @@ contains
!> @brief Initialize mechanical field related constitutive models !> @brief Initialize mechanical field related constitutive models
!> @details Initialize elasticity, plasticity and stiffness degradation models. !> @details Initialize elasticity, plasticity and stiffness degradation models.
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
module subroutine mech_init(phases) module subroutine mechanical_init(phases)
class(tNode), pointer :: & class(tNode), pointer :: &
phases phases
@ -206,7 +197,7 @@ module subroutine mech_init(phases)
elastic, & elastic, &
stiffDegradation stiffDegradation
print'(/,a)', ' <<<+- phase:mechanics init -+>>>' print'(/,a)', ' <<<+- phase:mechanical init -+>>>'
!------------------------------------------------------------------------------------------------- !-------------------------------------------------------------------------------------------------
! initialize elasticity (hooke) !ToDO: Maybe move to elastic submodule along with function homogenizedC? ! initialize elasticity (hooke) !ToDO: Maybe move to elastic submodule along with function homogenizedC?
@ -215,38 +206,38 @@ module subroutine mech_init(phases)
allocate(phase_NstiffnessDegradations(phases%length),source=0) allocate(phase_NstiffnessDegradations(phases%length),source=0)
allocate(output_constituent(phases%length)) allocate(output_constituent(phases%length))
allocate(constitutive_mech_Fe(phases%length)) allocate(phase_mechanical_Fe(phases%length))
allocate(constitutive_mech_Fi(phases%length)) allocate(phase_mechanical_Fi(phases%length))
allocate(constitutive_mech_Fi0(phases%length)) allocate(phase_mechanical_Fi0(phases%length))
allocate(constitutive_mech_Fp(phases%length)) allocate(phase_mechanical_Fp(phases%length))
allocate(constitutive_mech_Fp0(phases%length)) allocate(phase_mechanical_Fp0(phases%length))
allocate(constitutive_mech_F(phases%length)) allocate(phase_mechanical_F(phases%length))
allocate(constitutive_mech_F0(phases%length)) allocate(phase_mechanical_F0(phases%length))
allocate(constitutive_mech_Li(phases%length)) allocate(phase_mechanical_Li(phases%length))
allocate(constitutive_mech_Li0(phases%length)) allocate(phase_mechanical_Li0(phases%length))
allocate(constitutive_mech_Lp0(phases%length)) allocate(phase_mechanical_Lp0(phases%length))
allocate(constitutive_mech_Lp(phases%length)) allocate(phase_mechanical_Lp(phases%length))
allocate(constitutive_mech_S(phases%length)) allocate(phase_mechanical_S(phases%length))
allocate(constitutive_mech_P(phases%length)) allocate(phase_mechanical_P(phases%length))
allocate(constitutive_mech_S0(phases%length)) allocate(phase_mechanical_S0(phases%length))
do ph = 1, phases%length do ph = 1, phases%length
Nconstituents = count(material_phaseAt == ph) * discretization_nIPs Nconstituents = count(material_phaseAt == ph) * discretization_nIPs
allocate(constitutive_mech_Fi(ph)%data(3,3,Nconstituents)) allocate(phase_mechanical_Fi(ph)%data(3,3,Nconstituents))
allocate(constitutive_mech_Fe(ph)%data(3,3,Nconstituents)) allocate(phase_mechanical_Fe(ph)%data(3,3,Nconstituents))
allocate(constitutive_mech_Fi0(ph)%data(3,3,Nconstituents)) allocate(phase_mechanical_Fi0(ph)%data(3,3,Nconstituents))
allocate(constitutive_mech_Fp(ph)%data(3,3,Nconstituents)) allocate(phase_mechanical_Fp(ph)%data(3,3,Nconstituents))
allocate(constitutive_mech_Fp0(ph)%data(3,3,Nconstituents)) allocate(phase_mechanical_Fp0(ph)%data(3,3,Nconstituents))
allocate(constitutive_mech_Li(ph)%data(3,3,Nconstituents)) allocate(phase_mechanical_Li(ph)%data(3,3,Nconstituents))
allocate(constitutive_mech_Li0(ph)%data(3,3,Nconstituents)) allocate(phase_mechanical_Li0(ph)%data(3,3,Nconstituents))
allocate(constitutive_mech_Lp0(ph)%data(3,3,Nconstituents)) allocate(phase_mechanical_Lp0(ph)%data(3,3,Nconstituents))
allocate(constitutive_mech_Lp(ph)%data(3,3,Nconstituents)) allocate(phase_mechanical_Lp(ph)%data(3,3,Nconstituents))
allocate(constitutive_mech_S(ph)%data(3,3,Nconstituents),source=0.0_pReal) allocate(phase_mechanical_S(ph)%data(3,3,Nconstituents),source=0.0_pReal)
allocate(constitutive_mech_P(ph)%data(3,3,Nconstituents),source=0.0_pReal) allocate(phase_mechanical_P(ph)%data(3,3,Nconstituents),source=0.0_pReal)
allocate(constitutive_mech_S0(ph)%data(3,3,Nconstituents),source=0.0_pReal) allocate(phase_mechanical_S0(ph)%data(3,3,Nconstituents),source=0.0_pReal)
allocate(constitutive_mech_F(ph)%data(3,3,Nconstituents)) allocate(phase_mechanical_F(ph)%data(3,3,Nconstituents))
allocate(constitutive_mech_F0(ph)%data(3,3,Nconstituents)) allocate(phase_mechanical_F0(ph)%data(3,3,Nconstituents))
phase => phases%get(ph) phase => phases%get(ph)
mech => phase%get('mechanics') mech => phase%get('mechanics')
@ -287,17 +278,17 @@ module subroutine mech_init(phases)
ph = material_phaseAt(co,el) ph = material_phaseAt(co,el)
me = material_phaseMemberAt(co,ip,el) me = material_phaseMemberAt(co,ip,el)
constitutive_mech_Fp0(ph)%data(1:3,1:3,me) = material_orientation0(co,ip,el)%asMatrix() ! Fp reflects initial orientation (see 10.1016/j.actamat.2006.01.005) phase_mechanical_Fp0(ph)%data(1:3,1:3,me) = material_orientation0(co,ip,el)%asMatrix() ! Fp reflects initial orientation (see 10.1016/j.actamat.2006.01.005)
constitutive_mech_Fp0(ph)%data(1:3,1:3,me) = constitutive_mech_Fp0(ph)%data(1:3,1:3,me) & phase_mechanical_Fp0(ph)%data(1:3,1:3,me) = phase_mechanical_Fp0(ph)%data(1:3,1:3,me) &
/ math_det33(constitutive_mech_Fp0(ph)%data(1:3,1:3,me))**(1.0_pReal/3.0_pReal) / math_det33(phase_mechanical_Fp0(ph)%data(1:3,1:3,me))**(1.0_pReal/3.0_pReal)
constitutive_mech_Fi0(ph)%data(1:3,1:3,me) = math_I3 phase_mechanical_Fi0(ph)%data(1:3,1:3,me) = math_I3
constitutive_mech_F0(ph)%data(1:3,1:3,me) = math_I3 phase_mechanical_F0(ph)%data(1:3,1:3,me) = math_I3
constitutive_mech_Fe(ph)%data(1:3,1:3,me) = math_inv33(matmul(constitutive_mech_Fi0(ph)%data(1:3,1:3,me), & phase_mechanical_Fe(ph)%data(1:3,1:3,me) = math_inv33(matmul(phase_mechanical_Fi0(ph)%data(1:3,1:3,me), &
constitutive_mech_Fp0(ph)%data(1:3,1:3,me))) ! assuming that euler angles are given in internal strain free configuration phase_mechanical_Fp0(ph)%data(1:3,1:3,me))) ! assuming that euler angles are given in internal strain free configuration
constitutive_mech_Fp(ph)%data(1:3,1:3,me) = constitutive_mech_Fp0(ph)%data(1:3,1:3,me) phase_mechanical_Fp(ph)%data(1:3,1:3,me) = phase_mechanical_Fp0(ph)%data(1:3,1:3,me)
constitutive_mech_Fi(ph)%data(1:3,1:3,me) = constitutive_mech_Fi0(ph)%data(1:3,1:3,me) phase_mechanical_Fi(ph)%data(1:3,1:3,me) = phase_mechanical_Fi0(ph)%data(1:3,1:3,me)
constitutive_mech_F(ph)%data(1:3,1:3,me) = constitutive_mech_F0(ph)%data(1:3,1:3,me) phase_mechanical_F(ph)%data(1:3,1:3,me) = phase_mechanical_F0(ph)%data(1:3,1:3,me)
enddo enddo
enddo; enddo enddo; enddo
@ -307,14 +298,12 @@ module subroutine mech_init(phases)
! initialize plasticity ! initialize plasticity
allocate(plasticState(phases%length)) allocate(plasticState(phases%length))
allocate(phase_plasticity(phases%length),source = PLASTICITY_undefined_ID) allocate(phase_plasticity(phases%length),source = PLASTICITY_undefined_ID)
allocate(phase_plasticityInstance(phases%length),source = 0)
allocate(phase_localPlasticity(phases%length), source=.true.) allocate(phase_localPlasticity(phases%length), source=.true.)
call plastic_init() call plastic_init()
do ph = 1, phases%length do ph = 1, phases%length
phase_elasticityInstance(ph) = count(phase_elasticity(1:ph) == phase_elasticity(ph)) phase_elasticityInstance(ph) = count(phase_elasticity(1:ph) == phase_elasticity(ph))
phase_plasticityInstance(ph) = count(phase_plasticity(1:ph) == phase_plasticity(ph))
enddo enddo
num_crystallite => config_numerics%get('crystallite',defaultVal=emptyDict) num_crystallite => config_numerics%get('crystallite',defaultVal=emptyDict)
@ -345,14 +334,14 @@ module subroutine mech_init(phases)
call eigendeformation_init(phases) call eigendeformation_init(phases)
end subroutine mech_init end subroutine mechanical_init
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief returns the 2nd Piola-Kirchhoff stress tensor and its tangent with respect to !> @brief returns the 2nd Piola-Kirchhoff stress tensor and its tangent with respect to
!> the elastic and intermediate deformation gradients using Hooke's law !> the elastic and intermediate deformation gradients using Hooke's law
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
subroutine constitutive_hooke_SandItsTangents(S, dS_dFe, dS_dFi, & subroutine phase_hooke_SandItsTangents(S, dS_dFe, dS_dFi, &
Fe, Fi, co, ip, el) Fe, Fi, co, ip, el)
integer, intent(in) :: & integer, intent(in) :: &
@ -376,12 +365,12 @@ subroutine constitutive_hooke_SandItsTangents(S, dS_dFe, dS_dFi, &
i, j, ph, me i, j, ph, me
ho = material_homogenizationAt(el) ho = material_homogenizationAt(el)
C = math_66toSym3333(constitutive_homogenizedC(material_phaseAt(co,el),material_phaseMemberAt(co,ip,el))) C = math_66toSym3333(phase_homogenizedC(material_phaseAt(co,el),material_phaseMemberAt(co,ip,el)))
DegradationLoop: do d = 1, phase_NstiffnessDegradations(material_phaseAt(co,el)) DegradationLoop: do d = 1, phase_NstiffnessDegradations(material_phaseAt(co,el))
degradationType: select case(phase_stiffnessDegradation(d,material_phaseAt(co,el))) degradationType: select case(phase_stiffnessDegradation(d,material_phaseAt(co,el)))
case (STIFFNESS_DEGRADATION_damage_ID) degradationType case (STIFFNESS_DEGRADATION_damage_ID) degradationType
C = C * damage(ho)%p(material_homogenizationMemberAt(ip,el))**2 C = C * phase_damage_get_phi(co,ip,el)**2
end select degradationType end select degradationType
enddo DegradationLoop enddo DegradationLoop
@ -393,10 +382,10 @@ subroutine constitutive_hooke_SandItsTangents(S, dS_dFe, dS_dFi, &
dS_dFi(i,j,1:3,1:3) = 2.0_pReal*matmul(matmul(E,Fi),C(i,j,1:3,1:3)) !< dS_ij/dFi_kl = C_ijln * E_km * Fe_mn dS_dFi(i,j,1:3,1:3) = 2.0_pReal*matmul(matmul(E,Fi),C(i,j,1:3,1:3)) !< dS_ij/dFi_kl = C_ijln * E_km * Fe_mn
enddo; enddo enddo; enddo
end subroutine constitutive_hooke_SandItsTangents end subroutine phase_hooke_SandItsTangents
module subroutine mech_results(group,ph) module subroutine mechanical_results(group,ph)
character(len=*), intent(in) :: group character(len=*), intent(in) :: group
integer, intent(in) :: ph integer, intent(in) :: ph
@ -407,28 +396,28 @@ module subroutine mech_results(group,ph)
select case(phase_plasticity(ph)) select case(phase_plasticity(ph))
case(PLASTICITY_ISOTROPIC_ID) case(PLASTICITY_ISOTROPIC_ID)
call plastic_isotropic_results(phase_plasticityInstance(ph),group//'plastic/') call plastic_isotropic_results(ph,group//'plastic/')
case(PLASTICITY_PHENOPOWERLAW_ID) case(PLASTICITY_PHENOPOWERLAW_ID)
call plastic_phenopowerlaw_results(phase_plasticityInstance(ph),group//'plastic/') call plastic_phenopowerlaw_results(ph,group//'plastic/')
case(PLASTICITY_KINEHARDENING_ID) case(PLASTICITY_KINEHARDENING_ID)
call plastic_kinehardening_results(phase_plasticityInstance(ph),group//'plastic/') call plastic_kinehardening_results(ph,group//'plastic/')
case(PLASTICITY_DISLOTWIN_ID) case(PLASTICITY_DISLOTWIN_ID)
call plastic_dislotwin_results(phase_plasticityInstance(ph),group//'plastic/') call plastic_dislotwin_results(ph,group//'plastic/')
case(PLASTICITY_DISLOTUNGSTEN_ID) case(PLASTICITY_DISLOTUNGSTEN_ID)
call plastic_dislotungsten_results(phase_plasticityInstance(ph),group//'plastic/') call plastic_dislotungsten_results(ph,group//'plastic/')
case(PLASTICITY_NONLOCAL_ID) case(PLASTICITY_NONLOCAL_ID)
call plastic_nonlocal_results(phase_plasticityInstance(ph),group//'plastic/') call plastic_nonlocal_results(ph,group//'plastic/')
end select end select
call crystallite_results(group,ph) call crystallite_results(group,ph)
end subroutine mech_results end subroutine mechanical_results
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
@ -503,8 +492,8 @@ function integrateStress(F,subFp0,subFi0,Delta_t,co,ip,el) result(broken)
call plastic_dependentState(co,ip,el) call plastic_dependentState(co,ip,el)
Lpguess = constitutive_mech_Lp(ph)%data(1:3,1:3,me) ! take as first guess Lpguess = phase_mechanical_Lp(ph)%data(1:3,1:3,me) ! take as first guess
Liguess = constitutive_mech_Li(ph)%data(1:3,1:3,me) ! take as first guess Liguess = phase_mechanical_Li(ph)%data(1:3,1:3,me) ! take as first guess
call math_invert33(invFp_current,devNull,error,subFp0) call math_invert33(invFp_current,devNull,error,subFp0)
if (error) return ! error if (error) return ! error
@ -538,11 +527,11 @@ function integrateStress(F,subFp0,subFi0,Delta_t,co,ip,el) result(broken)
B = math_I3 - Delta_t*Lpguess B = math_I3 - Delta_t*Lpguess
Fe = matmul(matmul(A,B), invFi_new) Fe = matmul(matmul(A,B), invFi_new)
call constitutive_hooke_SandItsTangents(S, dS_dFe, dS_dFi, & call phase_hooke_SandItsTangents(S, dS_dFe, dS_dFi, &
Fe, Fi_new, co, ip, el) Fe, Fi_new, co, ip, el)
call plastic_LpAndItsTangents(Lp_constitutive, dLp_dS, dLp_dFi, & call plastic_LpAndItsTangents(Lp_constitutive, dLp_dS, dLp_dFi, &
S, Fi_new, co, ip, el) S, Fi_new, ph,me)
!* update current residuum and check for convergence of loop !* update current residuum and check for convergence of loop
atol_Lp = max(num%rtol_crystalliteStress * max(norm2(Lpguess),norm2(Lp_constitutive)), & ! absolute tolerance from largest acceptable relative error atol_Lp = max(num%rtol_crystalliteStress * max(norm2(Lpguess),norm2(Lp_constitutive)), & ! absolute tolerance from largest acceptable relative error
@ -582,8 +571,8 @@ function integrateStress(F,subFp0,subFi0,Delta_t,co,ip,el) result(broken)
+ deltaLp * steplengthLp + deltaLp * steplengthLp
enddo LpLoop enddo LpLoop
call constitutive_LiAndItsTangents(Li_constitutive, dLi_dS, dLi_dFi, & call phase_LiAndItsTangents(Li_constitutive, dLi_dS, dLi_dFi, &
S, Fi_new, co, ip, el) S, Fi_new, ph,me)
!* update current residuum and check for convergence of loop !* update current residuum and check for convergence of loop
atol_Li = max(num%rtol_crystalliteStress * max(norm2(Liguess),norm2(Li_constitutive)), & ! absolute tolerance from largest acceptable relative error atol_Li = max(num%rtol_crystalliteStress * max(norm2(Liguess),norm2(Li_constitutive)), & ! absolute tolerance from largest acceptable relative error
@ -633,13 +622,13 @@ function integrateStress(F,subFp0,subFi0,Delta_t,co,ip,el) result(broken)
call math_invert33(Fp_new,devNull,error,invFp_new) call math_invert33(Fp_new,devNull,error,invFp_new)
if (error) return ! error if (error) return ! error
constitutive_mech_P(ph)%data(1:3,1:3,me) = matmul(matmul(F,invFp_new),matmul(S,transpose(invFp_new))) phase_mechanical_P(ph)%data(1:3,1:3,me) = matmul(matmul(F,invFp_new),matmul(S,transpose(invFp_new)))
constitutive_mech_S(ph)%data(1:3,1:3,me) = S phase_mechanical_S(ph)%data(1:3,1:3,me) = S
constitutive_mech_Lp(ph)%data(1:3,1:3,me) = Lpguess phase_mechanical_Lp(ph)%data(1:3,1:3,me) = Lpguess
constitutive_mech_Li(ph)%data(1:3,1:3,me) = Liguess phase_mechanical_Li(ph)%data(1:3,1:3,me) = Liguess
constitutive_mech_Fp(ph)%data(1:3,1:3,me) = Fp_new / math_det33(Fp_new)**(1.0_pReal/3.0_pReal) ! regularize phase_mechanical_Fp(ph)%data(1:3,1:3,me) = Fp_new / math_det33(Fp_new)**(1.0_pReal/3.0_pReal) ! regularize
constitutive_mech_Fi(ph)%data(1:3,1:3,me) = Fi_new phase_mechanical_Fi(ph)%data(1:3,1:3,me) = Fi_new
constitutive_mech_Fe(ph)%data(1:3,1:3,me) = matmul(matmul(F,invFp_new),invFi_new) phase_mechanical_Fe(ph)%data(1:3,1:3,me) = matmul(matmul(F,invFp_new),invFi_new)
broken = .false. broken = .false.
end function integrateStress end function integrateStress
@ -668,9 +657,9 @@ function integrateStateFPI(F_0,F,subFp0,subFi0,subState0,Delta_t,co,ip,el) resul
sizeDotState sizeDotState
real(pReal) :: & real(pReal) :: &
zeta zeta
real(pReal), dimension(constitutive_plasticity_maxSizeDotState) :: & real(pReal), dimension(phase_plasticity_maxSizeDotState) :: &
r ! state residuum r ! state residuum
real(pReal), dimension(constitutive_plasticity_maxSizeDotState,2) :: & real(pReal), dimension(phase_plasticity_maxSizeDotState,2) :: &
dotState dotState
@ -706,7 +695,7 @@ function integrateStateFPI(F_0,F,subFp0,subFi0,subState0,Delta_t,co,ip,el) resul
plasticState(ph)%state(1:sizeDotState,me) = plasticState(ph)%state(1:sizeDotState,me) & plasticState(ph)%state(1:sizeDotState,me) = plasticState(ph)%state(1:sizeDotState,me) &
- r(1:sizeDotState) - r(1:sizeDotState)
if (converged(r(1:sizeDotState),plasticState(ph)%state(1:sizeDotState,me),plasticState(ph)%atol(1:sizeDotState))) then if (converged(r(1:sizeDotState),plasticState(ph)%state(1:sizeDotState,me),plasticState(ph)%atol(1:sizeDotState))) then
broken = plastic_deltaState(co,ip,el,ph,me) broken = plastic_deltaState(ph,me)
exit iteration exit iteration
endif endif
@ -769,7 +758,7 @@ function integrateStateEuler(F_0,F,subFp0,subFi0,subState0,Delta_t,co,ip,el) res
plasticState(ph)%state(1:sizeDotState,me) = subState0 & plasticState(ph)%state(1:sizeDotState,me) = subState0 &
+ plasticState(ph)%dotState(1:sizeDotState,me) * Delta_t + plasticState(ph)%dotState(1:sizeDotState,me) * Delta_t
broken = plastic_deltaState(co,ip,el,ph,me) broken = plastic_deltaState(ph,me)
if(broken) return if(broken) return
broken = integrateStress(F,subFp0,subFi0,Delta_t,co,ip,el) broken = integrateStress(F,subFp0,subFi0,Delta_t,co,ip,el)
@ -796,7 +785,7 @@ function integrateStateAdaptiveEuler(F_0,F,subFp0,subFi0,subState0,Delta_t,co,ip
ph, & ph, &
me, & me, &
sizeDotState sizeDotState
real(pReal), dimension(constitutive_plasticity_maxSizeDotState) :: residuum_plastic real(pReal), dimension(phase_plasticity_maxSizeDotState) :: residuum_plastic
ph = material_phaseAt(co,el) ph = material_phaseAt(co,el)
@ -811,7 +800,7 @@ function integrateStateAdaptiveEuler(F_0,F,subFp0,subFi0,subState0,Delta_t,co,ip
plasticState(ph)%state(1:sizeDotState,me) = subState0 & plasticState(ph)%state(1:sizeDotState,me) = subState0 &
+ plasticState(ph)%dotstate(1:sizeDotState,me) * Delta_t + plasticState(ph)%dotstate(1:sizeDotState,me) * Delta_t
broken = plastic_deltaState(co,ip,el,ph,me) broken = plastic_deltaState(ph,me)
if(broken) return if(broken) return
broken = integrateStress(F,subFp0,subFi0,Delta_t,co,ip,el) broken = integrateStress(F,subFp0,subFi0,Delta_t,co,ip,el)
@ -914,7 +903,7 @@ function integrateStateRK(F_0,F,subFp0,subFi0,subState0,Delta_t,co,ip,el,A,B,C,D
ph, & ph, &
me, & me, &
sizeDotState sizeDotState
real(pReal), dimension(constitutive_plasticity_maxSizeDotState,size(B)) :: plastic_RKdotState real(pReal), dimension(phase_plasticity_maxSizeDotState,size(B)) :: plastic_RKdotState
ph = material_phaseAt(co,el) ph = material_phaseAt(co,el)
@ -960,7 +949,7 @@ function integrateStateRK(F_0,F,subFp0,subFi0,subState0,Delta_t,co,ip,el,A,B,C,D
if(broken) return if(broken) return
broken = plastic_deltaState(co,ip,el,ph,me) broken = plastic_deltaState(ph,me)
if(broken) return if(broken) return
broken = integrateStress(F,subFp0,subFi0,Delta_t,co,ip,el) broken = integrateStress(F,subFp0,subFi0,Delta_t,co,ip,el)
@ -987,28 +976,28 @@ subroutine crystallite_results(group,ph)
select case (output_constituent(ph)%label(ou)) select case (output_constituent(ph)%label(ou))
case('F') case('F')
call results_writeDataset(group//'/mechanics/',constitutive_mech_F(ph)%data,'F',& call results_writeDataset(group//'/mechanics/',phase_mechanical_F(ph)%data,'F',&
'deformation gradient','1') 'deformation gradient','1')
case('F_e') case('F_e')
call results_writeDataset(group//'/mechanics/',constitutive_mech_Fe(ph)%data,'F_e',& call results_writeDataset(group//'/mechanics/',phase_mechanical_Fe(ph)%data,'F_e',&
'elastic deformation gradient','1') 'elastic deformation gradient','1')
case('F_p') case('F_p')
call results_writeDataset(group//'/mechanics/',constitutive_mech_Fp(ph)%data,'F_p', & call results_writeDataset(group//'/mechanics/',phase_mechanical_Fp(ph)%data,'F_p', &
'plastic deformation gradient','1') 'plastic deformation gradient','1')
case('F_i') case('F_i')
call results_writeDataset(group//'/mechanics/',constitutive_mech_Fi(ph)%data,'F_i', & call results_writeDataset(group//'/mechanics/',phase_mechanical_Fi(ph)%data,'F_i', &
'inelastic deformation gradient','1') 'inelastic deformation gradient','1')
case('L_p') case('L_p')
call results_writeDataset(group//'/mechanics/',constitutive_mech_Lp(ph)%data,'L_p', & call results_writeDataset(group//'/mechanics/',phase_mechanical_Lp(ph)%data,'L_p', &
'plastic velocity gradient','1/s') 'plastic velocity gradient','1/s')
case('L_i') case('L_i')
call results_writeDataset(group//'/mechanics/',constitutive_mech_Li(ph)%data,'L_i', & call results_writeDataset(group//'/mechanics/',phase_mechanical_Li(ph)%data,'L_i', &
'inelastic velocity gradient','1/s') 'inelastic velocity gradient','1/s')
case('P') case('P')
call results_writeDataset(group//'/mechanics/',constitutive_mech_P(ph)%data,'P', & call results_writeDataset(group//'/mechanics/',phase_mechanical_P(ph)%data,'P', &
'First Piola-Kirchhoff stress','Pa') 'First Piola-Kirchhoff stress','Pa')
case('S') case('S')
call results_writeDataset(group//'/mechanics/',constitutive_mech_S(ph)%data,'S', & call results_writeDataset(group//'/mechanics/',phase_mechanical_S(ph)%data,'S', &
'Second Piola-Kirchhoff stress','Pa') 'Second Piola-Kirchhoff stress','Pa')
case('O') case('O')
select case(lattice_structure(ph)) select case(lattice_structure(ph))
@ -1067,43 +1056,43 @@ end subroutine crystallite_results
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief Wind homog inc forward. !> @brief Wind homog inc forward.
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
module subroutine mech_windForward(ph,me) module subroutine mechanical_windForward(ph,me)
integer, intent(in) :: ph, me integer, intent(in) :: ph, me
constitutive_mech_Fp0(ph)%data(1:3,1:3,me) = constitutive_mech_Fp(ph)%data(1:3,1:3,me) phase_mechanical_Fp0(ph)%data(1:3,1:3,me) = phase_mechanical_Fp(ph)%data(1:3,1:3,me)
constitutive_mech_Fi0(ph)%data(1:3,1:3,me) = constitutive_mech_Fi(ph)%data(1:3,1:3,me) phase_mechanical_Fi0(ph)%data(1:3,1:3,me) = phase_mechanical_Fi(ph)%data(1:3,1:3,me)
constitutive_mech_F0(ph)%data(1:3,1:3,me) = constitutive_mech_F(ph)%data(1:3,1:3,me) phase_mechanical_F0(ph)%data(1:3,1:3,me) = phase_mechanical_F(ph)%data(1:3,1:3,me)
constitutive_mech_Li0(ph)%data(1:3,1:3,me) = constitutive_mech_Li(ph)%data(1:3,1:3,me) phase_mechanical_Li0(ph)%data(1:3,1:3,me) = phase_mechanical_Li(ph)%data(1:3,1:3,me)
constitutive_mech_Lp0(ph)%data(1:3,1:3,me) = constitutive_mech_Lp(ph)%data(1:3,1:3,me) phase_mechanical_Lp0(ph)%data(1:3,1:3,me) = phase_mechanical_Lp(ph)%data(1:3,1:3,me)
constitutive_mech_S0(ph)%data(1:3,1:3,me) = constitutive_mech_S(ph)%data(1:3,1:3,me) phase_mechanical_S0(ph)%data(1:3,1:3,me) = phase_mechanical_S(ph)%data(1:3,1:3,me)
plasticState(ph)%State0(:,me) = plasticState(ph)%state(:,me) plasticState(ph)%State0(:,me) = plasticState(ph)%state(:,me)
end subroutine mech_windForward end subroutine mechanical_windForward
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief Forward data after successful increment. !> @brief Forward data after successful increment.
! ToDo: Any guessing for the current states possible? ! ToDo: Any guessing for the current states possible?
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
module subroutine mech_forward() module subroutine mechanical_forward()
integer :: ph integer :: ph
do ph = 1, size(plasticState) do ph = 1, size(plasticState)
constitutive_mech_Fi0(ph) = constitutive_mech_Fi(ph) phase_mechanical_Fi0(ph) = phase_mechanical_Fi(ph)
constitutive_mech_Fp0(ph) = constitutive_mech_Fp(ph) phase_mechanical_Fp0(ph) = phase_mechanical_Fp(ph)
constitutive_mech_F0(ph) = constitutive_mech_F(ph) phase_mechanical_F0(ph) = phase_mechanical_F(ph)
constitutive_mech_Li0(ph) = constitutive_mech_Li(ph) phase_mechanical_Li0(ph) = phase_mechanical_Li(ph)
constitutive_mech_Lp0(ph) = constitutive_mech_Lp(ph) phase_mechanical_Lp0(ph) = phase_mechanical_Lp(ph)
constitutive_mech_S0(ph) = constitutive_mech_S(ph) phase_mechanical_S0(ph) = phase_mechanical_S(ph)
plasticState(ph)%state0 = plasticState(ph)%state plasticState(ph)%state0 = plasticState(ph)%state
enddo enddo
end subroutine mech_forward end subroutine mechanical_forward
@ -1111,19 +1100,19 @@ end subroutine mech_forward
!> @brief returns the homogenize elasticity matrix !> @brief returns the homogenize elasticity matrix
!> ToDo: homogenizedC66 would be more consistent !> ToDo: homogenizedC66 would be more consistent
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
module function constitutive_homogenizedC(ph,me) result(C) module function phase_homogenizedC(ph,me) result(C)
real(pReal), dimension(6,6) :: C real(pReal), dimension(6,6) :: C
integer, intent(in) :: ph, me integer, intent(in) :: ph, me
plasticityType: select case (phase_plasticity(ph)) plasticType: select case (phase_plasticity(ph))
case (PLASTICITY_DISLOTWIN_ID) plasticityType case (PLASTICITY_DISLOTWIN_ID) plasticType
C = plastic_dislotwin_homogenizedC(ph,me) C = plastic_dislotwin_homogenizedC(ph,me)
case default plasticityType case default plasticType
C = lattice_C66(1:6,1:6,ph) C = lattice_C66(1:6,1:6,ph)
end select plasticityType end select plasticType
end function constitutive_homogenizedC end function phase_homogenizedC
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
@ -1141,7 +1130,7 @@ module function crystallite_stress(dt,co,ip,el) result(converged_)
real(pReal) :: & real(pReal) :: &
formerSubStep formerSubStep
integer :: & integer :: &
so, ph, me, sizeDotState ph, me, sizeDotState
logical :: todo logical :: todo
real(pReal) :: subFrac,subStep real(pReal) :: subFrac,subStep
real(pReal), dimension(3,3) :: & real(pReal), dimension(3,3) :: &
@ -1158,17 +1147,16 @@ module function crystallite_stress(dt,co,ip,el) result(converged_)
me = material_phaseMemberAt(co,ip,el) me = material_phaseMemberAt(co,ip,el)
sizeDotState = plasticState(ph)%sizeDotState sizeDotState = plasticState(ph)%sizeDotState
subLi0 = constitutive_mech_Li0(ph)%data(1:3,1:3,me) subLi0 = phase_mechanical_Li0(ph)%data(1:3,1:3,me)
subLp0 = constitutive_mech_Lp0(ph)%data(1:3,1:3,me) subLp0 = phase_mechanical_Lp0(ph)%data(1:3,1:3,me)
subState0 = plasticState(ph)%State0(:,me) subState0 = plasticState(ph)%State0(:,me)
if (damageState(ph)%sizeState > 0) &
damageState(ph)%subState0(:,me) = damageState(ph)%state0(:,me)
do so = 1, phase_Nsources(ph) subFp0 = phase_mechanical_Fp0(ph)%data(1:3,1:3,me)
damageState(ph)%p(so)%subState0(:,me) = damageState(ph)%p(so)%state0(:,me) subFi0 = phase_mechanical_Fi0(ph)%data(1:3,1:3,me)
enddo subF0 = phase_mechanical_F0(ph)%data(1:3,1:3,me)
subFp0 = constitutive_mech_Fp0(ph)%data(1:3,1:3,me)
subFi0 = constitutive_mech_Fi0(ph)%data(1:3,1:3,me)
subF0 = constitutive_mech_F0(ph)%data(1:3,1:3,me)
subFrac = 0.0_pReal subFrac = 0.0_pReal
subStep = 1.0_pReal/num%subStepSizeCryst subStep = 1.0_pReal/num%subStepSizeCryst
todo = .true. todo = .true.
@ -1186,30 +1174,29 @@ module function crystallite_stress(dt,co,ip,el) result(converged_)
if (todo) then if (todo) then
subF0 = subF subF0 = subF
subLp0 = constitutive_mech_Lp(ph)%data(1:3,1:3,me) subLp0 = phase_mechanical_Lp(ph)%data(1:3,1:3,me)
subLi0 = constitutive_mech_Li(ph)%data(1:3,1:3,me) subLi0 = phase_mechanical_Li(ph)%data(1:3,1:3,me)
subFp0 = constitutive_mech_Fp(ph)%data(1:3,1:3,me) subFp0 = phase_mechanical_Fp(ph)%data(1:3,1:3,me)
subFi0 = constitutive_mech_Fi(ph)%data(1:3,1:3,me) subFi0 = phase_mechanical_Fi(ph)%data(1:3,1:3,me)
subState0 = plasticState(ph)%state(:,me) subState0 = plasticState(ph)%state(:,me)
do so = 1, phase_Nsources(ph) if (damageState(ph)%sizeState > 0) &
damageState(ph)%p(so)%subState0(:,me) = damageState(ph)%p(so)%state(:,me) damageState(ph)%subState0(:,me) = damageState(ph)%state(:,me)
enddo
endif endif
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
! cut back (reduced time and restore) ! cut back (reduced time and restore)
else else
subStep = num%subStepSizeCryst * subStep subStep = num%subStepSizeCryst * subStep
constitutive_mech_Fp(ph)%data(1:3,1:3,me) = subFp0 phase_mechanical_Fp(ph)%data(1:3,1:3,me) = subFp0
constitutive_mech_Fi(ph)%data(1:3,1:3,me) = subFi0 phase_mechanical_Fi(ph)%data(1:3,1:3,me) = subFi0
constitutive_mech_S(ph)%data(1:3,1:3,me) = constitutive_mech_S0(ph)%data(1:3,1:3,me) ! why no subS0 ? is S0 of any use? phase_mechanical_S(ph)%data(1:3,1:3,me) = phase_mechanical_S0(ph)%data(1:3,1:3,me) ! why no subS0 ? is S0 of any use?
if (subStep < 1.0_pReal) then ! actual (not initial) cutback if (subStep < 1.0_pReal) then ! actual (not initial) cutback
constitutive_mech_Lp(ph)%data(1:3,1:3,me) = subLp0 phase_mechanical_Lp(ph)%data(1:3,1:3,me) = subLp0
constitutive_mech_Li(ph)%data(1:3,1:3,me) = subLi0 phase_mechanical_Li(ph)%data(1:3,1:3,me) = subLi0
endif endif
plasticState(ph)%state(:,me) = subState0 plasticState(ph)%state(:,me) = subState0
do so = 1, phase_Nsources(ph) if (damageState(ph)%sizeState > 0) &
damageState(ph)%p(so)%state(:,me) = damageState(ph)%p(so)%subState0(:,me) damageState(ph)%state(:,me) = damageState(ph)%subState0(:,me)
enddo
todo = subStep > num%subStepMinCryst ! still on track or already done (beyond repair) todo = subStep > num%subStepMinCryst ! still on track or already done (beyond repair)
endif endif
@ -1218,9 +1205,9 @@ module function crystallite_stress(dt,co,ip,el) result(converged_)
! prepare for integration ! prepare for integration
if (todo) then if (todo) then
subF = subF0 & subF = subF0 &
+ subStep * (constitutive_mech_F(ph)%data(1:3,1:3,me) - constitutive_mech_F0(ph)%data(1:3,1:3,me)) + subStep * (phase_mechanical_F(ph)%data(1:3,1:3,me) - phase_mechanical_F0(ph)%data(1:3,1:3,me))
constitutive_mech_Fe(ph)%data(1:3,1:3,me) = matmul(subF,math_inv33(matmul(constitutive_mech_Fi(ph)%data(1:3,1:3,me), & phase_mechanical_Fe(ph)%data(1:3,1:3,me) = matmul(subF,math_inv33(matmul(phase_mechanical_Fi(ph)%data(1:3,1:3,me), &
constitutive_mech_Fp(ph)%data(1:3,1:3,me)))) phase_mechanical_Fp(ph)%data(1:3,1:3,me))))
converged_ = .not. integrateState(subF0,subF,subFp0,subFi0,subState0(1:sizeDotState),subStep * dt,co,ip,el) converged_ = .not. integrateState(subF0,subF,subFp0,subFi0,subState0(1:sizeDotState),subStep * dt,co,ip,el)
converged_ = converged_ .and. .not. integrateDamageState(subStep * dt,co,ip,el) converged_ = converged_ .and. .not. integrateDamageState(subStep * dt,co,ip,el)
endif endif
@ -1233,7 +1220,7 @@ end function crystallite_stress
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief Restore data after homog cutback. !> @brief Restore data after homog cutback.
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
module subroutine mech_restore(ce,includeL) module subroutine mechanical_restore(ce,includeL)
integer, intent(in) :: ce integer, intent(in) :: ce
logical, intent(in) :: & logical, intent(in) :: &
@ -1247,23 +1234,23 @@ module subroutine mech_restore(ce,includeL)
ph = material_phaseAt2(co,ce) ph = material_phaseAt2(co,ce)
me = material_phaseMemberAt2(co,ce) me = material_phaseMemberAt2(co,ce)
if (includeL) then if (includeL) then
constitutive_mech_Lp(ph)%data(1:3,1:3,me) = constitutive_mech_Lp0(ph)%data(1:3,1:3,me) phase_mechanical_Lp(ph)%data(1:3,1:3,me) = phase_mechanical_Lp0(ph)%data(1:3,1:3,me)
constitutive_mech_Li(ph)%data(1:3,1:3,me) = constitutive_mech_Li0(ph)%data(1:3,1:3,me) phase_mechanical_Li(ph)%data(1:3,1:3,me) = phase_mechanical_Li0(ph)%data(1:3,1:3,me)
endif ! maybe protecting everything from overwriting makes more sense endif ! maybe protecting everything from overwriting makes more sense
constitutive_mech_Fp(ph)%data(1:3,1:3,me) = constitutive_mech_Fp0(ph)%data(1:3,1:3,me) phase_mechanical_Fp(ph)%data(1:3,1:3,me) = phase_mechanical_Fp0(ph)%data(1:3,1:3,me)
constitutive_mech_Fi(ph)%data(1:3,1:3,me) = constitutive_mech_Fi0(ph)%data(1:3,1:3,me) phase_mechanical_Fi(ph)%data(1:3,1:3,me) = phase_mechanical_Fi0(ph)%data(1:3,1:3,me)
constitutive_mech_S(ph)%data(1:3,1:3,me) = constitutive_mech_S0(ph)%data(1:3,1:3,me) phase_mechanical_S(ph)%data(1:3,1:3,me) = phase_mechanical_S0(ph)%data(1:3,1:3,me)
plasticState(ph)%state(:,me) = plasticState(ph)%State0(:,me) plasticState(ph)%state(:,me) = plasticState(ph)%State0(:,me)
enddo enddo
end subroutine mech_restore end subroutine mechanical_restore
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief Calculate tangent (dPdF). !> @brief Calculate tangent (dPdF).
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
module function constitutive_mech_dPdF(dt,co,ip,el) result(dPdF) module function phase_mechanical_dPdF(dt,co,ip,el) result(dPdF)
real(pReal), intent(in) :: dt real(pReal), intent(in) :: dt
integer, intent(in) :: & integer, intent(in) :: &
@ -1297,18 +1284,18 @@ module function constitutive_mech_dPdF(dt,co,ip,el) result(dPdF)
ph = material_phaseAt(co,el) ph = material_phaseAt(co,el)
me = material_phaseMemberAt(co,ip,el) me = material_phaseMemberAt(co,ip,el)
call constitutive_hooke_SandItsTangents(devNull,dSdFe,dSdFi, & call phase_hooke_SandItsTangents(devNull,dSdFe,dSdFi, &
constitutive_mech_Fe(ph)%data(1:3,1:3,me), & phase_mechanical_Fe(ph)%data(1:3,1:3,me), &
constitutive_mech_Fi(ph)%data(1:3,1:3,me),co,ip,el) phase_mechanical_Fi(ph)%data(1:3,1:3,me),co,ip,el)
call constitutive_LiAndItsTangents(devNull,dLidS,dLidFi, & call phase_LiAndItsTangents(devNull,dLidS,dLidFi, &
constitutive_mech_S(ph)%data(1:3,1:3,me), & phase_mechanical_S(ph)%data(1:3,1:3,me), &
constitutive_mech_Fi(ph)%data(1:3,1:3,me), & phase_mechanical_Fi(ph)%data(1:3,1:3,me), &
co,ip,el) ph,me)
invFp = math_inv33(constitutive_mech_Fp(ph)%data(1:3,1:3,me)) invFp = math_inv33(phase_mechanical_Fp(ph)%data(1:3,1:3,me))
invFi = math_inv33(constitutive_mech_Fi(ph)%data(1:3,1:3,me)) invFi = math_inv33(phase_mechanical_Fi(ph)%data(1:3,1:3,me))
invSubFp0 = math_inv33(constitutive_mech_Fp0(ph)%data(1:3,1:3,me)) invSubFp0 = math_inv33(phase_mechanical_Fp0(ph)%data(1:3,1:3,me))
invSubFi0 = math_inv33(constitutive_mech_Fi0(ph)%data(1:3,1:3,me)) invSubFi0 = math_inv33(phase_mechanical_Fi0(ph)%data(1:3,1:3,me))
if (sum(abs(dLidS)) < tol_math_check) then if (sum(abs(dLidS)) < tol_math_check) then
dFidS = 0.0_pReal dFidS = 0.0_pReal
@ -1334,15 +1321,15 @@ module function constitutive_mech_dPdF(dt,co,ip,el) result(dPdF)
endif endif
call plastic_LpAndItsTangents(devNull,dLpdS,dLpdFi, & call plastic_LpAndItsTangents(devNull,dLpdS,dLpdFi, &
constitutive_mech_S(ph)%data(1:3,1:3,me), & phase_mechanical_S(ph)%data(1:3,1:3,me), &
constitutive_mech_Fi(ph)%data(1:3,1:3,me),co,ip,el) phase_mechanical_Fi(ph)%data(1:3,1:3,me),ph,me)
dLpdS = math_mul3333xx3333(dLpdFi,dFidS) + dLpdS dLpdS = math_mul3333xx3333(dLpdFi,dFidS) + dLpdS
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
! calculate dSdF ! calculate dSdF
temp_33_1 = transpose(matmul(invFp,invFi)) temp_33_1 = transpose(matmul(invFp,invFi))
temp_33_2 = matmul(constitutive_mech_F(ph)%data(1:3,1:3,me),invSubFp0) temp_33_2 = matmul(phase_mechanical_F(ph)%data(1:3,1:3,me),invSubFp0)
temp_33_3 = matmul(matmul(constitutive_mech_F(ph)%data(1:3,1:3,me),invFp), invSubFi0) temp_33_3 = matmul(matmul(phase_mechanical_F(ph)%data(1:3,1:3,me),invFp), invSubFi0)
do o=1,3; do p=1,3 do o=1,3; do p=1,3
rhs_3333(p,o,1:3,1:3) = matmul(dSdFe(p,o,1:3,1:3),temp_33_1) rhs_3333(p,o,1:3,1:3) = matmul(dSdFe(p,o,1:3,1:3),temp_33_1)
@ -1370,9 +1357,9 @@ module function constitutive_mech_dPdF(dt,co,ip,el) result(dPdF)
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
! assemble dPdF ! assemble dPdF
temp_33_1 = matmul(constitutive_mech_S(ph)%data(1:3,1:3,me),transpose(invFp)) temp_33_1 = matmul(phase_mechanical_S(ph)%data(1:3,1:3,me),transpose(invFp))
temp_33_2 = matmul(constitutive_mech_F(ph)%data(1:3,1:3,me),invFp) temp_33_2 = matmul(phase_mechanical_F(ph)%data(1:3,1:3,me),invFp)
temp_33_3 = matmul(temp_33_2,constitutive_mech_S(ph)%data(1:3,1:3,me)) temp_33_3 = matmul(temp_33_2,phase_mechanical_S(ph)%data(1:3,1:3,me))
dPdF = 0.0_pReal dPdF = 0.0_pReal
do p=1,3 do p=1,3
@ -1380,129 +1367,129 @@ module function constitutive_mech_dPdF(dt,co,ip,el) result(dPdF)
enddo enddo
do o=1,3; do p=1,3 do o=1,3; do p=1,3
dPdF(1:3,1:3,p,o) = dPdF(1:3,1:3,p,o) & dPdF(1:3,1:3,p,o) = dPdF(1:3,1:3,p,o) &
+ matmul(matmul(constitutive_mech_F(ph)%data(1:3,1:3,me),dFpinvdF(1:3,1:3,p,o)),temp_33_1) & + matmul(matmul(phase_mechanical_F(ph)%data(1:3,1:3,me),dFpinvdF(1:3,1:3,p,o)),temp_33_1) &
+ matmul(matmul(temp_33_2,dSdF(1:3,1:3,p,o)),transpose(invFp)) & + matmul(matmul(temp_33_2,dSdF(1:3,1:3,p,o)),transpose(invFp)) &
+ matmul(temp_33_3,transpose(dFpinvdF(1:3,1:3,p,o))) + matmul(temp_33_3,transpose(dFpinvdF(1:3,1:3,p,o)))
enddo; enddo enddo; enddo
end function constitutive_mech_dPdF end function phase_mechanical_dPdF
module subroutine mech_restartWrite(groupHandle,ph) module subroutine mechanical_restartWrite(groupHandle,ph)
integer(HID_T), intent(in) :: groupHandle integer(HID_T), intent(in) :: groupHandle
integer, intent(in) :: ph integer, intent(in) :: ph
call HDF5_write(groupHandle,plasticState(ph)%state,'omega') call HDF5_write(groupHandle,plasticState(ph)%state,'omega')
call HDF5_write(groupHandle,constitutive_mech_Fi(ph)%data,'F_i') call HDF5_write(groupHandle,phase_mechanical_Fi(ph)%data,'F_i')
call HDF5_write(groupHandle,constitutive_mech_Li(ph)%data,'L_i') call HDF5_write(groupHandle,phase_mechanical_Li(ph)%data,'L_i')
call HDF5_write(groupHandle,constitutive_mech_Lp(ph)%data,'L_p') call HDF5_write(groupHandle,phase_mechanical_Lp(ph)%data,'L_p')
call HDF5_write(groupHandle,constitutive_mech_Fp(ph)%data,'F_p') call HDF5_write(groupHandle,phase_mechanical_Fp(ph)%data,'F_p')
call HDF5_write(groupHandle,constitutive_mech_S(ph)%data,'S') call HDF5_write(groupHandle,phase_mechanical_S(ph)%data,'S')
call HDF5_write(groupHandle,constitutive_mech_F(ph)%data,'F') call HDF5_write(groupHandle,phase_mechanical_F(ph)%data,'F')
end subroutine mech_restartWrite end subroutine mechanical_restartWrite
module subroutine mech_restartRead(groupHandle,ph) module subroutine mechanical_restartRead(groupHandle,ph)
integer(HID_T), intent(in) :: groupHandle integer(HID_T), intent(in) :: groupHandle
integer, intent(in) :: ph integer, intent(in) :: ph
call HDF5_read(groupHandle,plasticState(ph)%state0,'omega') call HDF5_read(groupHandle,plasticState(ph)%state0,'omega')
call HDF5_read(groupHandle,constitutive_mech_Fi0(ph)%data,'F_i') call HDF5_read(groupHandle,phase_mechanical_Fi0(ph)%data,'F_i')
call HDF5_read(groupHandle,constitutive_mech_Li0(ph)%data,'L_i') call HDF5_read(groupHandle,phase_mechanical_Li0(ph)%data,'L_i')
call HDF5_read(groupHandle,constitutive_mech_Lp0(ph)%data,'L_p') call HDF5_read(groupHandle,phase_mechanical_Lp0(ph)%data,'L_p')
call HDF5_read(groupHandle,constitutive_mech_Fp0(ph)%data,'F_p') call HDF5_read(groupHandle,phase_mechanical_Fp0(ph)%data,'F_p')
call HDF5_read(groupHandle,constitutive_mech_S0(ph)%data,'S') call HDF5_read(groupHandle,phase_mechanical_S0(ph)%data,'S')
call HDF5_read(groupHandle,constitutive_mech_F0(ph)%data,'F') call HDF5_read(groupHandle,phase_mechanical_F0(ph)%data,'F')
end subroutine mech_restartRead end subroutine mechanical_restartRead
!---------------------------------------------------------------------------------------------- !----------------------------------------------------------------------------------------------
!< @brief Get first Piola-Kichhoff stress (for use by non-mech physics) !< @brief Get first Piola-Kichhoff stress (for use by non-mech physics)
!---------------------------------------------------------------------------------------------- !----------------------------------------------------------------------------------------------
module function mech_S(ph,me) result(S) module function mechanical_S(ph,me) result(S)
integer, intent(in) :: ph,me integer, intent(in) :: ph,me
real(pReal), dimension(3,3) :: S real(pReal), dimension(3,3) :: S
S = constitutive_mech_S(ph)%data(1:3,1:3,me) S = phase_mechanical_S(ph)%data(1:3,1:3,me)
end function mech_S end function mechanical_S
!---------------------------------------------------------------------------------------------- !----------------------------------------------------------------------------------------------
!< @brief Get plastic velocity gradient (for use by non-mech physics) !< @brief Get plastic velocity gradient (for use by non-mech physics)
!---------------------------------------------------------------------------------------------- !----------------------------------------------------------------------------------------------
module function mech_L_p(ph,me) result(L_p) module function mechanical_L_p(ph,me) result(L_p)
integer, intent(in) :: ph,me integer, intent(in) :: ph,me
real(pReal), dimension(3,3) :: L_p real(pReal), dimension(3,3) :: L_p
L_p = constitutive_mech_Lp(ph)%data(1:3,1:3,me) L_p = phase_mechanical_Lp(ph)%data(1:3,1:3,me)
end function mech_L_p end function mechanical_L_p
!---------------------------------------------------------------------------------------------- !----------------------------------------------------------------------------------------------
!< @brief Get deformation gradient (for use by homogenization) !< @brief Get deformation gradient (for use by homogenization)
!---------------------------------------------------------------------------------------------- !----------------------------------------------------------------------------------------------
module function constitutive_mech_getF(co,ip,el) result(F) module function phase_mechanical_getF(co,ip,el) result(F)
integer, intent(in) :: co, ip, el integer, intent(in) :: co, ip, el
real(pReal), dimension(3,3) :: F real(pReal), dimension(3,3) :: F
F = constitutive_mech_F(material_phaseAt(co,el))%data(1:3,1:3,material_phaseMemberAt(co,ip,el)) F = phase_mechanical_F(material_phaseAt(co,el))%data(1:3,1:3,material_phaseMemberAt(co,ip,el))
end function constitutive_mech_getF end function phase_mechanical_getF
!---------------------------------------------------------------------------------------------- !----------------------------------------------------------------------------------------------
!< @brief Get elastic deformation gradient (for use by non-mech physics) !< @brief Get elastic deformation gradient (for use by non-mech physics)
!---------------------------------------------------------------------------------------------- !----------------------------------------------------------------------------------------------
module function mech_F_e(ph,me) result(F_e) module function mechanical_F_e(ph,me) result(F_e)
integer, intent(in) :: ph,me integer, intent(in) :: ph,me
real(pReal), dimension(3,3) :: F_e real(pReal), dimension(3,3) :: F_e
F_e = constitutive_mech_Fe(ph)%data(1:3,1:3,me) F_e = phase_mechanical_Fe(ph)%data(1:3,1:3,me)
end function mech_F_e end function mechanical_F_e
!---------------------------------------------------------------------------------------------- !----------------------------------------------------------------------------------------------
!< @brief Get second Piola-Kichhoff stress (for use by homogenization) !< @brief Get second Piola-Kichhoff stress (for use by homogenization)
!---------------------------------------------------------------------------------------------- !----------------------------------------------------------------------------------------------
module function constitutive_mech_getP(co,ip,el) result(P) module function phase_mechanical_getP(co,ip,el) result(P)
integer, intent(in) :: co, ip, el integer, intent(in) :: co, ip, el
real(pReal), dimension(3,3) :: P real(pReal), dimension(3,3) :: P
P = constitutive_mech_P(material_phaseAt(co,el))%data(1:3,1:3,material_phaseMemberAt(co,ip,el)) P = phase_mechanical_P(material_phaseAt(co,el))%data(1:3,1:3,material_phaseMemberAt(co,ip,el))
end function constitutive_mech_getP end function phase_mechanical_getP
! setter for homogenization ! setter for homogenization
module subroutine constitutive_mech_setF(F,co,ip,el) module subroutine phase_mechanical_setF(F,co,ip,el)
real(pReal), dimension(3,3), intent(in) :: F real(pReal), dimension(3,3), intent(in) :: F
integer, intent(in) :: co, ip, el integer, intent(in) :: co, ip, el
constitutive_mech_F(material_phaseAt(co,el))%data(1:3,1:3,material_phaseMemberAt(co,ip,el)) = F phase_mechanical_F(material_phaseAt(co,el))%data(1:3,1:3,material_phaseMemberAt(co,ip,el)) = F
end subroutine constitutive_mech_setF end subroutine phase_mechanical_setF
end submodule mechanics end submodule mechanical

View File

@ -0,0 +1,228 @@
submodule(phase:mechanical) eigen
integer, dimension(:), allocatable :: &
Nmodels
integer(kind(KINEMATICS_UNDEFINED_ID)), dimension(:,:), allocatable :: &
model
integer(kind(KINEMATICS_UNDEFINED_ID)), dimension(:), allocatable :: &
model_damage
interface
module function kinematics_cleavage_opening_init() result(myKinematics)
logical, dimension(:), allocatable :: myKinematics
end function kinematics_cleavage_opening_init
module function kinematics_slipplane_opening_init() result(myKinematics)
logical, dimension(:), allocatable :: myKinematics
end function kinematics_slipplane_opening_init
module function thermalexpansion_init(kinematics_length) result(myKinematics)
integer, intent(in) :: kinematics_length
logical, dimension(:,:), allocatable :: myKinematics
end function thermalexpansion_init
module subroutine thermalexpansion_LiAndItsTangent(Li, dLi_dTstar, ph,me)
integer, intent(in) :: ph, me
real(pReal), intent(out), dimension(3,3) :: &
Li !< thermal velocity gradient
real(pReal), intent(out), dimension(3,3,3,3) :: &
dLi_dTstar !< derivative of Li with respect to Tstar (4th-order tensor defined to be zero)
end subroutine thermalexpansion_LiAndItsTangent
end interface
contains
module subroutine eigendeformation_init(phases)
class(tNode), pointer :: &
phases
integer :: &
ph
class(tNode), pointer :: &
phase, &
kinematics, &
damage, &
mechanics
print'(/,a)', ' <<<+- phase:mechanical:eigen init -+>>>'
!--------------------------------------------------------------------------------------------------
! explicit eigen mechanisms
allocate(Nmodels(phases%length),source = 0)
do ph = 1,phases%length
phase => phases%get(ph)
mechanics => phase%get('mechanics')
kinematics => mechanics%get('eigen',defaultVal=emptyList)
Nmodels(ph) = kinematics%length
enddo
allocate(model(maxval(Nmodels),phases%length), source = KINEMATICS_undefined_ID)
if(maxval(Nmodels) /= 0) then
where(thermalexpansion_init(maxval(Nmodels))) model = KINEMATICS_thermal_expansion_ID
endif
allocate(model_damage(phases%length), source = KINEMATICS_UNDEFINED_ID)
where(kinematics_cleavage_opening_init()) model_damage = KINEMATICS_cleavage_opening_ID
where(kinematics_slipplane_opening_init()) model_damage = KINEMATICS_slipplane_opening_ID
end subroutine eigendeformation_init
!--------------------------------------------------------------------------------------------------
!> @brief checks if a kinematic mechanism is active or not
!--------------------------------------------------------------------------------------------------
function kinematics_active(kinematics_label,kinematics_length) result(active_kinematics)
character(len=*), intent(in) :: kinematics_label !< name of kinematic mechanism
integer, intent(in) :: kinematics_length !< max. number of kinematics in system
logical, dimension(:,:), allocatable :: active_kinematics
class(tNode), pointer :: &
phases, &
phase, &
kinematics, &
kinematics_type, &
mechanics
integer :: p,k
phases => config_material%get('phase')
allocate(active_kinematics(kinematics_length,phases%length), source = .false. )
do p = 1, phases%length
phase => phases%get(p)
mechanics => phase%get('mechanics')
kinematics => mechanics%get('eigen',defaultVal=emptyList)
do k = 1, kinematics%length
kinematics_type => kinematics%get(k)
active_kinematics(k,p) = kinematics_type%get_asString('type') == kinematics_label
enddo
enddo
end function kinematics_active
!--------------------------------------------------------------------------------------------------
!> @brief checks if a kinematic mechanism is active or not
!--------------------------------------------------------------------------------------------------
function kinematics_active2(kinematics_label) result(active_kinematics)
character(len=*), intent(in) :: kinematics_label !< name of kinematic mechanism
logical, dimension(:), allocatable :: active_kinematics
class(tNode), pointer :: &
phases, &
phase, &
kinematics, &
kinematics_type
integer :: p
phases => config_material%get('phase')
allocate(active_kinematics(phases%length), source = .false. )
do p = 1, phases%length
phase => phases%get(p)
kinematics => phase%get('damage',defaultVal=emptyList)
if(kinematics%length < 1) return
kinematics_type => kinematics%get(1)
if (.not. kinematics_type%contains('type')) continue
active_kinematics(p) = kinematics_type%get_asString('type',defaultVal='n/a') == kinematics_label
enddo
end function kinematics_active2
!--------------------------------------------------------------------------------------------------
!> @brief contains the constitutive equation for calculating the velocity gradient
! ToDo: MD: S is Mi?
!--------------------------------------------------------------------------------------------------
module subroutine phase_LiAndItsTangents(Li, dLi_dS, dLi_dFi, &
S, Fi, ph,me)
integer, intent(in) :: &
ph,me
real(pReal), intent(in), dimension(3,3) :: &
S !< 2nd Piola-Kirchhoff stress
real(pReal), intent(in), dimension(3,3) :: &
Fi !< intermediate deformation gradient
real(pReal), intent(out), dimension(3,3) :: &
Li !< intermediate velocity gradient
real(pReal), intent(out), dimension(3,3,3,3) :: &
dLi_dS, & !< derivative of Li with respect to S
dLi_dFi
real(pReal), dimension(3,3) :: &
my_Li, & !< intermediate velocity gradient
FiInv, &
temp_33
real(pReal), dimension(3,3,3,3) :: &
my_dLi_dS
real(pReal) :: &
detFi
integer :: &
k, i, j
logical :: active
active = .false.
Li = 0.0_pReal
dLi_dS = 0.0_pReal
dLi_dFi = 0.0_pReal
plasticType: select case (phase_plasticity(ph))
case (PLASTICITY_isotropic_ID) plasticType
call plastic_isotropic_LiAndItsTangent(my_Li, my_dLi_dS, S ,ph,me)
Li = Li + my_Li
dLi_dS = dLi_dS + my_dLi_dS
active = .true.
end select plasticType
KinematicsLoop: do k = 1, Nmodels(ph)
kinematicsType: select case (model(k,ph))
case (KINEMATICS_thermal_expansion_ID) kinematicsType
call thermalexpansion_LiAndItsTangent(my_Li, my_dLi_dS, ph,me)
Li = Li + my_Li
dLi_dS = dLi_dS + my_dLi_dS
active = .true.
end select kinematicsType
enddo KinematicsLoop
select case (model_damage(ph))
case (KINEMATICS_cleavage_opening_ID)
call kinematics_cleavage_opening_LiAndItsTangent(my_Li, my_dLi_dS, S, ph, me)
Li = Li + my_Li
dLi_dS = dLi_dS + my_dLi_dS
active = .true.
case (KINEMATICS_slipplane_opening_ID)
call kinematics_slipplane_opening_LiAndItsTangent(my_Li, my_dLi_dS, S, ph, me)
Li = Li + my_Li
dLi_dS = dLi_dS + my_dLi_dS
active = .true.
end select
if(.not. active) return
FiInv = math_inv33(Fi)
detFi = math_det33(Fi)
Li = matmul(matmul(Fi,Li),FiInv)*detFi !< push forward to intermediate configuration
temp_33 = matmul(FiInv,Li)
do i = 1,3; do j = 1,3
dLi_dS(1:3,1:3,i,j) = matmul(matmul(Fi,dLi_dS(1:3,1:3,i,j)),FiInv)*detFi
dLi_dFi(1:3,1:3,i,j) = dLi_dFi(1:3,1:3,i,j) + Li*FiInv(j,i)
dLi_dFi(1:3,i,1:3,j) = dLi_dFi(1:3,i,1:3,j) + math_I3*temp_33(j,i) + Li*FiInv(j,i)
enddo; enddo
end subroutine phase_LiAndItsTangents
end submodule eigen

View File

@ -0,0 +1,32 @@
!--------------------------------------------------------------------------------------------------
!> @author Luv Sharma, Max-Planck-Institut für Eisenforschung GmbH
!> @author Pratheek Shanthraj, Max-Planck-Institut für Eisenforschung GmbH
!> @brief material subroutine incorporating kinematics resulting from opening of cleavage planes
!> @details to be done
!--------------------------------------------------------------------------------------------------
submodule(phase:eigen) cleavageopening
contains
!--------------------------------------------------------------------------------------------------
!> @brief module initialization
!> @details reads in material parameters, allocates arrays, and does sanity checks
!--------------------------------------------------------------------------------------------------
module function kinematics_cleavage_opening_init() result(myKinematics)
logical, dimension(:), allocatable :: myKinematics
myKinematics = kinematics_active2('anisobrittle')
if(count(myKinematics) == 0) return
print'(/,a)', ' <<<+- phase:mechanical:eigen:cleavageopening init -+>>>'
print'(a,i2)', ' # phases: ',count(myKinematics); flush(IO_STDOUT)
end function kinematics_cleavage_opening_init
end submodule cleavageopening

View File

@ -4,7 +4,7 @@
!> @brief material subroutine incorporating kinematics resulting from opening of slip planes !> @brief material subroutine incorporating kinematics resulting from opening of slip planes
!> @details to be done !> @details to be done
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
submodule(phase:eigendeformation) slipplaneopening submodule(phase:eigen) slipplaneopening
integer, dimension(:), allocatable :: kinematics_slipplane_opening_instance integer, dimension(:), allocatable :: kinematics_slipplane_opening_instance
@ -32,12 +32,11 @@ contains
!> @brief module initialization !> @brief module initialization
!> @details reads in material parameters, allocates arrays, and does sanity checks !> @details reads in material parameters, allocates arrays, and does sanity checks
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
module function kinematics_slipplane_opening_init(kinematics_length) result(myKinematics) module function kinematics_slipplane_opening_init() result(myKinematics)
integer, intent(in) :: kinematics_length logical, dimension(:), allocatable :: myKinematics
logical, dimension(:,:), allocatable :: myKinematics
integer :: Ninstances,p,i,k integer :: p,i
character(len=pStringLen) :: extmsg = '' character(len=pStringLen) :: extmsg = ''
integer, dimension(:), allocatable :: N_sl integer, dimension(:), allocatable :: N_sl
real(pReal), dimension(:,:), allocatable :: d,n,t real(pReal), dimension(:,:), allocatable :: d,n,t
@ -49,28 +48,26 @@ module function kinematics_slipplane_opening_init(kinematics_length) result(myKi
kinematics, & kinematics, &
kinematic_type kinematic_type
print'(/,a)', ' <<<+- phase:mechanics:eigendeformation:slipplaneopening init -+>>>'
myKinematics = kinematics_active('slipplane_opening',kinematics_length) myKinematics = kinematics_active2('isoductile')
Ninstances = count(myKinematics) if(count(myKinematics) == 0) return
print'(a,i2)', ' # instances: ',Ninstances; flush(IO_STDOUT) print'(/,a)', ' <<<+- phase:mechanical:eigen:slipplaneopening init -+>>>'
if(Ninstances == 0) return print'(a,i2)', ' # phases: ',count(myKinematics); flush(IO_STDOUT)
phases => config_material%get('phase') phases => config_material%get('phase')
allocate(kinematics_slipplane_opening_instance(phases%length), source=0) allocate(param(phases%length))
allocate(param(Ninstances))
do p = 1, phases%length do p = 1, phases%length
if(any(myKinematics(:,p))) kinematics_slipplane_opening_instance(p) = count(myKinematics(:,1:p)) if(myKinematics(p)) then
phase => phases%get(p) phase => phases%get(p)
mech => phase%get('mechanics') mech => phase%get('mechanics')
pl => mech%get('plasticity') pl => mech%get('plasticity')
if(count(myKinematics(:,p)) == 0) cycle
kinematics => phase%get('kinematics') kinematics => phase%get('damage')
do k = 1, kinematics%length
if(myKinematics(k,p)) then associate(prm => param(p))
associate(prm => param(kinematics_slipplane_opening_instance(p))) kinematic_type => kinematics%get(1)
kinematic_type => kinematics%get(k)
prm%dot_o = kinematic_type%get_asFloat('dot_o') prm%dot_o = kinematic_type%get_asFloat('dot_o')
prm%q = kinematic_type%get_asFloat('q') prm%q = kinematic_type%get_asFloat('q')
@ -105,9 +102,8 @@ module function kinematics_slipplane_opening_init(kinematics_length) result(myKi
! exit if any parameter is out of range ! exit if any parameter is out of range
if (extmsg /= '') call IO_error(211,ext_msg=trim(extmsg)//'(slipplane_opening)') if (extmsg /= '') call IO_error(211,ext_msg=trim(extmsg)//'(slipplane_opening)')
end associate end associate
endif endif
enddo
enddo enddo
@ -117,12 +113,10 @@ end function kinematics_slipplane_opening_init
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief contains the constitutive equation for calculating the velocity gradient !> @brief contains the constitutive equation for calculating the velocity gradient
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
module subroutine kinematics_slipplane_opening_LiAndItsTangent(Ld, dLd_dTstar, S, co, ip, el) module subroutine kinematics_slipplane_opening_LiAndItsTangent(Ld, dLd_dTstar, S, ph,me)
integer, intent(in) :: & integer, intent(in) :: &
co, & !< grain number ph, me
ip, & !< integration point number
el !< element number
real(pReal), intent(in), dimension(3,3) :: & real(pReal), intent(in), dimension(3,3) :: &
S S
real(pReal), intent(out), dimension(3,3) :: & real(pReal), intent(out), dimension(3,3) :: &
@ -131,19 +125,13 @@ module subroutine kinematics_slipplane_opening_LiAndItsTangent(Ld, dLd_dTstar, S
dLd_dTstar !< derivative of Ld with respect to Tstar (4th-order tensor) dLd_dTstar !< derivative of Ld with respect to Tstar (4th-order tensor)
integer :: & integer :: &
instance, phase, &
homog, damageOffset, &
i, k, l, m, n i, k, l, m, n
real(pReal) :: & real(pReal) :: &
traction_d, traction_t, traction_n, traction_crit, & traction_d, traction_t, traction_n, traction_crit, &
udotd, dudotd_dt, udott, dudott_dt, udotn, dudotn_dt udotd, dudotd_dt, udott, dudott_dt, udotn, dudotn_dt
phase = material_phaseAt(co,el)
instance = kinematics_slipplane_opening_instance(phase)
homog = material_homogenizationAt(el)
damageOffset = material_homogenizationMemberAt(ip,el)
associate(prm => param(instance)) associate(prm => param(ph))
Ld = 0.0_pReal Ld = 0.0_pReal
dLd_dTstar = 0.0_pReal dLd_dTstar = 0.0_pReal
do i = 1, prm%sum_N_sl do i = 1, prm%sum_N_sl
@ -152,7 +140,7 @@ module subroutine kinematics_slipplane_opening_LiAndItsTangent(Ld, dLd_dTstar, S
traction_t = math_tensordot(S,prm%P_t(1:3,1:3,i)) 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_n = math_tensordot(S,prm%P_n(1:3,1:3,i))
traction_crit = prm%g_crit(i)* damage(homog)%p(damageOffset) ! degrading critical load carrying capacity by damage traction_crit = prm%g_crit(i)* damage_phi(ph,me)
udotd = sign(1.0_pReal,traction_d)* prm%dot_o* ( abs(traction_d)/traction_crit & udotd = sign(1.0_pReal,traction_d)* prm%dot_o* ( abs(traction_d)/traction_crit &
- abs(traction_d)/prm%g_crit(i))**prm%q - abs(traction_d)/prm%g_crit(i))**prm%q

View File

@ -3,7 +3,7 @@
!> @brief material subroutine incorporating kinematics resulting from thermal expansion !> @brief material subroutine incorporating kinematics resulting from thermal expansion
!> @details to be done !> @details to be done
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
submodule(phase:eigendeformation) thermalexpansion submodule(phase:eigen) thermalexpansion
integer, dimension(:), allocatable :: kinematics_thermal_expansion_instance integer, dimension(:), allocatable :: kinematics_thermal_expansion_instance
@ -23,7 +23,7 @@ contains
!> @brief module initialization !> @brief module initialization
!> @details reads in material parameters, allocates arrays, and does sanity checks !> @details reads in material parameters, allocates arrays, and does sanity checks
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
module function kinematics_thermal_expansion_init(kinematics_length) result(myKinematics) module function thermalexpansion_init(kinematics_length) result(myKinematics)
integer, intent(in) :: kinematics_length integer, intent(in) :: kinematics_length
logical, dimension(:,:), allocatable :: myKinematics logical, dimension(:,:), allocatable :: myKinematics
@ -36,7 +36,7 @@ module function kinematics_thermal_expansion_init(kinematics_length) result(myKi
kinematics, & kinematics, &
kinematic_type kinematic_type
print'(/,a)', ' <<<+- phase:mechanics:eigendeformation:thermalexpansion init -+>>>' print'(/,a)', ' <<<+- phase:mechanical:eigen:thermalexpansion init -+>>>'
myKinematics = kinematics_active('thermal_expansion',kinematics_length) myKinematics = kinematics_active('thermal_expansion',kinematics_length)
Ninstances = count(myKinematics) Ninstances = count(myKinematics)
@ -77,7 +77,7 @@ module function kinematics_thermal_expansion_init(kinematics_length) result(myKi
enddo enddo
end function kinematics_thermal_expansion_init end function thermalexpansion_init
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------

View File

@ -1,4 +1,4 @@
submodule(phase:mechanics) plastic submodule(phase:mechanical) plastic
interface interface
@ -104,7 +104,7 @@ submodule(phase:mechanics) plastic
end subroutine dislotungsten_LpAndItsTangent end subroutine dislotungsten_LpAndItsTangent
module subroutine nonlocal_LpAndItsTangent(Lp,dLp_dMp, & module subroutine nonlocal_LpAndItsTangent(Lp,dLp_dMp, &
Mp,Temperature,ph,me,ip,el) Mp,Temperature,ph,me)
real(pReal), dimension(3,3), intent(out) :: & real(pReal), dimension(3,3), intent(out) :: &
Lp Lp
real(pReal), dimension(3,3,3,3), intent(out) :: & real(pReal), dimension(3,3,3,3), intent(out) :: &
@ -116,9 +116,7 @@ submodule(phase:mechanics) plastic
Temperature Temperature
integer, intent(in) :: & integer, intent(in) :: &
ph, & ph, &
me, & me
ip, & !< current integration point
el !< current element number
end subroutine nonlocal_LpAndItsTangent end subroutine nonlocal_LpAndItsTangent
@ -179,44 +177,42 @@ submodule(phase:mechanics) plastic
el !< current element number el !< current element number
end subroutine nonlocal_dotState end subroutine nonlocal_dotState
module subroutine dislotwin_dependentState(T,instance,me) module subroutine dislotwin_dependentState(T,ph,me)
integer, intent(in) :: & integer, intent(in) :: &
instance, & ph, &
me me
real(pReal), intent(in) :: & real(pReal), intent(in) :: &
T T
end subroutine dislotwin_dependentState end subroutine dislotwin_dependentState
module subroutine dislotungsten_dependentState(instance,me) module subroutine dislotungsten_dependentState(ph,me)
integer, intent(in) :: & integer, intent(in) :: &
instance, & ph, &
me me
end subroutine dislotungsten_dependentState end subroutine dislotungsten_dependentState
module subroutine nonlocal_dependentState(instance, me, ip, el) module subroutine nonlocal_dependentState(ph, me, ip, el)
integer, intent(in) :: & integer, intent(in) :: &
instance, & ph, &
me, & me, &
ip, & !< current integration point ip, & !< current integration point
el !< current element number el !< current element number
end subroutine nonlocal_dependentState end subroutine nonlocal_dependentState
module subroutine plastic_kinehardening_deltaState(Mp,instance,me) module subroutine plastic_kinehardening_deltaState(Mp,ph,me)
real(pReal), dimension(3,3), intent(in) :: & real(pReal), dimension(3,3), intent(in) :: &
Mp !< Mandel stress Mp !< Mandel stress
integer, intent(in) :: & integer, intent(in) :: &
instance, & ph, &
me me
end subroutine plastic_kinehardening_deltaState end subroutine plastic_kinehardening_deltaState
module subroutine plastic_nonlocal_deltaState(Mp,instance,me,ip,el) module subroutine plastic_nonlocal_deltaState(Mp,ph,me)
real(pReal), dimension(3,3), intent(in) :: & real(pReal), dimension(3,3), intent(in) :: &
Mp Mp
integer, intent(in) :: & integer, intent(in) :: &
instance, & ph, &
me, & me
ip, &
el
end subroutine plastic_nonlocal_deltaState end subroutine plastic_nonlocal_deltaState
end interface end interface
@ -226,7 +222,7 @@ contains
module subroutine plastic_init module subroutine plastic_init
print'(/,a)', ' <<<+- phase:mechanics:plastic init -+>>>' print'(/,a)', ' <<<+- phase:mechanical:plastic init -+>>>'
where(plastic_none_init()) phase_plasticity = PLASTICITY_NONE_ID where(plastic_none_init()) phase_plasticity = PLASTICITY_NONE_ID
where(plastic_isotropic_init()) phase_plasticity = PLASTICITY_ISOTROPIC_ID where(plastic_isotropic_init()) phase_plasticity = PLASTICITY_ISOTROPIC_ID
@ -244,11 +240,9 @@ end subroutine plastic_init
! Mp in, dLp_dMp out ! Mp in, dLp_dMp out
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
module subroutine plastic_LpAndItsTangents(Lp, dLp_dS, dLp_dFi, & module subroutine plastic_LpAndItsTangents(Lp, dLp_dS, dLp_dFi, &
S, Fi, co, ip, el) S, Fi, ph,me)
integer, intent(in) :: & integer, intent(in) :: &
co, & !< component-ID of integration point ph,me
ip, & !< integration point
el !< element
real(pReal), intent(in), dimension(3,3) :: & real(pReal), intent(in), dimension(3,3) :: &
S, & !< 2nd Piola-Kirchhoff stress S, & !< 2nd Piola-Kirchhoff stress
Fi !< intermediate deformation gradient Fi !< intermediate deformation gradient
@ -263,38 +257,37 @@ module subroutine plastic_LpAndItsTangents(Lp, dLp_dS, dLp_dFi, &
real(pReal), dimension(3,3) :: & real(pReal), dimension(3,3) :: &
Mp !< Mandel stress work conjugate with Lp Mp !< Mandel stress work conjugate with Lp
integer :: & integer :: &
i, j, me, ph i, j
Mp = matmul(matmul(transpose(Fi),Fi),S) Mp = matmul(matmul(transpose(Fi),Fi),S)
me = material_phasememberAt(co,ip,el)
ph = material_phaseAt(co,el)
plasticityType: select case (phase_plasticity(material_phaseAt(co,el)))
case (PLASTICITY_NONE_ID) plasticityType plasticType: select case (phase_plasticity(ph))
case (PLASTICITY_NONE_ID) plasticType
Lp = 0.0_pReal Lp = 0.0_pReal
dLp_dMp = 0.0_pReal dLp_dMp = 0.0_pReal
case (PLASTICITY_ISOTROPIC_ID) plasticityType case (PLASTICITY_ISOTROPIC_ID) plasticType
call isotropic_LpAndItsTangent(Lp,dLp_dMp,Mp,ph,me) call isotropic_LpAndItsTangent(Lp,dLp_dMp,Mp,ph,me)
case (PLASTICITY_PHENOPOWERLAW_ID) plasticityType case (PLASTICITY_PHENOPOWERLAW_ID) plasticType
call phenopowerlaw_LpAndItsTangent(Lp,dLp_dMp,Mp,ph,me) call phenopowerlaw_LpAndItsTangent(Lp,dLp_dMp,Mp,ph,me)
case (PLASTICITY_KINEHARDENING_ID) plasticityType case (PLASTICITY_KINEHARDENING_ID) plasticType
call kinehardening_LpAndItsTangent(Lp,dLp_dMp,Mp,ph,me) call kinehardening_LpAndItsTangent(Lp,dLp_dMp,Mp,ph,me)
case (PLASTICITY_NONLOCAL_ID) plasticityType case (PLASTICITY_NONLOCAL_ID) plasticType
call nonlocal_LpAndItsTangent(Lp,dLp_dMp,Mp, thermal_T(ph,me),ph,me,ip,el) call nonlocal_LpAndItsTangent(Lp,dLp_dMp,Mp, thermal_T(ph,me),ph,me)
case (PLASTICITY_DISLOTWIN_ID) plasticityType case (PLASTICITY_DISLOTWIN_ID) plasticType
call dislotwin_LpAndItsTangent(Lp,dLp_dMp,Mp, thermal_T(ph,me),ph,me) call dislotwin_LpAndItsTangent(Lp,dLp_dMp,Mp, thermal_T(ph,me),ph,me)
case (PLASTICITY_DISLOTUNGSTEN_ID) plasticityType case (PLASTICITY_DISLOTUNGSTEN_ID) plasticType
call dislotungsten_LpAndItsTangent(Lp,dLp_dMp,Mp, thermal_T(ph,me),ph,me) call dislotungsten_LpAndItsTangent(Lp,dLp_dMp,Mp, thermal_T(ph,me),ph,me)
end select plasticityType end select plasticType
do i=1,3; do j=1,3 do i=1,3; do j=1,3
dLp_dFi(i,j,1:3,1:3) = matmul(matmul(Fi,S),transpose(dLp_dMp(i,j,1:3,1:3))) + & dLp_dFi(i,j,1:3,1:3) = matmul(matmul(Fi,S),transpose(dLp_dMp(i,j,1:3,1:3))) + &
@ -323,29 +316,29 @@ module function plastic_dotState(subdt,co,ip,el,ph,me) result(broken)
logical :: broken logical :: broken
Mp = matmul(matmul(transpose(constitutive_mech_Fi(ph)%data(1:3,1:3,me)),& Mp = matmul(matmul(transpose(phase_mechanical_Fi(ph)%data(1:3,1:3,me)),&
constitutive_mech_Fi(ph)%data(1:3,1:3,me)),constitutive_mech_S(ph)%data(1:3,1:3,me)) phase_mechanical_Fi(ph)%data(1:3,1:3,me)),phase_mechanical_S(ph)%data(1:3,1:3,me))
plasticityType: select case (phase_plasticity(ph)) plasticType: select case (phase_plasticity(ph))
case (PLASTICITY_ISOTROPIC_ID) plasticityType case (PLASTICITY_ISOTROPIC_ID) plasticType
call isotropic_dotState(Mp,ph,me) call isotropic_dotState(Mp,ph,me)
case (PLASTICITY_PHENOPOWERLAW_ID) plasticityType case (PLASTICITY_PHENOPOWERLAW_ID) plasticType
call phenopowerlaw_dotState(Mp,ph,me) call phenopowerlaw_dotState(Mp,ph,me)
case (PLASTICITY_KINEHARDENING_ID) plasticityType case (PLASTICITY_KINEHARDENING_ID) plasticType
call plastic_kinehardening_dotState(Mp,ph,me) call plastic_kinehardening_dotState(Mp,ph,me)
case (PLASTICITY_DISLOTWIN_ID) plasticityType case (PLASTICITY_DISLOTWIN_ID) plasticType
call dislotwin_dotState(Mp,thermal_T(ph,me),ph,me) call dislotwin_dotState(Mp,thermal_T(ph,me),ph,me)
case (PLASTICITY_DISLOTUNGSTEN_ID) plasticityType case (PLASTICITY_DISLOTUNGSTEN_ID) plasticType
call dislotungsten_dotState(Mp,thermal_T(ph,me),ph,me) call dislotungsten_dotState(Mp,thermal_T(ph,me),ph,me)
case (PLASTICITY_NONLOCAL_ID) plasticityType case (PLASTICITY_NONLOCAL_ID) plasticType
call nonlocal_dotState(Mp,thermal_T(ph,me),subdt,ph,me,ip,el) call nonlocal_dotState(Mp,thermal_T(ph,me),subdt,ph,me,ip,el)
end select plasticityType end select plasticType
broken = any(IEEE_is_NaN(plasticState(ph)%dotState(:,me))) broken = any(IEEE_is_NaN(plasticState(ph)%dotState(:,me)))
@ -364,25 +357,24 @@ module subroutine plastic_dependentState(co, ip, el)
integer :: & integer :: &
ph, & ph, &
instance, me me
ph = material_phaseAt(co,el) ph = material_phaseAt(co,el)
me = material_phasememberAt(co,ip,el) me = material_phasememberAt(co,ip,el)
instance = phase_plasticityInstance(ph)
plasticityType: select case (phase_plasticity(material_phaseAt(co,el))) plasticType: select case (phase_plasticity(material_phaseAt(co,el)))
case (PLASTICITY_DISLOTWIN_ID) plasticityType case (PLASTICITY_DISLOTWIN_ID) plasticType
call dislotwin_dependentState(thermal_T(ph,me),instance,me) call dislotwin_dependentState(thermal_T(ph,me),ph,me)
case (PLASTICITY_DISLOTUNGSTEN_ID) plasticityType case (PLASTICITY_DISLOTUNGSTEN_ID) plasticType
call dislotungsten_dependentState(instance,me) call dislotungsten_dependentState(ph,me)
case (PLASTICITY_NONLOCAL_ID) plasticityType case (PLASTICITY_NONLOCAL_ID) plasticType
call nonlocal_dependentState(instance,me,ip,el) call nonlocal_dependentState(ph,me,ip,el)
end select plasticityType end select plasticType
end subroutine plastic_dependentState end subroutine plastic_dependentState
@ -391,12 +383,9 @@ end subroutine plastic_dependentState
!> @brief for constitutive models having an instantaneous change of state !> @brief for constitutive models having an instantaneous change of state
!> will return false if delta state is not needed/supported by the constitutive model !> will return false if delta state is not needed/supported by the constitutive model
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
module function plastic_deltaState(co, ip, el, ph, me) result(broken) module function plastic_deltaState(ph, me) result(broken)
integer, intent(in) :: & integer, intent(in) :: &
co, & !< component-ID of integration point
ip, & !< integration point
el, & !< element
ph, & ph, &
me me
logical :: & logical :: &
@ -405,29 +394,27 @@ module function plastic_deltaState(co, ip, el, ph, me) result(broken)
real(pReal), dimension(3,3) :: & real(pReal), dimension(3,3) :: &
Mp Mp
integer :: & integer :: &
instance, &
myOffset, & myOffset, &
mySize mySize
Mp = matmul(matmul(transpose(constitutive_mech_Fi(ph)%data(1:3,1:3,me)),& Mp = matmul(matmul(transpose(phase_mechanical_Fi(ph)%data(1:3,1:3,me)),&
constitutive_mech_Fi(ph)%data(1:3,1:3,me)),constitutive_mech_S(ph)%data(1:3,1:3,me)) phase_mechanical_Fi(ph)%data(1:3,1:3,me)),phase_mechanical_S(ph)%data(1:3,1:3,me))
instance = phase_plasticityInstance(ph)
plasticityType: select case (phase_plasticity(ph)) plasticType: select case (phase_plasticity(ph))
case (PLASTICITY_KINEHARDENING_ID) plasticityType case (PLASTICITY_KINEHARDENING_ID) plasticType
call plastic_kinehardening_deltaState(Mp,instance,me) call plastic_kinehardening_deltaState(Mp,ph,me)
broken = any(IEEE_is_NaN(plasticState(ph)%deltaState(:,me))) broken = any(IEEE_is_NaN(plasticState(ph)%deltaState(:,me)))
case (PLASTICITY_NONLOCAL_ID) plasticityType case (PLASTICITY_NONLOCAL_ID) plasticType
call plastic_nonlocal_deltaState(Mp,instance,me,ip,el) call plastic_nonlocal_deltaState(Mp,ph,me)
broken = any(IEEE_is_NaN(plasticState(ph)%deltaState(:,me))) broken = any(IEEE_is_NaN(plasticState(ph)%deltaState(:,me)))
case default case default
broken = .false. broken = .false.
end select plasticityType end select plasticType
if(.not. broken) then if(.not. broken) then
select case(phase_plasticity(ph)) select case(phase_plasticity(ph))

View File

@ -78,8 +78,7 @@ module function plastic_dislotungsten_init() result(myPlasticity)
logical, dimension(:), allocatable :: myPlasticity logical, dimension(:), allocatable :: myPlasticity
integer :: & integer :: &
Ninstances, & ph, i, &
p, i, &
Nconstituents, & Nconstituents, &
sizeState, sizeDotState, & sizeState, sizeDotState, &
startIndex, endIndex startIndex, endIndex
@ -97,32 +96,31 @@ module function plastic_dislotungsten_init() result(myPlasticity)
mech, & mech, &
pl pl
print'(/,a)', ' <<<+- phase:mechanics:plastic:dislotungsten init -+>>>'
myPlasticity = plastic_active('dislotungsten') myPlasticity = plastic_active('dislotungsten')
Ninstances = count(myPlasticity) if(count(myPlasticity) == 0) return
print'(a,i2)', ' # instances: ',Ninstances; flush(IO_STDOUT)
if(Ninstances == 0) return print'(/,a)', ' <<<+- phase:mechanical:plastic:dislotungsten init -+>>>'
print'(a,i0)', ' # phases: ',count(myPlasticity); flush(IO_STDOUT)
print*, 'Cereceda et al., International Journal of Plasticity 78:242256, 2016' print*, 'Cereceda et al., International Journal of Plasticity 78:242256, 2016'
print*, 'https://dx.doi.org/10.1016/j.ijplas.2015.09.002' print*, 'https://dx.doi.org/10.1016/j.ijplas.2015.09.002'
allocate(param(Ninstances))
allocate(state(Ninstances))
allocate(dotState(Ninstances))
allocate(dependentState(Ninstances))
phases => config_material%get('phase') phases => config_material%get('phase')
i = 0 allocate(param(phases%length))
do p = 1, phases%length allocate(state(phases%length))
phase => phases%get(p) allocate(dotState(phases%length))
allocate(dependentState(phases%length))
do ph = 1, phases%length
if(.not. myPlasticity(ph)) cycle
associate(prm => param(ph), dot => dotState(ph), stt => state(ph), dst => dependentState(ph))
phase => phases%get(ph)
mech => phase%get('mechanics') mech => phase%get('mechanics')
if(.not. myPlasticity(p)) cycle
i = i + 1
associate(prm => param(i), &
dot => dotState(i), &
stt => state(i), &
dst => dependentState(i))
pl => mech%get('plasticity') pl => mech%get('plasticity')
#if defined (__GFORTRAN__) #if defined (__GFORTRAN__)
@ -132,7 +130,7 @@ module function plastic_dislotungsten_init() result(myPlasticity)
#endif #endif
! This data is read in already in lattice ! This data is read in already in lattice
prm%mu = lattice_mu(p) prm%mu = lattice_mu(ph)
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
! slip related parameters ! slip related parameters
@ -222,41 +220,41 @@ module function plastic_dislotungsten_init() result(myPlasticity)
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
! allocate state arrays ! allocate state arrays
Nconstituents = count(material_phaseAt2 == p) Nconstituents = count(material_phaseAt2 == ph)
sizeDotState = size(['rho_mob ','rho_dip ','gamma_sl']) * prm%sum_N_sl sizeDotState = size(['rho_mob ','rho_dip ','gamma_sl']) * prm%sum_N_sl
sizeState = sizeDotState sizeState = sizeDotState
call constitutive_allocateState(plasticState(p),Nconstituents,sizeState,sizeDotState,0) call phase_allocateState(plasticState(ph),Nconstituents,sizeState,sizeDotState,0)
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
! state aliases and initialization ! state aliases and initialization
startIndex = 1 startIndex = 1
endIndex = prm%sum_N_sl endIndex = prm%sum_N_sl
stt%rho_mob => plasticState(p)%state(startIndex:endIndex,:) stt%rho_mob => plasticState(ph)%state(startIndex:endIndex,:)
stt%rho_mob = spread(rho_mob_0,2,Nconstituents) stt%rho_mob = spread(rho_mob_0,2,Nconstituents)
dot%rho_mob => plasticState(p)%dotState(startIndex:endIndex,:) dot%rho_mob => plasticState(ph)%dotState(startIndex:endIndex,:)
plasticState(p)%atol(startIndex:endIndex) = pl%get_asFloat('atol_rho',defaultVal=1.0_pReal) plasticState(ph)%atol(startIndex:endIndex) = pl%get_asFloat('atol_rho',defaultVal=1.0_pReal)
if (any(plasticState(p)%atol(startIndex:endIndex) < 0.0_pReal)) extmsg = trim(extmsg)//' atol_rho' if (any(plasticState(ph)%atol(startIndex:endIndex) < 0.0_pReal)) extmsg = trim(extmsg)//' atol_rho'
startIndex = endIndex + 1 startIndex = endIndex + 1
endIndex = endIndex + prm%sum_N_sl endIndex = endIndex + prm%sum_N_sl
stt%rho_dip => plasticState(p)%state(startIndex:endIndex,:) stt%rho_dip => plasticState(ph)%state(startIndex:endIndex,:)
stt%rho_dip = spread(rho_dip_0,2,Nconstituents) stt%rho_dip = spread(rho_dip_0,2,Nconstituents)
dot%rho_dip => plasticState(p)%dotState(startIndex:endIndex,:) dot%rho_dip => plasticState(ph)%dotState(startIndex:endIndex,:)
plasticState(p)%atol(startIndex:endIndex) = pl%get_asFloat('atol_rho',defaultVal=1.0_pReal) plasticState(ph)%atol(startIndex:endIndex) = pl%get_asFloat('atol_rho',defaultVal=1.0_pReal)
startIndex = endIndex + 1 startIndex = endIndex + 1
endIndex = endIndex + prm%sum_N_sl endIndex = endIndex + prm%sum_N_sl
stt%gamma_sl => plasticState(p)%state(startIndex:endIndex,:) stt%gamma_sl => plasticState(ph)%state(startIndex:endIndex,:)
dot%gamma_sl => plasticState(p)%dotState(startIndex:endIndex,:) dot%gamma_sl => plasticState(ph)%dotState(startIndex:endIndex,:)
plasticState(p)%atol(startIndex:endIndex) = 1.0e-2_pReal plasticState(ph)%atol(startIndex:endIndex) = 1.0e-2_pReal
! global alias ! global alias
plasticState(p)%slipRate => plasticState(p)%dotState(startIndex:endIndex,:) plasticState(ph)%slipRate => plasticState(ph)%dotState(startIndex:endIndex,:)
allocate(dst%Lambda_sl(prm%sum_N_sl,Nconstituents), source=0.0_pReal) allocate(dst%Lambda_sl(prm%sum_N_sl,Nconstituents), source=0.0_pReal)
allocate(dst%threshold_stress(prm%sum_N_sl,Nconstituents), source=0.0_pReal) allocate(dst%threshold_stress(prm%sum_N_sl,Nconstituents), source=0.0_pReal)
plasticState(p)%state0 = plasticState(p)%state ! ToDo: this could be done centrally plasticState(ph)%state0 = plasticState(ph)%state ! ToDo: this could be done centrally
end associate end associate
@ -289,16 +287,16 @@ pure module subroutine dislotungsten_LpAndItsTangent(Lp,dLp_dMp, &
integer :: & integer :: &
i,k,l,m,n i,k,l,m,n
real(pReal), dimension(param(phase_plasticityInstance(ph))%sum_N_sl) :: & real(pReal), dimension(param(ph)%sum_N_sl) :: &
dot_gamma_pos,dot_gamma_neg, & dot_gamma_pos,dot_gamma_neg, &
ddot_gamma_dtau_pos,ddot_gamma_dtau_neg ddot_gamma_dtau_pos,ddot_gamma_dtau_neg
Lp = 0.0_pReal Lp = 0.0_pReal
dLp_dMp = 0.0_pReal dLp_dMp = 0.0_pReal
associate(prm => param(phase_plasticityInstance(ph))) associate(prm => param(ph))
call kinetics(Mp,T,phase_plasticityInstance(ph),me,dot_gamma_pos,dot_gamma_neg,ddot_gamma_dtau_pos,ddot_gamma_dtau_neg) call kinetics(Mp,T,ph,me,dot_gamma_pos,dot_gamma_neg,ddot_gamma_dtau_pos,ddot_gamma_dtau_neg)
do i = 1, prm%sum_N_sl do i = 1, prm%sum_N_sl
Lp = Lp + (dot_gamma_pos(i)+dot_gamma_neg(i))*prm%P_sl(1:3,1:3,i) Lp = Lp + (dot_gamma_pos(i)+dot_gamma_neg(i))*prm%P_sl(1:3,1:3,i)
forall (k=1:3,l=1:3,m=1:3,n=1:3) & forall (k=1:3,l=1:3,m=1:3,n=1:3) &
@ -327,7 +325,7 @@ module subroutine dislotungsten_dotState(Mp,T,ph,me)
real(pReal) :: & real(pReal) :: &
VacancyDiffusion VacancyDiffusion
real(pReal), dimension(param(phase_plasticityInstance(ph))%sum_N_sl) :: & real(pReal), dimension(param(ph)%sum_N_sl) :: &
gdot_pos, gdot_neg,& gdot_pos, gdot_neg,&
tau_pos,& tau_pos,&
tau_neg, & tau_neg, &
@ -336,10 +334,10 @@ module subroutine dislotungsten_dotState(Mp,T,ph,me)
dot_rho_dip_climb, & dot_rho_dip_climb, &
dip_distance dip_distance
associate(prm => param(phase_plasticityInstance(ph)), stt => state(phase_plasticityInstance(ph)),& associate(prm => param(ph), stt => state(ph),&
dot => dotState(phase_plasticityInstance(ph)), dst => dependentState(phase_plasticityInstance(ph))) dot => dotState(ph), dst => dependentState(ph))
call kinetics(Mp,T,phase_plasticityInstance(ph),me,& call kinetics(Mp,T,ph,me,&
gdot_pos,gdot_neg, & gdot_pos,gdot_neg, &
tau_pos_out = tau_pos,tau_neg_out = tau_neg) tau_pos_out = tau_pos,tau_neg_out = tau_neg)
@ -376,16 +374,16 @@ end subroutine dislotungsten_dotState
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief Calculate derived quantities from state. !> @brief Calculate derived quantities from state.
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
module subroutine dislotungsten_dependentState(instance,me) module subroutine dislotungsten_dependentState(ph,me)
integer, intent(in) :: & integer, intent(in) :: &
instance, & ph, &
me me
real(pReal), dimension(param(instance)%sum_N_sl) :: & real(pReal), dimension(param(ph)%sum_N_sl) :: &
dislocationSpacing dislocationSpacing
associate(prm => param(instance), stt => state(instance),dst => dependentState(instance)) associate(prm => param(ph), stt => state(ph),dst => dependentState(ph))
dislocationSpacing = sqrt(matmul(prm%forestProjection,stt%rho_mob(:,me)+stt%rho_dip(:,me))) dislocationSpacing = sqrt(matmul(prm%forestProjection,stt%rho_mob(:,me)+stt%rho_dip(:,me)))
dst%threshold_stress(:,me) = prm%mu*prm%b_sl & dst%threshold_stress(:,me) = prm%mu*prm%b_sl &
@ -401,14 +399,14 @@ end subroutine dislotungsten_dependentState
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief Write results to HDF5 output file. !> @brief Write results to HDF5 output file.
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
module subroutine plastic_dislotungsten_results(instance,group) module subroutine plastic_dislotungsten_results(ph,group)
integer, intent(in) :: instance integer, intent(in) :: ph
character(len=*), intent(in) :: group character(len=*), intent(in) :: group
integer :: o integer :: o
associate(prm => param(instance), stt => state(instance), dst => dependentState(instance)) associate(prm => param(ph), stt => state(ph), dst => dependentState(ph))
outputsLoop: do o = 1,size(prm%output) outputsLoop: do o = 1,size(prm%output)
select case(trim(prm%output(o))) select case(trim(prm%output(o)))
case('rho_mob') case('rho_mob')
@ -440,7 +438,7 @@ end subroutine plastic_dislotungsten_results
! NOTE: Against the common convention, the result (i.e. intent(out)) variables are the last to ! NOTE: Against the common convention, the result (i.e. intent(out)) variables are the last to
! have the optional arguments at the end ! have the optional arguments at the end
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
pure subroutine kinetics(Mp,T,instance,me, & pure subroutine kinetics(Mp,T,ph,me, &
dot_gamma_pos,dot_gamma_neg,ddot_gamma_dtau_pos,ddot_gamma_dtau_neg,tau_pos_out,tau_neg_out) dot_gamma_pos,dot_gamma_neg,ddot_gamma_dtau_pos,ddot_gamma_dtau_neg,tau_pos_out,tau_neg_out)
real(pReal), dimension(3,3), intent(in) :: & real(pReal), dimension(3,3), intent(in) :: &
@ -448,18 +446,18 @@ pure subroutine kinetics(Mp,T,instance,me, &
real(pReal), intent(in) :: & real(pReal), intent(in) :: &
T !< temperature T !< temperature
integer, intent(in) :: & integer, intent(in) :: &
instance, & ph, &
me me
real(pReal), intent(out), dimension(param(instance)%sum_N_sl) :: & real(pReal), intent(out), dimension(param(ph)%sum_N_sl) :: &
dot_gamma_pos, & dot_gamma_pos, &
dot_gamma_neg dot_gamma_neg
real(pReal), intent(out), optional, dimension(param(instance)%sum_N_sl) :: & real(pReal), intent(out), optional, dimension(param(ph)%sum_N_sl) :: &
ddot_gamma_dtau_pos, & ddot_gamma_dtau_pos, &
ddot_gamma_dtau_neg, & ddot_gamma_dtau_neg, &
tau_pos_out, & tau_pos_out, &
tau_neg_out tau_neg_out
real(pReal), dimension(param(instance)%sum_N_sl) :: & real(pReal), dimension(param(ph)%sum_N_sl) :: &
StressRatio, & StressRatio, &
StressRatio_p,StressRatio_pminus1, & StressRatio_p,StressRatio_pminus1, &
dvel, vel, & dvel, vel, &
@ -468,7 +466,7 @@ pure subroutine kinetics(Mp,T,instance,me, &
needsGoodName ! ToDo: @Karo: any idea? needsGoodName ! ToDo: @Karo: any idea?
integer :: j integer :: j
associate(prm => param(instance), stt => state(instance), dst => dependentState(instance)) associate(prm => param(ph), stt => state(ph), dst => dependentState(ph))
do j = 1, prm%sum_N_sl do j = 1, prm%sum_N_sl
tau_pos(j) = math_tensordot(Mp,prm%nonSchmid_pos(1:3,1:3,j)) tau_pos(j) = math_tensordot(Mp,prm%nonSchmid_pos(1:3,1:3,j))

View File

@ -48,7 +48,7 @@ submodule(phase:plastic) dislotwin
dot_N_0_tr, & !< trans nucleation rate [1/m³s] for each trans system dot_N_0_tr, & !< trans nucleation rate [1/m³s] for each trans system
t_tw, & !< twin thickness [m] for each twin system t_tw, & !< twin thickness [m] for each twin system
i_sl, & !< 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 t_tr, & !< martensite lamellar thickness [m] for each trans system
p, & !< p-exponent in glide velocity p, & !< p-exponent in glide velocity
q, & !< q-exponent in glide velocity q, & !< q-exponent in glide velocity
r, & !< r-exponent in twin nucleation rate r, & !< r-exponent in twin nucleation rate
@ -126,8 +126,7 @@ module function plastic_dislotwin_init() result(myPlasticity)
logical, dimension(:), allocatable :: myPlasticity logical, dimension(:), allocatable :: myPlasticity
integer :: & integer :: &
Ninstances, & ph, i, &
p, i, &
Nconstituents, & Nconstituents, &
sizeState, sizeDotState, & sizeState, sizeDotState, &
startIndex, endIndex startIndex, endIndex
@ -144,12 +143,12 @@ module function plastic_dislotwin_init() result(myPlasticity)
mech, & mech, &
pl pl
print'(/,a)', ' <<<+- phase:mechanics:plastic:dislotwin init -+>>>'
myPlasticity = plastic_active('dislotwin') myPlasticity = plastic_active('dislotwin')
Ninstances = count(myPlasticity) if(count(myPlasticity) == 0) return
print'(a,i2)', ' # instances: ',Ninstances; flush(IO_STDOUT)
if(Ninstances == 0) return print'(/,a)', ' <<<+- phase:mechanical:plastic:dislotwin init -+>>>'
print'(a,i0)', ' # phases: ',count(myPlasticity); flush(IO_STDOUT)
print*, 'Ma and Roters, Acta Materialia 52(12):36033612, 2004' print*, 'Ma and Roters, Acta Materialia 52(12):36033612, 2004'
print*, 'https://doi.org/10.1016/j.actamat.2004.04.012'//IO_EOL print*, 'https://doi.org/10.1016/j.actamat.2004.04.012'//IO_EOL
@ -160,22 +159,21 @@ module function plastic_dislotwin_init() result(myPlasticity)
print*, 'Wong et al., Acta Materialia 118:140151, 2016' print*, 'Wong et al., Acta Materialia 118:140151, 2016'
print*, 'https://doi.org/10.1016/j.actamat.2016.07.032' print*, 'https://doi.org/10.1016/j.actamat.2016.07.032'
allocate(param(Ninstances))
allocate(state(Ninstances))
allocate(dotState(Ninstances))
allocate(dependentState(Ninstances))
phases => config_material%get('phase') phases => config_material%get('phase')
i = 0 allocate(param(phases%length))
do p = 1, phases%length allocate(state(phases%length))
phase => phases%get(p) allocate(dotState(phases%length))
allocate(dependentState(phases%length))
do ph = 1, phases%length
if(.not. myPlasticity(ph)) cycle
associate(prm => param(ph), dot => dotState(ph), stt => state(ph), dst => dependentState(ph))
phase => phases%get(ph)
mech => phase%get('mechanics') mech => phase%get('mechanics')
if(.not. myPlasticity(p)) cycle
i = i + 1
associate(prm => param(i), &
dot => dotState(i), &
stt => state(i), &
dst => dependentState(i))
pl => mech%get('plasticity') pl => mech%get('plasticity')
#if defined (__GFORTRAN__) #if defined (__GFORTRAN__)
@ -185,9 +183,9 @@ module function plastic_dislotwin_init() result(myPlasticity)
#endif #endif
! This data is read in already in lattice ! This data is read in already in lattice
prm%mu = lattice_mu(p) prm%mu = lattice_mu(ph)
prm%nu = lattice_nu(p) prm%nu = lattice_nu(ph)
prm%C66 = lattice_C66(1:6,1:6,p) prm%C66 = lattice_C66(1:6,1:6,ph)
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
! slip related parameters ! slip related parameters
@ -204,8 +202,7 @@ module function plastic_dislotwin_init() result(myPlasticity)
prm%n0_sl = lattice_slip_normal(N_sl,phase%get_asString('lattice'),& prm%n0_sl = lattice_slip_normal(N_sl,phase%get_asString('lattice'),&
phase%get_asFloat('c/a',defaultVal=0.0_pReal)) phase%get_asFloat('c/a',defaultVal=0.0_pReal))
prm%fccTwinTransNucleation = merge(.true., .false., lattice_structure(p) == lattice_FCC_ID) & prm%fccTwinTransNucleation = lattice_structure(ph) == lattice_FCC_ID .and. (N_sl(1) == 12)
.and. (N_sl(1) == 12)
if(prm%fccTwinTransNucleation) prm%fcc_twinNucleationSlipPair = lattice_FCC_TWINNUCLEATIONSLIPPAIR if(prm%fccTwinTransNucleation) prm%fcc_twinNucleationSlipPair = lattice_FCC_TWINNUCLEATIONSLIPPAIR
rho_mob_0 = pl%get_asFloats('rho_mob_0', requiredSize=size(N_sl)) rho_mob_0 = pl%get_asFloats('rho_mob_0', requiredSize=size(N_sl))
@ -234,7 +231,7 @@ module function plastic_dislotwin_init() result(myPlasticity)
! multiplication factor according to crystal structure (nearest neighbors bcc vs fcc/hex) ! multiplication factor according to crystal structure (nearest neighbors bcc vs fcc/hex)
! details: Argon & Moffat, Acta Metallurgica, Vol. 29, pg 293 to 299, 1981 ! details: Argon & Moffat, Acta Metallurgica, Vol. 29, pg 293 to 299, 1981
prm%omega = pl%get_asFloat('omega', defaultVal = 1000.0_pReal) & prm%omega = pl%get_asFloat('omega', defaultVal = 1000.0_pReal) &
* merge(12.0_pReal,8.0_pReal,any(lattice_structure(p) == [lattice_FCC_ID,lattice_HEX_ID])) * merge(12.0_pReal,8.0_pReal,any(lattice_structure(ph) == [lattice_FCC_ID,lattice_HEX_ID]))
! expand: family => system ! expand: family => system
rho_mob_0 = math_expand(rho_mob_0, N_sl) rho_mob_0 = math_expand(rho_mob_0, N_sl)
@ -342,7 +339,7 @@ module function plastic_dislotwin_init() result(myPlasticity)
pl%get_asFloat('a_cI', defaultVal=0.0_pReal), & pl%get_asFloat('a_cI', defaultVal=0.0_pReal), &
pl%get_asFloat('a_cF', defaultVal=0.0_pReal)) pl%get_asFloat('a_cF', defaultVal=0.0_pReal))
if (lattice_structure(p) /= lattice_FCC_ID) then if (lattice_structure(ph) /= lattice_FCC_ID) then
prm%dot_N_0_tr = pl%get_asFloats('dot_N_0_tr') prm%dot_N_0_tr = pl%get_asFloats('dot_N_0_tr')
prm%dot_N_0_tr = math_expand(prm%dot_N_0_tr,N_tr) prm%dot_N_0_tr = math_expand(prm%dot_N_0_tr,N_tr)
endif endif
@ -357,7 +354,7 @@ module function plastic_dislotwin_init() result(myPlasticity)
if ( prm%i_tr < 0.0_pReal) extmsg = trim(extmsg)//' i_tr' if ( prm%i_tr < 0.0_pReal) extmsg = trim(extmsg)//' i_tr'
if (any(prm%t_tr < 0.0_pReal)) extmsg = trim(extmsg)//' t_tr' if (any(prm%t_tr < 0.0_pReal)) extmsg = trim(extmsg)//' t_tr'
if (any(prm%s < 0.0_pReal)) extmsg = trim(extmsg)//' p_tr' if (any(prm%s < 0.0_pReal)) extmsg = trim(extmsg)//' p_tr'
if (lattice_structure(p) /= lattice_FCC_ID) then if (lattice_structure(ph) /= lattice_FCC_ID) then
if (any(prm%dot_N_0_tr < 0.0_pReal)) extmsg = trim(extmsg)//' dot_N_0_tr' if (any(prm%dot_N_0_tr < 0.0_pReal)) extmsg = trim(extmsg)//' dot_N_0_tr'
endif endif
else transActive else transActive
@ -408,53 +405,53 @@ module function plastic_dislotwin_init() result(myPlasticity)
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
! allocate state arrays ! allocate state arrays
Nconstituents = count(material_phaseAt2 == p) Nconstituents = count(material_phaseAt2 == ph)
sizeDotState = size(['rho_mob ','rho_dip ','gamma_sl']) * prm%sum_N_sl & sizeDotState = size(['rho_mob ','rho_dip ','gamma_sl']) * prm%sum_N_sl &
+ size(['f_tw']) * prm%sum_N_tw & + size(['f_tw']) * prm%sum_N_tw &
+ size(['f_tr']) * prm%sum_N_tr + size(['f_tr']) * prm%sum_N_tr
sizeState = sizeDotState sizeState = sizeDotState
call constitutive_allocateState(plasticState(p),Nconstituents,sizeState,sizeDotState,0) call phase_allocateState(plasticState(ph),Nconstituents,sizeState,sizeDotState,0)
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
! locally defined state aliases and initialization of state0 and atol ! locally defined state aliases and initialization of state0 and atol
startIndex = 1 startIndex = 1
endIndex = prm%sum_N_sl endIndex = prm%sum_N_sl
stt%rho_mob=>plasticState(p)%state(startIndex:endIndex,:) stt%rho_mob=>plasticState(ph)%state(startIndex:endIndex,:)
stt%rho_mob= spread(rho_mob_0,2,Nconstituents) stt%rho_mob= spread(rho_mob_0,2,Nconstituents)
dot%rho_mob=>plasticState(p)%dotState(startIndex:endIndex,:) dot%rho_mob=>plasticState(ph)%dotState(startIndex:endIndex,:)
plasticState(p)%atol(startIndex:endIndex) = pl%get_asFloat('atol_rho',defaultVal=1.0_pReal) plasticState(ph)%atol(startIndex:endIndex) = pl%get_asFloat('atol_rho',defaultVal=1.0_pReal)
if (any(plasticState(p)%atol(startIndex:endIndex) < 0.0_pReal)) extmsg = trim(extmsg)//' atol_rho' if (any(plasticState(ph)%atol(startIndex:endIndex) < 0.0_pReal)) extmsg = trim(extmsg)//' atol_rho'
startIndex = endIndex + 1 startIndex = endIndex + 1
endIndex = endIndex + prm%sum_N_sl endIndex = endIndex + prm%sum_N_sl
stt%rho_dip=>plasticState(p)%state(startIndex:endIndex,:) stt%rho_dip=>plasticState(ph)%state(startIndex:endIndex,:)
stt%rho_dip= spread(rho_dip_0,2,Nconstituents) stt%rho_dip= spread(rho_dip_0,2,Nconstituents)
dot%rho_dip=>plasticState(p)%dotState(startIndex:endIndex,:) dot%rho_dip=>plasticState(ph)%dotState(startIndex:endIndex,:)
plasticState(p)%atol(startIndex:endIndex) = pl%get_asFloat('atol_rho',defaultVal=1.0_pReal) plasticState(ph)%atol(startIndex:endIndex) = pl%get_asFloat('atol_rho',defaultVal=1.0_pReal)
startIndex = endIndex + 1 startIndex = endIndex + 1
endIndex = endIndex + prm%sum_N_sl endIndex = endIndex + prm%sum_N_sl
stt%gamma_sl=>plasticState(p)%state(startIndex:endIndex,:) stt%gamma_sl=>plasticState(ph)%state(startIndex:endIndex,:)
dot%gamma_sl=>plasticState(p)%dotState(startIndex:endIndex,:) dot%gamma_sl=>plasticState(ph)%dotState(startIndex:endIndex,:)
plasticState(p)%atol(startIndex:endIndex) = 1.0e-2_pReal plasticState(ph)%atol(startIndex:endIndex) = 1.0e-2_pReal
! global alias ! global alias
plasticState(p)%slipRate => plasticState(p)%dotState(startIndex:endIndex,:) plasticState(ph)%slipRate => plasticState(ph)%dotState(startIndex:endIndex,:)
startIndex = endIndex + 1 startIndex = endIndex + 1
endIndex = endIndex + prm%sum_N_tw endIndex = endIndex + prm%sum_N_tw
stt%f_tw=>plasticState(p)%state(startIndex:endIndex,:) stt%f_tw=>plasticState(ph)%state(startIndex:endIndex,:)
dot%f_tw=>plasticState(p)%dotState(startIndex:endIndex,:) dot%f_tw=>plasticState(ph)%dotState(startIndex:endIndex,:)
plasticState(p)%atol(startIndex:endIndex) = pl%get_asFloat('f_twin',defaultVal=1.0e-7_pReal) plasticState(ph)%atol(startIndex:endIndex) = pl%get_asFloat('f_twin',defaultVal=1.0e-7_pReal)
if (any(plasticState(p)%atol(startIndex:endIndex) < 0.0_pReal)) extmsg = trim(extmsg)//' f_twin' if (any(plasticState(ph)%atol(startIndex:endIndex) < 0.0_pReal)) extmsg = trim(extmsg)//' f_twin'
startIndex = endIndex + 1 startIndex = endIndex + 1
endIndex = endIndex + prm%sum_N_tr endIndex = endIndex + prm%sum_N_tr
stt%f_tr=>plasticState(p)%state(startIndex:endIndex,:) stt%f_tr=>plasticState(ph)%state(startIndex:endIndex,:)
dot%f_tr=>plasticState(p)%dotState(startIndex:endIndex,:) dot%f_tr=>plasticState(ph)%dotState(startIndex:endIndex,:)
plasticState(p)%atol(startIndex:endIndex) = pl%get_asFloat('f_trans',defaultVal=1.0e-6_pReal) plasticState(ph)%atol(startIndex:endIndex) = pl%get_asFloat('f_trans',defaultVal=1.0e-6_pReal)
if (any(plasticState(p)%atol(startIndex:endIndex) < 0.0_pReal)) extmsg = trim(extmsg)//' f_trans' if (any(plasticState(ph)%atol(startIndex:endIndex) < 0.0_pReal)) extmsg = trim(extmsg)//' f_trans'
allocate(dst%Lambda_sl (prm%sum_N_sl,Nconstituents),source=0.0_pReal) allocate(dst%Lambda_sl (prm%sum_N_sl,Nconstituents),source=0.0_pReal)
allocate(dst%tau_pass (prm%sum_N_sl,Nconstituents),source=0.0_pReal) allocate(dst%tau_pass (prm%sum_N_sl,Nconstituents),source=0.0_pReal)
@ -469,7 +466,7 @@ module function plastic_dislotwin_init() result(myPlasticity)
allocate(dst%tau_r_tr (prm%sum_N_tr,Nconstituents),source=0.0_pReal) allocate(dst%tau_r_tr (prm%sum_N_tr,Nconstituents),source=0.0_pReal)
allocate(dst%V_tr (prm%sum_N_tr,Nconstituents),source=0.0_pReal) allocate(dst%V_tr (prm%sum_N_tr,Nconstituents),source=0.0_pReal)
plasticState(p)%state0 = plasticState(p)%state ! ToDo: this could be done centrally plasticState(ph)%state0 = plasticState(ph)%state ! ToDo: this could be done centrally
end associate end associate
@ -496,8 +493,8 @@ module function plastic_dislotwin_homogenizedC(ph,me) result(homogenizedC)
real(pReal) :: f_unrotated real(pReal) :: f_unrotated
associate(prm => param(phase_plasticityInstance(ph)),& associate(prm => param(ph),&
stt => state(phase_plasticityInstance(ph))) stt => state(ph))
f_unrotated = 1.0_pReal & f_unrotated = 1.0_pReal &
- sum(stt%f_tw(1:prm%sum_N_tw,me)) & - sum(stt%f_tw(1:prm%sum_N_tw,me)) &
@ -535,11 +532,11 @@ module subroutine dislotwin_LpAndItsTangent(Lp,dLp_dMp,Mp,T,ph,me)
BoltzmannRatio, & BoltzmannRatio, &
ddot_gamma_dtau, & ddot_gamma_dtau, &
tau tau
real(pReal), dimension(param(phase_plasticityInstance(ph))%sum_N_sl) :: & real(pReal), dimension(param(ph)%sum_N_sl) :: &
dot_gamma_sl,ddot_gamma_dtau_slip dot_gamma_sl,ddot_gamma_dtau_slip
real(pReal), dimension(param(phase_plasticityInstance(ph))%sum_N_tw) :: & real(pReal), dimension(param(ph)%sum_N_tw) :: &
dot_gamma_twin,ddot_gamma_dtau_twin dot_gamma_twin,ddot_gamma_dtau_twin
real(pReal), dimension(param(phase_plasticityInstance(ph))%sum_N_tr) :: & real(pReal), dimension(param(ph)%sum_N_tr) :: &
dot_gamma_tr,ddot_gamma_dtau_trans dot_gamma_tr,ddot_gamma_dtau_trans
real(pReal):: dot_gamma_sb real(pReal):: dot_gamma_sb
real(pReal), dimension(3,3) :: eigVectors, P_sb real(pReal), dimension(3,3) :: eigVectors, P_sb
@ -564,7 +561,7 @@ module subroutine dislotwin_LpAndItsTangent(Lp,dLp_dMp,Mp,T,ph,me)
0, 1, 1 & 0, 1, 1 &
],pReal),[ 3,6]) ],pReal),[ 3,6])
associate(prm => param(phase_plasticityInstance(ph)), stt => state(phase_plasticityInstance(ph))) associate(prm => param(ph), stt => state(ph))
f_unrotated = 1.0_pReal & f_unrotated = 1.0_pReal &
- sum(stt%f_tw(1:prm%sum_N_tw,me)) & - sum(stt%f_tw(1:prm%sum_N_tw,me)) &
@ -573,7 +570,7 @@ module subroutine dislotwin_LpAndItsTangent(Lp,dLp_dMp,Mp,T,ph,me)
Lp = 0.0_pReal Lp = 0.0_pReal
dLp_dMp = 0.0_pReal dLp_dMp = 0.0_pReal
call kinetics_slip(Mp,T,phase_plasticityInstance(ph),me,dot_gamma_sl,ddot_gamma_dtau_slip) call kinetics_slip(Mp,T,ph,me,dot_gamma_sl,ddot_gamma_dtau_slip)
slipContribution: do i = 1, prm%sum_N_sl slipContribution: do i = 1, prm%sum_N_sl
Lp = Lp + dot_gamma_sl(i)*prm%P_sl(1:3,1:3,i) Lp = Lp + dot_gamma_sl(i)*prm%P_sl(1:3,1:3,i)
forall (k=1:3,l=1:3,m=1:3,n=1:3) & forall (k=1:3,l=1:3,m=1:3,n=1:3) &
@ -581,7 +578,7 @@ module subroutine dislotwin_LpAndItsTangent(Lp,dLp_dMp,Mp,T,ph,me)
+ ddot_gamma_dtau_slip(i) * prm%P_sl(k,l,i) * prm%P_sl(m,n,i) + ddot_gamma_dtau_slip(i) * prm%P_sl(k,l,i) * prm%P_sl(m,n,i)
enddo slipContribution enddo slipContribution
call kinetics_twin(Mp,T,dot_gamma_sl,phase_plasticityInstance(ph),me,dot_gamma_twin,ddot_gamma_dtau_twin) call kinetics_twin(Mp,T,dot_gamma_sl,ph,me,dot_gamma_twin,ddot_gamma_dtau_twin)
twinContibution: do i = 1, prm%sum_N_tw twinContibution: do i = 1, prm%sum_N_tw
Lp = Lp + dot_gamma_twin(i)*prm%P_tw(1:3,1:3,i) Lp = Lp + dot_gamma_twin(i)*prm%P_tw(1:3,1:3,i)
forall (k=1:3,l=1:3,m=1:3,n=1:3) & forall (k=1:3,l=1:3,m=1:3,n=1:3) &
@ -589,7 +586,7 @@ module subroutine dislotwin_LpAndItsTangent(Lp,dLp_dMp,Mp,T,ph,me)
+ ddot_gamma_dtau_twin(i)* prm%P_tw(k,l,i)*prm%P_tw(m,n,i) + ddot_gamma_dtau_twin(i)* prm%P_tw(k,l,i)*prm%P_tw(m,n,i)
enddo twinContibution enddo twinContibution
call kinetics_trans(Mp,T,dot_gamma_sl,phase_plasticityInstance(ph),me,dot_gamma_tr,ddot_gamma_dtau_trans) call kinetics_trans(Mp,T,dot_gamma_sl,ph,me,dot_gamma_tr,ddot_gamma_dtau_trans)
transContibution: do i = 1, prm%sum_N_tr transContibution: do i = 1, prm%sum_N_tr
Lp = Lp + dot_gamma_tr(i)*prm%P_tr(1:3,1:3,i) Lp = Lp + dot_gamma_tr(i)*prm%P_tr(1:3,1:3,i)
forall (k=1:3,l=1:3,m=1:3,n=1:3) & forall (k=1:3,l=1:3,m=1:3,n=1:3) &
@ -653,24 +650,24 @@ module subroutine dislotwin_dotState(Mp,T,ph,me)
tau, & tau, &
sigma_cl, & !< climb stress 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(phase_plasticityInstance(ph))%sum_N_sl) :: & real(pReal), dimension(param(ph)%sum_N_sl) :: &
dot_rho_dip_formation, & dot_rho_dip_formation, &
dot_rho_dip_climb, & dot_rho_dip_climb, &
rho_dip_distance_min, & rho_dip_distance_min, &
dot_gamma_sl dot_gamma_sl
real(pReal), dimension(param(phase_plasticityInstance(ph))%sum_N_tw) :: & real(pReal), dimension(param(ph)%sum_N_tw) :: &
dot_gamma_twin dot_gamma_twin
real(pReal), dimension(param(phase_plasticityInstance(ph))%sum_N_tr) :: & real(pReal), dimension(param(ph)%sum_N_tr) :: &
dot_gamma_tr dot_gamma_tr
associate(prm => param(phase_plasticityInstance(ph)), stt => state(phase_plasticityInstance(ph)), & associate(prm => param(ph), stt => state(ph), &
dot => dotState(phase_plasticityInstance(ph)), dst => dependentState(phase_plasticityInstance(ph))) dot => dotState(ph), dst => dependentState(ph))
f_unrotated = 1.0_pReal & f_unrotated = 1.0_pReal &
- sum(stt%f_tw(1:prm%sum_N_tw,me)) & - sum(stt%f_tw(1:prm%sum_N_tw,me)) &
- sum(stt%f_tr(1:prm%sum_N_tr,me)) - sum(stt%f_tr(1:prm%sum_N_tr,me))
call kinetics_slip(Mp,T,phase_plasticityInstance(ph),me,dot_gamma_sl) call kinetics_slip(Mp,T,ph,me,dot_gamma_sl)
dot%gamma_sl(:,me) = abs(dot_gamma_sl) dot%gamma_sl(:,me) = abs(dot_gamma_sl)
rho_dip_distance_min = prm%D_a*prm%b_sl rho_dip_distance_min = prm%D_a*prm%b_sl
@ -721,10 +718,10 @@ module subroutine dislotwin_dotState(Mp,T,ph,me)
- 2.0_pReal*rho_dip_distance_min/prm%b_sl * stt%rho_dip(:,me)*abs(dot_gamma_sl) & - 2.0_pReal*rho_dip_distance_min/prm%b_sl * stt%rho_dip(:,me)*abs(dot_gamma_sl) &
- dot_rho_dip_climb - dot_rho_dip_climb
call kinetics_twin(Mp,T,dot_gamma_sl,phase_plasticityInstance(ph),me,dot_gamma_twin) call kinetics_twin(Mp,T,dot_gamma_sl,ph,me,dot_gamma_twin)
dot%f_tw(:,me) = f_unrotated*dot_gamma_twin/prm%gamma_char dot%f_tw(:,me) = f_unrotated*dot_gamma_twin/prm%gamma_char
call kinetics_trans(Mp,T,dot_gamma_sl,phase_plasticityInstance(ph),me,dot_gamma_tr) call kinetics_trans(Mp,T,dot_gamma_sl,ph,me,dot_gamma_tr)
dot%f_tr(:,me) = f_unrotated*dot_gamma_tr dot%f_tr(:,me) = f_unrotated*dot_gamma_tr
end associate end associate
@ -735,33 +732,33 @@ end subroutine dislotwin_dotState
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief Calculate derived quantities from state. !> @brief Calculate derived quantities from state.
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
module subroutine dislotwin_dependentState(T,instance,me) module subroutine dislotwin_dependentState(T,ph,me)
integer, intent(in) :: & integer, intent(in) :: &
instance, & ph, &
me me
real(pReal), intent(in) :: & real(pReal), intent(in) :: &
T T
real(pReal) :: & real(pReal) :: &
sumf_twin,Gamma,sumf_trans sumf_twin,Gamma,sumf_trans
real(pReal), dimension(param(instance)%sum_N_sl) :: & real(pReal), dimension(param(ph)%sum_N_sl) :: &
inv_lambda_sl_sl, & !< 1/mean free distance between 2 forest dislocations seen by a moving dislocation inv_lambda_sl_sl, & !< 1/mean free distance between 2 forest dislocations seen by a moving dislocation
inv_lambda_sl_tw, & !< 1/mean free distance between 2 twin stacks from different systems seen by a moving dislocation inv_lambda_sl_tw, & !< 1/mean free distance between 2 twin stacks from different systems seen by a moving dislocation
inv_lambda_sl_tr !< 1/mean free distance between 2 martensite lamellar from different systems seen by a moving dislocation inv_lambda_sl_tr !< 1/mean free distance between 2 martensite lamellar from different systems seen by a moving dislocation
real(pReal), dimension(param(instance)%sum_N_tw) :: & real(pReal), dimension(param(ph)%sum_N_tw) :: &
inv_lambda_tw_tw, & !< 1/mean free distance between 2 twin stacks from different systems seen by a growing twin inv_lambda_tw_tw, & !< 1/mean free distance between 2 twin stacks from different systems seen by a growing twin
f_over_t_tw f_over_t_tw
real(pReal), dimension(param(instance)%sum_N_tr) :: & real(pReal), dimension(param(ph)%sum_N_tr) :: &
inv_lambda_tr_tr, & !< 1/mean free distance between 2 martensite stacks from different systems seen by a growing martensite inv_lambda_tr_tr, & !< 1/mean free distance between 2 martensite stacks from different systems seen by a growing martensite
f_over_t_tr f_over_t_tr
real(pReal), dimension(:), allocatable :: & real(pReal), dimension(:), allocatable :: &
x0 x0
associate(prm => param(instance),& associate(prm => param(ph),&
stt => state(instance),& stt => state(ph),&
dst => dependentState(instance)) dst => dependentState(ph))
sumf_twin = sum(stt%f_tw(1:prm%sum_N_tw,me)) sumf_twin = sum(stt%f_tw(1:prm%sum_N_tw,me))
sumf_trans = sum(stt%f_tr(1:prm%sum_N_tr,me)) sumf_trans = sum(stt%f_tr(1:prm%sum_N_tr,me))
@ -827,14 +824,14 @@ end subroutine dislotwin_dependentState
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief Write results to HDF5 output file. !> @brief Write results to HDF5 output file.
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
module subroutine plastic_dislotwin_results(instance,group) module subroutine plastic_dislotwin_results(ph,group)
integer, intent(in) :: instance integer, intent(in) :: ph
character(len=*), intent(in) :: group character(len=*), intent(in) :: group
integer :: o integer :: o
associate(prm => param(instance), stt => state(instance), dst => dependentState(instance)) associate(prm => param(ph), stt => state(ph), dst => dependentState(ph))
outputsLoop: do o = 1,size(prm%output) outputsLoop: do o = 1,size(prm%output)
select case(trim(prm%output(o))) select case(trim(prm%output(o)))
@ -882,7 +879,7 @@ end subroutine plastic_dislotwin_results
! NOTE: Against the common convention, the result (i.e. intent(out)) variables are the last to ! NOTE: Against the common convention, the result (i.e. intent(out)) variables are the last to
! have the optional arguments at the end ! have the optional arguments at the end
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
pure subroutine kinetics_slip(Mp,T,instance,me, & pure subroutine kinetics_slip(Mp,T,ph,me, &
dot_gamma_sl,ddot_gamma_dtau_slip,tau_slip) dot_gamma_sl,ddot_gamma_dtau_slip,tau_slip)
real(pReal), dimension(3,3), intent(in) :: & real(pReal), dimension(3,3), intent(in) :: &
@ -890,18 +887,18 @@ pure subroutine kinetics_slip(Mp,T,instance,me, &
real(pReal), intent(in) :: & real(pReal), intent(in) :: &
T !< temperature T !< temperature
integer, intent(in) :: & integer, intent(in) :: &
instance, & ph, &
me me
real(pReal), dimension(param(instance)%sum_N_sl), intent(out) :: & real(pReal), dimension(param(ph)%sum_N_sl), intent(out) :: &
dot_gamma_sl dot_gamma_sl
real(pReal), dimension(param(instance)%sum_N_sl), optional, intent(out) :: & real(pReal), dimension(param(ph)%sum_N_sl), optional, intent(out) :: &
ddot_gamma_dtau_slip, & ddot_gamma_dtau_slip, &
tau_slip tau_slip
real(pReal), dimension(param(instance)%sum_N_sl) :: & real(pReal), dimension(param(ph)%sum_N_sl) :: &
ddot_gamma_dtau ddot_gamma_dtau
real(pReal), dimension(param(instance)%sum_N_sl) :: & real(pReal), dimension(param(ph)%sum_N_sl) :: &
tau, & tau, &
stressRatio, & stressRatio, &
StressRatio_p, & StressRatio_p, &
@ -914,7 +911,7 @@ pure subroutine kinetics_slip(Mp,T,instance,me, &
tau_eff !< effective resolved stress tau_eff !< effective resolved stress
integer :: i integer :: i
associate(prm => param(instance), stt => state(instance), dst => dependentState(instance)) associate(prm => param(ph), stt => state(ph), dst => dependentState(ph))
do i = 1, prm%sum_N_sl do i = 1, prm%sum_N_sl
tau(i) = math_tensordot(Mp,prm%P_sl(1:3,1:3,i)) tau(i) = math_tensordot(Mp,prm%P_sl(1:3,1:3,i))
@ -959,7 +956,7 @@ end subroutine kinetics_slip
! NOTE: Against the common convention, the result (i.e. intent(out)) variables are the last to ! NOTE: Against the common convention, the result (i.e. intent(out)) variables are the last to
! have the optional arguments at the end. ! have the optional arguments at the end.
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
pure subroutine kinetics_twin(Mp,T,dot_gamma_sl,instance,me,& pure subroutine kinetics_twin(Mp,T,dot_gamma_sl,ph,me,&
dot_gamma_twin,ddot_gamma_dtau_twin) dot_gamma_twin,ddot_gamma_dtau_twin)
real(pReal), dimension(3,3), intent(in) :: & real(pReal), dimension(3,3), intent(in) :: &
@ -967,17 +964,17 @@ pure subroutine kinetics_twin(Mp,T,dot_gamma_sl,instance,me,&
real(pReal), intent(in) :: & real(pReal), intent(in) :: &
T !< temperature T !< temperature
integer, intent(in) :: & integer, intent(in) :: &
instance, & ph, &
me me
real(pReal), dimension(param(instance)%sum_N_sl), intent(in) :: & real(pReal), dimension(param(ph)%sum_N_sl), intent(in) :: &
dot_gamma_sl dot_gamma_sl
real(pReal), dimension(param(instance)%sum_N_tw), intent(out) :: & real(pReal), dimension(param(ph)%sum_N_tw), intent(out) :: &
dot_gamma_twin dot_gamma_twin
real(pReal), dimension(param(instance)%sum_N_tw), optional, intent(out) :: & real(pReal), dimension(param(ph)%sum_N_tw), optional, intent(out) :: &
ddot_gamma_dtau_twin ddot_gamma_dtau_twin
real, dimension(param(instance)%sum_N_tw) :: & real, dimension(param(ph)%sum_N_tw) :: &
tau, & tau, &
Ndot0, & Ndot0, &
stressRatio_r, & stressRatio_r, &
@ -985,7 +982,7 @@ pure subroutine kinetics_twin(Mp,T,dot_gamma_sl,instance,me,&
integer :: i,s1,s2 integer :: i,s1,s2
associate(prm => param(instance), stt => state(instance), dst => dependentState(instance)) associate(prm => param(ph), stt => state(ph), dst => dependentState(ph))
do i = 1, prm%sum_N_tw do i = 1, prm%sum_N_tw
tau(i) = math_tensordot(Mp,prm%P_tw(1:3,1:3,i)) tau(i) = math_tensordot(Mp,prm%P_tw(1:3,1:3,i))
@ -1028,7 +1025,7 @@ end subroutine kinetics_twin
! NOTE: Against the common convention, the result (i.e. intent(out)) variables are the last to ! NOTE: Against the common convention, the result (i.e. intent(out)) variables are the last to
! have the optional arguments at the end. ! have the optional arguments at the end.
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
pure subroutine kinetics_trans(Mp,T,dot_gamma_sl,instance,me,& pure subroutine kinetics_trans(Mp,T,dot_gamma_sl,ph,me,&
dot_gamma_tr,ddot_gamma_dtau_trans) dot_gamma_tr,ddot_gamma_dtau_trans)
real(pReal), dimension(3,3), intent(in) :: & real(pReal), dimension(3,3), intent(in) :: &
@ -1036,24 +1033,24 @@ pure subroutine kinetics_trans(Mp,T,dot_gamma_sl,instance,me,&
real(pReal), intent(in) :: & real(pReal), intent(in) :: &
T !< temperature T !< temperature
integer, intent(in) :: & integer, intent(in) :: &
instance, & ph, &
me me
real(pReal), dimension(param(instance)%sum_N_sl), intent(in) :: & real(pReal), dimension(param(ph)%sum_N_sl), intent(in) :: &
dot_gamma_sl dot_gamma_sl
real(pReal), dimension(param(instance)%sum_N_tr), intent(out) :: & real(pReal), dimension(param(ph)%sum_N_tr), intent(out) :: &
dot_gamma_tr dot_gamma_tr
real(pReal), dimension(param(instance)%sum_N_tr), optional, intent(out) :: & real(pReal), dimension(param(ph)%sum_N_tr), optional, intent(out) :: &
ddot_gamma_dtau_trans ddot_gamma_dtau_trans
real, dimension(param(instance)%sum_N_tr) :: & real, dimension(param(ph)%sum_N_tr) :: &
tau, & tau, &
Ndot0, & Ndot0, &
stressRatio_s, & stressRatio_s, &
ddot_gamma_dtau ddot_gamma_dtau
integer :: i,s1,s2 integer :: i,s1,s2
associate(prm => param(instance), stt => state(instance), dst => dependentState(instance)) associate(prm => param(ph), stt => state(ph), dst => dependentState(ph))
do i = 1, prm%sum_N_tr do i = 1, prm%sum_N_tr
tau(i) = math_tensordot(Mp,prm%P_tr(1:3,1:3,i)) tau(i) = math_tensordot(Mp,prm%P_tr(1:3,1:3,i))

View File

@ -22,8 +22,6 @@ submodule(phase:plastic) isotropic
c_4, & c_4, &
c_3, & c_3, &
c_2 c_2
integer :: &
of_debug = 0
logical :: & logical :: &
dilatation dilatation
character(len=pStringLen), allocatable, dimension(:) :: & character(len=pStringLen), allocatable, dimension(:) :: &
@ -53,9 +51,7 @@ module function plastic_isotropic_init() result(myPlasticity)
logical, dimension(:), allocatable :: myPlasticity logical, dimension(:), allocatable :: myPlasticity
integer :: & integer :: &
Ninstances, & ph, &
p, &
i, &
Nconstituents, & Nconstituents, &
sizeState, sizeDotState sizeState, sizeDotState
real(pReal) :: & real(pReal) :: &
@ -68,32 +64,29 @@ module function plastic_isotropic_init() result(myPlasticity)
mech, & mech, &
pl pl
print'(/,a)', ' <<<+- phase:mechanics:plastic:isotropic init -+>>>'
myPlasticity = plastic_active('isotropic') myPlasticity = plastic_active('isotropic')
Ninstances = count(myPlasticity) if(count(myPlasticity) == 0) return
print'(a,i2)', ' # instances: ',Ninstances; flush(IO_STDOUT)
if(Ninstances == 0) return print'(/,a)', ' <<<+- phase:mechanical:plastic:isotropic init -+>>>'
print'(a,i0)', ' # phases: ',count(myPlasticity); flush(IO_STDOUT)
print*, 'Maiti and Eisenlohr, Scripta Materialia 145:3740, 2018' print*, 'Maiti and Eisenlohr, Scripta Materialia 145:3740, 2018'
print*, 'https://doi.org/10.1016/j.scriptamat.2017.09.047' print*, 'https://doi.org/10.1016/j.scriptamat.2017.09.047'
allocate(param(Ninstances))
allocate(state(Ninstances))
allocate(dotState(Ninstances))
phases => config_material%get('phase') phases => config_material%get('phase')
i = 0 allocate(param(phases%length))
do p = 1, phases%length allocate(state(phases%length))
phase => phases%get(p) allocate(dotState(phases%length))
mech => phase%get('mechanics')
if(.not. myPlasticity(p)) cycle
i = i + 1
associate(prm => param(i), &
dot => dotState(i), &
stt => state(i))
pl => mech%get('plasticity')
do ph = 1, phases%length
if(.not. myPlasticity(ph)) cycle
associate(prm => param(ph), dot => dotState(ph), stt => state(ph))
phase => phases%get(ph)
mech => phase%get('mechanics')
pl => mech%get('plasticity')
#if defined (__GFORTRAN__) #if defined (__GFORTRAN__)
prm%output = output_asStrings(pl) prm%output = output_asStrings(pl)
@ -101,11 +94,6 @@ module function plastic_isotropic_init() result(myPlasticity)
prm%output = pl%get_asStrings('output',defaultVal=emptyStringArray) prm%output = pl%get_asStrings('output',defaultVal=emptyStringArray)
#endif #endif
#ifdef DEBUG
if (p==material_phaseAt(debugConstitutive%grain,debugConstitutive%element)) &
prm%of_debug = material_phasememberAt(debugConstitutive%grain,debugConstitutive%ip,debugConstitutive%element)
#endif
xi_0 = pl%get_asFloat('xi_0') xi_0 = pl%get_asFloat('xi_0')
prm%xi_inf = pl%get_asFloat('xi_inf') prm%xi_inf = pl%get_asFloat('xi_inf')
prm%dot_gamma_0 = pl%get_asFloat('dot_gamma_0') prm%dot_gamma_0 = pl%get_asFloat('dot_gamma_0')
@ -131,28 +119,28 @@ module function plastic_isotropic_init() result(myPlasticity)
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
! allocate state arrays ! allocate state arrays
Nconstituents = count(material_phaseAt2 == p) Nconstituents = count(material_phaseAt2 == ph)
sizeDotState = size(['xi ','gamma']) sizeDotState = size(['xi ','gamma'])
sizeState = sizeDotState sizeState = sizeDotState
call constitutive_allocateState(plasticState(p),Nconstituents,sizeState,sizeDotState,0) call phase_allocateState(plasticState(ph),Nconstituents,sizeState,sizeDotState,0)
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
! state aliases and initialization ! state aliases and initialization
stt%xi => plasticState(p)%state (1,:) stt%xi => plasticState(ph)%state (1,:)
stt%xi = xi_0 stt%xi = xi_0
dot%xi => plasticState(p)%dotState(1,:) dot%xi => plasticState(ph)%dotState(1,:)
plasticState(p)%atol(1) = pl%get_asFloat('atol_xi',defaultVal=1.0_pReal) plasticState(ph)%atol(1) = pl%get_asFloat('atol_xi',defaultVal=1.0_pReal)
if (plasticState(p)%atol(1) < 0.0_pReal) extmsg = trim(extmsg)//' atol_xi' if (plasticState(ph)%atol(1) < 0.0_pReal) extmsg = trim(extmsg)//' atol_xi'
stt%gamma => plasticState(p)%state (2,:) stt%gamma => plasticState(ph)%state (2,:)
dot%gamma => plasticState(p)%dotState(2,:) dot%gamma => plasticState(ph)%dotState(2,:)
plasticState(p)%atol(2) = pl%get_asFloat('atol_gamma',defaultVal=1.0e-6_pReal) plasticState(ph)%atol(2) = pl%get_asFloat('atol_gamma',defaultVal=1.0e-6_pReal)
if (plasticState(p)%atol(2) < 0.0_pReal) extmsg = trim(extmsg)//' atol_gamma' if (plasticState(ph)%atol(2) < 0.0_pReal) extmsg = trim(extmsg)//' atol_gamma'
! global alias ! global alias
plasticState(p)%slipRate => plasticState(p)%dotState(2:2,:) plasticState(ph)%slipRate => plasticState(ph)%dotState(2:2,:)
plasticState(p)%state0 = plasticState(p)%state ! ToDo: this could be done centrally plasticState(ph)%state0 = plasticState(ph)%state ! ToDo: this could be done centrally
end associate end associate
@ -190,7 +178,7 @@ module subroutine isotropic_LpAndItsTangent(Lp,dLp_dMp,Mp,ph,me)
integer :: & integer :: &
k, l, m, n k, l, m, n
associate(prm => param(phase_plasticityInstance(ph)), stt => state(phase_plasticityInstance(ph))) associate(prm => param(ph), stt => state(ph))
Mp_dev = math_deviatoric33(Mp) Mp_dev = math_deviatoric33(Mp)
squarenorm_Mp_dev = math_tensordot(Mp_dev,Mp_dev) squarenorm_Mp_dev = math_tensordot(Mp_dev,Mp_dev)
@ -220,7 +208,7 @@ end subroutine isotropic_LpAndItsTangent
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief Calculate inelastic velocity gradient and its tangent. !> @brief Calculate inelastic velocity gradient and its tangent.
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
module subroutine plastic_isotropic_LiAndItsTangent(Li,dLi_dMi,Mi,instance,me) module subroutine plastic_isotropic_LiAndItsTangent(Li,dLi_dMi,Mi,ph,me)
real(pReal), dimension(3,3), intent(out) :: & real(pReal), dimension(3,3), intent(out) :: &
Li !< inleastic velocity gradient Li !< inleastic velocity gradient
@ -230,7 +218,7 @@ module subroutine plastic_isotropic_LiAndItsTangent(Li,dLi_dMi,Mi,instance,me)
real(pReal), dimension(3,3), intent(in) :: & real(pReal), dimension(3,3), intent(in) :: &
Mi !< Mandel stress Mi !< Mandel stress
integer, intent(in) :: & integer, intent(in) :: &
instance, & ph, &
me me
real(pReal) :: & real(pReal) :: &
@ -238,17 +226,15 @@ module subroutine plastic_isotropic_LiAndItsTangent(Li,dLi_dMi,Mi,instance,me)
integer :: & integer :: &
k, l, m, n k, l, m, n
associate(prm => param(instance), stt => state(instance)) associate(prm => param(ph), stt => state(ph))
tr=math_trace33(math_spherical33(Mi)) tr=math_trace33(math_spherical33(Mi))
if (prm%dilatation .and. abs(tr) > 0.0_pReal) then ! no stress or J2 plasticity --> Li and its derivative are zero if (prm%dilatation .and. abs(tr) > 0.0_pReal) then ! no stress or J2 plasticity --> Li and its derivative are zero
Li = math_I3 & Li = math_I3 &
* prm%dot_gamma_0/prm%M * (3.0_pReal*prm%M*stt%xi(me))**(-prm%n) & * prm%dot_gamma_0/prm%M * (3.0_pReal*prm%M*stt%xi(me))**(-prm%n) &
* tr * abs(tr)**(prm%n-1.0_pReal) * tr * abs(tr)**(prm%n-1.0_pReal)
forall (k=1:3,l=1:3,m=1:3,n=1:3) dLi_dMi(k,l,m,n) = prm%n / tr * Li(k,l) * math_I3(m,n) forall (k=1:3,l=1:3,m=1:3,n=1:3) dLi_dMi(k,l,m,n) = prm%n / tr * Li(k,l) * math_I3(m,n)
else else
Li = 0.0_pReal Li = 0.0_pReal
dLi_dMi = 0.0_pReal dLi_dMi = 0.0_pReal
@ -275,8 +261,8 @@ module subroutine isotropic_dotState(Mp,ph,me)
xi_inf_star, & !< saturation xi xi_inf_star, & !< saturation xi
norm_Mp !< norm of the (deviatoric) Mandel stress norm_Mp !< norm of the (deviatoric) Mandel stress
associate(prm => param(phase_plasticityInstance(ph)), stt => state(phase_plasticityInstance(ph)), & associate(prm => param(ph), stt => state(ph), &
dot => dotState(phase_plasticityInstance(ph))) dot => dotState(ph))
if (prm%dilatation) then if (prm%dilatation) then
norm_Mp = sqrt(math_tensordot(Mp,Mp)) norm_Mp = sqrt(math_tensordot(Mp,Mp))
@ -312,14 +298,14 @@ end subroutine isotropic_dotState
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief Write results to HDF5 output file. !> @brief Write results to HDF5 output file.
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
module subroutine plastic_isotropic_results(instance,group) module subroutine plastic_isotropic_results(ph,group)
integer, intent(in) :: instance integer, intent(in) :: ph
character(len=*), intent(in) :: group character(len=*), intent(in) :: group
integer :: o integer :: o
associate(prm => param(instance), stt => state(instance)) associate(prm => param(ph), stt => state(ph))
outputsLoop: do o = 1,size(prm%output) outputsLoop: do o = 1,size(prm%output)
select case(trim(prm%output(o))) select case(trim(prm%output(o)))
case ('xi') case ('xi')

View File

@ -25,8 +25,7 @@ submodule(phase:plastic) kinehardening
nonSchmid_pos, & nonSchmid_pos, &
nonSchmid_neg nonSchmid_neg
integer :: & integer :: &
sum_N_sl, & !< total number of active slip system sum_N_sl
of_debug = 0
logical :: & logical :: &
nonSchmidActive = .false. nonSchmidActive = .false.
character(len=pStringLen), allocatable, dimension(:) :: & character(len=pStringLen), allocatable, dimension(:) :: &
@ -62,8 +61,7 @@ module function plastic_kinehardening_init() result(myPlasticity)
logical, dimension(:), allocatable :: myPlasticity logical, dimension(:), allocatable :: myPlasticity
integer :: & integer :: &
Ninstances, & ph, o, &
p, i, o, &
Nconstituents, & Nconstituents, &
sizeState, sizeDeltaState, sizeDotState, & sizeState, sizeDeltaState, sizeDotState, &
startIndex, endIndex startIndex, endIndex
@ -80,29 +78,27 @@ module function plastic_kinehardening_init() result(myPlasticity)
mech, & mech, &
pl pl
print'(/,a)', ' <<<+- phase:mechanics:plastic:kinehardening init -+>>>'
myPlasticity = plastic_active('kinehardening') myPlasticity = plastic_active('kinehardening')
Ninstances = count(myPlasticity) if(count(myPlasticity) == 0) return
print'(a,i2)', ' # instances: ',Ninstances; flush(IO_STDOUT)
if(Ninstances == 0) return print'(/,a)', ' <<<+- phase:mechanical:plastic:kinehardening init -+>>>'
print'(a,i0)', ' # phases: ',count(myPlasticity); flush(IO_STDOUT)
allocate(param(Ninstances))
allocate(state(Ninstances))
allocate(dotState(Ninstances))
allocate(deltaState(Ninstances))
phases => config_material%get('phase') phases => config_material%get('phase')
i = 0 allocate(param(phases%length))
do p = 1, phases%length allocate(state(phases%length))
phase => phases%get(p) allocate(dotState(phases%length))
allocate(deltaState(phases%length))
do ph = 1, phases%length
if(.not. myPlasticity(ph)) cycle
associate(prm => param(ph), dot => dotState(ph), dlt => deltaState(ph), stt => state(ph))
phase => phases%get(ph)
mech => phase%get('mechanics') mech => phase%get('mechanics')
if(.not. myPlasticity(p)) cycle
i = i + 1
associate(prm => param(i), &
dot => dotState(i), &
dlt => deltaState(i), &
stt => state(i))
pl => mech%get('plasticity') pl => mech%get('plasticity')
#if defined (__GFORTRAN__) #if defined (__GFORTRAN__)
@ -111,12 +107,6 @@ module function plastic_kinehardening_init() result(myPlasticity)
prm%output = pl%get_asStrings('output',defaultVal=emptyStringArray) prm%output = pl%get_asStrings('output',defaultVal=emptyStringArray)
#endif #endif
#ifdef DEBUG
if (p==material_phaseAt(debugConstitutive%grain,debugConstitutive%element)) then
prm%of_debug = material_phasememberAt(debugConstitutive%grain,debugConstitutive%ip,debugConstitutive%element)
endif
#endif
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
! slip related parameters ! slip related parameters
N_sl = pl%get_asInts('N_sl',defaultVal=emptyIntArray) N_sl = pl%get_asInts('N_sl',defaultVal=emptyIntArray)
@ -175,55 +165,55 @@ module function plastic_kinehardening_init() result(myPlasticity)
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
! allocate state arrays ! allocate state arrays
Nconstituents = count(material_phaseAt2 == p) Nconstituents = count(material_phaseAt2 == ph)
sizeDotState = size(['crss ','crss_back', 'accshear ']) * prm%sum_N_sl!ToDo: adjust names, ask Philip sizeDotState = size(['crss ','crss_back', 'accshear ']) * prm%sum_N_sl !ToDo: adjust names like in material.yaml
sizeDeltaState = size(['sense ', 'chi0 ', 'gamma0' ]) * prm%sum_N_sl !ToDo: adjust names sizeDeltaState = size(['sense ', 'chi0 ', 'gamma0' ]) * prm%sum_N_sl !ToDo: adjust names like in material.yaml
sizeState = sizeDotState + sizeDeltaState sizeState = sizeDotState + sizeDeltaState
call constitutive_allocateState(plasticState(p),Nconstituents,sizeState,sizeDotState,sizeDeltaState) call phase_allocateState(plasticState(ph),Nconstituents,sizeState,sizeDotState,sizeDeltaState)
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
! state aliases and initialization ! state aliases and initialization
startIndex = 1 startIndex = 1
endIndex = prm%sum_N_sl endIndex = prm%sum_N_sl
stt%crss => plasticState(p)%state (startIndex:endIndex,:) stt%crss => plasticState(ph)%state (startIndex:endIndex,:)
stt%crss = spread(xi_0, 2, Nconstituents) stt%crss = spread(xi_0, 2, Nconstituents)
dot%crss => plasticState(p)%dotState(startIndex:endIndex,:) dot%crss => plasticState(ph)%dotState(startIndex:endIndex,:)
plasticState(p)%atol(startIndex:endIndex) = pl%get_asFloat('atol_xi',defaultVal=1.0_pReal) plasticState(ph)%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' if(any(plasticState(ph)%atol(startIndex:endIndex) < 0.0_pReal)) extmsg = trim(extmsg)//' atol_xi'
startIndex = endIndex + 1 startIndex = endIndex + 1
endIndex = endIndex + prm%sum_N_sl endIndex = endIndex + prm%sum_N_sl
stt%crss_back => plasticState(p)%state (startIndex:endIndex,:) stt%crss_back => plasticState(ph)%state (startIndex:endIndex,:)
dot%crss_back => plasticState(p)%dotState(startIndex:endIndex,:) dot%crss_back => plasticState(ph)%dotState(startIndex:endIndex,:)
plasticState(p)%atol(startIndex:endIndex) = pl%get_asFloat('atol_xi',defaultVal=1.0_pReal) plasticState(ph)%atol(startIndex:endIndex) = pl%get_asFloat('atol_xi',defaultVal=1.0_pReal)
startIndex = endIndex + 1 startIndex = endIndex + 1
endIndex = endIndex + prm%sum_N_sl endIndex = endIndex + prm%sum_N_sl
stt%accshear => plasticState(p)%state (startIndex:endIndex,:) stt%accshear => plasticState(ph)%state (startIndex:endIndex,:)
dot%accshear => plasticState(p)%dotState(startIndex:endIndex,:) dot%accshear => plasticState(ph)%dotState(startIndex:endIndex,:)
plasticState(p)%atol(startIndex:endIndex) = pl%get_asFloat('atol_gamma',defaultVal=1.0e-6_pReal) plasticState(ph)%atol(startIndex:endIndex) = pl%get_asFloat('atol_gamma',defaultVal=1.0e-6_pReal)
if(any(plasticState(p)%atol(startIndex:endIndex) < 0.0_pReal)) extmsg = trim(extmsg)//' atol_gamma' if(any(plasticState(ph)%atol(startIndex:endIndex) < 0.0_pReal)) extmsg = trim(extmsg)//' atol_gamma'
! global alias ! global alias
plasticState(p)%slipRate => plasticState(p)%dotState(startIndex:endIndex,:) plasticState(ph)%slipRate => plasticState(ph)%dotState(startIndex:endIndex,:)
o = plasticState(p)%offsetDeltaState o = plasticState(ph)%offsetDeltaState
startIndex = endIndex + 1 startIndex = endIndex + 1
endIndex = endIndex + prm%sum_N_sl endIndex = endIndex + prm%sum_N_sl
stt%sense => plasticState(p)%state (startIndex :endIndex ,:) stt%sense => plasticState(ph)%state (startIndex :endIndex ,:)
dlt%sense => plasticState(p)%deltaState(startIndex-o:endIndex-o,:) dlt%sense => plasticState(ph)%deltaState(startIndex-o:endIndex-o,:)
startIndex = endIndex + 1 startIndex = endIndex + 1
endIndex = endIndex + prm%sum_N_sl endIndex = endIndex + prm%sum_N_sl
stt%chi0 => plasticState(p)%state (startIndex :endIndex ,:) stt%chi0 => plasticState(ph)%state (startIndex :endIndex ,:)
dlt%chi0 => plasticState(p)%deltaState(startIndex-o:endIndex-o,:) dlt%chi0 => plasticState(ph)%deltaState(startIndex-o:endIndex-o,:)
startIndex = endIndex + 1 startIndex = endIndex + 1
endIndex = endIndex + prm%sum_N_sl endIndex = endIndex + prm%sum_N_sl
stt%gamma0 => plasticState(p)%state (startIndex :endIndex ,:) stt%gamma0 => plasticState(ph)%state (startIndex :endIndex ,:)
dlt%gamma0 => plasticState(p)%deltaState(startIndex-o:endIndex-o,:) dlt%gamma0 => plasticState(ph)%deltaState(startIndex-o:endIndex-o,:)
plasticState(p)%state0 = plasticState(p)%state ! ToDo: this could be done centrally plasticState(ph)%state0 = plasticState(ph)%state ! ToDo: this could be done centrally
end associate end associate
@ -255,16 +245,16 @@ pure module subroutine kinehardening_LpAndItsTangent(Lp,dLp_dMp,Mp,ph,me)
integer :: & integer :: &
i,k,l,m,n i,k,l,m,n
real(pReal), dimension(param(phase_plasticityInstance(ph))%sum_N_sl) :: & real(pReal), dimension(param(ph)%sum_N_sl) :: &
gdot_pos,gdot_neg, & gdot_pos,gdot_neg, &
dgdot_dtau_pos,dgdot_dtau_neg dgdot_dtau_pos,dgdot_dtau_neg
Lp = 0.0_pReal Lp = 0.0_pReal
dLp_dMp = 0.0_pReal dLp_dMp = 0.0_pReal
associate(prm => param(phase_plasticityInstance(ph))) associate(prm => param(ph))
call kinetics(Mp,phase_plasticityInstance(ph),me,gdot_pos,gdot_neg,dgdot_dtau_pos,dgdot_dtau_neg) call kinetics(Mp,ph,me,gdot_pos,gdot_neg,dgdot_dtau_pos,dgdot_dtau_neg)
do i = 1, prm%sum_N_sl do i = 1, prm%sum_N_sl
Lp = Lp + (gdot_pos(i)+gdot_neg(i))*prm%P(1:3,1:3,i) Lp = Lp + (gdot_pos(i)+gdot_neg(i))*prm%P(1:3,1:3,i)
@ -292,14 +282,14 @@ module subroutine plastic_kinehardening_dotState(Mp,ph,me)
real(pReal) :: & real(pReal) :: &
sumGamma sumGamma
real(pReal), dimension(param(phase_plasticityInstance(ph))%sum_N_sl) :: & real(pReal), dimension(param(ph)%sum_N_sl) :: &
gdot_pos,gdot_neg gdot_pos,gdot_neg
associate(prm => param(phase_plasticityInstance(ph)), stt => state(phase_plasticityInstance(ph)),& associate(prm => param(ph), stt => state(ph),&
dot => dotState(phase_plasticityInstance(ph))) dot => dotState(ph))
call kinetics(Mp,phase_plasticityInstance(ph),me,gdot_pos,gdot_neg) call kinetics(Mp,ph,me,gdot_pos,gdot_neg)
dot%accshear(:,me) = abs(gdot_pos+gdot_neg) dot%accshear(:,me) = abs(gdot_pos+gdot_neg)
sumGamma = sum(stt%accshear(:,me)) sumGamma = sum(stt%accshear(:,me))
@ -325,32 +315,25 @@ end subroutine plastic_kinehardening_dotState
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief Calculate (instantaneous) incremental change of microstructure. !> @brief Calculate (instantaneous) incremental change of microstructure.
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
module subroutine plastic_kinehardening_deltaState(Mp,instance,me) module subroutine plastic_kinehardening_deltaState(Mp,ph,me)
real(pReal), dimension(3,3), intent(in) :: & real(pReal), dimension(3,3), intent(in) :: &
Mp !< Mandel stress Mp !< Mandel stress
integer, intent(in) :: & integer, intent(in) :: &
instance, & ph, &
me me
real(pReal), dimension(param(instance)%sum_N_sl) :: & real(pReal), dimension(param(ph)%sum_N_sl) :: &
gdot_pos,gdot_neg, & gdot_pos,gdot_neg, &
sense sense
associate(prm => param(instance), stt => state(instance), dlt => deltaState(instance)) associate(prm => param(ph), stt => state(ph), dlt => deltaState(ph))
call kinetics(Mp,instance,me,gdot_pos,gdot_neg) call kinetics(Mp,ph,me,gdot_pos,gdot_neg)
sense = merge(state(instance)%sense(:,me), & ! keep existing... sense = merge(state(ph)%sense(:,me), & ! keep existing...
sign(1.0_pReal,gdot_pos+gdot_neg), & ! ...or have a defined sign(1.0_pReal,gdot_pos+gdot_neg), & ! ...or have a defined
dEq0(gdot_pos+gdot_neg,1e-10_pReal)) ! current sense of shear direction dEq0(gdot_pos+gdot_neg,1e-10_pReal)) ! current sense of shear direction
#ifdef DEBUG
if (debugConstitutive%extensive &
.and. (me == prm%of_debug .or. .not. debugConstitutive%selective)) then
print*, '======= kinehardening delta state ======='
print*, sense,state(instance)%sense(:,me)
endif
#endif
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
! switch in sense me shear? ! switch in sense me shear?
@ -372,14 +355,14 @@ end subroutine plastic_kinehardening_deltaState
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief Write results to HDF5 output file. !> @brief Write results to HDF5 output file.
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
module subroutine plastic_kinehardening_results(instance,group) module subroutine plastic_kinehardening_results(ph,group)
integer, intent(in) :: instance integer, intent(in) :: ph
character(len=*), intent(in) :: group character(len=*), intent(in) :: group
integer :: o integer :: o
associate(prm => param(instance), stt => state(instance)) associate(prm => param(ph), stt => state(ph))
outputsLoop: do o = 1,size(prm%output) outputsLoop: do o = 1,size(prm%output)
select case(trim(prm%output(o))) select case(trim(prm%output(o)))
case('xi') case('xi')
@ -414,28 +397,28 @@ end subroutine plastic_kinehardening_results
! NOTE: Against the common convention, the result (i.e. intent(out)) variables are the last to ! NOTE: Against the common convention, the result (i.e. intent(out)) variables are the last to
! have the optional arguments at the end. ! have the optional arguments at the end.
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
pure subroutine kinetics(Mp,instance,me, & pure subroutine kinetics(Mp,ph,me, &
gdot_pos,gdot_neg,dgdot_dtau_pos,dgdot_dtau_neg) gdot_pos,gdot_neg,dgdot_dtau_pos,dgdot_dtau_neg)
real(pReal), dimension(3,3), intent(in) :: & real(pReal), dimension(3,3), intent(in) :: &
Mp !< Mandel stress Mp !< Mandel stress
integer, intent(in) :: & integer, intent(in) :: &
instance, & ph, &
me me
real(pReal), intent(out), dimension(param(instance)%sum_N_sl) :: & real(pReal), intent(out), dimension(param(ph)%sum_N_sl) :: &
gdot_pos, & gdot_pos, &
gdot_neg gdot_neg
real(pReal), intent(out), optional, dimension(param(instance)%sum_N_sl) :: & real(pReal), intent(out), optional, dimension(param(ph)%sum_N_sl) :: &
dgdot_dtau_pos, & dgdot_dtau_pos, &
dgdot_dtau_neg dgdot_dtau_neg
real(pReal), dimension(param(instance)%sum_N_sl) :: & real(pReal), dimension(param(ph)%sum_N_sl) :: &
tau_pos, & tau_pos, &
tau_neg tau_neg
integer :: i integer :: i
associate(prm => param(instance), stt => state(instance)) associate(prm => param(ph), stt => state(ph))
do i = 1, prm%sum_N_sl do i = 1, prm%sum_N_sl
tau_pos(i) = math_tensordot(Mp,prm%nonSchmid_pos(1:3,1:3,i)) - stt%crss_back(i,me) tau_pos(i) = math_tensordot(Mp,prm%nonSchmid_pos(1:3,1:3,i)) - stt%crss_back(i,me)

View File

@ -16,35 +16,21 @@ module function plastic_none_init() result(myPlasticity)
logical, dimension(:), allocatable :: myPlasticity logical, dimension(:), allocatable :: myPlasticity
integer :: & integer :: &
Ninstances, & ph
p, &
Nconstituents
class(tNode), pointer :: & class(tNode), pointer :: &
phases, & phases
phase, &
mech, &
pl
print'(/,a)', ' <<<+- phase:mechanics:plastic:none init -+>>>'
myPlasticity = plastic_active('none')
if(count(myPlasticity) == 0) return
print'(/,a)', ' <<<+- phase:mechanical:plastic:none init -+>>>'
print'(a,i0)', ' # phases: ',count(myPlasticity); flush(IO_STDOUT)
phases => config_material%get('phase') phases => config_material%get('phase')
allocate(myPlasticity(phases%length), source = .false.) do ph = 1, phases%length
do p = 1, phases%length if(.not. myPlasticity(ph)) cycle
phase => phases%get(p) call phase_allocateState(plasticState(ph),count(material_phaseAt2 == ph),0,0,0)
mech => phase%get('mechanics')
pl => mech%get ('plasticity')
if(pl%get_asString('type') == 'none') myPlasticity(p) = .true.
enddo
Ninstances = count(myPlasticity)
print'(a,i2)', ' # instances: ',Ninstances; flush(IO_STDOUT)
if(Ninstances == 0) return
do p = 1, phases%length
phase => phases%get(p)
if(.not. myPlasticity(p)) cycle
Nconstituents = count(material_phaseAt2 == p)
call constitutive_allocateState(plasticState(p),Nconstituents,0,0,0)
enddo enddo
end function plastic_none_init end function plastic_none_init

View File

@ -13,6 +13,12 @@ submodule(phase:plastic) nonlocal
IPareaNormal => geometry_plastic_nonlocal_IPareaNormal0, & IPareaNormal => geometry_plastic_nonlocal_IPareaNormal0, &
geometry_plastic_nonlocal_disable geometry_plastic_nonlocal_disable
type :: tGeometry
real(pReal), dimension(:), allocatable :: V_0
end type tGeometry
type(tGeometry), dimension(:), allocatable :: geom
real(pReal), parameter :: & real(pReal), parameter :: &
kB = 1.38e-23_pReal !< Boltzmann constant in J/Kelvin kB = 1.38e-23_pReal !< Boltzmann constant in J/Kelvin
@ -154,7 +160,7 @@ submodule(phase:plastic) nonlocal
state, & state, &
state0 state0
type(tParameters), dimension(:), allocatable :: param !< containers of constitutive parameters (len Ninstances) type(tParameters), dimension(:), allocatable :: param !< containers of constitutive parameters
type(tNonlocalMicrostructure), dimension(:), allocatable :: microstructure type(tNonlocalMicrostructure), dimension(:), allocatable :: microstructure
@ -170,7 +176,7 @@ module function plastic_nonlocal_init() result(myPlasticity)
logical, dimension(:), allocatable :: myPlasticity logical, dimension(:), allocatable :: myPlasticity
integer :: & integer :: &
Ninstances, & Ninstances, &
p, i, & ph, &
Nconstituents, & Nconstituents, &
sizeState, sizeDotState, sizeDependentState, sizeDeltaState, & sizeState, sizeDotState, sizeDependentState, sizeDeltaState, &
s1, s2, & s1, s2, &
@ -187,45 +193,44 @@ module function plastic_nonlocal_init() result(myPlasticity)
mech, & mech, &
pl pl
print'(/,a)', ' <<<+- phase:mechanics:plastic:nonlocal init -+>>>'
myPlasticity = plastic_active('nonlocal') myPlasticity = plastic_active('nonlocal')
Ninstances = count(myPlasticity) Ninstances = count(myPlasticity)
print'(a,i2)', ' # instances: ',Ninstances; flush(IO_STDOUT)
if(Ninstances == 0) then if(Ninstances == 0) then
call geometry_plastic_nonlocal_disable call geometry_plastic_nonlocal_disable
return return
endif endif
print'(/,a)', ' <<<+- phase:mechanical:plastic:nonlocal init -+>>>'
print'(a,i0)', ' # phases: ',Ninstances; flush(IO_STDOUT)
print*, 'Reuber et al., Acta Materialia 71:333348, 2014' print*, 'Reuber et al., Acta Materialia 71:333348, 2014'
print*, 'https://doi.org/10.1016/j.actamat.2014.03.012'//IO_EOL print*, 'https://doi.org/10.1016/j.actamat.2014.03.012'//IO_EOL
print*, 'Kords, Dissertation RWTH Aachen, 2014' print*, 'Kords, Dissertation RWTH Aachen, 2014'
print*, 'http://publications.rwth-aachen.de/record/229993' print*, 'http://publications.rwth-aachen.de/record/229993'
allocate(param(Ninstances))
allocate(state(Ninstances))
allocate(state0(Ninstances))
allocate(dotState(Ninstances))
allocate(deltaState(Ninstances))
allocate(microstructure(Ninstances))
phases => config_material%get('phase') phases => config_material%get('phase')
i = 0 allocate(geom(phases%length))
do p = 1, phases%length
phase => phases%get(p) allocate(param(phases%length))
allocate(state(phases%length))
allocate(state0(phases%length))
allocate(dotState(phases%length))
allocate(deltaState(phases%length))
allocate(microstructure(phases%length))
do ph = 1, phases%length
if(.not. myPlasticity(ph)) cycle
associate(prm => param(ph), dot => dotState(ph), stt => state(ph), &
st0 => state0(ph), del => deltaState(ph), dst => microstructure(ph))
phase => phases%get(ph)
mech => phase%get('mechanics') mech => phase%get('mechanics')
if(.not. myPlasticity(p)) cycle
i = i + 1
associate(prm => param(i), &
dot => dotState(i), &
stt => state(i), &
st0 => state0(i), &
del => deltaState(i), &
dst => microstructure(i))
pl => mech%get('plasticity') pl => mech%get('plasticity')
phase_localPlasticity(p) = .not. pl%contains('nonlocal') phase_localPlasticity(ph) = .not. pl%contains('nonlocal')
#if defined (__GFORTRAN__) #if defined (__GFORTRAN__)
prm%output = output_asStrings(pl) prm%output = output_asStrings(pl)
@ -236,8 +241,8 @@ module function plastic_nonlocal_init() result(myPlasticity)
prm%atol_rho = pl%get_asFloat('atol_rho',defaultVal=1.0e4_pReal) prm%atol_rho = pl%get_asFloat('atol_rho',defaultVal=1.0e4_pReal)
! This data is read in already in lattice ! This data is read in already in lattice
prm%mu = lattice_mu(p) prm%mu = lattice_mu(ph)
prm%nu = lattice_nu(p) prm%nu = lattice_nu(ph)
ini%N_sl = pl%get_asInts('N_sl',defaultVal=emptyIntArray) ini%N_sl = pl%get_asInts('N_sl',defaultVal=emptyIntArray)
prm%sum_N_sl = sum(abs(ini%N_sl)) prm%sum_N_sl = sum(abs(ini%N_sl))
@ -393,7 +398,7 @@ module function plastic_nonlocal_init() result(myPlasticity)
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
! allocate state arrays ! allocate state arrays
Nconstituents = count(material_phaseAt2 == p) Nconstituents = count(material_phaseAt2 == ph)
sizeDotState = size([ 'rhoSglEdgePosMobile ','rhoSglEdgeNegMobile ', & sizeDotState = size([ 'rhoSglEdgePosMobile ','rhoSglEdgeNegMobile ', &
'rhoSglScrewPosMobile ','rhoSglScrewNegMobile ', & 'rhoSglScrewPosMobile ','rhoSglScrewNegMobile ', &
'rhoSglEdgePosImmobile ','rhoSglEdgeNegImmobile ', & 'rhoSglEdgePosImmobile ','rhoSglEdgeNegImmobile ', &
@ -407,98 +412,101 @@ module function plastic_nonlocal_init() result(myPlasticity)
'maxDipoleHeightEdge ','maxDipoleHeightScrew' ]) * prm%sum_N_sl !< other dependent state variables that are not updated by microstructure 'maxDipoleHeightEdge ','maxDipoleHeightScrew' ]) * prm%sum_N_sl !< other dependent state variables that are not updated by microstructure
sizeDeltaState = sizeDotState sizeDeltaState = sizeDotState
call constitutive_allocateState(plasticState(p),Nconstituents,sizeState,sizeDotState,sizeDeltaState) call phase_allocateState(plasticState(ph),Nconstituents,sizeState,sizeDotState,sizeDeltaState)
plasticState(p)%nonlocal = pl%get_asBool('nonlocal') allocate(geom(ph)%V_0(Nconstituents))
if(plasticState(p)%nonlocal .and. .not. allocated(IPneighborhood)) & call storeGeometry(ph)
plasticState(ph)%nonlocal = pl%get_asBool('nonlocal')
if(plasticState(ph)%nonlocal .and. .not. allocated(IPneighborhood)) &
call IO_error(212,ext_msg='IPneighborhood does not exist') call IO_error(212,ext_msg='IPneighborhood does not exist')
plasticState(p)%offsetDeltaState = 0 ! ToDo: state structure does not follow convention plasticState(ph)%offsetDeltaState = 0 ! ToDo: state structure does not follow convention
st0%rho => plasticState(p)%state0 (0*prm%sum_N_sl+1:10*prm%sum_N_sl,:) st0%rho => plasticState(ph)%state0 (0*prm%sum_N_sl+1:10*prm%sum_N_sl,:)
stt%rho => plasticState(p)%state (0*prm%sum_N_sl+1:10*prm%sum_N_sl,:) stt%rho => plasticState(ph)%state (0*prm%sum_N_sl+1:10*prm%sum_N_sl,:)
dot%rho => plasticState(p)%dotState (0*prm%sum_N_sl+1:10*prm%sum_N_sl,:) dot%rho => plasticState(ph)%dotState (0*prm%sum_N_sl+1:10*prm%sum_N_sl,:)
del%rho => plasticState(p)%deltaState (0*prm%sum_N_sl+1:10*prm%sum_N_sl,:) del%rho => plasticState(ph)%deltaState (0*prm%sum_N_sl+1:10*prm%sum_N_sl,:)
plasticState(p)%atol(1:10*prm%sum_N_sl) = prm%atol_rho plasticState(ph)%atol(1:10*prm%sum_N_sl) = prm%atol_rho
stt%rhoSgl => plasticState(p)%state (0*prm%sum_N_sl+1: 8*prm%sum_N_sl,:) stt%rhoSgl => plasticState(ph)%state (0*prm%sum_N_sl+1: 8*prm%sum_N_sl,:)
dot%rhoSgl => plasticState(p)%dotState (0*prm%sum_N_sl+1: 8*prm%sum_N_sl,:) dot%rhoSgl => plasticState(ph)%dotState (0*prm%sum_N_sl+1: 8*prm%sum_N_sl,:)
del%rhoSgl => plasticState(p)%deltaState (0*prm%sum_N_sl+1: 8*prm%sum_N_sl,:) del%rhoSgl => plasticState(ph)%deltaState (0*prm%sum_N_sl+1: 8*prm%sum_N_sl,:)
stt%rhoSglMobile => plasticState(p)%state (0*prm%sum_N_sl+1: 4*prm%sum_N_sl,:) stt%rhoSglMobile => plasticState(ph)%state (0*prm%sum_N_sl+1: 4*prm%sum_N_sl,:)
dot%rhoSglMobile => plasticState(p)%dotState (0*prm%sum_N_sl+1: 4*prm%sum_N_sl,:) dot%rhoSglMobile => plasticState(ph)%dotState (0*prm%sum_N_sl+1: 4*prm%sum_N_sl,:)
del%rhoSglMobile => plasticState(p)%deltaState (0*prm%sum_N_sl+1: 4*prm%sum_N_sl,:) del%rhoSglMobile => plasticState(ph)%deltaState (0*prm%sum_N_sl+1: 4*prm%sum_N_sl,:)
stt%rho_sgl_mob_edg_pos => plasticState(p)%state (0*prm%sum_N_sl+1: 1*prm%sum_N_sl,:) stt%rho_sgl_mob_edg_pos => plasticState(ph)%state (0*prm%sum_N_sl+1: 1*prm%sum_N_sl,:)
dot%rho_sgl_mob_edg_pos => plasticState(p)%dotState (0*prm%sum_N_sl+1: 1*prm%sum_N_sl,:) dot%rho_sgl_mob_edg_pos => plasticState(ph)%dotState (0*prm%sum_N_sl+1: 1*prm%sum_N_sl,:)
del%rho_sgl_mob_edg_pos => plasticState(p)%deltaState (0*prm%sum_N_sl+1: 1*prm%sum_N_sl,:) del%rho_sgl_mob_edg_pos => plasticState(ph)%deltaState (0*prm%sum_N_sl+1: 1*prm%sum_N_sl,:)
stt%rho_sgl_mob_edg_neg => plasticState(p)%state (1*prm%sum_N_sl+1: 2*prm%sum_N_sl,:) stt%rho_sgl_mob_edg_neg => plasticState(ph)%state (1*prm%sum_N_sl+1: 2*prm%sum_N_sl,:)
dot%rho_sgl_mob_edg_neg => plasticState(p)%dotState (1*prm%sum_N_sl+1: 2*prm%sum_N_sl,:) dot%rho_sgl_mob_edg_neg => plasticState(ph)%dotState (1*prm%sum_N_sl+1: 2*prm%sum_N_sl,:)
del%rho_sgl_mob_edg_neg => plasticState(p)%deltaState (1*prm%sum_N_sl+1: 2*prm%sum_N_sl,:) del%rho_sgl_mob_edg_neg => plasticState(ph)%deltaState (1*prm%sum_N_sl+1: 2*prm%sum_N_sl,:)
stt%rho_sgl_mob_scr_pos => plasticState(p)%state (2*prm%sum_N_sl+1: 3*prm%sum_N_sl,:) stt%rho_sgl_mob_scr_pos => plasticState(ph)%state (2*prm%sum_N_sl+1: 3*prm%sum_N_sl,:)
dot%rho_sgl_mob_scr_pos => plasticState(p)%dotState (2*prm%sum_N_sl+1: 3*prm%sum_N_sl,:) dot%rho_sgl_mob_scr_pos => plasticState(ph)%dotState (2*prm%sum_N_sl+1: 3*prm%sum_N_sl,:)
del%rho_sgl_mob_scr_pos => plasticState(p)%deltaState (2*prm%sum_N_sl+1: 3*prm%sum_N_sl,:) del%rho_sgl_mob_scr_pos => plasticState(ph)%deltaState (2*prm%sum_N_sl+1: 3*prm%sum_N_sl,:)
stt%rho_sgl_mob_scr_neg => plasticState(p)%state (3*prm%sum_N_sl+1: 4*prm%sum_N_sl,:) stt%rho_sgl_mob_scr_neg => plasticState(ph)%state (3*prm%sum_N_sl+1: 4*prm%sum_N_sl,:)
dot%rho_sgl_mob_scr_neg => plasticState(p)%dotState (3*prm%sum_N_sl+1: 4*prm%sum_N_sl,:) dot%rho_sgl_mob_scr_neg => plasticState(ph)%dotState (3*prm%sum_N_sl+1: 4*prm%sum_N_sl,:)
del%rho_sgl_mob_scr_neg => plasticState(p)%deltaState (3*prm%sum_N_sl+1: 4*prm%sum_N_sl,:) del%rho_sgl_mob_scr_neg => plasticState(ph)%deltaState (3*prm%sum_N_sl+1: 4*prm%sum_N_sl,:)
stt%rhoSglImmobile => plasticState(p)%state (4*prm%sum_N_sl+1: 8*prm%sum_N_sl,:) stt%rhoSglImmobile => plasticState(ph)%state (4*prm%sum_N_sl+1: 8*prm%sum_N_sl,:)
dot%rhoSglImmobile => plasticState(p)%dotState (4*prm%sum_N_sl+1: 8*prm%sum_N_sl,:) dot%rhoSglImmobile => plasticState(ph)%dotState (4*prm%sum_N_sl+1: 8*prm%sum_N_sl,:)
del%rhoSglImmobile => plasticState(p)%deltaState (4*prm%sum_N_sl+1: 8*prm%sum_N_sl,:) del%rhoSglImmobile => plasticState(ph)%deltaState (4*prm%sum_N_sl+1: 8*prm%sum_N_sl,:)
stt%rho_sgl_imm_edg_pos => plasticState(p)%state (4*prm%sum_N_sl+1: 5*prm%sum_N_sl,:) stt%rho_sgl_imm_edg_pos => plasticState(ph)%state (4*prm%sum_N_sl+1: 5*prm%sum_N_sl,:)
dot%rho_sgl_imm_edg_pos => plasticState(p)%dotState (4*prm%sum_N_sl+1: 5*prm%sum_N_sl,:) dot%rho_sgl_imm_edg_pos => plasticState(ph)%dotState (4*prm%sum_N_sl+1: 5*prm%sum_N_sl,:)
del%rho_sgl_imm_edg_pos => plasticState(p)%deltaState (4*prm%sum_N_sl+1: 5*prm%sum_N_sl,:) del%rho_sgl_imm_edg_pos => plasticState(ph)%deltaState (4*prm%sum_N_sl+1: 5*prm%sum_N_sl,:)
stt%rho_sgl_imm_edg_neg => plasticState(p)%state (5*prm%sum_N_sl+1: 6*prm%sum_N_sl,:) stt%rho_sgl_imm_edg_neg => plasticState(ph)%state (5*prm%sum_N_sl+1: 6*prm%sum_N_sl,:)
dot%rho_sgl_imm_edg_neg => plasticState(p)%dotState (5*prm%sum_N_sl+1: 6*prm%sum_N_sl,:) dot%rho_sgl_imm_edg_neg => plasticState(ph)%dotState (5*prm%sum_N_sl+1: 6*prm%sum_N_sl,:)
del%rho_sgl_imm_edg_neg => plasticState(p)%deltaState (5*prm%sum_N_sl+1: 6*prm%sum_N_sl,:) del%rho_sgl_imm_edg_neg => plasticState(ph)%deltaState (5*prm%sum_N_sl+1: 6*prm%sum_N_sl,:)
stt%rho_sgl_imm_scr_pos => plasticState(p)%state (6*prm%sum_N_sl+1: 7*prm%sum_N_sl,:) stt%rho_sgl_imm_scr_pos => plasticState(ph)%state (6*prm%sum_N_sl+1: 7*prm%sum_N_sl,:)
dot%rho_sgl_imm_scr_pos => plasticState(p)%dotState (6*prm%sum_N_sl+1: 7*prm%sum_N_sl,:) dot%rho_sgl_imm_scr_pos => plasticState(ph)%dotState (6*prm%sum_N_sl+1: 7*prm%sum_N_sl,:)
del%rho_sgl_imm_scr_pos => plasticState(p)%deltaState (6*prm%sum_N_sl+1: 7*prm%sum_N_sl,:) del%rho_sgl_imm_scr_pos => plasticState(ph)%deltaState (6*prm%sum_N_sl+1: 7*prm%sum_N_sl,:)
stt%rho_sgl_imm_scr_neg => plasticState(p)%state (7*prm%sum_N_sl+1: 8*prm%sum_N_sl,:) stt%rho_sgl_imm_scr_neg => plasticState(ph)%state (7*prm%sum_N_sl+1: 8*prm%sum_N_sl,:)
dot%rho_sgl_imm_scr_neg => plasticState(p)%dotState (7*prm%sum_N_sl+1: 8*prm%sum_N_sl,:) dot%rho_sgl_imm_scr_neg => plasticState(ph)%dotState (7*prm%sum_N_sl+1: 8*prm%sum_N_sl,:)
del%rho_sgl_imm_scr_neg => plasticState(p)%deltaState (7*prm%sum_N_sl+1: 8*prm%sum_N_sl,:) del%rho_sgl_imm_scr_neg => plasticState(ph)%deltaState (7*prm%sum_N_sl+1: 8*prm%sum_N_sl,:)
stt%rhoDip => plasticState(p)%state (8*prm%sum_N_sl+1:10*prm%sum_N_sl,:) stt%rhoDip => plasticState(ph)%state (8*prm%sum_N_sl+1:10*prm%sum_N_sl,:)
dot%rhoDip => plasticState(p)%dotState (8*prm%sum_N_sl+1:10*prm%sum_N_sl,:) dot%rhoDip => plasticState(ph)%dotState (8*prm%sum_N_sl+1:10*prm%sum_N_sl,:)
del%rhoDip => plasticState(p)%deltaState (8*prm%sum_N_sl+1:10*prm%sum_N_sl,:) del%rhoDip => plasticState(ph)%deltaState (8*prm%sum_N_sl+1:10*prm%sum_N_sl,:)
stt%rho_dip_edg => plasticState(p)%state (8*prm%sum_N_sl+1: 9*prm%sum_N_sl,:) stt%rho_dip_edg => plasticState(ph)%state (8*prm%sum_N_sl+1: 9*prm%sum_N_sl,:)
dot%rho_dip_edg => plasticState(p)%dotState (8*prm%sum_N_sl+1: 9*prm%sum_N_sl,:) dot%rho_dip_edg => plasticState(ph)%dotState (8*prm%sum_N_sl+1: 9*prm%sum_N_sl,:)
del%rho_dip_edg => plasticState(p)%deltaState (8*prm%sum_N_sl+1: 9*prm%sum_N_sl,:) del%rho_dip_edg => plasticState(ph)%deltaState (8*prm%sum_N_sl+1: 9*prm%sum_N_sl,:)
stt%rho_dip_scr => plasticState(p)%state (9*prm%sum_N_sl+1:10*prm%sum_N_sl,:) stt%rho_dip_scr => plasticState(ph)%state (9*prm%sum_N_sl+1:10*prm%sum_N_sl,:)
dot%rho_dip_scr => plasticState(p)%dotState (9*prm%sum_N_sl+1:10*prm%sum_N_sl,:) dot%rho_dip_scr => plasticState(ph)%dotState (9*prm%sum_N_sl+1:10*prm%sum_N_sl,:)
del%rho_dip_scr => plasticState(p)%deltaState (9*prm%sum_N_sl+1:10*prm%sum_N_sl,:) del%rho_dip_scr => plasticState(ph)%deltaState (9*prm%sum_N_sl+1:10*prm%sum_N_sl,:)
stt%gamma => plasticState(p)%state (10*prm%sum_N_sl + 1:11*prm%sum_N_sl,1:Nconstituents) stt%gamma => plasticState(ph)%state (10*prm%sum_N_sl + 1:11*prm%sum_N_sl,1:Nconstituents)
dot%gamma => plasticState(p)%dotState (10*prm%sum_N_sl + 1:11*prm%sum_N_sl,1:Nconstituents) dot%gamma => plasticState(ph)%dotState (10*prm%sum_N_sl + 1:11*prm%sum_N_sl,1:Nconstituents)
del%gamma => plasticState(p)%deltaState (10*prm%sum_N_sl + 1:11*prm%sum_N_sl,1:Nconstituents) del%gamma => plasticState(ph)%deltaState (10*prm%sum_N_sl + 1:11*prm%sum_N_sl,1:Nconstituents)
plasticState(p)%atol(10*prm%sum_N_sl+1:11*prm%sum_N_sl ) = pl%get_asFloat('atol_gamma', defaultVal = 1.0e-2_pReal) plasticState(ph)%atol(10*prm%sum_N_sl+1:11*prm%sum_N_sl ) = pl%get_asFloat('atol_gamma', defaultVal = 1.0e-2_pReal)
if(any(plasticState(p)%atol(10*prm%sum_N_sl+1:11*prm%sum_N_sl) < 0.0_pReal)) & if(any(plasticState(ph)%atol(10*prm%sum_N_sl+1:11*prm%sum_N_sl) < 0.0_pReal)) &
extmsg = trim(extmsg)//' atol_gamma' extmsg = trim(extmsg)//' atol_gamma'
plasticState(p)%slipRate => plasticState(p)%dotState (10*prm%sum_N_sl + 1:11*prm%sum_N_sl,1:Nconstituents) plasticState(ph)%slipRate => plasticState(ph)%dotState (10*prm%sum_N_sl + 1:11*prm%sum_N_sl,1:Nconstituents)
stt%rho_forest => plasticState(p)%state (11*prm%sum_N_sl + 1:12*prm%sum_N_sl,1:Nconstituents) stt%rho_forest => plasticState(ph)%state (11*prm%sum_N_sl + 1:12*prm%sum_N_sl,1:Nconstituents)
stt%v => plasticState(p)%state (12*prm%sum_N_sl + 1:16*prm%sum_N_sl,1:Nconstituents) stt%v => plasticState(ph)%state (12*prm%sum_N_sl + 1:16*prm%sum_N_sl,1:Nconstituents)
stt%v_edg_pos => plasticState(p)%state (12*prm%sum_N_sl + 1:13*prm%sum_N_sl,1:Nconstituents) stt%v_edg_pos => plasticState(ph)%state (12*prm%sum_N_sl + 1:13*prm%sum_N_sl,1:Nconstituents)
stt%v_edg_neg => plasticState(p)%state (13*prm%sum_N_sl + 1:14*prm%sum_N_sl,1:Nconstituents) stt%v_edg_neg => plasticState(ph)%state (13*prm%sum_N_sl + 1:14*prm%sum_N_sl,1:Nconstituents)
stt%v_scr_pos => plasticState(p)%state (14*prm%sum_N_sl + 1:15*prm%sum_N_sl,1:Nconstituents) stt%v_scr_pos => plasticState(ph)%state (14*prm%sum_N_sl + 1:15*prm%sum_N_sl,1:Nconstituents)
stt%v_scr_neg => plasticState(p)%state (15*prm%sum_N_sl + 1:16*prm%sum_N_sl,1:Nconstituents) stt%v_scr_neg => plasticState(ph)%state (15*prm%sum_N_sl + 1:16*prm%sum_N_sl,1:Nconstituents)
allocate(dst%tau_pass(prm%sum_N_sl,Nconstituents),source=0.0_pReal) allocate(dst%tau_pass(prm%sum_N_sl,Nconstituents),source=0.0_pReal)
allocate(dst%tau_back(prm%sum_N_sl,Nconstituents),source=0.0_pReal) allocate(dst%tau_back(prm%sum_N_sl,Nconstituents),source=0.0_pReal)
end associate end associate
if (Nconstituents > 0) call stateInit(ini,p,Nconstituents,i) if (Nconstituents > 0) call stateInit(ini,ph,Nconstituents)
plasticState(p)%state0 = plasticState(p)%state plasticState(ph)%state0 = plasticState(ph)%state
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
! exit if any parameter is out of range ! exit if any parameter is out of range
@ -510,40 +518,38 @@ module function plastic_nonlocal_init() result(myPlasticity)
discretization_nIPs,discretization_Nelems), source=0.0_pReal) discretization_nIPs,discretization_Nelems), source=0.0_pReal)
! BEGIN DEPRECATED---------------------------------------------------------------------------------- ! BEGIN DEPRECATED----------------------------------------------------------------------------------
allocate(iRhoU(maxval(param%sum_N_sl),4,Ninstances), source=0) allocate(iRhoU(maxval(param%sum_N_sl),4,phases%length), source=0)
allocate(iV(maxval(param%sum_N_sl),4,Ninstances), source=0) allocate(iV(maxval(param%sum_N_sl),4,phases%length), source=0)
allocate(iD(maxval(param%sum_N_sl),2,Ninstances), source=0) allocate(iD(maxval(param%sum_N_sl),2,phases%length), source=0)
i = 0 do ph = 1, phases%length
do p = 1, phases%length
phase => phases%get(p)
if(.not. myPlasticity(p)) cycle if(.not. myPlasticity(ph)) cycle
i = i + 1
Nconstituents = count(material_phaseAt==p) * discretization_nIPs phase => phases%get(ph)
Nconstituents = count(material_phaseAt2 == ph)
l = 0 l = 0
do t = 1,4 do t = 1,4
do s = 1,param(i)%sum_N_sl do s = 1,param(ph)%sum_N_sl
l = l + 1 l = l + 1
iRhoU(s,t,i) = l iRhoU(s,t,ph) = l
enddo enddo
enddo enddo
l = l + (4+2+1+1)*param(i)%sum_N_sl ! immobile(4), dipole(2), shear, forest l = l + (4+2+1+1)*param(ph)%sum_N_sl ! immobile(4), dipole(2), shear, forest
do t = 1,4 do t = 1,4
do s = 1,param(i)%sum_N_sl do s = 1,param(ph)%sum_N_sl
l = l + 1 l = l + 1
iV(s,t,i) = l iV(s,t,ph) = l
enddo enddo
enddo enddo
do t = 1,2 do t = 1,2
do s = 1,param(i)%sum_N_sl do s = 1,param(ph)%sum_N_sl
l = l + 1 l = l + 1
iD(s,t,i) = l iD(s,t,ph) = l
enddo enddo
enddo enddo
if (iD(param(i)%sum_N_sl,2,i) /= plasticState(p)%sizeState) & if (iD(param(ph)%sum_N_sl,2,ph) /= plasticState(ph)%sizeState) &
call IO_error(0, ext_msg = 'state indices not properly set (nonlocal)') error stop 'state indices not properly set (nonlocal)'
enddo enddo
end function plastic_nonlocal_init end function plastic_nonlocal_init
@ -552,20 +558,18 @@ end function plastic_nonlocal_init
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief calculates quantities characterizing the microstructure !> @brief calculates quantities characterizing the microstructure
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
module subroutine nonlocal_dependentState(instance, me, ip, el) module subroutine nonlocal_dependentState(ph, me, ip, el)
integer, intent(in) :: & integer, intent(in) :: &
instance, & ph, &
me, & me, &
ip, & ip, &
el el
integer :: & integer :: &
ph, &
no, & !< neighbor offset no, & !< neighbor offset
neighbor_el, & ! element number of neighboring material point neighbor_el, & ! element number of neighboring material point
neighbor_ip, & ! integration point of neighboring material point neighbor_ip, & ! integration point of neighboring material point
neighbor_instance, & ! instance of this plasticity of neighboring material point
c, & ! index of dilsocation character (edge, screw) c, & ! index of dilsocation character (edge, screw)
s, & ! slip system index s, & ! slip system index
dir, & dir, &
@ -589,29 +593,29 @@ module subroutine nonlocal_dependentState(instance, me, ip, el)
invConnections invConnections
real(pReal), dimension(3,nIPneighbors) :: & real(pReal), dimension(3,nIPneighbors) :: &
connection_latticeConf connection_latticeConf
real(pReal), dimension(2,param(instance)%sum_N_sl) :: & real(pReal), dimension(2,param(ph)%sum_N_sl) :: &
rhoExcess rhoExcess
real(pReal), dimension(param(instance)%sum_N_sl) :: & real(pReal), dimension(param(ph)%sum_N_sl) :: &
rho_edg_delta, & rho_edg_delta, &
rho_scr_delta rho_scr_delta
real(pReal), dimension(param(instance)%sum_N_sl,10) :: & real(pReal), dimension(param(ph)%sum_N_sl,10) :: &
rho, & rho, &
rho0, & rho0, &
rho_neighbor0 rho_neighbor0
real(pReal), dimension(param(instance)%sum_N_sl,param(instance)%sum_N_sl) :: & real(pReal), dimension(param(ph)%sum_N_sl,param(ph)%sum_N_sl) :: &
myInteractionMatrix ! corrected slip interaction matrix myInteractionMatrix ! corrected slip interaction matrix
real(pReal), dimension(param(instance)%sum_N_sl,nIPneighbors) :: & real(pReal), dimension(param(ph)%sum_N_sl,nIPneighbors) :: &
rho_edg_delta_neighbor, & rho_edg_delta_neighbor, &
rho_scr_delta_neighbor rho_scr_delta_neighbor
real(pReal), dimension(2,maxval(param%sum_N_sl),nIPneighbors) :: & real(pReal), dimension(2,maxval(param%sum_N_sl),nIPneighbors) :: &
neighbor_rhoExcess, & ! excess density at neighboring material point neighbor_rhoExcess, & ! excess density at neighboring material point
neighbor_rhoTotal ! total density at neighboring material point neighbor_rhoTotal ! total density at neighboring material point
real(pReal), dimension(3,param(instance)%sum_N_sl,2) :: & real(pReal), dimension(3,param(ph)%sum_N_sl,2) :: &
m ! direction of dislocation motion m ! direction of dislocation motion
associate(prm => param(instance),dst => microstructure(instance), stt => state(instance)) associate(prm => param(ph),dst => microstructure(ph), stt => state(ph))
rho = getRho(instance,me,ip,el) rho = getRho(ph,me)
stt%rho_forest(:,me) = matmul(prm%forestProjection_Edge, sum(abs(rho(:,edg)),2)) & stt%rho_forest(:,me) = matmul(prm%forestProjection_Edge, sum(abs(rho(:,edg)),2)) &
+ matmul(prm%forestProjection_Screw,sum(abs(rho(:,scr)),2)) + matmul(prm%forestProjection_Screw,sum(abs(rho(:,scr)),2))
@ -639,11 +643,10 @@ module subroutine nonlocal_dependentState(instance, me, ip, el)
! ToDo: MD: this is most likely only correct for F_i = I ! ToDo: MD: this is most likely only correct for F_i = I
!################################################################################################# !#################################################################################################
rho0 = getRho0(instance,me,ip,el) rho0 = getRho0(ph,me)
if (.not. phase_localPlasticity(material_phaseAt(1,el)) .and. prm%shortRangeStressCorrection) then if (.not. phase_localPlasticity(material_phaseAt(1,el)) .and. prm%shortRangeStressCorrection) then
ph = material_phaseAt(1,el) invFp = math_inv33(phase_mechanical_Fp(ph)%data(1:3,1:3,me))
invFp = math_inv33(constitutive_mech_Fp(ph)%data(1:3,1:3,me)) invFe = math_inv33(phase_mechanical_Fe(ph)%data(1:3,1:3,me))
invFe = math_inv33(constitutive_mech_Fe(ph)%data(1:3,1:3,me))
rho_edg_delta = rho0(:,mob_edg_pos) - rho0(:,mob_edg_neg) rho_edg_delta = rho0(:,mob_edg_pos) - rho0(:,mob_edg_neg)
rho_scr_delta = rho0(:,mob_scr_pos) - rho0(:,mob_scr_neg) rho_scr_delta = rho0(:,mob_scr_pos) - rho0(:,mob_scr_neg)
@ -651,7 +654,7 @@ module subroutine nonlocal_dependentState(instance, me, ip, el)
rhoExcess(1,:) = rho_edg_delta rhoExcess(1,:) = rho_edg_delta
rhoExcess(2,:) = rho_scr_delta rhoExcess(2,:) = rho_scr_delta
FVsize = IPvolume(ip,el) ** (1.0_pReal/3.0_pReal) FVsize = geom(ph)%V_0(me) ** (1.0_pReal/3.0_pReal)
!* loop through my neighborhood and get the connection vectors (in lattice frame) and the excess densities !* loop through my neighborhood and get the connection vectors (in lattice frame) and the excess densities
@ -662,11 +665,10 @@ module subroutine nonlocal_dependentState(instance, me, ip, el)
neighbor_ip = IPneighborhood(2,n,ip,el) neighbor_ip = IPneighborhood(2,n,ip,el)
no = material_phasememberAt(1,neighbor_ip,neighbor_el) no = material_phasememberAt(1,neighbor_ip,neighbor_el)
if (neighbor_el > 0 .and. neighbor_ip > 0) then if (neighbor_el > 0 .and. neighbor_ip > 0) then
neighbor_instance = phase_plasticityInstance(material_phaseAt(1,neighbor_el)) if (material_phaseAt(1,neighbor_el) == ph) then
if (neighbor_instance == instance) then
nRealNeighbors = nRealNeighbors + 1.0_pReal nRealNeighbors = nRealNeighbors + 1.0_pReal
rho_neighbor0 = getRho0(instance,no,neighbor_ip,neighbor_el) rho_neighbor0 = getRho0(ph,no)
rho_edg_delta_neighbor(:,n) = rho_neighbor0(:,mob_edg_pos) - rho_neighbor0(:,mob_edg_neg) rho_edg_delta_neighbor(:,n) = rho_neighbor0(:,mob_edg_pos) - rho_neighbor0(:,mob_edg_neg)
rho_scr_delta_neighbor(:,n) = rho_neighbor0(:,mob_scr_pos) - rho_neighbor0(:,mob_scr_neg) rho_scr_delta_neighbor(:,n) = rho_neighbor0(:,mob_scr_pos) - rho_neighbor0(:,mob_scr_neg)
@ -758,16 +760,14 @@ end subroutine nonlocal_dependentState
!> @brief calculates plastic velocity gradient and its tangent !> @brief calculates plastic velocity gradient and its tangent
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
module subroutine nonlocal_LpAndItsTangent(Lp,dLp_dMp, & module subroutine nonlocal_LpAndItsTangent(Lp,dLp_dMp, &
Mp,Temperature,ph,me,ip,el) Mp,Temperature,ph,me)
real(pReal), dimension(3,3), intent(out) :: & real(pReal), dimension(3,3), intent(out) :: &
Lp !< plastic velocity gradient Lp !< plastic velocity gradient
real(pReal), dimension(3,3,3,3), intent(out) :: & real(pReal), dimension(3,3,3,3), intent(out) :: &
dLp_dMp dLp_dMp
integer, intent(in) :: & integer, intent(in) :: &
ph, & ph, &
me, & me
ip, & !< current integration point
el !< current element number
real(pReal), intent(in) :: & real(pReal), intent(in) :: &
Temperature !< temperature Temperature !< temperature
@ -782,25 +782,25 @@ module subroutine nonlocal_LpAndItsTangent(Lp,dLp_dMp, &
l, & l, &
t, & !< dislocation type t, & !< dislocation type
s !< index of my current slip system s !< index of my current slip system
real(pReal), dimension(param(phase_plasticityInstance(ph))%sum_N_sl,8) :: & real(pReal), dimension(param(ph)%sum_N_sl,8) :: &
rhoSgl !< single dislocation densities (including blocked) rhoSgl !< single dislocation densities (including blocked)
real(pReal), dimension(param(phase_plasticityInstance(ph))%sum_N_sl,10) :: & real(pReal), dimension(param(ph)%sum_N_sl,10) :: &
rho rho
real(pReal), dimension(param(phase_plasticityInstance(ph))%sum_N_sl,4) :: & real(pReal), dimension(param(ph)%sum_N_sl,4) :: &
v, & !< velocity v, & !< velocity
tauNS, & !< resolved shear stress including non Schmid and backstress terms tauNS, & !< resolved shear stress including non Schmid and backstress terms
dv_dtau, & !< velocity derivative with respect to the shear stress dv_dtau, & !< velocity derivative with respect to the shear stress
dv_dtauNS !< velocity derivative with respect to the shear stress dv_dtauNS !< velocity derivative with respect to the shear stress
real(pReal), dimension(param(phase_plasticityInstance(ph))%sum_N_sl) :: & real(pReal), dimension(param(ph)%sum_N_sl) :: &
tau, & !< resolved shear stress including backstress terms tau, & !< resolved shear stress including backstress terms
gdotTotal !< shear rate gdotTotal !< shear rate
associate(prm => param(phase_plasticityInstance(ph)),dst=>microstructure(phase_plasticityInstance(ph)),& associate(prm => param(ph),dst=>microstructure(ph),&
stt=>state(phase_plasticityInstance(ph))) stt=>state(ph))
ns = prm%sum_N_sl ns = prm%sum_N_sl
!*** shortcut to state variables !*** shortcut to state variables
rho = getRho(phase_plasticityInstance(ph),me,ip,el) rho = getRho(ph,me)
rhoSgl = rho(:,sgl) rhoSgl = rho(:,sgl)
do s = 1,ns do s = 1,ns
@ -820,7 +820,7 @@ module subroutine nonlocal_LpAndItsTangent(Lp,dLp_dMp, &
! edges ! edges
call kinetics(v(:,1), dv_dtau(:,1), dv_dtauNS(:,1), & call kinetics(v(:,1), dv_dtau(:,1), dv_dtauNS(:,1), &
tau, tauNS(:,1), dst%tau_pass(:,me),1,Temperature, phase_plasticityInstance(ph)) tau, tauNS(:,1), dst%tau_pass(:,me),1,Temperature, ph)
v(:,2) = v(:,1) v(:,2) = v(:,1)
dv_dtau(:,2) = dv_dtau(:,1) dv_dtau(:,2) = dv_dtau(:,1)
dv_dtauNS(:,2) = dv_dtauNS(:,1) dv_dtauNS(:,2) = dv_dtauNS(:,1)
@ -833,7 +833,7 @@ module subroutine nonlocal_LpAndItsTangent(Lp,dLp_dMp, &
else else
do t = 3,4 do t = 3,4
call kinetics(v(:,t), dv_dtau(:,t), dv_dtauNS(:,t), & call kinetics(v(:,t), dv_dtau(:,t), dv_dtauNS(:,t), &
tau, tauNS(:,t), dst%tau_pass(:,me),2,Temperature, phase_plasticityInstance(ph)) tau, tauNS(:,t), dst%tau_pass(:,me),2,Temperature, ph)
enddo enddo
endif endif
@ -866,47 +866,42 @@ end subroutine nonlocal_LpAndItsTangent
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief (instantaneous) incremental change of microstructure !> @brief (instantaneous) incremental change of microstructure
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
module subroutine plastic_nonlocal_deltaState(Mp,instance,me,ip,el) module subroutine plastic_nonlocal_deltaState(Mp,ph,me)
real(pReal), dimension(3,3), intent(in) :: & real(pReal), dimension(3,3), intent(in) :: &
Mp !< MandelStress Mp !< MandelStress
integer, intent(in) :: & integer, intent(in) :: &
instance, & ! current instance of this plasticity ph, &
me, & !< offset me
ip, &
el
integer :: & integer :: &
ph, & !< phase
ns, & ! short notation for the total number of active slip systems ns, & ! short notation for the total number of active slip systems
c, & ! character of dislocation c, & ! character of dislocation
t, & ! type of dislocation t, & ! type of dislocation
s ! index of my current slip system s ! index of my current slip system
real(pReal), dimension(param(instance)%sum_N_sl,10) :: & real(pReal), dimension(param(ph)%sum_N_sl,10) :: &
deltaRhoRemobilization, & ! density increment by remobilization deltaRhoRemobilization, & ! density increment by remobilization
deltaRhoDipole2SingleStress ! density increment by dipole dissociation (by stress change) deltaRhoDipole2SingleStress ! density increment by dipole dissociation (by stress change)
real(pReal), dimension(param(instance)%sum_N_sl,10) :: & real(pReal), dimension(param(ph)%sum_N_sl,10) :: &
rho ! current dislocation densities rho ! current dislocation densities
real(pReal), dimension(param(instance)%sum_N_sl,4) :: & real(pReal), dimension(param(ph)%sum_N_sl,4) :: &
v ! dislocation glide velocity v ! dislocation glide velocity
real(pReal), dimension(param(instance)%sum_N_sl) :: & real(pReal), dimension(param(ph)%sum_N_sl) :: &
tau ! current resolved shear stress tau ! current resolved shear stress
real(pReal), dimension(param(instance)%sum_N_sl,2) :: & real(pReal), dimension(param(ph)%sum_N_sl,2) :: &
rhoDip, & ! current dipole dislocation densities (screw and edge dipoles) rhoDip, & ! current dipole dislocation densities (screw and edge dipoles)
dUpper, & ! current maximum stable dipole distance for edges and screws dUpper, & ! current maximum stable dipole distance for edges and screws
dUpperOld, & ! old maximum stable dipole distance for edges and screws dUpperOld, & ! old maximum stable dipole distance for edges and screws
deltaDUpper ! change in maximum stable dipole distance for edges and screws deltaDUpper ! change in maximum stable dipole distance for edges and screws
ph = material_phaseAt(1,el) associate(prm => param(ph),dst => microstructure(ph),del => deltaState(ph))
ns = prm%sum_N_sl
associate(prm => param(instance),dst => microstructure(instance),del => deltaState(instance))
ns = prm%sum_N_sl
!*** shortcut to state variables !*** shortcut to state variables
forall (s = 1:ns, t = 1:4) v(s,t) = plasticState(ph)%state(iV(s,t,instance),me) forall (s = 1:ns, t = 1:4) v(s,t) = plasticState(ph)%state(iV(s,t,ph),me)
forall (s = 1:ns, c = 1:2) dUpperOld(s,c) = plasticState(ph)%state(iD(s,c,instance),me) forall (s = 1:ns, c = 1:2) dUpperOld(s,c) = plasticState(ph)%state(iD(s,c,ph),me)
rho = getRho(instance,me,ip,el) rho = getRho(ph,me)
rhoDip = rho(:,dip) rhoDip = rho(:,dip)
!**************************************************************************** !****************************************************************************
@ -951,20 +946,11 @@ module subroutine plastic_nonlocal_deltaState(Mp,instance,me,ip,el)
/ (dUpperOld(s,c) - prm%minDipoleHeight(s,c)) / (dUpperOld(s,c) - prm%minDipoleHeight(s,c))
forall (t=1:4) deltaRhoDipole2SingleStress(:,t) = -0.5_pReal * deltaRhoDipole2SingleStress(:,(t-1)/2+9) forall (t=1:4) deltaRhoDipole2SingleStress(:,t) = -0.5_pReal * deltaRhoDipole2SingleStress(:,(t-1)/2+9)
forall (s = 1:ns, c = 1:2) plasticState(ph)%state(iD(s,c,instance),me) = dUpper(s,c) forall (s = 1:ns, c = 1:2) plasticState(ph)%state(iD(s,c,ph),me) = dUpper(s,c)
plasticState(ph)%deltaState(:,me) = 0.0_pReal plasticState(ph)%deltaState(:,me) = 0.0_pReal
del%rho(:,me) = reshape(deltaRhoRemobilization + deltaRhoDipole2SingleStress, [10*ns]) del%rho(:,me) = reshape(deltaRhoRemobilization + deltaRhoDipole2SingleStress, [10*ns])
#ifdef DEBUG
if (debugConstitutive%extensive &
.and. ((debugConstitutive%element == el .and. debugConstitutive%ip == ip)&
.or. .not. debugConstitutive%selective)) then
print'(a,/,8(12x,12(e12.5,1x),/))', '<< CONST >> dislocation remobilization', deltaRhoRemobilization(:,1:8)
print'(a,/,10(12x,12(e12.5,1x),/),/)', '<< CONST >> dipole dissociation by stress increase', deltaRhoDipole2SingleStress
endif
#endif
end associate end associate
end subroutine plastic_nonlocal_deltaState end subroutine plastic_nonlocal_deltaState
@ -992,7 +978,7 @@ module subroutine nonlocal_dotState(Mp, Temperature,timestep, &
c, & !< character of dislocation c, & !< character of dislocation
t, & !< type of dislocation t, & !< type of dislocation
s !< index of my current slip system s !< index of my current slip system
real(pReal), dimension(param(phase_plasticityInstance(ph))%sum_N_sl,10) :: & real(pReal), dimension(param(ph)%sum_N_sl,10) :: &
rho, & rho, &
rho0, & !< dislocation density at beginning of time step rho0, & !< dislocation density at beginning of time step
rhoDot, & !< density evolution rhoDot, & !< density evolution
@ -1000,17 +986,17 @@ module subroutine nonlocal_dotState(Mp, Temperature,timestep, &
rhoDotSingle2DipoleGlide, & !< density evolution by dipole formation (by glide) rhoDotSingle2DipoleGlide, & !< density evolution by dipole formation (by glide)
rhoDotAthermalAnnihilation, & !< density evolution by athermal annihilation rhoDotAthermalAnnihilation, & !< density evolution by athermal annihilation
rhoDotThermalAnnihilation !< density evolution by thermal annihilation rhoDotThermalAnnihilation !< density evolution by thermal annihilation
real(pReal), dimension(param(phase_plasticityInstance(ph))%sum_N_sl,8) :: & real(pReal), dimension(param(ph)%sum_N_sl,8) :: &
rhoSgl, & !< current single dislocation densities (positive/negative screw and edge without dipoles) rhoSgl, & !< current single dislocation densities (positive/negative screw and edge without dipoles)
my_rhoSgl0 !< single dislocation densities of central ip (positive/negative screw and edge without dipoles) my_rhoSgl0 !< single dislocation densities of central ip (positive/negative screw and edge without dipoles)
real(pReal), dimension(param(phase_plasticityInstance(ph))%sum_N_sl,4) :: & real(pReal), dimension(param(ph)%sum_N_sl,4) :: &
v, & !< current dislocation glide velocity v, & !< current dislocation glide velocity
v0, & v0, &
gdot !< shear rates gdot !< shear rates
real(pReal), dimension(param(phase_plasticityInstance(ph))%sum_N_sl) :: & real(pReal), dimension(param(ph)%sum_N_sl) :: &
tau, & !< current resolved shear stress tau, & !< current resolved shear stress
vClimb !< climb velocity of edge dipoles vClimb !< climb velocity of edge dipoles
real(pReal), dimension(param(phase_plasticityInstance(ph))%sum_N_sl,2) :: & real(pReal), dimension(param(ph)%sum_N_sl,2) :: &
rhoDip, & !< current dipole dislocation densities (screw and edge dipoles) rhoDip, & !< current dipole dislocation densities (screw and edge dipoles)
dLower, & !< minimum stable dipole distance for edges and screws dLower, & !< minimum stable dipole distance for edges and screws
dUpper !< current maximum stable dipole distance for edges and screws dUpper !< current maximum stable dipole distance for edges and screws
@ -1022,22 +1008,22 @@ module subroutine nonlocal_dotState(Mp, Temperature,timestep, &
return return
endif endif
associate(prm => param(phase_plasticityInstance(ph)), & associate(prm => param(ph), &
dst => microstructure(phase_plasticityInstance(ph)), & dst => microstructure(ph), &
dot => dotState(phase_plasticityInstance(ph)), & dot => dotState(ph), &
stt => state(phase_plasticityInstance(ph))) stt => state(ph))
ns = prm%sum_N_sl ns = prm%sum_N_sl
tau = 0.0_pReal tau = 0.0_pReal
gdot = 0.0_pReal gdot = 0.0_pReal
rho = getRho(phase_plasticityInstance(ph),me,ip,el) rho = getRho(ph,me)
rhoSgl = rho(:,sgl) rhoSgl = rho(:,sgl)
rhoDip = rho(:,dip) rhoDip = rho(:,dip)
rho0 = getRho0(phase_plasticityInstance(ph),me,ip,el) rho0 = getRho0(ph,me)
my_rhoSgl0 = rho0(:,sgl) my_rhoSgl0 = rho0(:,sgl)
forall (s = 1:ns, t = 1:4) v(s,t) = plasticState(ph)%state(iV(s,t,phase_plasticityInstance(ph)),me) forall (s = 1:ns, t = 1:4) v(s,t) = plasticState(ph)%state(iV(s,t,ph),me)
gdot = rhoSgl(:,1:4) * v * spread(prm%b_sl,2,4) gdot = rhoSgl(:,1:4) * v * spread(prm%b_sl,2,4)
#ifdef DEBUG #ifdef DEBUG
@ -1086,7 +1072,7 @@ module subroutine nonlocal_dotState(Mp, Temperature,timestep, &
* sqrt(stt%rho_forest(:,me)) / prm%i_sl / prm%b_sl, 2, 4) * sqrt(stt%rho_forest(:,me)) / prm%i_sl / prm%b_sl, 2, 4)
endif isBCC endif isBCC
forall (s = 1:ns, t = 1:4) v0(s,t) = plasticState(ph)%state0(iV(s,t,phase_plasticityInstance(ph)),me) forall (s = 1:ns, t = 1:4) v0(s,t) = plasticState(ph)%state0(iV(s,t,ph),me)
!**************************************************************************** !****************************************************************************
@ -1142,7 +1128,7 @@ module subroutine nonlocal_dotState(Mp, Temperature,timestep, &
- rhoDip(s,1) / timestep - rhoDotAthermalAnnihilation(s,9) & - rhoDip(s,1) / timestep - rhoDotAthermalAnnihilation(s,9) &
- rhoDotSingle2DipoleGlide(s,9)) ! make sure that we do not annihilate more dipoles than we have - rhoDotSingle2DipoleGlide(s,9)) ! make sure that we do not annihilate more dipoles than we have
rhoDot = rhoDotFlux(timestep, phase_plasticityInstance(ph),me,ip,el) & rhoDot = rhoDotFlux(timestep, ph,me,ip,el) &
+ rhoDotMultiplication & + rhoDotMultiplication &
+ rhoDotSingle2DipoleGlide & + rhoDotSingle2DipoleGlide &
+ rhoDotAthermalAnnihilation & + rhoDotAthermalAnnihilation &
@ -1171,19 +1157,18 @@ end subroutine nonlocal_dotState
!--------------------------------------------------------------------------------------------------- !---------------------------------------------------------------------------------------------------
!> @brief calculates the rate of change of microstructure !> @brief calculates the rate of change of microstructure
!--------------------------------------------------------------------------------------------------- !---------------------------------------------------------------------------------------------------
function rhoDotFlux(timestep,instance,me,ip,el) function rhoDotFlux(timestep,ph,me,ip,el)
real(pReal), intent(in) :: & real(pReal), intent(in) :: &
timestep !< substepped crystallite time increment timestep !< substepped crystallite time increment
integer, intent(in) :: & integer, intent(in) :: &
instance, & ph, &
me, & me, &
ip, & !< current integration point ip, & !< current integration point
el !< current element number el !< current element number
integer :: & integer :: &
ph, & neighbor_ph, & !< phase of my neighbor's plasticity
neighbor_instance, & !< instance of my neighbor's plasticity
ns, & !< short notation for the total number of active slip systems ns, & !< short notation for the total number of active slip systems
c, & !< character of dislocation c, & !< character of dislocation
n, & !< index of my current neighbor n, & !< index of my current neighbor
@ -1199,20 +1184,20 @@ function rhoDotFlux(timestep,instance,me,ip,el)
np,& !< neighbor phase shortcut np,& !< neighbor phase shortcut
topp, & !< type of dislocation with opposite sign to t topp, & !< type of dislocation with opposite sign to t
s !< index of my current slip system s !< index of my current slip system
real(pReal), dimension(param(instance)%sum_N_sl,10) :: & real(pReal), dimension(param(ph)%sum_N_sl,10) :: &
rho, & rho, &
rho0, & !< dislocation density at beginning of time step rho0, & !< dislocation density at beginning of time step
rhoDotFlux !< density evolution by flux rhoDotFlux !< density evolution by flux
real(pReal), dimension(param(instance)%sum_N_sl,8) :: & real(pReal), dimension(param(ph)%sum_N_sl,8) :: &
rhoSgl, & !< current single dislocation densities (positive/negative screw and edge without dipoles) rhoSgl, & !< current single dislocation densities (positive/negative screw and edge without dipoles)
neighbor_rhoSgl0, & !< current single dislocation densities of neighboring ip (positive/negative screw and edge without dipoles) neighbor_rhoSgl0, & !< current single dislocation densities of neighboring ip (positive/negative screw and edge without dipoles)
my_rhoSgl0 !< single dislocation densities of central ip (positive/negative screw and edge without dipoles) my_rhoSgl0 !< single dislocation densities of central ip (positive/negative screw and edge without dipoles)
real(pReal), dimension(param(instance)%sum_N_sl,4) :: & real(pReal), dimension(param(ph)%sum_N_sl,4) :: &
v, & !< current dislocation glide velocity v, & !< current dislocation glide velocity
v0, & v0, &
neighbor_v0, & !< dislocation glide velocity of enighboring ip neighbor_v0, & !< dislocation glide velocity of enighboring ip
gdot !< shear rates gdot !< shear rates
real(pReal), dimension(3,param(instance)%sum_N_sl,4) :: & real(pReal), dimension(3,param(ph)%sum_N_sl,4) :: &
m !< direction of dislocation motion m !< direction of dislocation motion
real(pReal), dimension(3,3) :: & real(pReal), dimension(3,3) :: &
my_F, & !< my total deformation gradient my_F, & !< my total deformation gradient
@ -1230,26 +1215,25 @@ function rhoDotFlux(timestep,instance,me,ip,el)
transmissivity, & !< overall transmissivity of dislocation flux to neighboring material point transmissivity, & !< overall transmissivity of dislocation flux to neighboring material point
lineLength !< dislocation line length leaving the current interface lineLength !< dislocation line length leaving the current interface
ph = material_phaseAt(1,el)
associate(prm => param(instance), & associate(prm => param(ph), &
dst => microstructure(instance), & dst => microstructure(ph), &
dot => dotState(instance), & dot => dotState(ph), &
stt => state(instance)) stt => state(ph))
ns = prm%sum_N_sl ns = prm%sum_N_sl
gdot = 0.0_pReal gdot = 0.0_pReal
rho = getRho(instance,me,ip,el) rho = getRho(ph,me)
rhoSgl = rho(:,sgl) rhoSgl = rho(:,sgl)
rho0 = getRho0(instance,me,ip,el) rho0 = getRho0(ph,me)
my_rhoSgl0 = rho0(:,sgl) my_rhoSgl0 = rho0(:,sgl)
forall (s = 1:ns, t = 1:4) v(s,t) = plasticState(ph)%state(iV(s,t,instance),me) !ToDo: MD: I think we should use state0 here forall (s = 1:ns, t = 1:4) v(s,t) = plasticState(ph)%state(iV(s,t,ph),me) !ToDo: MD: I think we should use state0 here
gdot = rhoSgl(:,1:4) * v * spread(prm%b_sl,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),me) forall (s = 1:ns, t = 1:4) v0(s,t) = plasticState(ph)%state0(iV(s,t,ph),me)
!**************************************************************************** !****************************************************************************
!*** calculate dislocation fluxes (only for nonlocal plasticity) !*** calculate dislocation fluxes (only for nonlocal plasticity)
@ -1284,8 +1268,8 @@ function rhoDotFlux(timestep,instance,me,ip,el)
m(1:3,:,3) = -prm%slip_transverse m(1:3,:,3) = -prm%slip_transverse
m(1:3,:,4) = prm%slip_transverse m(1:3,:,4) = prm%slip_transverse
my_F = constitutive_mech_F(ph)%data(1:3,1:3,me) my_F = phase_mechanical_F(ph)%data(1:3,1:3,me)
my_Fe = matmul(my_F, math_inv33(constitutive_mech_Fp(ph)%data(1:3,1:3,me))) my_Fe = matmul(my_F, math_inv33(phase_mechanical_Fp(ph)%data(1:3,1:3,me)))
neighbors: do n = 1,nIPneighbors neighbors: do n = 1,nIPneighbors
@ -1301,9 +1285,9 @@ function rhoDotFlux(timestep,instance,me,ip,el)
opposite_n = IPneighborhood(3,opposite_neighbor,ip,el) opposite_n = IPneighborhood(3,opposite_neighbor,ip,el)
if (neighbor_n > 0) then ! if neighbor exists, average deformation gradient if (neighbor_n > 0) then ! if neighbor exists, average deformation gradient
neighbor_instance = phase_plasticityInstance(material_phaseAt(1,neighbor_el)) neighbor_ph = material_phaseAt(1,neighbor_el)
neighbor_F = constitutive_mech_F(np)%data(1:3,1:3,no) neighbor_F = phase_mechanical_F(np)%data(1:3,1:3,no)
neighbor_Fe = matmul(neighbor_F, math_inv33(constitutive_mech_Fp(np)%data(1:3,1:3,no))) neighbor_Fe = matmul(neighbor_F, math_inv33(phase_mechanical_Fp(np)%data(1:3,1:3,no)))
Favg = 0.5_pReal * (my_F + neighbor_F) Favg = 0.5_pReal * (my_F + neighbor_F)
else ! if no neighbor, take my value as average else ! if no neighbor, take my value as average
Favg = my_F Favg = my_F
@ -1324,8 +1308,8 @@ function rhoDotFlux(timestep,instance,me,ip,el)
any(compatibility(:,:,:,n,ip,el) > 0.0_pReal)) then any(compatibility(:,:,:,n,ip,el) > 0.0_pReal)) then
forall (s = 1:ns, t = 1:4) forall (s = 1:ns, t = 1:4)
neighbor_v0(s,t) = plasticState(np)%state0(iV (s,t,neighbor_instance),no) neighbor_v0(s,t) = plasticState(np)%state0(iV (s,t,neighbor_ph),no)
neighbor_rhoSgl0(s,t) = max(plasticState(np)%state0(iRhoU(s,t,neighbor_instance),no),0.0_pReal) neighbor_rhoSgl0(s,t) = max(plasticState(np)%state0(iRhoU(s,t,neighbor_ph),no),0.0_pReal)
endforall endforall
where (neighbor_rhoSgl0 * IPvolume(neighbor_ip,neighbor_el) ** 0.667_pReal < prm%rho_min & where (neighbor_rhoSgl0 * IPvolume(neighbor_ip,neighbor_el) ** 0.667_pReal < prm%rho_min &
@ -1408,12 +1392,12 @@ end function rhoDotFlux
! plane normals and signed cosine of the angle between the slip directions. Only the largest values ! plane normals and signed cosine of the angle between the slip directions. Only the largest values
! that sum up to a total of 1 are considered, all others are set to zero. ! that sum up to a total of 1 are considered, all others are set to zero.
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
module subroutine plastic_nonlocal_updateCompatibility(orientation,instance,i,e) module subroutine plastic_nonlocal_updateCompatibility(orientation,ph,i,e)
type(rotation), dimension(1,discretization_nIPs,discretization_Nelems), intent(in) :: & type(rotation), dimension(1,discretization_nIPs,discretization_Nelems), intent(in) :: &
orientation ! crystal orientation orientation ! crystal orientation
integer, intent(in) :: & integer, intent(in) :: &
instance, & ph, &
i, & i, &
e e
@ -1421,24 +1405,21 @@ module subroutine plastic_nonlocal_updateCompatibility(orientation,instance,i,e)
n, & ! neighbor index n, & ! neighbor index
neighbor_e, & ! element index of my neighbor neighbor_e, & ! element index of my neighbor
neighbor_i, & ! integration point index of my neighbor neighbor_i, & ! integration point index of my neighbor
ph, &
neighbor_phase, & neighbor_phase, &
ns, & ! number of active slip systems ns, & ! number of active slip systems
s1, & ! slip system index (me) s1, & ! slip system index (me)
s2 ! slip system index (my neighbor) s2 ! slip system index (my neighbor)
real(pReal), dimension(2,param(instance)%sum_N_sl,param(instance)%sum_N_sl,nIPneighbors) :: & real(pReal), dimension(2,param(ph)%sum_N_sl,param(ph)%sum_N_sl,nIPneighbors) :: &
my_compatibility ! my_compatibility for current element and ip my_compatibility ! my_compatibility for current element and ip
real(pReal) :: & real(pReal) :: &
my_compatibilitySum, & my_compatibilitySum, &
thresholdValue, & thresholdValue, &
nThresholdValues nThresholdValues
logical, dimension(param(instance)%sum_N_sl) :: & logical, dimension(param(ph)%sum_N_sl) :: &
belowThreshold belowThreshold
type(rotation) :: mis type(rotation) :: mis
ph = material_phaseAt(1,e) associate(prm => param(ph))
associate(prm => param(instance))
ns = prm%sum_N_sl ns = prm%sum_N_sl
!*** start out fully compatible !*** start out fully compatible
@ -1524,14 +1505,14 @@ end subroutine plastic_nonlocal_updateCompatibility
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief writes results to HDF5 output file !> @brief writes results to HDF5 output file
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
module subroutine plastic_nonlocal_results(instance,group) module subroutine plastic_nonlocal_results(ph,group)
integer, intent(in) :: instance integer, intent(in) :: ph
character(len=*),intent(in) :: group character(len=*),intent(in) :: group
integer :: o integer :: o
associate(prm => param(instance),dst => microstructure(instance),stt=>state(instance)) associate(prm => param(ph),dst => microstructure(ph),stt=>state(ph))
outputsLoop: do o = 1,size(prm%output) outputsLoop: do o = 1,size(prm%output)
select case(trim(prm%output(o))) select case(trim(prm%output(o)))
case('rho_u_ed_pos') case('rho_u_ed_pos')
@ -1595,17 +1576,16 @@ end subroutine plastic_nonlocal_results
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief populates the initial dislocation density !> @brief populates the initial dislocation density
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
subroutine stateInit(ini,phase,Nconstituents,instance) subroutine stateInit(ini,phase,Nconstituents)
type(tInitialParameters) :: & type(tInitialParameters) :: &
ini ini
integer,intent(in) :: & integer,intent(in) :: &
phase, & phase, &
Nconstituents, & Nconstituents
instance
integer :: & integer :: &
e, &
i, & i, &
e, &
f, & f, &
from, & from, &
upto, & upto, &
@ -1623,7 +1603,7 @@ subroutine stateInit(ini,phase,Nconstituents,instance)
volume volume
associate(stt => state(instance)) associate(stt => state(phase))
if (ini%random_rho_u > 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_Nelems do e = 1,discretization_Nelems
@ -1652,8 +1632,8 @@ subroutine stateInit(ini,phase,Nconstituents,instance)
do s = from,upto do s = from,upto
noise = [math_sampleGaussVar(0.0_pReal, ini%sigma_rho_u), & noise = [math_sampleGaussVar(0.0_pReal, ini%sigma_rho_u), &
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_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_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_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) stt%rho_sgl_mob_scr_neg(s,e) = ini%rho_u_sc_neg_0(f) + noise(2)
enddo enddo
@ -1671,18 +1651,18 @@ end subroutine stateInit
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief calculates kinetics !> @brief calculates kinetics
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
pure subroutine kinetics(v, dv_dtau, dv_dtauNS, tau, tauNS, tauThreshold, c, Temperature, instance) pure subroutine kinetics(v, dv_dtau, dv_dtauNS, tau, tauNS, tauThreshold, c, Temperature, ph)
integer, intent(in) :: & integer, intent(in) :: &
c, & !< dislocation character (1:edge, 2:screw) c, & !< dislocation character (1:edge, 2:screw)
instance ph
real(pReal), intent(in) :: & real(pReal), intent(in) :: &
Temperature !< temperature Temperature !< temperature
real(pReal), dimension(param(instance)%sum_N_sl), intent(in) :: & real(pReal), dimension(param(ph)%sum_N_sl), intent(in) :: &
tau, & !< resolved external shear stress (without non Schmid effects) tau, & !< resolved external shear stress (without non Schmid effects)
tauNS, & !< resolved external shear stress (including non Schmid effects) tauNS, & !< resolved external shear stress (including non Schmid effects)
tauThreshold !< threshold shear stress tauThreshold !< threshold shear stress
real(pReal), dimension(param(instance)%sum_N_sl), intent(out) :: & real(pReal), dimension(param(ph)%sum_N_sl), intent(out) :: &
v, & !< velocity v, & !< velocity
dv_dtau, & !< velocity derivative with respect to resolved shear stress (without non Schmid contributions) dv_dtau, & !< velocity derivative with respect to resolved shear stress (without non Schmid contributions)
dv_dtauNS !< velocity derivative with respect to resolved shear stress (including non Schmid contributions) dv_dtauNS !< velocity derivative with respect to resolved shear stress (including non Schmid contributions)
@ -1713,7 +1693,7 @@ pure subroutine kinetics(v, dv_dtau, dv_dtauNS, tau, tauNS, tauThreshold, c, Tem
criticalStress_S, & !< maximum obstacle strength criticalStress_S, & !< maximum obstacle strength
mobility !< dislocation mobility mobility !< dislocation mobility
associate(prm => param(instance)) associate(prm => param(ph))
ns = prm%sum_N_sl ns = prm%sum_N_sl
v = 0.0_pReal v = 0.0_pReal
dv_dtau = 0.0_pReal dv_dtau = 0.0_pReal
@ -1786,21 +1766,22 @@ end subroutine kinetics
!> @brief returns copy of current dislocation densities from state !> @brief returns copy of current dislocation densities from state
!> @details raw values is rectified !> @details raw values is rectified
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
pure function getRho(instance,me,ip,el) pure function getRho(ph,me)
integer, intent(in) :: instance, me,ip,el integer, intent(in) :: ph, me
real(pReal), dimension(param(instance)%sum_N_sl,10) :: getRho real(pReal), dimension(param(ph)%sum_N_sl,10) :: getRho
associate(prm => param(instance))
getRho = reshape(state(instance)%rho(:,me),[prm%sum_N_sl,10]) associate(prm => param(ph))
! ensure positive densities (not for imm, they have a sign) getRho = reshape(state(ph)%rho(:,me),[prm%sum_N_sl,10])
getRho(:,mob) = max(getRho(:,mob),0.0_pReal)
getRho(:,dip) = max(getRho(:,dip),0.0_pReal)
where(abs(getRho) < max(prm%rho_min/IPvolume(ip,el)**(2.0_pReal/3.0_pReal),prm%rho_significant)) & ! ensure positive densities (not for imm, they have a sign)
getRho = 0.0_pReal getRho(:,mob) = max(getRho(:,mob),0.0_pReal)
getRho(:,dip) = max(getRho(:,dip),0.0_pReal)
where(abs(getRho) < max(prm%rho_min/geom(ph)%V_0(me)**(2.0_pReal/3.0_pReal),prm%rho_significant)) &
getRho = 0.0_pReal
end associate end associate
@ -1811,24 +1792,46 @@ end function getRho
!> @brief returns copy of current dislocation densities from state !> @brief returns copy of current dislocation densities from state
!> @details raw values is rectified !> @details raw values is rectified
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
pure function getRho0(instance,me,ip,el) pure function getRho0(ph,me)
integer, intent(in) :: instance, me,ip,el integer, intent(in) :: ph, me
real(pReal), dimension(param(instance)%sum_N_sl,10) :: getRho0 real(pReal), dimension(param(ph)%sum_N_sl,10) :: getRho0
associate(prm => param(instance))
getRho0 = reshape(state0(instance)%rho(:,me),[prm%sum_N_sl,10]) associate(prm => param(ph))
! ensure positive densities (not for imm, they have a sign) getRho0 = reshape(state0(ph)%rho(:,me),[prm%sum_N_sl,10])
getRho0(:,mob) = max(getRho0(:,mob),0.0_pReal)
getRho0(:,dip) = max(getRho0(:,dip),0.0_pReal)
where(abs(getRho0) < max(prm%rho_min/IPvolume(ip,el)**(2.0_pReal/3.0_pReal),prm%rho_significant)) & ! ensure positive densities (not for imm, they have a sign)
getRho0 = 0.0_pReal getRho0(:,mob) = max(getRho0(:,mob),0.0_pReal)
getRho0(:,dip) = max(getRho0(:,dip),0.0_pReal)
where(abs(getRho0) < max(prm%rho_min/geom(ph)%V_0(me)**(2.0_pReal/3.0_pReal),prm%rho_significant)) &
getRho0 = 0.0_pReal
end associate end associate
end function getRho0 end function getRho0
subroutine storeGeometry(ph)
integer, intent(in) :: ph
integer :: ip, el, ce, co
ce = 0
do el = 1, size(material_homogenizationMemberAt,2)
do ip = 1, size(material_homogenizationMemberAt,1)
ce = ce + 1
do co = 1, homogenization_maxNconstituents
if(material_phaseAt2(co,ce) == ph) then
geom(ph)%V_0(material_phaseMemberAt2(co,ce)) = IPvolume(ip,el)
endif
enddo
enddo
enddo
end subroutine
end submodule nonlocal end submodule nonlocal

View File

@ -70,8 +70,7 @@ module function plastic_phenopowerlaw_init() result(myPlasticity)
logical, dimension(:), allocatable :: myPlasticity logical, dimension(:), allocatable :: myPlasticity
integer :: & integer :: &
Ninstances, & ph, i, &
p, i, &
Nconstituents, & Nconstituents, &
sizeState, sizeDotState, & sizeState, sizeDotState, &
startIndex, endIndex startIndex, endIndex
@ -89,27 +88,26 @@ module function plastic_phenopowerlaw_init() result(myPlasticity)
mech, & mech, &
pl pl
print'(/,a)', ' <<<+- phase:mechanics:plastic:phenopowerlaw init -+>>>'
myPlasticity = plastic_active('phenopowerlaw') myPlasticity = plastic_active('phenopowerlaw')
Ninstances = count(myPlasticity) if(count(myPlasticity) == 0) return
print'(a,i2)', ' # instances: ',Ninstances; flush(IO_STDOUT)
if(Ninstances == 0) return print'(/,a)', ' <<<+- phase:mechanical:plastic:phenopowerlaw init -+>>>'
print'(a,i0)', ' # phases: ',count(myPlasticity); flush(IO_STDOUT)
allocate(param(Ninstances))
allocate(state(Ninstances))
allocate(dotState(Ninstances))
phases => config_material%get('phase') phases => config_material%get('phase')
i = 0 allocate(param(phases%length))
do p = 1, phases%length allocate(state(phases%length))
phase => phases%get(p) allocate(dotState(phases%length))
do ph = 1, phases%length
if(.not. myPlasticity(ph)) cycle
associate(prm => param(ph), dot => dotState(ph), stt => state(ph))
phase => phases%get(ph)
mech => phase%get('mechanics') mech => phase%get('mechanics')
if(.not. myPlasticity(p)) cycle
i = i + 1
associate(prm => param(i), &
dot => dotState(i), &
stt => state(i))
pl => mech%get('plasticity') pl => mech%get('plasticity')
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
@ -136,7 +134,7 @@ module function plastic_phenopowerlaw_init() result(myPlasticity)
xi_0_sl = pl%get_asFloats('xi_0_sl', 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%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), & prm%h_int = pl%get_asFloats('h_int', requiredSize=size(N_sl), &
defaultVal=[(0.0_pReal,i=1,size(N_sl))]) defaultVal=[(0.0_pReal,i=1,size(N_sl))])
prm%dot_gamma_0_sl = pl%get_asFloat('dot_gamma_0_sl') prm%dot_gamma_0_sl = pl%get_asFloat('dot_gamma_0_sl')
prm%n_sl = pl%get_asFloat('n_sl') prm%n_sl = pl%get_asFloat('n_sl')
@ -225,49 +223,49 @@ module function plastic_phenopowerlaw_init() result(myPlasticity)
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
! allocate state arrays ! allocate state arrays
Nconstituents = count(material_phaseAt2 == p) Nconstituents = count(material_phaseAt2 == ph)
sizeDotState = size(['xi_sl ','gamma_sl']) * prm%sum_N_sl & sizeDotState = size(['xi_sl ','gamma_sl']) * prm%sum_N_sl &
+ size(['xi_tw ','gamma_tw']) * prm%sum_N_tw + size(['xi_tw ','gamma_tw']) * prm%sum_N_tw
sizeState = sizeDotState sizeState = sizeDotState
call constitutive_allocateState(plasticState(p),Nconstituents,sizeState,sizeDotState,0) call phase_allocateState(plasticState(ph),Nconstituents,sizeState,sizeDotState,0)
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
! state aliases and initialization ! state aliases and initialization
startIndex = 1 startIndex = 1
endIndex = prm%sum_N_sl endIndex = prm%sum_N_sl
stt%xi_slip => plasticState(p)%state (startIndex:endIndex,:) stt%xi_slip => plasticState(ph)%state (startIndex:endIndex,:)
stt%xi_slip = spread(xi_0_sl, 2, Nconstituents) stt%xi_slip = spread(xi_0_sl, 2, Nconstituents)
dot%xi_slip => plasticState(p)%dotState(startIndex:endIndex,:) dot%xi_slip => plasticState(ph)%dotState(startIndex:endIndex,:)
plasticState(p)%atol(startIndex:endIndex) = pl%get_asFloat('atol_xi',defaultVal=1.0_pReal) plasticState(ph)%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' if(any(plasticState(ph)%atol(startIndex:endIndex) < 0.0_pReal)) extmsg = trim(extmsg)//' atol_xi'
startIndex = endIndex + 1 startIndex = endIndex + 1
endIndex = endIndex + prm%sum_N_tw endIndex = endIndex + prm%sum_N_tw
stt%xi_twin => plasticState(p)%state (startIndex:endIndex,:) stt%xi_twin => plasticState(ph)%state (startIndex:endIndex,:)
stt%xi_twin = spread(xi_0_tw, 2, Nconstituents) stt%xi_twin = spread(xi_0_tw, 2, Nconstituents)
dot%xi_twin => plasticState(p)%dotState(startIndex:endIndex,:) dot%xi_twin => plasticState(ph)%dotState(startIndex:endIndex,:)
plasticState(p)%atol(startIndex:endIndex) = pl%get_asFloat('atol_xi',defaultVal=1.0_pReal) plasticState(ph)%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' if(any(plasticState(ph)%atol(startIndex:endIndex) < 0.0_pReal)) extmsg = trim(extmsg)//' atol_xi'
startIndex = endIndex + 1 startIndex = endIndex + 1
endIndex = endIndex + prm%sum_N_sl endIndex = endIndex + prm%sum_N_sl
stt%gamma_slip => plasticState(p)%state (startIndex:endIndex,:) stt%gamma_slip => plasticState(ph)%state (startIndex:endIndex,:)
dot%gamma_slip => plasticState(p)%dotState(startIndex:endIndex,:) dot%gamma_slip => plasticState(ph)%dotState(startIndex:endIndex,:)
plasticState(p)%atol(startIndex:endIndex) = pl%get_asFloat('atol_gamma',defaultVal=1.0e-6_pReal) plasticState(ph)%atol(startIndex:endIndex) = pl%get_asFloat('atol_gamma',defaultVal=1.0e-6_pReal)
if(any(plasticState(p)%atol(startIndex:endIndex) < 0.0_pReal)) extmsg = trim(extmsg)//' atol_gamma' if(any(plasticState(ph)%atol(startIndex:endIndex) < 0.0_pReal)) extmsg = trim(extmsg)//' atol_gamma'
! global alias ! global alias
plasticState(p)%slipRate => plasticState(p)%dotState(startIndex:endIndex,:) plasticState(ph)%slipRate => plasticState(ph)%dotState(startIndex:endIndex,:)
startIndex = endIndex + 1 startIndex = endIndex + 1
endIndex = endIndex + prm%sum_N_tw endIndex = endIndex + prm%sum_N_tw
stt%gamma_twin => plasticState(p)%state (startIndex:endIndex,:) stt%gamma_twin => plasticState(ph)%state (startIndex:endIndex,:)
dot%gamma_twin => plasticState(p)%dotState(startIndex:endIndex,:) dot%gamma_twin => plasticState(ph)%dotState(startIndex:endIndex,:)
plasticState(p)%atol(startIndex:endIndex) = pl%get_asFloat('atol_gamma',defaultVal=1.0e-6_pReal) plasticState(ph)%atol(startIndex:endIndex) = pl%get_asFloat('atol_gamma',defaultVal=1.0e-6_pReal)
if(any(plasticState(p)%atol(startIndex:endIndex) < 0.0_pReal)) extmsg = trim(extmsg)//' atol_gamma' if(any(plasticState(ph)%atol(startIndex:endIndex) < 0.0_pReal)) extmsg = trim(extmsg)//' atol_gamma'
plasticState(p)%state0 = plasticState(p)%state ! ToDo: this could be done centrally plasticState(ph)%state0 = plasticState(ph)%state ! ToDo: this could be done centrally
end associate end associate
@ -300,18 +298,18 @@ pure module subroutine phenopowerlaw_LpAndItsTangent(Lp,dLp_dMp,Mp,ph,me)
integer :: & integer :: &
i,k,l,m,n i,k,l,m,n
real(pReal), dimension(param(phase_plasticityInstance(ph))%sum_N_sl) :: & real(pReal), dimension(param(ph)%sum_N_sl) :: &
gdot_slip_pos,gdot_slip_neg, & gdot_slip_pos,gdot_slip_neg, &
dgdot_dtauslip_pos,dgdot_dtauslip_neg dgdot_dtauslip_pos,dgdot_dtauslip_neg
real(pReal), dimension(param(phase_plasticityInstance(ph))%sum_N_tw) :: & real(pReal), dimension(param(ph)%sum_N_tw) :: &
gdot_twin,dgdot_dtautwin gdot_twin,dgdot_dtautwin
Lp = 0.0_pReal Lp = 0.0_pReal
dLp_dMp = 0.0_pReal dLp_dMp = 0.0_pReal
associate(prm => param(phase_plasticityInstance(ph))) associate(prm => param(ph))
call kinetics_slip(Mp,phase_plasticityInstance(ph),me,gdot_slip_pos,gdot_slip_neg,dgdot_dtauslip_pos,dgdot_dtauslip_neg) call kinetics_slip(Mp,ph,me,gdot_slip_pos,gdot_slip_neg,dgdot_dtauslip_pos,dgdot_dtauslip_neg)
slipSystems: do i = 1, prm%sum_N_sl slipSystems: do i = 1, prm%sum_N_sl
Lp = Lp + (gdot_slip_pos(i)+gdot_slip_neg(i))*prm%P_sl(1:3,1:3,i) Lp = Lp + (gdot_slip_pos(i)+gdot_slip_neg(i))*prm%P_sl(1:3,1:3,i)
forall (k=1:3,l=1:3,m=1:3,n=1:3) & forall (k=1:3,l=1:3,m=1:3,n=1:3) &
@ -320,7 +318,7 @@ pure module subroutine phenopowerlaw_LpAndItsTangent(Lp,dLp_dMp,Mp,ph,me)
+ dgdot_dtauslip_neg(i) * prm%P_sl(k,l,i) * prm%nonSchmid_neg(m,n,i) + dgdot_dtauslip_neg(i) * prm%P_sl(k,l,i) * prm%nonSchmid_neg(m,n,i)
enddo slipSystems enddo slipSystems
call kinetics_twin(Mp,phase_plasticityInstance(ph),me,gdot_twin,dgdot_dtautwin) call kinetics_twin(Mp,ph,me,gdot_twin,dgdot_dtautwin)
twinSystems: do i = 1, prm%sum_N_tw twinSystems: do i = 1, prm%sum_N_tw
Lp = Lp + gdot_twin(i)*prm%P_tw(1:3,1:3,i) Lp = Lp + gdot_twin(i)*prm%P_tw(1:3,1:3,i)
forall (k=1:3,l=1:3,m=1:3,n=1:3) & forall (k=1:3,l=1:3,m=1:3,n=1:3) &
@ -348,12 +346,12 @@ module subroutine phenopowerlaw_dotState(Mp,ph,me)
c_SlipSlip,c_TwinSlip,c_TwinTwin, & c_SlipSlip,c_TwinSlip,c_TwinTwin, &
xi_slip_sat_offset,& xi_slip_sat_offset,&
sumGamma,sumF sumGamma,sumF
real(pReal), dimension(param(phase_plasticityInstance(ph))%sum_N_sl) :: & real(pReal), dimension(param(ph)%sum_N_sl) :: &
left_SlipSlip,right_SlipSlip, & left_SlipSlip,right_SlipSlip, &
gdot_slip_pos,gdot_slip_neg gdot_slip_pos,gdot_slip_neg
associate(prm => param(phase_plasticityInstance(ph)), stt => state(phase_plasticityInstance(ph)), & associate(prm => param(ph), stt => state(ph), &
dot => dotState(phase_plasticityInstance(ph))) dot => dotState(ph))
sumGamma = sum(stt%gamma_slip(:,me)) sumGamma = sum(stt%gamma_slip(:,me))
sumF = sum(stt%gamma_twin(:,me)/prm%gamma_tw_char) sumF = sum(stt%gamma_twin(:,me)/prm%gamma_tw_char)
@ -373,9 +371,9 @@ module subroutine phenopowerlaw_dotState(Mp,ph,me)
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
! shear rates ! shear rates
call kinetics_slip(Mp,phase_plasticityInstance(ph),me,gdot_slip_pos,gdot_slip_neg) call kinetics_slip(Mp,ph,me,gdot_slip_pos,gdot_slip_neg)
dot%gamma_slip(:,me) = abs(gdot_slip_pos+gdot_slip_neg) dot%gamma_slip(:,me) = abs(gdot_slip_pos+gdot_slip_neg)
call kinetics_twin(Mp,phase_plasticityInstance(ph),me,dot%gamma_twin(:,me)) call kinetics_twin(Mp,ph,me,dot%gamma_twin(:,me))
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
! hardening ! hardening
@ -393,14 +391,14 @@ end subroutine phenopowerlaw_dotState
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief Write results to HDF5 output file. !> @brief Write results to HDF5 output file.
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
module subroutine plastic_phenopowerlaw_results(instance,group) module subroutine plastic_phenopowerlaw_results(ph,group)
integer, intent(in) :: instance integer, intent(in) :: ph
character(len=*), intent(in) :: group character(len=*), intent(in) :: group
integer :: o integer :: o
associate(prm => param(instance), stt => state(instance)) associate(prm => param(ph), stt => state(ph))
outputsLoop: do o = 1,size(prm%output) outputsLoop: do o = 1,size(prm%output)
select case(trim(prm%output(o))) select case(trim(prm%output(o)))
@ -432,28 +430,28 @@ end subroutine plastic_phenopowerlaw_results
! NOTE: Against the common convention, the result (i.e. intent(out)) variables are the last to ! NOTE: Against the common convention, the result (i.e. intent(out)) variables are the last to
! have the optional arguments at the end. ! have the optional arguments at the end.
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
pure subroutine kinetics_slip(Mp,instance,me, & pure subroutine kinetics_slip(Mp,ph,me, &
gdot_slip_pos,gdot_slip_neg,dgdot_dtau_slip_pos,dgdot_dtau_slip_neg) gdot_slip_pos,gdot_slip_neg,dgdot_dtau_slip_pos,dgdot_dtau_slip_neg)
real(pReal), dimension(3,3), intent(in) :: & real(pReal), dimension(3,3), intent(in) :: &
Mp !< Mandel stress Mp !< Mandel stress
integer, intent(in) :: & integer, intent(in) :: &
instance, & ph, &
me me
real(pReal), intent(out), dimension(param(instance)%sum_N_sl) :: & real(pReal), intent(out), dimension(param(ph)%sum_N_sl) :: &
gdot_slip_pos, & gdot_slip_pos, &
gdot_slip_neg gdot_slip_neg
real(pReal), intent(out), optional, dimension(param(instance)%sum_N_sl) :: & real(pReal), intent(out), optional, dimension(param(ph)%sum_N_sl) :: &
dgdot_dtau_slip_pos, & dgdot_dtau_slip_pos, &
dgdot_dtau_slip_neg dgdot_dtau_slip_neg
real(pReal), dimension(param(instance)%sum_N_sl) :: & real(pReal), dimension(param(ph)%sum_N_sl) :: &
tau_slip_pos, & tau_slip_pos, &
tau_slip_neg tau_slip_neg
integer :: i integer :: i
associate(prm => param(instance), stt => state(instance)) associate(prm => param(ph), stt => state(ph))
do i = 1, prm%sum_N_sl do i = 1, prm%sum_N_sl
tau_slip_pos(i) = math_tensordot(Mp,prm%nonSchmid_pos(1:3,1:3,i)) tau_slip_pos(i) = math_tensordot(Mp,prm%nonSchmid_pos(1:3,1:3,i))
@ -501,25 +499,25 @@ end subroutine kinetics_slip
! NOTE: Against the common convention, the result (i.e. intent(out)) variables are the last to ! NOTE: Against the common convention, the result (i.e. intent(out)) variables are the last to
! have the optional arguments at the end. ! have the optional arguments at the end.
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
pure subroutine kinetics_twin(Mp,instance,me,& pure subroutine kinetics_twin(Mp,ph,me,&
gdot_twin,dgdot_dtau_twin) gdot_twin,dgdot_dtau_twin)
real(pReal), dimension(3,3), intent(in) :: & real(pReal), dimension(3,3), intent(in) :: &
Mp !< Mandel stress Mp !< Mandel stress
integer, intent(in) :: & integer, intent(in) :: &
instance, & ph, &
me me
real(pReal), dimension(param(instance)%sum_N_tw), intent(out) :: & real(pReal), dimension(param(ph)%sum_N_tw), intent(out) :: &
gdot_twin gdot_twin
real(pReal), dimension(param(instance)%sum_N_tw), intent(out), optional :: & real(pReal), dimension(param(ph)%sum_N_tw), intent(out), optional :: &
dgdot_dtau_twin dgdot_dtau_twin
real(pReal), dimension(param(instance)%sum_N_tw) :: & real(pReal), dimension(param(ph)%sum_N_tw) :: &
tau_twin tau_twin
integer :: i integer :: i
associate(prm => param(instance), stt => state(instance)) associate(prm => param(ph), stt => state(ph))
do i = 1, prm%sum_N_tw do i = 1, prm%sum_N_tw
tau_twin(i) = math_tensordot(Mp,prm%P_tw(1:3,1:3,i)) tau_twin(i) = math_tensordot(Mp,prm%P_tw(1:3,1:3,i))

View File

@ -1,207 +0,0 @@
submodule(phase:mechanics) eigendeformation
interface
module function kinematics_cleavage_opening_init(kinematics_length) result(myKinematics)
integer, intent(in) :: kinematics_length
logical, dimension(:,:), allocatable :: myKinematics
end function kinematics_cleavage_opening_init
module function kinematics_slipplane_opening_init(kinematics_length) result(myKinematics)
integer, intent(in) :: kinematics_length
logical, dimension(:,:), allocatable :: myKinematics
end function kinematics_slipplane_opening_init
module function kinematics_thermal_expansion_init(kinematics_length) result(myKinematics)
integer, intent(in) :: kinematics_length
logical, dimension(:,:), allocatable :: myKinematics
end function kinematics_thermal_expansion_init
module subroutine kinematics_cleavage_opening_LiAndItsTangent(Ld, dLd_dTstar, S, co, ip, el)
integer, intent(in) :: &
co, & !< grain number
ip, & !< integration point number
el !< element number
real(pReal), intent(in), dimension(3,3) :: &
S
real(pReal), intent(out), dimension(3,3) :: &
Ld !< damage velocity gradient
real(pReal), intent(out), dimension(3,3,3,3) :: &
dLd_dTstar !< derivative of Ld with respect to Tstar (4th-order tensor)
end subroutine kinematics_cleavage_opening_LiAndItsTangent
module subroutine kinematics_slipplane_opening_LiAndItsTangent(Ld, dLd_dTstar, S, co, ip, el)
integer, intent(in) :: &
co, & !< grain number
ip, & !< integration point number
el !< element number
real(pReal), intent(in), dimension(3,3) :: &
S
real(pReal), intent(out), dimension(3,3) :: &
Ld !< damage velocity gradient
real(pReal), intent(out), dimension(3,3,3,3) :: &
dLd_dTstar !< derivative of Ld with respect to Tstar (4th-order tensor)
end subroutine kinematics_slipplane_opening_LiAndItsTangent
module subroutine thermalexpansion_LiAndItsTangent(Li, dLi_dTstar, ph,me)
integer, intent(in) :: ph, me
!< element number
real(pReal), intent(out), dimension(3,3) :: &
Li !< thermal velocity gradient
real(pReal), intent(out), dimension(3,3,3,3) :: &
dLi_dTstar !< derivative of Li with respect to Tstar (4th-order tensor defined to be zero)
end subroutine thermalexpansion_LiAndItsTangent
end interface
contains
module subroutine eigendeformation_init(phases)
class(tNode), pointer :: &
phases
integer :: &
ph
class(tNode), pointer :: &
phase, &
kinematics
print'(/,a)', ' <<<+- phase:mechanics:eigendeformation init -+>>>'
!--------------------------------------------------------------------------------------------------
! initialize kinematic mechanisms
allocate(phase_Nkinematics(phases%length),source = 0)
do ph = 1,phases%length
phase => phases%get(ph)
kinematics => phase%get('kinematics',defaultVal=emptyList)
phase_Nkinematics(ph) = kinematics%length
enddo
allocate(phase_kinematics(maxval(phase_Nkinematics),phases%length), source = KINEMATICS_undefined_ID)
if(maxval(phase_Nkinematics) /= 0) then
where(kinematics_cleavage_opening_init(maxval(phase_Nkinematics))) phase_kinematics = KINEMATICS_cleavage_opening_ID
where(kinematics_slipplane_opening_init(maxval(phase_Nkinematics))) phase_kinematics = KINEMATICS_slipplane_opening_ID
where(kinematics_thermal_expansion_init(maxval(phase_Nkinematics))) phase_kinematics = KINEMATICS_thermal_expansion_ID
endif
end subroutine eigendeformation_init
!--------------------------------------------------------------------------------------------------
!> @brief checks if a kinematic mechanism is active or not
!--------------------------------------------------------------------------------------------------
function kinematics_active(kinematics_label,kinematics_length) result(active_kinematics)
character(len=*), intent(in) :: kinematics_label !< name of kinematic mechanism
integer, intent(in) :: kinematics_length !< max. number of kinematics in system
logical, dimension(:,:), allocatable :: active_kinematics
class(tNode), pointer :: &
phases, &
phase, &
kinematics, &
kinematics_type
integer :: p,k
phases => config_material%get('phase')
allocate(active_kinematics(kinematics_length,phases%length), source = .false. )
do p = 1, phases%length
phase => phases%get(p)
kinematics => phase%get('kinematics',defaultVal=emptyList)
do k = 1, kinematics%length
kinematics_type => kinematics%get(k)
if(kinematics_type%get_asString('type') == kinematics_label) active_kinematics(k,p) = .true.
enddo
enddo
end function kinematics_active
!--------------------------------------------------------------------------------------------------
!> @brief contains the constitutive equation for calculating the velocity gradient
! ToDo: MD: S is Mi?
!--------------------------------------------------------------------------------------------------
module subroutine constitutive_LiAndItsTangents(Li, dLi_dS, dLi_dFi, &
S, Fi, co, ip, el)
integer, intent(in) :: &
co, & !< component-ID of integration point
ip, & !< integration point
el !< element
real(pReal), intent(in), dimension(3,3) :: &
S !< 2nd Piola-Kirchhoff stress
real(pReal), intent(in), dimension(3,3) :: &
Fi !< intermediate deformation gradient
real(pReal), intent(out), dimension(3,3) :: &
Li !< intermediate velocity gradient
real(pReal), intent(out), dimension(3,3,3,3) :: &
dLi_dS, & !< derivative of Li with respect to S
dLi_dFi
real(pReal), dimension(3,3) :: &
my_Li, & !< intermediate velocity gradient
FiInv, &
temp_33
real(pReal), dimension(3,3,3,3) :: &
my_dLi_dS
real(pReal) :: &
detFi
integer :: &
k, i, j, &
instance, of, me, ph
Li = 0.0_pReal
dLi_dS = 0.0_pReal
dLi_dFi = 0.0_pReal
plasticityType: select case (phase_plasticity(material_phaseAt(co,el)))
case (PLASTICITY_isotropic_ID) plasticityType
of = material_phasememberAt(co,ip,el)
instance = phase_plasticityInstance(material_phaseAt(co,el))
call plastic_isotropic_LiAndItsTangent(my_Li, my_dLi_dS, S ,instance,of)
case default plasticityType
my_Li = 0.0_pReal
my_dLi_dS = 0.0_pReal
end select plasticityType
Li = Li + my_Li
dLi_dS = dLi_dS + my_dLi_dS
KinematicsLoop: do k = 1, phase_Nkinematics(material_phaseAt(co,el))
kinematicsType: select case (phase_kinematics(k,material_phaseAt(co,el)))
case (KINEMATICS_cleavage_opening_ID) kinematicsType
call kinematics_cleavage_opening_LiAndItsTangent(my_Li, my_dLi_dS, S, co, ip, el)
case (KINEMATICS_slipplane_opening_ID) kinematicsType
call kinematics_slipplane_opening_LiAndItsTangent(my_Li, my_dLi_dS, S, co, ip, el)
case (KINEMATICS_thermal_expansion_ID) kinematicsType
me = material_phaseMemberAt(co,ip,el)
ph = material_phaseAt(co,el)
call thermalexpansion_LiAndItsTangent(my_Li, my_dLi_dS, ph,me)
case default kinematicsType
my_Li = 0.0_pReal
my_dLi_dS = 0.0_pReal
end select kinematicsType
Li = Li + my_Li
dLi_dS = dLi_dS + my_dLi_dS
enddo KinematicsLoop
FiInv = math_inv33(Fi)
detFi = math_det33(Fi)
Li = matmul(matmul(Fi,Li),FiInv)*detFi !< push forward to intermediate configuration
temp_33 = matmul(FiInv,Li)
do i = 1,3; do j = 1,3
dLi_dS(1:3,1:3,i,j) = matmul(matmul(Fi,dLi_dS(1:3,1:3,i,j)),FiInv)*detFi
dLi_dFi(1:3,1:3,i,j) = dLi_dFi(1:3,1:3,i,j) + Li*FiInv(j,i)
dLi_dFi(1:3,i,1:3,j) = dLi_dFi(1:3,i,1:3,j) + math_I3*temp_33(j,i) + Li*FiInv(j,i)
enddo; enddo
end subroutine constitutive_LiAndItsTangents
end submodule eigendeformation

View File

@ -1,165 +0,0 @@
!--------------------------------------------------------------------------------------------------
!> @author Luv Sharma, Max-Planck-Institut für Eisenforschung GmbH
!> @author Pratheek Shanthraj, Max-Planck-Institut für Eisenforschung GmbH
!> @brief material subroutine incorporating kinematics resulting from opening of cleavage planes
!> @details to be done
!--------------------------------------------------------------------------------------------------
submodule(phase:eigendeformation) cleavageopening
integer, dimension(:), allocatable :: kinematics_cleavage_opening_instance
type :: tParameters !< container type for internal constitutive parameters
integer :: &
sum_N_cl !< total number of cleavage planes
real(pReal) :: &
dot_o, & !< opening rate of cleavage planes
q !< damage rate sensitivity
real(pReal), dimension(:), allocatable :: &
g_crit
real(pReal), dimension(:,:,:,:), allocatable :: &
cleavage_systems
end type tParameters
type(tParameters), dimension(:), allocatable :: param !< containers of constitutive parameters (len Ninstances)
contains
!--------------------------------------------------------------------------------------------------
!> @brief module initialization
!> @details reads in material parameters, allocates arrays, and does sanity checks
!--------------------------------------------------------------------------------------------------
module function kinematics_cleavage_opening_init(kinematics_length) result(myKinematics)
integer, intent(in) :: kinematics_length
logical, dimension(:,:), allocatable :: myKinematics
integer :: Ninstances,p,k
integer, dimension(:), allocatable :: N_cl !< active number of cleavage systems per family
character(len=pStringLen) :: extmsg = ''
class(tNode), pointer :: &
phases, &
phase, &
kinematics, &
kinematic_type
print'(/,a)', ' <<<+- phase:mechanics:eigendeformation:cleavageopening init -+>>>'
myKinematics = kinematics_active('cleavage_opening',kinematics_length)
Ninstances = count(myKinematics)
print'(a,i2)', ' # instances: ',Ninstances; flush(IO_STDOUT)
if(Ninstances == 0) return
phases => config_material%get('phase')
allocate(param(Ninstances))
allocate(kinematics_cleavage_opening_instance(phases%length), source=0)
do p = 1, phases%length
if(any(myKinematics(:,p))) kinematics_cleavage_opening_instance(p) = count(myKinematics(:,1:p))
phase => phases%get(p)
if(count(myKinematics(:,p)) == 0) cycle
kinematics => phase%get('kinematics')
do k = 1, kinematics%length
if(myKinematics(k,p)) then
associate(prm => param(kinematics_cleavage_opening_instance(p)))
kinematic_type => kinematics%get(k)
N_cl = kinematic_type%get_asInts('N_cl')
prm%sum_N_cl = sum(abs(N_cl))
prm%q = kinematic_type%get_asFloat('q')
prm%dot_o = kinematic_type%get_asFloat('dot_o')
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%g_crit = math_expand(prm%g_crit,N_cl)
! sanity checks
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
if (extmsg /= '') call IO_error(211,ext_msg=trim(extmsg)//'(cleavage_opening)')
end associate
endif
enddo
enddo
end function kinematics_cleavage_opening_init
!--------------------------------------------------------------------------------------------------
!> @brief contains the constitutive equation for calculating the velocity gradient
!--------------------------------------------------------------------------------------------------
module subroutine kinematics_cleavage_opening_LiAndItsTangent(Ld, dLd_dTstar, S, co, ip, el)
integer, intent(in) :: &
co, & !< grain number
ip, & !< integration point number
el !< element number
real(pReal), intent(in), dimension(3,3) :: &
S
real(pReal), intent(out), dimension(3,3) :: &
Ld !< damage velocity gradient
real(pReal), intent(out), dimension(3,3,3,3) :: &
dLd_dTstar !< derivative of Ld with respect to Tstar (4th-order tensor)
integer :: &
homog, damageOffset, &
i, k, l, m, n
real(pReal) :: &
traction_d, traction_t, traction_n, traction_crit, &
udotd, dudotd_dt, udott, dudott_dt, udotn, dudotn_dt
homog = material_homogenizationAt(el)
damageOffset = material_homogenizationMemberAt(ip,el)
Ld = 0.0_pReal
dLd_dTstar = 0.0_pReal
associate(prm => param(kinematics_cleavage_opening_instance(material_phaseAt(co,el))))
do i = 1,prm%sum_N_cl
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%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%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)
endif
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%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%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)
endif
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%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%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)
endif
enddo
end associate
end subroutine kinematics_cleavage_opening_LiAndItsTangent
end submodule cleavageopening

View File

@ -3,6 +3,12 @@
!---------------------------------------------------------------------------------------------------- !----------------------------------------------------------------------------------------------------
submodule(phase) thermal submodule(phase) thermal
integer, dimension(:), allocatable :: &
thermal_Nsources
type(tSourceState), allocatable, dimension(:) :: &
thermalState
enum, bind(c); enumerator :: & enum, bind(c); enumerator :: &
THERMAL_UNDEFINED_ID ,& THERMAL_UNDEFINED_ID ,&
THERMAL_DISSIPATION_ID, & THERMAL_DISSIPATION_ID, &
@ -33,8 +39,6 @@ submodule(phase) thermal
end function externalheat_init end function externalheat_init
module subroutine externalheat_dotState(ph, me) module subroutine externalheat_dotState(ph, me)
integer, intent(in) :: & integer, intent(in) :: &
ph, & ph, &
@ -124,7 +128,7 @@ end subroutine thermal_init
!---------------------------------------------------------------------------------------------- !----------------------------------------------------------------------------------------------
!< @brief calculates thermal dissipation rate !< @brief calculates thermal dissipation rate
!---------------------------------------------------------------------------------------------- !----------------------------------------------------------------------------------------------
module subroutine constitutive_thermal_getRate(TDot, ph,me) module subroutine phase_thermal_getRate(TDot, ph,me)
integer, intent(in) :: ph, me integer, intent(in) :: ph, me
real(pReal), intent(out) :: & real(pReal), intent(out) :: &
@ -153,13 +157,13 @@ module subroutine constitutive_thermal_getRate(TDot, ph,me)
enddo enddo
end subroutine constitutive_thermal_getRate end subroutine phase_thermal_getRate
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief contains the constitutive equation for calculating the rate of change of microstructure !> @brief contains the constitutive equation for calculating the rate of change of microstructure
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
function constitutive_thermal_collectDotState(ph,me) result(broken) function phase_thermal_collectDotState(ph,me) result(broken)
integer, intent(in) :: ph, me integer, intent(in) :: ph, me
logical :: broken logical :: broken
@ -178,7 +182,7 @@ function constitutive_thermal_collectDotState(ph,me) result(broken)
enddo SourceLoop enddo SourceLoop
end function constitutive_thermal_collectDotState end function phase_thermal_collectDotState
module function thermal_stress(Delta_t,ph,me) result(converged_) module function thermal_stress(Delta_t,ph,me) result(converged_)
@ -207,7 +211,7 @@ function integrateThermalState(Delta_t, ph,me) result(broken)
so, & so, &
sizeDotState sizeDotState
broken = constitutive_thermal_collectDotState(ph,me) broken = phase_thermal_collectDotState(ph,me)
if(broken) return if(broken) return
do so = 1, thermal_Nsources(ph) do so = 1, thermal_Nsources(ph)
@ -264,7 +268,7 @@ end function thermal_dot_T
!---------------------------------------------------------------------------------------------- !----------------------------------------------------------------------------------------------
!< @brief Set temperature !< @brief Set temperature
!---------------------------------------------------------------------------------------------- !----------------------------------------------------------------------------------------------
module subroutine constitutive_thermal_setField(T,dot_T, co,ce) module subroutine phase_thermal_setField(T,dot_T, co,ce)
real(pReal), intent(in) :: T, dot_T real(pReal), intent(in) :: T, dot_T
integer, intent(in) :: ce, co integer, intent(in) :: ce, co
@ -273,7 +277,7 @@ module subroutine constitutive_thermal_setField(T,dot_T, co,ce)
current(material_phaseAt2(co,ce))%T(material_phaseMemberAt2(co,ce)) = T current(material_phaseAt2(co,ce))%T(material_phaseMemberAt2(co,ce)) = T
current(material_phaseAt2(co,ce))%dot_T(material_phaseMemberAt2(co,ce)) = dot_T current(material_phaseAt2(co,ce))%dot_T(material_phaseMemberAt2(co,ce)) = dot_T
end subroutine constitutive_thermal_setField end subroutine phase_thermal_setField

View File

@ -31,15 +31,14 @@ module function dissipation_init(source_length) result(mySources)
phase, & phase, &
sources, thermal, & sources, thermal, &
src src
integer :: Ninstances,so,Nconstituents,ph integer :: so,Nconstituents,ph
print'(/,a)', ' <<<+- phase:thermal:dissipation init -+>>>'
mySources = thermal_active('dissipation',source_length) mySources = thermal_active('dissipation',source_length)
if(count(mySources) == 0) return
print'(/,a)', ' <<<+- phase:thermal:dissipation init -+>>>'
print'(a,i2)', ' # phases: ',count(mySources); flush(IO_STDOUT)
Ninstances = count(mySources)
print'(a,i2)', ' # instances: ',Ninstances; flush(IO_STDOUT)
if(Ninstances == 0) return
phases => config_material%get('phase') phases => config_material%get('phase')
allocate(param(phases%length)) allocate(param(phases%length))
@ -56,7 +55,7 @@ module function dissipation_init(source_length) result(mySources)
prm%kappa = src%get_asFloat('kappa') prm%kappa = src%get_asFloat('kappa')
Nconstituents = count(material_phaseAt2 == ph) Nconstituents = count(material_phaseAt2 == ph)
call constitutive_allocateState(thermalState(ph)%p(so),Nconstituents,0,0,0) call phase_allocateState(thermalState(ph)%p(so),Nconstituents,0,0,0)
end associate end associate
endif endif
@ -78,7 +77,7 @@ module subroutine dissipation_getRate(TDot, ph,me)
associate(prm => param(ph)) associate(prm => param(ph))
TDot = prm%kappa*sum(abs(mech_S(ph,me)*mech_L_p(ph,me))) TDot = prm%kappa*sum(abs(mechanical_S(ph,me)*mechanical_L_p(ph,me)))
end associate end associate
end subroutine dissipation_getRate end subroutine dissipation_getRate

View File

@ -8,7 +8,7 @@ submodule(phase:thermal) externalheat
integer, dimension(:), allocatable :: & integer, dimension(:), allocatable :: &
source_thermal_externalheat_offset !< which source is my current thermal dissipation mechanism? source_thermal_externalheat_offset !< which source is my current thermal dissipation mechanism?
type :: tParameters !< container type for internal constitutive parameters type :: tParameters !< container type for internal constitutive parameters
real(pReal), dimension(:), allocatable :: & real(pReal), dimension(:), allocatable :: &
@ -38,15 +38,14 @@ module function externalheat_init(source_length) result(mySources)
phase, & phase, &
sources, thermal, & sources, thermal, &
src src
integer :: Ninstances,so,Nconstituents,ph integer :: so,Nconstituents,ph
print'(/,a)', ' <<<+- phase:thermal:externalheat init -+>>>'
mySources = thermal_active('externalheat',source_length) mySources = thermal_active('externalheat',source_length)
if(count(mySources) == 0) return
print'(/,a)', ' <<<+- phase:thermal:externalheat init -+>>>'
print'(a,i2)', ' # phases: ',count(mySources); flush(IO_STDOUT)
Ninstances = count(mySources)
print'(a,i2)', ' # instances: ',Ninstances; flush(IO_STDOUT)
if(Ninstances == 0) return
phases => config_material%get('phase') phases => config_material%get('phase')
allocate(param(phases%length)) allocate(param(phases%length))
@ -69,7 +68,7 @@ module function externalheat_init(source_length) result(mySources)
prm%f_T = src%get_asFloats('f_T',requiredSize = size(prm%t_n)) prm%f_T = src%get_asFloats('f_T',requiredSize = size(prm%t_n))
Nconstituents = count(material_phaseAt2 == ph) Nconstituents = count(material_phaseAt2 == ph)
call constitutive_allocateState(thermalState(ph)%p(so),Nconstituents,1,1,0) call phase_allocateState(thermalState(ph)%p(so),Nconstituents,1,1,0)
end associate end associate
endif endif
enddo enddo