Merge remote-tracking branch 'origin/general-N_constituents' into vtr-only
This commit is contained in:
commit
bac7ace413
|
@ -8,6 +8,7 @@
|
|||
*.jpg binary
|
||||
*.hdf5 binary
|
||||
*.pdf binary
|
||||
*.dream3d binary
|
||||
|
||||
# ignore files from MSC.Marc in language statistics
|
||||
installation/mods_MarcMentat/20*/* linguist-vendored
|
||||
|
|
|
@ -193,6 +193,8 @@ grid_mech_compile_Intel:
|
|||
- module load $IntelCompiler $MPICH_Intel $PETSc_MPICH_Intel
|
||||
- cp -r grid_mech_compile grid_mech_compile_Intel
|
||||
- grid_mech_compile_Intel/test.py
|
||||
- cd pytest
|
||||
- pytest -k 'compile and grid'
|
||||
except:
|
||||
- master
|
||||
- release
|
||||
|
@ -203,6 +205,8 @@ Compile_FEM_Intel:
|
|||
- module load $IntelCompiler $MPICH_Intel $PETSc_MPICH_Intel
|
||||
- cp -r FEM_compile FEM_compile_Intel
|
||||
- FEM_compile_Intel/test.py
|
||||
- cd pytest
|
||||
- pytest -k 'compile and mesh'
|
||||
except:
|
||||
- master
|
||||
- release
|
||||
|
@ -213,6 +217,8 @@ grid_mech_compile_GNU:
|
|||
- module load $GNUCompiler $MPICH_GNU $PETSc_MPICH_GNU
|
||||
- cp -r grid_mech_compile grid_mech_compile_GNU
|
||||
- grid_mech_compile_GNU/test.py
|
||||
- cd pytest
|
||||
- pytest -k 'compile and grid'
|
||||
except:
|
||||
- master
|
||||
- release
|
||||
|
@ -223,6 +229,8 @@ Compile_FEM_GNU:
|
|||
- module load $GNUCompiler $MPICH_GNU $PETSc_MPICH_GNU
|
||||
- cp -r FEM_compile FEM_compile_GNU
|
||||
- FEM_compile_GNU/test.py
|
||||
- cd pytest
|
||||
- pytest -k 'compile and mesh'
|
||||
except:
|
||||
- master
|
||||
- release
|
||||
|
@ -244,7 +252,7 @@ Pytest_grid:
|
|||
script:
|
||||
- module load $IntelCompiler $MPICH_Intel $PETSc_MPICH_Intel
|
||||
- cd pytest
|
||||
- pytest
|
||||
- pytest -m 'not compile'
|
||||
except:
|
||||
- master
|
||||
- release
|
||||
|
@ -306,6 +314,8 @@ Marc_compileIfort:
|
|||
script:
|
||||
- module load $IntelMarc $HDF5Marc $MSC
|
||||
- Marc_compileIfort/test.py
|
||||
- cd pytest
|
||||
- pytest -k 'compile and Marc'
|
||||
except:
|
||||
- master
|
||||
- release
|
||||
|
|
|
@ -1,21 +0,0 @@
|
|||
# Tasan et.al. 2015 Acta Materalia
|
||||
# Tasan et.al. 2015 International Journal of Plasticity
|
||||
# Diehl et.al. 2015 Meccanica
|
||||
[BCC-Ferrite]
|
||||
|
||||
elasticity hooke
|
||||
plasticity phenopowerlaw
|
||||
|
||||
lattice_structure bcc
|
||||
Nslip 12 12 # per family
|
||||
Ntwin 0 # per family
|
||||
c11 233.3e9
|
||||
c12 135.5e9
|
||||
c44 118.0e9
|
||||
gdot0_slip 0.001
|
||||
n_slip 20
|
||||
tau0_slip 95.e6 97.e6 # per family, optimization long simplex 109
|
||||
tausat_slip 222.e6 412.7e6 # per family, optimization long simplex 109
|
||||
h0_slipslip 1000.0e6
|
||||
interaction_slipslip 1 1 1.4 1.4 1.4 1.4
|
||||
a_slip 2.0
|
|
@ -0,0 +1,16 @@
|
|||
# Tasan et.al. 2015 Acta Materalia
|
||||
# Tasan et.al. 2015 International Journal of Plasticity
|
||||
# Diehl et.al. 2015 Meccanica
|
||||
Ferrite:
|
||||
elasticity: {C_11: 233.3e9, C_12: 135.5e9, C_44: 118.0e9, type: hooke}
|
||||
lattice: bcc
|
||||
plasticity:
|
||||
N_sl: [12, 12]
|
||||
a_sl: 2.0
|
||||
dot_gamma_0_sl: 0.001
|
||||
h_0_sl_sl: 1000.0e6
|
||||
h_sl_sl: [1, 1, 1.4, 1.4, 1.4, 1.4]
|
||||
n_sl: 20
|
||||
type: phenopowerlaw
|
||||
xi_0_sl: [95.e6, 96.e6]
|
||||
xi_inf_sl: [222.e6, 412.7e6]
|
|
@ -1,21 +0,0 @@
|
|||
# Tasan et.al. 2015 Acta Materalia
|
||||
# Tasan et.al. 2015 International Journal of Plasticity
|
||||
# Diehl et.al. 2015 Meccanica
|
||||
[BCC-Martensite]
|
||||
|
||||
elasticity hooke
|
||||
plasticity phenopowerlaw
|
||||
|
||||
lattice_structure bcc
|
||||
Nslip 12 12 # per family
|
||||
Ntwin 0 # per family
|
||||
c11 417.4e9
|
||||
c12 242.4e9
|
||||
c44 211.1e9
|
||||
gdot0_slip 0.001
|
||||
n_slip 20
|
||||
tau0_slip 405.8e6 456.7e6 # per family
|
||||
tausat_slip 872.9e6 971.2e6 # per family
|
||||
h0_slipslip 563.0e9
|
||||
interaction_slipslip 1 1 1.4 1.4 1.4 1.4
|
||||
a_slip 2.0
|
|
@ -0,0 +1,16 @@
|
|||
# Tasan et.al. 2015 Acta Materalia
|
||||
# Tasan et.al. 2015 International Journal of Plasticity
|
||||
# Diehl et.al. 2015 Meccanica
|
||||
Martensite:
|
||||
elasticity: {C_11: 417.4e9, C_12: 242.4e9, C_44: 211.1e9, type: hooke}
|
||||
lattice: bcc
|
||||
plasticity:
|
||||
N_sl: [12, 12]
|
||||
a_sl: 2.0
|
||||
dot_gamma_0_sl: 0.001
|
||||
h_0_sl_sl: 563.0e9
|
||||
h_sl_sl: [1, 1, 1.4, 1.4, 1.4, 1.4]
|
||||
n_sl: 20
|
||||
type: phenopowerlaw
|
||||
xi_0_sl: [405.8e6, 456.7e6]
|
||||
xi_inf_sl: [872.9e6, 971.2e6]
|
|
@ -1,3 +1,4 @@
|
|||
---
|
||||
homogenization:
|
||||
SX:
|
||||
N_constituents: 1
|
||||
|
|
|
@ -1,76 +0,0 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import os
|
||||
import sys
|
||||
from io import StringIO
|
||||
from optparse import OptionParser
|
||||
|
||||
from scipy import ndimage
|
||||
|
||||
import damask
|
||||
|
||||
|
||||
scriptName = os.path.splitext(os.path.basename(__file__))[0]
|
||||
scriptID = ' '.join([scriptName,damask.version])
|
||||
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# MAIN
|
||||
# --------------------------------------------------------------------
|
||||
|
||||
parser = OptionParser(option_class=damask.extendableOption, usage='%prog option [ASCIItable(s)]', description = """
|
||||
Add column(s) containing Gaussian filtered values of requested column(s).
|
||||
Operates on periodic and non-periodic ordered three-dimensional data sets.
|
||||
For details see scipy.ndimage documentation.
|
||||
|
||||
""", version = scriptID)
|
||||
|
||||
parser.add_option('-p','--pos','--periodiccellcenter',
|
||||
dest = 'pos',
|
||||
type = 'string', metavar = 'string',
|
||||
help = 'label of coordinates [%default]')
|
||||
parser.add_option('-s','--scalar',
|
||||
dest = 'labels',
|
||||
action = 'extend', metavar = '<string LIST>',
|
||||
help = 'label(s) of scalar field values')
|
||||
parser.add_option('-o','--order',
|
||||
dest = 'order',
|
||||
type = int,
|
||||
metavar = 'int',
|
||||
help = 'order of the filter [%default]')
|
||||
parser.add_option('--sigma',
|
||||
dest = 'sigma',
|
||||
type = float,
|
||||
metavar = 'float',
|
||||
help = 'standard deviation [%default]')
|
||||
parser.add_option('--periodic',
|
||||
dest = 'periodic',
|
||||
action = 'store_true',
|
||||
help = 'assume periodic grain structure')
|
||||
|
||||
|
||||
|
||||
parser.set_defaults(pos = 'pos',
|
||||
order = 0,
|
||||
sigma = 1,
|
||||
)
|
||||
|
||||
(options,filenames) = parser.parse_args()
|
||||
if filenames == []: filenames = [None]
|
||||
|
||||
if options.labels is None: parser.error('no data column specified.')
|
||||
|
||||
for name in filenames:
|
||||
damask.util.report(scriptName,name)
|
||||
|
||||
table = damask.Table.load(StringIO(''.join(sys.stdin.read())) if name is None else name)
|
||||
damask.grid_filters.coord0_check(table.get(options.pos))
|
||||
|
||||
for label in options.labels:
|
||||
table = table.add('Gauss{}({})'.format(options.sigma,label),
|
||||
ndimage.filters.gaussian_filter(table.get(label).reshape(-1),
|
||||
options.sigma,options.order,
|
||||
mode = 'wrap' if options.periodic else 'nearest'),
|
||||
scriptID+' '+' '.join(sys.argv[1:]))
|
||||
|
||||
table.save((sys.stdout if name is None else name), legacy=True)
|
|
@ -1,12 +1,8 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import os
|
||||
import sys
|
||||
from optparse import OptionParser
|
||||
|
||||
import h5py
|
||||
import numpy as np
|
||||
|
||||
import damask
|
||||
|
||||
|
||||
|
@ -64,88 +60,12 @@ parser.set_defaults(pointwise = 'CellData',
|
|||
if options.basegroup is None:
|
||||
parser.error('No base group selected')
|
||||
|
||||
rootDir ='DataContainers'
|
||||
|
||||
|
||||
if filenames == []: parser.error('no input file specified.')
|
||||
|
||||
for name in filenames:
|
||||
damask.util.report(scriptName,name)
|
||||
|
||||
errors = []
|
||||
|
||||
inFile = h5py.File(name, 'r')
|
||||
group_geom = os.path.join(rootDir,options.basegroup,'_SIMPL_GEOMETRY')
|
||||
try:
|
||||
size = inFile[os.path.join(group_geom,'DIMENSIONS')][...] \
|
||||
* inFile[os.path.join(group_geom,'SPACING')][...]
|
||||
grid = inFile[os.path.join(group_geom,'DIMENSIONS')][...]
|
||||
origin = inFile[os.path.join(group_geom,'ORIGIN')][...]
|
||||
except KeyError:
|
||||
errors.append('Geometry data ({}) not found'.format(group_geom))
|
||||
|
||||
|
||||
group_pointwise = os.path.join(rootDir,options.basegroup,options.pointwise)
|
||||
if options.average is None:
|
||||
label = 'Point'
|
||||
|
||||
dataset = os.path.join(group_pointwise,options.quaternion)
|
||||
try:
|
||||
quats = np.reshape(inFile[dataset][...],(np.product(grid),4))
|
||||
rot = [damask.Rotation.from_quaternion(q,True,P=+1) for q in quats]
|
||||
except KeyError:
|
||||
errors.append('Pointwise orientation (quaternion) data ({}) not readable'.format(dataset))
|
||||
|
||||
dataset = os.path.join(group_pointwise,options.phase)
|
||||
try:
|
||||
phase = np.reshape(inFile[dataset][...],(np.product(grid)))
|
||||
except KeyError:
|
||||
errors.append('Pointwise phase data ({}) not readable'.format(dataset))
|
||||
|
||||
microstructure = np.arange(1,np.product(grid)+1,dtype=int).reshape(grid,order='F')
|
||||
|
||||
|
||||
else:
|
||||
label = 'Grain'
|
||||
|
||||
dataset = os.path.join(group_pointwise,options.microstructure)
|
||||
try:
|
||||
microstructure = np.transpose(inFile[dataset][...].reshape(grid[::-1]),(2,1,0)) # convert from C ordering
|
||||
except KeyError:
|
||||
errors.append('Link between pointwise and grain average data ({}) not readable'.format(dataset))
|
||||
|
||||
group_average = os.path.join(rootDir,options.basegroup,options.average)
|
||||
|
||||
dataset = os.path.join(group_average,options.quaternion)
|
||||
try:
|
||||
rot = [damask.Rotation.from_quaternion(q,True,P=+1) for q in inFile[dataset][...][1:]] # skip first entry (unindexed)
|
||||
except KeyError:
|
||||
errors.append('Average orientation data ({}) not readable'.format(dataset))
|
||||
|
||||
dataset = os.path.join(group_average,options.phase)
|
||||
try:
|
||||
phase = [i[0] for i in inFile[dataset][...]][1:] # skip first entry (unindexed)
|
||||
except KeyError:
|
||||
errors.append('Average phase data ({}) not readable'.format(dataset))
|
||||
|
||||
if errors != []:
|
||||
damask.util.croak(errors)
|
||||
continue
|
||||
|
||||
config_header = ['<texture>']
|
||||
for i in range(np.nanmax(microstructure)):
|
||||
config_header += ['[{}{}]'.format(label,i+1),
|
||||
'(gauss)\tphi1 {:.2f}\tPhi {:.2f}\tphi2 {:.2f}'.format(*rot[i].as_Eulers(degrees = True)),
|
||||
]
|
||||
config_header += ['<microstructure>']
|
||||
for i in range(np.nanmax(microstructure)):
|
||||
config_header += ['[{}{}]'.format(label,i+1),
|
||||
'(constituent)\tphase {}\ttexture {}\tfraction 1.0'.format(phase[i],i+1),
|
||||
]
|
||||
|
||||
header = [scriptID + ' ' + ' '.join(sys.argv[1:])]\
|
||||
+ config_header
|
||||
geom = damask.Geom(microstructure,size,origin,comments=header)
|
||||
geom = damask.Geom.load_DREAM3D(name,options.basegroup,options.pointwise)
|
||||
damask.util.croak(geom)
|
||||
|
||||
geom.save_ASCII(os.path.splitext(name)[0]+'.geom')
|
||||
|
|
|
@ -2,11 +2,8 @@
|
|||
|
||||
import os
|
||||
import sys
|
||||
from io import StringIO
|
||||
from optparse import OptionParser
|
||||
|
||||
import numpy as np
|
||||
|
||||
import damask
|
||||
|
||||
|
||||
|
@ -40,64 +37,21 @@ parser.add_option('-q', '--quaternion',
|
|||
dest = 'quaternion',
|
||||
type = 'string', metavar='string',
|
||||
help = 'quaternion label')
|
||||
parser.add_option('--axes',
|
||||
dest = 'axes',
|
||||
type = 'string', nargs = 3, metavar = ' '.join(['string']*3),
|
||||
help = 'orientation coordinate frame in terms of position coordinate frame [+x +y +z]')
|
||||
|
||||
|
||||
parser.set_defaults(pos = 'pos',
|
||||
)
|
||||
parser.set_defaults(pos= 'pos')
|
||||
|
||||
(options,filenames) = parser.parse_args()
|
||||
if filenames == []: filenames = [None]
|
||||
|
||||
if np.sum([options.quaternion is not None,
|
||||
options.microstructure is not None]) != 1:
|
||||
parser.error('need either microstructure or quaternion (and optionally phase) as input.')
|
||||
if options.microstructure is not None and options.phase is not None:
|
||||
parser.error('need either microstructure or phase (and mandatory quaternion) as input.')
|
||||
if options.axes is not None and not set(options.axes).issubset(set(['x','+x','-x','y','+y','-y','z','+z','-z'])):
|
||||
parser.error('invalid axes {} {} {}.'.format(*options.axes))
|
||||
|
||||
for name in filenames:
|
||||
damask.util.report(scriptName,name)
|
||||
|
||||
table = damask.Table.load(StringIO(''.join(sys.stdin.read())) if name is None else name)
|
||||
table.sort_by(['{}_{}'.format(i,options.pos) for i in range(3,0,-1)]) # x fast, y slow
|
||||
grid,size,origin = damask.grid_filters.cell_coord0_gridSizeOrigin(table.get(options.pos))
|
||||
labels = []
|
||||
for l in [options.quaternion,options.phase,options.microstructure]:
|
||||
if l is not None: labels.append(l)
|
||||
|
||||
config_header = table.comments
|
||||
|
||||
if options.microstructure:
|
||||
microstructure = table.get(options.microstructure).reshape(grid,order='F')
|
||||
|
||||
elif options.quaternion:
|
||||
q = table.get(options.quaternion)
|
||||
phase = table.get(options.phase).astype(int) if options.phase else \
|
||||
np.ones((table.data.shape[0],1),dtype=int)
|
||||
|
||||
unique,unique_inverse = np.unique(np.hstack((q,phase)),return_inverse=True,axis=0)
|
||||
microstructure = unique_inverse.reshape(grid,order='F') + 1
|
||||
|
||||
config_header = ['<texture>']
|
||||
for i,data in enumerate(unique):
|
||||
ori = damask.Rotation(data[0:4])
|
||||
config_header += ['[Grain{}]'.format(i+1),
|
||||
'(gauss)\tphi1 {:.2f}\tPhi {:.2f}\tphi2 {:.2f}'.format(*ori.as_Eulers(degrees = True)),
|
||||
]
|
||||
if options.axes is not None: config_header += ['axes\t{} {} {}'.format(*options.axes)]
|
||||
|
||||
config_header += ['<microstructure>']
|
||||
for i,data in enumerate(unique):
|
||||
config_header += ['[Grain{}]'.format(i+1),
|
||||
'(constituent)\tphase {}\ttexture {}\tfraction 1.0'.format(int(data[4]),i+1),
|
||||
]
|
||||
|
||||
header = [scriptID + ' ' + ' '.join(sys.argv[1:])]\
|
||||
+ config_header
|
||||
geom = damask.Geom(microstructure,size,origin,
|
||||
comments=header)
|
||||
t = damask.Table.load(name)
|
||||
geom = damask.Geom.from_table(t,options.pos,labels)
|
||||
damask.util.croak(geom)
|
||||
|
||||
geom.save_ASCII(sys.stdout if name is None else os.path.splitext(name)[0]+'.geom')
|
||||
|
|
|
@ -10,20 +10,21 @@ with open(_Path(__file__).parent/_Path('VERSION')) as _f:
|
|||
# make classes directly accessible as damask.Class
|
||||
from ._environment import Environment as _ # noqa
|
||||
environment = _()
|
||||
from ._table import Table # noqa
|
||||
from ._vtk import VTK # noqa
|
||||
from ._colormap import Colormap # noqa
|
||||
from ._rotation import Rotation # noqa
|
||||
from ._lattice import Symmetry, Lattice# noqa
|
||||
from ._orientation import Orientation # noqa
|
||||
from ._result import Result # noqa
|
||||
from ._geom import Geom # noqa
|
||||
from ._material import Material # noqa
|
||||
from . import solver # noqa
|
||||
from . import util # noqa
|
||||
from . import seeds # noqa
|
||||
from . import grid_filters # noqa
|
||||
from . import mechanics # noqa
|
||||
from . import solver # noqa
|
||||
from . import grid_filters # noqa
|
||||
from ._lattice import Symmetry, Lattice# noqa
|
||||
from ._table import Table # noqa
|
||||
from ._rotation import Rotation # noqa
|
||||
from ._vtk import VTK # noqa
|
||||
from ._colormap import Colormap # noqa
|
||||
from ._orientation import Orientation # noqa
|
||||
from ._config import Config # noqa
|
||||
from ._configmaterial import ConfigMaterial # noqa
|
||||
from ._geom import Geom # noqa
|
||||
from ._result import Result # noqa
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
from io import StringIO
|
||||
import abc
|
||||
|
||||
import yaml
|
||||
|
||||
class NiceDumper(yaml.SafeDumper):
|
||||
"""Make YAML readable for humans."""
|
||||
|
||||
def write_line_break(self, data=None):
|
||||
super().write_line_break(data)
|
||||
|
||||
if len(self.indents) == 1:
|
||||
super().write_line_break()
|
||||
|
||||
def increase_indent(self, flow=False, indentless=False):
|
||||
return super().increase_indent(flow, False)
|
||||
|
||||
|
||||
class Config(dict):
|
||||
"""YAML-based configuration."""
|
||||
|
||||
def __repr__(self):
|
||||
"""Show as in file."""
|
||||
output = StringIO()
|
||||
self.save(output)
|
||||
output.seek(0)
|
||||
return ''.join(output.readlines())
|
||||
|
||||
@classmethod
|
||||
def load(cls,fname):
|
||||
"""
|
||||
Load from yaml file.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
fname : file, str, or pathlib.Path
|
||||
Filename or file for writing.
|
||||
|
||||
"""
|
||||
try:
|
||||
fhandle = open(fname)
|
||||
except TypeError:
|
||||
fhandle = fname
|
||||
return cls(yaml.safe_load(fhandle))
|
||||
|
||||
def save(self,fname,**kwargs):
|
||||
"""
|
||||
Save to yaml file.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
fname : file, str, or pathlib.Path
|
||||
Filename or file for writing.
|
||||
**kwargs : dict
|
||||
Keyword arguments parsed to yaml.dump.
|
||||
|
||||
"""
|
||||
try:
|
||||
fhandle = open(fname,'w')
|
||||
except TypeError:
|
||||
fhandle = fname
|
||||
|
||||
if 'width' not in kwargs:
|
||||
kwargs['width'] = 256
|
||||
if 'default_flow_style' not in kwargs:
|
||||
kwargs['default_flow_style'] = None
|
||||
fhandle.write(yaml.dump(dict(self),Dumper=NiceDumper,**kwargs))
|
||||
|
||||
|
||||
@property
|
||||
@abc.abstractmethod
|
||||
def is_complete(self):
|
||||
"""Check for completeness."""
|
||||
pass
|
||||
|
||||
@property
|
||||
@abc.abstractmethod
|
||||
def is_valid(self):
|
||||
"""Check for valid file layout."""
|
||||
pass
|
|
@ -0,0 +1,299 @@
|
|||
import copy
|
||||
|
||||
import numpy as np
|
||||
|
||||
from . import grid_filters
|
||||
from . import Config
|
||||
from . import Lattice
|
||||
from . import Rotation
|
||||
|
||||
class ConfigMaterial(Config):
|
||||
"""Material configuration."""
|
||||
|
||||
def save(self,fname='material.yaml',**kwargs):
|
||||
"""
|
||||
Save to yaml file.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
fname : file, str, or pathlib.Path, optional
|
||||
Filename or file for writing. Defaults to 'material.yaml'.
|
||||
**kwargs
|
||||
Keyword arguments parsed to yaml.dump.
|
||||
|
||||
"""
|
||||
super().save(fname,**kwargs)
|
||||
|
||||
|
||||
@staticmethod
|
||||
def from_table(table,coordinates=None,constituents={},**kwargs):
|
||||
"""
|
||||
Load from an ASCII table.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
table : damask.Table
|
||||
Table that contains material information.
|
||||
coordinates : str, optional
|
||||
Label of spatial coordiates. Used for sorting and performing a
|
||||
sanity check. Default to None, in which case no sorting or checking is
|
||||
peformed.
|
||||
constituents : dict, optional
|
||||
Entries for 'constituents'. The key is the name and the value specifies
|
||||
the label of the data column in the table
|
||||
**kwargs
|
||||
Keyword arguments where the key is the name and the value specifies
|
||||
the label of the data column in the table
|
||||
|
||||
Examples
|
||||
--------
|
||||
>>> import damask
|
||||
>>> import damask.ConfigMaterial as cm
|
||||
>>> t = damask.Table.load('small.txt')
|
||||
>>> t
|
||||
pos pos pos qu qu qu qu phase homog
|
||||
0 0 0 0 0.19 0.8 0.24 -0.51 Aluminum SX
|
||||
1 1 0 0 0.8 0.19 0.24 -0.51 Steel SX
|
||||
>>> cm.from_table(t,'pos',{'O':'qu','phase':'phase'},homogenization='homog')
|
||||
material:
|
||||
- constituents:
|
||||
- O: [0.19, 0.8, 0.24, -0.51]
|
||||
fraction: 1.0
|
||||
phase: Aluminum
|
||||
homogenization: SX
|
||||
- constituents:
|
||||
- O: [0.8, 0.19, 0.24, -0.51]
|
||||
fraction: 1.0
|
||||
phase: Steel
|
||||
homogenization: SX
|
||||
|
||||
"""
|
||||
if coordinates is not None:
|
||||
t = table.sort_by([f'{i}_{coordinates}' for i in range(3,0,-1)])
|
||||
grid_filters.coord0_check(t.get(coordinates))
|
||||
else:
|
||||
t = table
|
||||
|
||||
constituents_ = {k:t.get(v) for k,v in constituents.items()}
|
||||
kwargs_ = {k:t.get(v) for k,v in kwargs.items()}
|
||||
|
||||
_,idx = np.unique(np.hstack(list({**constituents_,**kwargs_}.values())),return_index=True,axis=0)
|
||||
|
||||
constituents_ = {k:v[idx].squeeze() for k,v in constituents_.items()}
|
||||
kwargs_ = {k:v[idx].squeeze() for k,v in kwargs_.items()}
|
||||
|
||||
return ConfigMaterial().material_add(constituents_,**kwargs_)
|
||||
|
||||
|
||||
@property
|
||||
def is_complete(self):
|
||||
"""Check for completeness."""
|
||||
ok = True
|
||||
for top_level in ['homogenization','phase','material']:
|
||||
# ToDo: With python 3.8 as prerequisite we can shorten with :=
|
||||
ok &= top_level in self
|
||||
if top_level not in self: print(f'{top_level} entry missing')
|
||||
|
||||
if ok:
|
||||
ok &= len(self['material']) > 0
|
||||
if len(self['material']) < 1: print('Incomplete material definition')
|
||||
|
||||
if ok:
|
||||
homogenization = set()
|
||||
phase = set()
|
||||
for i,v in enumerate(self['material']):
|
||||
if 'homogenization' in v:
|
||||
homogenization.add(v['homogenization'])
|
||||
else:
|
||||
print(f'No homogenization specified in material {i}')
|
||||
ok = False
|
||||
|
||||
if 'constituents' in v:
|
||||
for ii,vv in enumerate(v['constituents']):
|
||||
if 'O' not in vv:
|
||||
print('No orientation specified in constituent {ii} of material {i}')
|
||||
ok = False
|
||||
if 'phase' in vv:
|
||||
phase.add(vv['phase'])
|
||||
else:
|
||||
print(f'No phase specified in constituent {ii} of material {i}')
|
||||
ok = False
|
||||
|
||||
for k,v in self['phase'].items():
|
||||
if 'lattice' not in v:
|
||||
print(f'No lattice specified in phase {k}')
|
||||
ok = False
|
||||
|
||||
for k,v in self['homogenization'].items():
|
||||
if 'N_constituents' not in v:
|
||||
print(f'No. of constituents not specified in homogenization {k}')
|
||||
ok = False
|
||||
|
||||
if phase - set(self['phase']):
|
||||
print(f'Phase(s) {phase-set(self["phase"])} missing')
|
||||
ok = False
|
||||
if homogenization - set(self['homogenization']):
|
||||
print(f'Homogenization(s) {homogenization-set(self["homogenization"])} missing')
|
||||
ok = False
|
||||
|
||||
return ok
|
||||
|
||||
|
||||
@property
|
||||
def is_valid(self):
|
||||
"""Check for valid file layout."""
|
||||
ok = True
|
||||
|
||||
if 'phase' in self:
|
||||
for k,v in self['phase'].items():
|
||||
if 'lattice' in v:
|
||||
try:
|
||||
Lattice(v['lattice'])
|
||||
except KeyError:
|
||||
s = v['lattice']
|
||||
print(f"Invalid lattice: '{s}' in phase '{k}'")
|
||||
ok = False
|
||||
|
||||
if 'material' in self:
|
||||
for i,v in enumerate(self['material']):
|
||||
if 'constituents' in v:
|
||||
f = 0.0
|
||||
for c in v['constituents']:
|
||||
f+= float(c['fraction'])
|
||||
if 'O' in c:
|
||||
try:
|
||||
Rotation.from_quaternion(c['O'])
|
||||
except ValueError:
|
||||
o = c['O']
|
||||
print(f"Invalid orientation: '{o}' in material '{i}'")
|
||||
ok = False
|
||||
if not np.isclose(f,1.0):
|
||||
print(f"Invalid total fraction '{f}' in material '{i}'")
|
||||
ok = False
|
||||
|
||||
return ok
|
||||
|
||||
|
||||
def material_rename_phase(self,mapping,ID=None,constituent=None):
|
||||
"""
|
||||
Change phase name in material.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
mapping: dictionary
|
||||
Mapping from old name to new name
|
||||
ID: list of ints, optional
|
||||
Limit renaming to selected material IDs.
|
||||
constituent: list of ints, optional
|
||||
Limit renaming to selected constituents.
|
||||
|
||||
"""
|
||||
dup = copy.deepcopy(self)
|
||||
for i,m in enumerate(dup['material']):
|
||||
if ID and i not in ID: continue
|
||||
for c in m['constituents']:
|
||||
if constituent is not None and c not in constituent: continue
|
||||
try:
|
||||
c['phase'] = mapping[c['phase']]
|
||||
except KeyError:
|
||||
continue
|
||||
return dup
|
||||
|
||||
|
||||
def material_rename_homogenization(self,mapping,ID=None):
|
||||
"""
|
||||
Change homogenization name in material.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
mapping: dictionary
|
||||
Mapping from old name to new name
|
||||
ID: list of ints, optional
|
||||
Limit renaming to selected homogenization IDs.
|
||||
|
||||
"""
|
||||
dup = copy.deepcopy(self)
|
||||
for i,m in enumerate(dup['material']):
|
||||
if ID and i not in ID: continue
|
||||
try:
|
||||
m['homogenization'] = mapping[m['homogenization']]
|
||||
except KeyError:
|
||||
continue
|
||||
return dup
|
||||
|
||||
|
||||
def material_add(self,constituents,**kwargs):
|
||||
"""
|
||||
Add material entries.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
constituents : dict
|
||||
Entries for 'constituents'. The key is the name and the value specifies
|
||||
the label of the data column in the table
|
||||
**kwargs
|
||||
Keyword arguments where the key is the name and the value specifies
|
||||
the label of the data column in the table
|
||||
|
||||
Examples
|
||||
--------
|
||||
>>> import damask
|
||||
>>> m = damask.ConfigMaterial()
|
||||
>>> O = damask.Rotation.from_random(3).as_quaternion()
|
||||
>>> phase = ['Aluminum','Steel','Aluminum']
|
||||
>>> m.material_add(constituents={'phase':phase,'O':O},homogenization='SX')
|
||||
material:
|
||||
- constituents:
|
||||
- O: [0.577764, -0.146299, -0.617669, 0.513010]
|
||||
fraction: 1.0
|
||||
phase: Aluminum
|
||||
homogenization: SX
|
||||
- constituents:
|
||||
- O: [0.184176, 0.340305, 0.737247, 0.553840]
|
||||
fraction: 1.0
|
||||
phase: Steel
|
||||
homogenization: SX
|
||||
- constituents:
|
||||
- O: [0.0886257, -0.144848, 0.615674, -0.769487]
|
||||
fraction: 1.0
|
||||
phase: Aluminum
|
||||
homogenization: SX
|
||||
|
||||
"""
|
||||
c = [{'constituents':u} for u in ConfigMaterial._constituents(**constituents)]
|
||||
for k,v in kwargs.items():
|
||||
if hasattr(v,'__len__') and not isinstance(v,str):
|
||||
if len(v) != len(c):
|
||||
raise ValueError('len mismatch 1')
|
||||
for i,vv in enumerate(v):
|
||||
c[i][k] = [w.item() for w in vv] if isinstance(vv,np.ndarray) else vv.item()
|
||||
else:
|
||||
for i in range(len(c)):
|
||||
c[i][k] = v
|
||||
dup = copy.deepcopy(self)
|
||||
if 'material' not in dup: dup['material'] = []
|
||||
dup['material'] +=c
|
||||
|
||||
return dup
|
||||
|
||||
|
||||
@staticmethod
|
||||
def _constituents(N=1,**kwargs):
|
||||
"""Construct list of constituents."""
|
||||
for v in kwargs.values():
|
||||
if hasattr(v,'__len__') and not isinstance(v,str): N_material = len(v)
|
||||
|
||||
if N == 1:
|
||||
m = [[{'fraction':1.0}] for _ in range(N_material)]
|
||||
for k,v in kwargs.items():
|
||||
if hasattr(v,'__len__') and not isinstance(v,str):
|
||||
if len(v) != N_material:
|
||||
raise ValueError('len mismatch 2')
|
||||
for i,vv in enumerate(np.array(v)):
|
||||
m[i][0][k] = [w.item() for w in vv] if isinstance(vv,np.ndarray) else vv.item()
|
||||
else:
|
||||
for i in range(N_material):
|
||||
m[i][0][k] = v
|
||||
return m
|
||||
else:
|
||||
raise NotImplementedError
|
|
@ -1,15 +1,17 @@
|
|||
import copy
|
||||
import multiprocessing as mp
|
||||
from functools import partial
|
||||
from os import path
|
||||
|
||||
import numpy as np
|
||||
import h5py
|
||||
from scipy import ndimage,spatial
|
||||
|
||||
from . import environment
|
||||
from . import Rotation
|
||||
from . import VTK
|
||||
from . import util
|
||||
from . import grid_filters
|
||||
from . import Rotation
|
||||
|
||||
|
||||
class Geom:
|
||||
|
@ -207,6 +209,68 @@ class Geom:
|
|||
return Geom(material.reshape(grid,order='F'),size,origin,comments)
|
||||
|
||||
|
||||
|
||||
@staticmethod
|
||||
def load_DREAM3D(fname,base_group,point_data=None,material='FeatureIds'):
|
||||
"""
|
||||
Load a DREAM.3D file.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
fname : str
|
||||
Filename of the DREAM.3D file
|
||||
base_group : str
|
||||
Name of the group (folder) below 'DataContainers'. For example
|
||||
'SyntheticVolumeDataContainer'.
|
||||
point_data : str, optional
|
||||
Name of the group (folder) containing the point wise material data,
|
||||
for example 'CellData'. Defaults to None, in which case points consecutively numbered.
|
||||
material : str, optional
|
||||
Name of the dataset containing the material ID. Defaults to
|
||||
'FeatureIds'.
|
||||
|
||||
"""
|
||||
root_dir ='DataContainers'
|
||||
f = h5py.File(fname, 'r')
|
||||
g = path.join(root_dir,base_group,'_SIMPL_GEOMETRY')
|
||||
size = f[path.join(g,'DIMENSIONS')][()] * f[path.join(g,'SPACING')][()]
|
||||
grid = f[path.join(g,'DIMENSIONS')][()]
|
||||
origin = f[path.join(g,'ORIGIN')][()]
|
||||
group_pointwise = path.join(root_dir,base_group,point_data)
|
||||
|
||||
ma = np.arange(1,np.product(grid)+1,dtype=int) if point_data is None else \
|
||||
np.reshape(f[path.join(group_pointwise,material)],grid.prod())
|
||||
|
||||
return Geom(ma.reshape(grid,order='F'),size,origin,util.execution_stamp('Geom','load_DREAM3D'))
|
||||
|
||||
|
||||
@staticmethod
|
||||
def from_table(table,coordinates,labels):
|
||||
"""
|
||||
Load an ASCII table.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
table : damask.Table
|
||||
Table that contains material information.
|
||||
coordinates : str
|
||||
Label of the column containing the spatial coordinates.
|
||||
labels : str or list of str
|
||||
Label(s) of the columns containing the material definition.
|
||||
Each unique combintation of values results in a material.
|
||||
|
||||
"""
|
||||
t = table.sort_by([f'{i}_{coordinates}' for i in range(3,0,-1)])
|
||||
|
||||
grid,size,origin = grid_filters.cell_coord0_gridSizeOrigin(t.get(coordinates))
|
||||
|
||||
labels_ = [labels] if isinstance(labels,str) else labels
|
||||
_,unique_inverse = np.unique(np.hstack([t.get(l) for l in labels_]),return_inverse=True,axis=0)
|
||||
ma = unique_inverse.reshape(grid,order='F') + 1
|
||||
|
||||
return Geom(ma,size,origin,util.execution_stamp('Geom','from_table'))
|
||||
|
||||
|
||||
@staticmethod
|
||||
def _find_closest_seed(seeds, weights, point):
|
||||
return np.argmin(np.sum((np.broadcast_to(point,(len(seeds),3))-seeds)**2,axis=1) - weights)
|
||||
|
@ -399,7 +463,7 @@ class Geom:
|
|||
|
||||
def save(self,fname,compress=True):
|
||||
"""
|
||||
Generate vtk rectilinear grid.
|
||||
Store as vtk rectilinear grid.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
@ -489,7 +553,7 @@ class Geom:
|
|||
coords_rot = R.broadcast_to(tuple(self.grid))@coords
|
||||
|
||||
with np.errstate(all='ignore'):
|
||||
mask = np.where(np.sum(np.power(coords_rot/r,2.0**exponent),axis=-1) > 1.0,True,False)
|
||||
mask = np.sum(np.power(coords_rot/r,2.0**np.array(exponent)),axis=-1) > 1.0
|
||||
|
||||
if periodic: # translate back to center
|
||||
mask = np.roll(mask,((c-np.ones(3)*.5)*self.grid).astype(int),(0,1,2))
|
||||
|
|
|
@ -1,193 +0,0 @@
|
|||
from io import StringIO
|
||||
import copy
|
||||
|
||||
import yaml
|
||||
import numpy as np
|
||||
|
||||
from . import Lattice
|
||||
from . import Rotation
|
||||
|
||||
class NiceDumper(yaml.SafeDumper):
|
||||
"""Make YAML readable for humans."""
|
||||
|
||||
def write_line_break(self, data=None):
|
||||
super().write_line_break(data)
|
||||
|
||||
if len(self.indents) == 1:
|
||||
super().write_line_break()
|
||||
|
||||
def increase_indent(self, flow=False, indentless=False):
|
||||
return super().increase_indent(flow, False)
|
||||
|
||||
|
||||
class Material(dict):
|
||||
"""Material configuration."""
|
||||
|
||||
def __repr__(self):
|
||||
"""Show as in file."""
|
||||
output = StringIO()
|
||||
self.save(output)
|
||||
output.seek(0)
|
||||
return ''.join(output.readlines())
|
||||
|
||||
@staticmethod
|
||||
def load(fname):
|
||||
"""Load from yaml file."""
|
||||
try:
|
||||
fhandle = open(fname)
|
||||
except TypeError:
|
||||
fhandle = fname
|
||||
return Material(yaml.safe_load(fhandle))
|
||||
|
||||
def save(self,fname='material.yaml'):
|
||||
"""
|
||||
Save to yaml file.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
fname : file, str, or pathlib.Path
|
||||
Filename or file for reading.
|
||||
|
||||
"""
|
||||
try:
|
||||
fhandle = open(fname,'w')
|
||||
except TypeError:
|
||||
fhandle = fname
|
||||
fhandle.write(yaml.dump(dict(self),width=256,default_flow_style=None,Dumper=NiceDumper))
|
||||
|
||||
|
||||
@property
|
||||
def is_complete(self):
|
||||
"""Check for completeness."""
|
||||
ok = True
|
||||
for top_level in ['homogenization','phase','microstructure']:
|
||||
# ToDo: With python 3.8 as prerequisite we can shorten with :=
|
||||
ok &= top_level in self
|
||||
if top_level not in self: print(f'{top_level} entry missing')
|
||||
|
||||
if ok:
|
||||
ok &= len(self['microstructure']) > 0
|
||||
if len(self['microstructure']) < 1: print('Incomplete microstructure definition')
|
||||
|
||||
if ok:
|
||||
homogenization = set()
|
||||
phase = set()
|
||||
for i,v in enumerate(self['microstructure']):
|
||||
if 'homogenization' in v:
|
||||
homogenization.add(v['homogenization'])
|
||||
else:
|
||||
print(f'No homogenization specified in microstructure {i}')
|
||||
ok = False
|
||||
|
||||
if 'constituents' in v:
|
||||
for ii,vv in enumerate(v['constituents']):
|
||||
if 'orientation' not in vv:
|
||||
print('No orientation specified in constituent {ii} of microstructure {i}')
|
||||
ok = False
|
||||
if 'phase' in vv:
|
||||
phase.add(vv['phase'])
|
||||
else:
|
||||
print(f'No phase specified in constituent {ii} of microstructure {i}')
|
||||
ok = False
|
||||
|
||||
for k,v in self['phase'].items():
|
||||
if 'lattice' not in v:
|
||||
print(f'No lattice specified in phase {k}')
|
||||
ok = False
|
||||
|
||||
#for k,v in self['homogenization'].items():
|
||||
# if 'N_constituents' not in v:
|
||||
# print(f'No. of constituents not specified in homogenization {k}'}
|
||||
# ok = False
|
||||
|
||||
if phase - set(self['phase']):
|
||||
print(f'Phase(s) {phase-set(self["phase"])} missing')
|
||||
ok = False
|
||||
if homogenization - set(self['homogenization']):
|
||||
print(f'Homogenization(s) {homogenization-set(self["homogenization"])} missing')
|
||||
ok = False
|
||||
|
||||
return ok
|
||||
|
||||
|
||||
@property
|
||||
def is_valid(self):
|
||||
"""Check for valid file layout."""
|
||||
ok = True
|
||||
|
||||
if 'phase' in self:
|
||||
for k,v in self['phase'].items():
|
||||
if 'lattice' in v:
|
||||
try:
|
||||
Lattice(v['lattice'])
|
||||
except KeyError:
|
||||
s = v['lattice']
|
||||
print(f"Invalid lattice: '{s}' in phase '{k}'")
|
||||
ok = False
|
||||
|
||||
if 'microstructure' in self:
|
||||
for i,v in enumerate(self['microstructure']):
|
||||
if 'constituents' in v:
|
||||
f = 0.0
|
||||
for c in v['constituents']:
|
||||
f+= float(c['fraction'])
|
||||
if 'orientation' in c:
|
||||
try:
|
||||
Rotation.from_quaternion(c['orientation'])
|
||||
except ValueError:
|
||||
o = c['orientation']
|
||||
print(f"Invalid orientation: '{o}' in microstructure '{i}'")
|
||||
ok = False
|
||||
if not np.isclose(f,1.0):
|
||||
print(f"Invalid total fraction '{f}' in microstructure '{i}'")
|
||||
ok = False
|
||||
|
||||
return ok
|
||||
|
||||
|
||||
def microstructure_rename_phase(self,mapping,ID=None,constituent=None):
|
||||
"""
|
||||
Change phase name in microstructure.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
mapping: dictionary
|
||||
Mapping from old name to new name
|
||||
ID: list of ints, optional
|
||||
Limit renaming to selected microstructure IDs.
|
||||
constituent: list of ints, optional
|
||||
Limit renaming to selected constituents.
|
||||
|
||||
"""
|
||||
dup = copy.deepcopy(self)
|
||||
for i,m in enumerate(dup['microstructure']):
|
||||
if ID and i not in ID: continue
|
||||
for c in m['constituents']:
|
||||
if constituent is not None and c not in constituent: continue
|
||||
try:
|
||||
c['phase'] = mapping[c['phase']]
|
||||
except KeyError:
|
||||
continue
|
||||
return dup
|
||||
|
||||
|
||||
def microstructure_rename_homogenization(self,mapping,ID=None):
|
||||
"""
|
||||
Change homogenization name in microstructure.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
mapping: dictionary
|
||||
Mapping from old name to new name
|
||||
ID: list of ints, optional
|
||||
Limit renaming to selected homogenization IDs.
|
||||
|
||||
"""
|
||||
dup = copy.deepcopy(self)
|
||||
for i,m in enumerate(dup['microstructure']):
|
||||
if ID and i not in ID: continue
|
||||
try:
|
||||
m['homogenization'] = mapping[m['homogenization']]
|
||||
except KeyError:
|
||||
continue
|
||||
return dup
|
|
@ -33,6 +33,10 @@ class Table:
|
|||
"""Brief overview."""
|
||||
return util.srepr(self.comments)+'\n'+self.data.__repr__()
|
||||
|
||||
def __len__(self):
|
||||
"""Number of rows."""
|
||||
return len(self.data)
|
||||
|
||||
def __copy__(self):
|
||||
"""Copy Table."""
|
||||
return copy.deepcopy(self)
|
||||
|
|
|
@ -1,33 +1,35 @@
|
|||
homogenization:
|
||||
SX:
|
||||
N_constituents: 2
|
||||
mech: {type: none}
|
||||
Taylor:
|
||||
mech: {type: isostrain, N_constituents: 2}
|
||||
N_constituents: 2
|
||||
mech: {type: isostrain}
|
||||
|
||||
microstructure:
|
||||
material:
|
||||
- constituents:
|
||||
- fraction: 1.0
|
||||
orientation: [1.0, 0.0, 0.0, 0.0]
|
||||
O: [1.0, 0.0, 0.0, 0.0]
|
||||
phase: Aluminum
|
||||
homogenization: SX
|
||||
- constituents:
|
||||
- fraction: 1.0
|
||||
orientation: [0.7936696712125002, -0.28765777461664166, -0.3436487135089419, 0.4113964260949434]
|
||||
O: [0.7936696712125002, -0.28765777461664166, -0.3436487135089419, 0.4113964260949434]
|
||||
phase: Aluminum
|
||||
homogenization: SX
|
||||
- constituents:
|
||||
- fraction: 1.0
|
||||
orientation: [0.3986143167493579, -0.7014883552495493, 0.2154871765709027, 0.5500781677772945]
|
||||
O: [0.3986143167493579, -0.7014883552495493, 0.2154871765709027, 0.5500781677772945]
|
||||
phase: Aluminum
|
||||
homogenization: SX
|
||||
- homogenization: Taylor
|
||||
constituents:
|
||||
- fraction: .5
|
||||
orientation: [0.28645844315788244, -0.022571491243423537, -0.467933059311115, -0.8357456192708106]
|
||||
- constituents:
|
||||
- fraction: 0.5
|
||||
O: [0.28645844315788244, -0.022571491243423537, -0.467933059311115, -0.8357456192708106]
|
||||
phase: Aluminum
|
||||
- fraction: .5
|
||||
orientation: [0.3986143167493579, -0.7014883552495493, 0.2154871765709027, 0.5500781677772945]
|
||||
- fraction: 0.5
|
||||
O: [0.3986143167493579, -0.7014883552495493, 0.2154871765709027, 0.5500781677772945]
|
||||
phase: Steel
|
||||
homogenization: Taylor
|
||||
|
||||
phase:
|
||||
Aluminum:
|
|
@ -0,0 +1,37 @@
|
|||
import pytest
|
||||
|
||||
from damask import Config
|
||||
|
||||
class TestConfig:
|
||||
|
||||
@pytest.mark.parametrize('flow_style',[None,True,False])
|
||||
def test_load_save_str(self,tmp_path,flow_style):
|
||||
config = Config()
|
||||
config['A'] = 1
|
||||
config['B'] = [2,3]
|
||||
config.save(tmp_path/'config.yaml',default_flow_style=flow_style)
|
||||
assert Config.load(tmp_path/'config.yaml') == config
|
||||
|
||||
def test_load_save_file(self,tmp_path):
|
||||
config = Config()
|
||||
config['A'] = 1
|
||||
config['B'] = [2,3]
|
||||
with open(tmp_path/'config.yaml','w') as f:
|
||||
config.save(f)
|
||||
with open(tmp_path/'config.yaml') as f:
|
||||
assert Config.load(f) == config
|
||||
|
||||
def test_repr(self,tmp_path):
|
||||
config = Config()
|
||||
config['A'] = 1
|
||||
config['B'] = [2,3]
|
||||
with open(tmp_path/'config.yaml','w') as f:
|
||||
f.write(config.__repr__())
|
||||
assert Config.load(tmp_path/'config.yaml') == config
|
||||
|
||||
|
||||
def test_abstract_is_valid(self):
|
||||
assert Config().is_valid is None
|
||||
|
||||
def test_abstract_is_complete(self):
|
||||
assert Config().is_complete is None
|
|
@ -0,0 +1,76 @@
|
|||
import os
|
||||
|
||||
import pytest
|
||||
|
||||
from damask import ConfigMaterial
|
||||
|
||||
@pytest.fixture
|
||||
def reference_dir(reference_dir_base):
|
||||
"""Directory containing reference results."""
|
||||
return reference_dir_base/'ConfigMaterial'
|
||||
|
||||
|
||||
class TestConfigMaterial:
|
||||
|
||||
@pytest.mark.parametrize('fname',[None,'test.yaml'])
|
||||
def test_load_save(self,reference_dir,tmp_path,fname):
|
||||
reference = ConfigMaterial.load(reference_dir/'material.yaml')
|
||||
os.chdir(tmp_path)
|
||||
if fname is None:
|
||||
reference.save()
|
||||
new = ConfigMaterial.load('material.yaml')
|
||||
else:
|
||||
reference.save(fname)
|
||||
new = ConfigMaterial.load(fname)
|
||||
assert reference == new
|
||||
|
||||
def test_valid_complete(self,reference_dir):
|
||||
material_config = ConfigMaterial.load(reference_dir/'material.yaml')
|
||||
assert material_config.is_valid and material_config.is_complete
|
||||
|
||||
def test_invalid_lattice(self,reference_dir):
|
||||
material_config = ConfigMaterial.load(reference_dir/'material.yaml')
|
||||
material_config['phase']['Aluminum']['lattice']='fxc'
|
||||
assert not material_config.is_valid
|
||||
|
||||
def test_invalid_orientation(self,reference_dir):
|
||||
material_config = ConfigMaterial.load(reference_dir/'material.yaml')
|
||||
material_config['material'][0]['constituents'][0]['O']=[0,0,0,0]
|
||||
assert not material_config.is_valid
|
||||
|
||||
def test_invalid_fraction(self,reference_dir):
|
||||
material_config = ConfigMaterial.load(reference_dir/'material.yaml')
|
||||
material_config['material'][0]['constituents'][0]['fraction']=.9
|
||||
assert not material_config.is_valid
|
||||
|
||||
@pytest.mark.parametrize('item',['homogenization','phase','material'])
|
||||
def test_incomplete_missing(self,reference_dir,item):
|
||||
material_config = ConfigMaterial.load(reference_dir/'material.yaml')
|
||||
del material_config[item]
|
||||
assert not material_config.is_complete
|
||||
|
||||
@pytest.mark.parametrize('item',['O','phase'])
|
||||
def test_incomplete_material_constituent(self,reference_dir,item):
|
||||
material_config = ConfigMaterial.load(reference_dir/'material.yaml')
|
||||
del material_config['material'][0]['constituents'][0][item]
|
||||
assert not material_config.is_complete
|
||||
|
||||
def test_incomplete_material_homogenization(self,reference_dir):
|
||||
material_config = ConfigMaterial.load(reference_dir/'material.yaml')
|
||||
del material_config['material'][0]['homogenization']
|
||||
assert not material_config.is_complete
|
||||
|
||||
def test_incomplete_phase_lattice(self,reference_dir):
|
||||
material_config = ConfigMaterial.load(reference_dir/'material.yaml')
|
||||
del material_config['phase']['Aluminum']['lattice']
|
||||
assert not material_config.is_complete
|
||||
|
||||
def test_incomplete_wrong_phase(self,reference_dir):
|
||||
material_config = ConfigMaterial.load(reference_dir/'material.yaml')
|
||||
new = material_config.material_rename_phase({'Steel':'FeNbC'})
|
||||
assert not new.is_complete
|
||||
|
||||
def test_incomplete_wrong_homogenization(self,reference_dir):
|
||||
material_config = ConfigMaterial.load(reference_dir/'material.yaml')
|
||||
new = material_config.material_rename_homogenization({'Taylor':'isostrain'})
|
||||
assert not new.is_complete
|
|
@ -1,61 +0,0 @@
|
|||
import os
|
||||
|
||||
import pytest
|
||||
|
||||
from damask import Material
|
||||
|
||||
@pytest.fixture
|
||||
def reference_dir(reference_dir_base):
|
||||
"""Directory containing reference results."""
|
||||
return reference_dir_base/'Material'
|
||||
|
||||
|
||||
class TestMaterial:
|
||||
|
||||
@pytest.mark.parametrize('fname',[None,'test.yaml'])
|
||||
def test_load_save(self,reference_dir,tmp_path,fname):
|
||||
reference = Material.load(reference_dir/'material.yaml')
|
||||
os.chdir(tmp_path)
|
||||
if fname is None:
|
||||
reference.save()
|
||||
new = Material.load('material.yaml')
|
||||
else:
|
||||
reference.save(fname)
|
||||
new = Material.load(fname)
|
||||
assert reference == new
|
||||
|
||||
def test_valid_complete(self,reference_dir):
|
||||
material_config = Material.load(reference_dir/'material.yaml')
|
||||
assert material_config.is_valid and material_config.is_complete
|
||||
|
||||
def test_invalid_lattice(self,reference_dir):
|
||||
material_config = Material.load(reference_dir/'material.yaml')
|
||||
material_config['phase']['Aluminum']['lattice']='fxc'
|
||||
assert not material_config.is_valid
|
||||
|
||||
def test_invalid_orientation(self,reference_dir):
|
||||
material_config = Material.load(reference_dir/'material.yaml')
|
||||
material_config['microstructure'][0]['constituents'][0]['orientation']=[0,0,0,0]
|
||||
assert not material_config.is_valid
|
||||
|
||||
def test_invalid_fraction(self,reference_dir):
|
||||
material_config = Material.load(reference_dir/'material.yaml')
|
||||
material_config['microstructure'][0]['constituents'][0]['fraction']=.9
|
||||
assert not material_config.is_valid
|
||||
|
||||
|
||||
@pytest.mark.parametrize('item',['homogenization','phase','microstructure'])
|
||||
def test_incomplete_missing(self,reference_dir,item):
|
||||
material_config = Material.load(reference_dir/'material.yaml')
|
||||
del material_config[item]
|
||||
assert not material_config.is_complete
|
||||
|
||||
def test_incomplete_wrong_phase(self,reference_dir):
|
||||
material_config = Material.load(reference_dir/'material.yaml')
|
||||
new = material_config.microstructure_rename_phase({'Steel':'FeNbC'})
|
||||
assert not new.is_complete
|
||||
|
||||
def test_incomplete_wrong_homogenization(self,reference_dir):
|
||||
material_config = Material.load(reference_dir/'material.yaml')
|
||||
new = material_config.microstructure_rename_homogenization({'Taylor':'isostrain'})
|
||||
assert not new.is_complete
|
|
@ -220,13 +220,26 @@ logical function isKey(line)
|
|||
if(len(IO_rmComment(line)) == 0) then
|
||||
isKey = .false.
|
||||
else
|
||||
isKey = IO_rmComment(line(len(IO_rmComment(line)):len(IO_rmComment(line)))) == ':' &
|
||||
.and. .not. isFlow(line)
|
||||
isKey = index(IO_rmComment(line),':',back=.false.) == len(IO_rmComment(line)) .and. &
|
||||
index(IO_rmComment(line),':',back=.true.) == len(IO_rmComment(line)) .and. &
|
||||
.not. isFlow(line)
|
||||
endif
|
||||
|
||||
end function isKey
|
||||
|
||||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! @brief check whether a string is a list in flow style
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
logical function isFlowList(line)
|
||||
|
||||
character(len=*), intent(in) :: line
|
||||
|
||||
isFlowList = index(adjustl(line),'[') == 1
|
||||
|
||||
end function isFlowList
|
||||
|
||||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! @brief skip empty lines
|
||||
! @details update start position in the block by skipping empty lines if present.
|
||||
|
@ -244,7 +257,6 @@ subroutine skip_empty_lines(blck,s_blck)
|
|||
if(empty) s_blck = s_blck + index(blck(s_blck:),IO_EOL)
|
||||
enddo
|
||||
|
||||
|
||||
end subroutine skip_empty_lines
|
||||
|
||||
|
||||
|
@ -273,6 +285,58 @@ subroutine skip_file_header(blck,s_blck)
|
|||
end subroutine skip_file_header
|
||||
|
||||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
!> @brief check if a line in flow YAML starts and ends in the same line
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
logical function flow_is_closed(str,e_char)
|
||||
|
||||
character(len=*), intent(in) :: str
|
||||
character, intent(in) :: e_char !< end of list/dict ( '}' or ']')
|
||||
integer :: N_sq, & !< number of open square brackets
|
||||
N_cu, & !< number of open curly brackets
|
||||
i
|
||||
character(len=:), allocatable:: line
|
||||
|
||||
flow_is_closed = .false.
|
||||
N_sq = 0
|
||||
N_cu = 0
|
||||
if(e_char == ']') line = str(index(str(:),'[')+1:)
|
||||
if(e_char == '}') line = str(index(str(:),'{')+1:)
|
||||
|
||||
do i = 1, len_trim(line)
|
||||
flow_is_closed = (N_sq==0 .and. N_cu==0 .and. scan(line(i:i),e_char) == 1)
|
||||
N_sq = N_sq + merge(1,0,line(i:i) == '[')
|
||||
N_cu = N_cu + merge(1,0,line(i:i) == '{')
|
||||
N_sq = N_sq - merge(1,0,line(i:i) == ']')
|
||||
N_cu = N_cu - merge(1,0,line(i:i) == '}')
|
||||
enddo
|
||||
|
||||
end function flow_is_closed
|
||||
|
||||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
!> @brief return the flow YAML line without line break
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
subroutine remove_line_break(blck,s_blck,e_char,flow_line)
|
||||
|
||||
character(len=*), intent(in) :: blck !< YAML in mixed style
|
||||
integer, intent(inout) :: s_blck
|
||||
character, intent(in) :: e_char !< end of list/dict ( '}' or ']')
|
||||
character(len=:), allocatable, intent(out) :: flow_line
|
||||
logical :: line_end
|
||||
|
||||
line_end =.false.
|
||||
flow_line = ''
|
||||
|
||||
do while(.not.line_end)
|
||||
flow_line = flow_line//IO_rmComment(blck(s_blck:s_blck + index(blck(s_blck:),IO_EOL) - 2))//' '
|
||||
line_end = flow_is_closed(flow_line,e_char)
|
||||
s_blck = s_blck + index(blck(s_blck:),IO_EOL)
|
||||
enddo
|
||||
|
||||
end subroutine remove_line_break
|
||||
|
||||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! @brief reads a line of YAML block which is already in flow style
|
||||
! @details Dicts should be enlcosed within '{}' for it to be consistent with DAMASK YAML parser
|
||||
|
@ -402,7 +466,7 @@ recursive subroutine lst(blck,flow,s_blck,s_flow,offset)
|
|||
integer, intent(inout) :: s_blck, & !< start position in blck
|
||||
s_flow, & !< start position in flow
|
||||
offset !< stores leading '- ' in nested lists
|
||||
character(len=:), allocatable :: line
|
||||
character(len=:), allocatable :: line,flow_line
|
||||
integer :: e_blck,indent
|
||||
|
||||
indent = indentDepth(blck(s_blck:),offset)
|
||||
|
@ -437,8 +501,12 @@ recursive subroutine lst(blck,flow,s_blck,s_flow,offset)
|
|||
s_blck = e_blck +2
|
||||
offset = 0
|
||||
elseif(isFlow(line)) then
|
||||
call line_isFlow(flow,s_flow,line)
|
||||
s_blck = e_blck +2
|
||||
if(isFlowList(line)) then
|
||||
call remove_line_break(blck,s_blck,']',flow_line)
|
||||
else
|
||||
call remove_line_break(blck,s_blck,'}',flow_line)
|
||||
endif
|
||||
call line_isFlow(flow,s_flow,flow_line)
|
||||
offset = 0
|
||||
endif
|
||||
else ! list item in the same line
|
||||
|
@ -448,8 +516,13 @@ recursive subroutine lst(blck,flow,s_blck,s_flow,offset)
|
|||
s_blck = e_blck +2
|
||||
offset = 0
|
||||
elseif(isFlow(line)) then
|
||||
call line_isFlow(flow,s_flow,line)
|
||||
s_blck = e_blck +2
|
||||
s_blck = s_blck + index(blck(s_blck:),'-')
|
||||
if(isFlowList(line)) then
|
||||
call remove_line_break(blck,s_blck,']',flow_line)
|
||||
else
|
||||
call remove_line_break(blck,s_blck,'}',flow_line)
|
||||
endif
|
||||
call line_isFlow(flow,s_flow,flow_line)
|
||||
offset = 0
|
||||
else ! non scalar list item
|
||||
offset = offset + indentDepth(blck(s_blck:))+1 ! offset in spaces to be ignored
|
||||
|
@ -486,8 +559,8 @@ recursive subroutine dct(blck,flow,s_blck,s_flow,offset)
|
|||
s_flow, & !< start position in flow
|
||||
offset
|
||||
|
||||
character(len=:), allocatable :: line
|
||||
integer :: e_blck,indent
|
||||
character(len=:), allocatable :: line,flow_line
|
||||
integer :: e_blck,indent,col_pos
|
||||
logical :: previous_isKey
|
||||
|
||||
previous_isKey = .false.
|
||||
|
@ -521,13 +594,23 @@ recursive subroutine dct(blck,flow,s_blck,s_flow,offset)
|
|||
endif
|
||||
|
||||
if(isKeyValue(line)) then
|
||||
col_pos = index(line,':')
|
||||
if(isFlow(line(col_pos+1:))) then
|
||||
if(isFlowList(line(col_pos+1:))) then
|
||||
call remove_line_break(blck,s_blck,']',flow_line)
|
||||
else
|
||||
call remove_line_break(blck,s_blck,'}',flow_line)
|
||||
endif
|
||||
call keyValue_toFlow(flow,s_flow,flow_line)
|
||||
else
|
||||
call keyValue_toFlow(flow,s_flow,line)
|
||||
s_blck = e_blck + 2
|
||||
endif
|
||||
else
|
||||
call line_toFlow(flow,s_flow,line)
|
||||
endif
|
||||
|
||||
s_blck = e_blck + 2
|
||||
endif
|
||||
end if
|
||||
|
||||
if(isScalar(line) .or. isKeyValue(line)) then
|
||||
flow(s_flow:s_flow) = ','
|
||||
|
@ -559,7 +642,7 @@ recursive subroutine decide(blck,flow,s_blck,s_flow,offset)
|
|||
s_flow, & !< start position in flow
|
||||
offset
|
||||
integer :: e_blck
|
||||
character(len=:), allocatable :: line
|
||||
character(len=:), allocatable :: line,flow_line
|
||||
|
||||
if(s_blck <= len(blck)) then
|
||||
call skip_empty_lines(blck,s_blck)
|
||||
|
@ -583,8 +666,12 @@ recursive subroutine decide(blck,flow,s_blck,s_flow,offset)
|
|||
flow(s_flow:s_flow) = '}'
|
||||
s_flow = s_flow + 1
|
||||
elseif(isFlow(line)) then
|
||||
if(isFlowList(line)) then
|
||||
call remove_line_break(blck,s_blck,']',flow_line)
|
||||
else
|
||||
call remove_line_break(blck,s_blck,'}',flow_line)
|
||||
endif
|
||||
call line_isFlow(flow,s_flow,line)
|
||||
s_blck = e_blck +2
|
||||
else
|
||||
line = line(indentDepth(line)+1:)
|
||||
call line_toFlow(flow,s_flow,line)
|
||||
|
@ -723,6 +810,36 @@ subroutine selfTest
|
|||
if (.not. to_flow(flow_mixed_braces) == flow) error stop 'to_flow'
|
||||
end block basic_flow
|
||||
|
||||
multi_line_flow1: block
|
||||
character(len=*), parameter :: flow_multi = &
|
||||
"%YAML 1.1"//IO_EOL//&
|
||||
"---"//IO_EOL//&
|
||||
"a: [b,"//IO_EOL//&
|
||||
"c: "//IO_EOL//&
|
||||
"d, e]"//IO_EOL
|
||||
|
||||
character(len=*), parameter :: flow = &
|
||||
"{a: [b, {c: d}, e]}"
|
||||
|
||||
if( .not. to_flow(flow_multi) == flow) error stop 'to_flow'
|
||||
end block multi_line_flow1
|
||||
|
||||
multi_line_flow2: block
|
||||
character(len=*), parameter :: flow_multi = &
|
||||
"%YAML 1.1"//IO_EOL//&
|
||||
"---"//IO_EOL//&
|
||||
"-"//IO_EOL//&
|
||||
" a: {b:"//IO_EOL//&
|
||||
"[c,"//IO_EOL//&
|
||||
"d"//IO_EOL//&
|
||||
"e, f]}"//IO_EOL
|
||||
|
||||
character(len=*), parameter :: flow = &
|
||||
"[{a: {b: [c, d e, f]}}]"
|
||||
|
||||
if( .not. to_flow(flow_multi) == flow) error stop 'to_flow'
|
||||
end block multi_line_flow2
|
||||
|
||||
basic_mixed: block
|
||||
character(len=*), parameter :: block_flow = &
|
||||
"%YAML 1.1"//IO_EOL//&
|
||||
|
|
|
@ -952,6 +952,9 @@ function tNode_get_byKey_asIndex(self,key) result(keyIndex)
|
|||
endif
|
||||
enddo
|
||||
|
||||
if(keyIndex == -1) call IO_error(140,ext_msg=key)
|
||||
|
||||
|
||||
end function tNode_get_byKey_asIndex
|
||||
|
||||
|
||||
|
|
|
@ -452,11 +452,11 @@ subroutine constitutive_init
|
|||
PhaseLoop2:do p = 1,phases%length
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! partition and initialize state
|
||||
plasticState(p)%partionedState0 = plasticState(p)%state0
|
||||
plasticState(p)%state = plasticState(p)%partionedState0
|
||||
plasticState(p)%partitionedState0 = plasticState(p)%state0
|
||||
plasticState(p)%state = plasticState(p)%partitionedState0
|
||||
forall(s = 1:phase_Nsources(p))
|
||||
sourceState(p)%p(s)%partionedState0 = sourceState(p)%p(s)%state0
|
||||
sourceState(p)%p(s)%state = sourceState(p)%p(s)%partionedState0
|
||||
sourceState(p)%p(s)%partitionedState0 = sourceState(p)%p(s)%state0
|
||||
sourceState(p)%p(s)%state = sourceState(p)%p(s)%partitionedState0
|
||||
end forall
|
||||
|
||||
constitutive_source_maxSizeDotState = max(constitutive_source_maxSizeDotState, &
|
||||
|
@ -922,7 +922,7 @@ subroutine constitutive_allocateState(state, &
|
|||
|
||||
allocate(state%atol (sizeState), source=0.0_pReal)
|
||||
allocate(state%state0 (sizeState,NipcMyPhase), source=0.0_pReal)
|
||||
allocate(state%partionedState0(sizeState,NipcMyPhase), source=0.0_pReal)
|
||||
allocate(state%partitionedState0(sizeState,NipcMyPhase), source=0.0_pReal)
|
||||
allocate(state%subState0 (sizeState,NipcMyPhase), source=0.0_pReal)
|
||||
allocate(state%state (sizeState,NipcMyPhase), source=0.0_pReal)
|
||||
|
||||
|
|
|
@ -44,30 +44,30 @@ module crystallite
|
|||
!
|
||||
crystallite_Fp, & !< current plastic def grad (end of converged time step)
|
||||
crystallite_Fp0, & !< plastic def grad at start of FE inc
|
||||
crystallite_partionedFp0,& !< plastic def grad at start of homog inc
|
||||
crystallite_partitionedFp0,& !< plastic def grad at start of homog inc
|
||||
crystallite_subFp0,& !< plastic def grad at start of crystallite inc
|
||||
!
|
||||
crystallite_Fi, & !< current intermediate def grad (end of converged time step)
|
||||
crystallite_Fi0, & !< intermediate def grad at start of FE inc
|
||||
crystallite_partionedFi0,& !< intermediate def grad at start of homog inc
|
||||
crystallite_partitionedFi0,& !< intermediate def grad at start of homog inc
|
||||
crystallite_subFi0,& !< intermediate def grad at start of crystallite inc
|
||||
!
|
||||
crystallite_Lp0, & !< plastic velocitiy grad at start of FE inc
|
||||
crystallite_partionedLp0, & !< plastic velocity grad at start of homog inc
|
||||
crystallite_partitionedLp0, & !< plastic velocity grad at start of homog inc
|
||||
!
|
||||
crystallite_Li, & !< current intermediate velocitiy grad (end of converged time step)
|
||||
crystallite_Li0, & !< intermediate velocitiy grad at start of FE inc
|
||||
crystallite_partionedLi0, & !< intermediate velocity grad at start of homog inc
|
||||
crystallite_partitionedLi0, & !< intermediate velocity grad at start of homog inc
|
||||
!
|
||||
crystallite_S0, & !< 2nd Piola-Kirchhoff stress vector at start of FE inc
|
||||
crystallite_partionedS0 !< 2nd Piola-Kirchhoff stress vector at start of homog inc
|
||||
crystallite_partitionedS0 !< 2nd Piola-Kirchhoff stress vector at start of homog inc
|
||||
real(pReal), dimension(:,:,:,:,:), allocatable, public, protected :: &
|
||||
crystallite_P, & !< 1st Piola-Kirchhoff stress per grain
|
||||
crystallite_Lp, & !< current plastic velocitiy grad (end of converged time step)
|
||||
crystallite_S, & !< current 2nd Piola-Kirchhoff stress vector (end of converged time step)
|
||||
crystallite_partionedF0 !< def grad at start of homog inc
|
||||
crystallite_partitionedF0 !< def grad at start of homog inc
|
||||
real(pReal), dimension(:,:,:,:,:), allocatable, public :: &
|
||||
crystallite_partionedF !< def grad to be reached at end of homog inc
|
||||
crystallite_partitionedF !< def grad to be reached at end of homog inc
|
||||
|
||||
logical, dimension(:,:,:), allocatable, public :: &
|
||||
crystallite_requested !< used by upper level (homogenization) to request crystallite calculation
|
||||
|
@ -166,20 +166,20 @@ subroutine crystallite_init
|
|||
iMax = discretization_nIP
|
||||
eMax = discretization_nElem
|
||||
|
||||
allocate(crystallite_partionedF(3,3,cMax,iMax,eMax),source=0.0_pReal)
|
||||
allocate(crystallite_partitionedF(3,3,cMax,iMax,eMax),source=0.0_pReal)
|
||||
|
||||
allocate(crystallite_S0, &
|
||||
crystallite_F0, crystallite_Fi0,crystallite_Fp0, &
|
||||
crystallite_Li0,crystallite_Lp0, &
|
||||
crystallite_partionedS0, &
|
||||
crystallite_partionedF0,crystallite_partionedFp0,crystallite_partionedFi0, &
|
||||
crystallite_partionedLp0,crystallite_partionedLi0, &
|
||||
crystallite_partitionedS0, &
|
||||
crystallite_partitionedF0,crystallite_partitionedFp0,crystallite_partitionedFi0, &
|
||||
crystallite_partitionedLp0,crystallite_partitionedLi0, &
|
||||
crystallite_S,crystallite_P, &
|
||||
crystallite_Fe,crystallite_Fi,crystallite_Fp, &
|
||||
crystallite_Li,crystallite_Lp, &
|
||||
crystallite_subF,crystallite_subF0, &
|
||||
crystallite_subFp0,crystallite_subFi0, &
|
||||
source = crystallite_partionedF)
|
||||
source = crystallite_partitionedF)
|
||||
|
||||
allocate(crystallite_dt(cMax,iMax,eMax),source=0.0_pReal)
|
||||
allocate(crystallite_subdt,crystallite_subFrac,crystallite_subStep, &
|
||||
|
@ -269,10 +269,10 @@ subroutine crystallite_init
|
|||
!$OMP END PARALLEL DO
|
||||
|
||||
|
||||
crystallite_partionedFp0 = crystallite_Fp0
|
||||
crystallite_partionedFi0 = crystallite_Fi0
|
||||
crystallite_partionedF0 = crystallite_F0
|
||||
crystallite_partionedF = crystallite_F0
|
||||
crystallite_partitionedFp0 = crystallite_Fp0
|
||||
crystallite_partitionedFi0 = crystallite_Fi0
|
||||
crystallite_partitionedF0 = crystallite_F0
|
||||
crystallite_partitionedF = crystallite_F0
|
||||
|
||||
call crystallite_orientations()
|
||||
|
||||
|
@ -280,8 +280,8 @@ subroutine crystallite_init
|
|||
do e = FEsolving_execElem(1),FEsolving_execElem(2)
|
||||
do i = FEsolving_execIP(1),FEsolving_execIP(2)
|
||||
do c = 1,homogenization_Ngrains(material_homogenizationAt(e))
|
||||
call constitutive_dependentState(crystallite_partionedF0(1:3,1:3,c,i,e), &
|
||||
crystallite_partionedFp0(1:3,1:3,c,i,e), &
|
||||
call constitutive_dependentState(crystallite_partitionedF0(1:3,1:3,c,i,e), &
|
||||
crystallite_partitionedFp0(1:3,1:3,c,i,e), &
|
||||
c,i,e) ! update dependent state variables to be consistent with basic states
|
||||
enddo
|
||||
enddo
|
||||
|
@ -325,8 +325,8 @@ function crystallite_stress()
|
|||
|
||||
todo = .false.
|
||||
|
||||
subLp0 = crystallite_partionedLp0
|
||||
subLi0 = crystallite_partionedLi0
|
||||
subLp0 = crystallite_partitionedLp0
|
||||
subLi0 = crystallite_partitionedLi0
|
||||
|
||||
|
||||
|
||||
|
@ -338,15 +338,15 @@ function crystallite_stress()
|
|||
do i = FEsolving_execIP(1),FEsolving_execIP(2); do c = 1,homogenization_Ngrains(material_homogenizationAt(e))
|
||||
homogenizationRequestsCalculation: if (crystallite_requested(c,i,e)) then
|
||||
plasticState (material_phaseAt(c,e))%subState0( :,material_phaseMemberAt(c,i,e)) = &
|
||||
plasticState (material_phaseAt(c,e))%partionedState0(:,material_phaseMemberAt(c,i,e))
|
||||
plasticState (material_phaseAt(c,e))%partitionedState0(:,material_phaseMemberAt(c,i,e))
|
||||
|
||||
do s = 1, phase_Nsources(material_phaseAt(c,e))
|
||||
sourceState(material_phaseAt(c,e))%p(s)%subState0( :,material_phaseMemberAt(c,i,e)) = &
|
||||
sourceState(material_phaseAt(c,e))%p(s)%partionedState0(:,material_phaseMemberAt(c,i,e))
|
||||
sourceState(material_phaseAt(c,e))%p(s)%partitionedState0(:,material_phaseMemberAt(c,i,e))
|
||||
enddo
|
||||
crystallite_subFp0(1:3,1:3,c,i,e) = crystallite_partionedFp0(1:3,1:3,c,i,e)
|
||||
crystallite_subFi0(1:3,1:3,c,i,e) = crystallite_partionedFi0(1:3,1:3,c,i,e)
|
||||
crystallite_subF0(1:3,1:3,c,i,e) = crystallite_partionedF0(1:3,1:3,c,i,e)
|
||||
crystallite_subFp0(1:3,1:3,c,i,e) = crystallite_partitionedFp0(1:3,1:3,c,i,e)
|
||||
crystallite_subFi0(1:3,1:3,c,i,e) = crystallite_partitionedFi0(1:3,1:3,c,i,e)
|
||||
crystallite_subF0(1:3,1:3,c,i,e) = crystallite_partitionedF0(1:3,1:3,c,i,e)
|
||||
crystallite_subFrac(c,i,e) = 0.0_pReal
|
||||
crystallite_subStep(c,i,e) = 1.0_pReal/num%subStepSizeCryst
|
||||
todo(c,i,e) = .true.
|
||||
|
@ -426,8 +426,8 @@ function crystallite_stress()
|
|||
! prepare for integration
|
||||
if (todo(c,i,e)) then
|
||||
crystallite_subF(1:3,1:3,c,i,e) = crystallite_subF0(1:3,1:3,c,i,e) &
|
||||
+ crystallite_subStep(c,i,e) *( crystallite_partionedF (1:3,1:3,c,i,e) &
|
||||
-crystallite_partionedF0(1:3,1:3,c,i,e))
|
||||
+ crystallite_subStep(c,i,e) *( crystallite_partitionedF (1:3,1:3,c,i,e) &
|
||||
-crystallite_partitionedF0(1:3,1:3,c,i,e))
|
||||
crystallite_Fe(1:3,1:3,c,i,e) = matmul(matmul(crystallite_subF(1:3,1:3,c,i,e), &
|
||||
math_inv33(crystallite_Fp(1:3,1:3,c,i,e))), &
|
||||
math_inv33(crystallite_Fi(1:3,1:3,c,i,e)))
|
||||
|
@ -441,8 +441,6 @@ function crystallite_stress()
|
|||
enddo elementLooping3
|
||||
!$OMP END PARALLEL DO
|
||||
|
||||
call nonlocalConvergenceCheck
|
||||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! integrate --- requires fully defined state array (basic + dependent state)
|
||||
where(.not. crystallite_converged .and. crystallite_subStep > num%subStepMinCryst) & ! do not try non-converged but fully cutbacked any further
|
||||
|
@ -475,17 +473,17 @@ subroutine crystallite_initializeRestorationPoints(i,e)
|
|||
s
|
||||
|
||||
do c = 1,homogenization_Ngrains(material_homogenizationAt(e))
|
||||
crystallite_partionedFp0(1:3,1:3,c,i,e) = crystallite_Fp0(1:3,1:3,c,i,e)
|
||||
crystallite_partionedLp0(1:3,1:3,c,i,e) = crystallite_Lp0(1:3,1:3,c,i,e)
|
||||
crystallite_partionedFi0(1:3,1:3,c,i,e) = crystallite_Fi0(1:3,1:3,c,i,e)
|
||||
crystallite_partionedLi0(1:3,1:3,c,i,e) = crystallite_Li0(1:3,1:3,c,i,e)
|
||||
crystallite_partionedF0(1:3,1:3,c,i,e) = crystallite_F0(1:3,1:3,c,i,e)
|
||||
crystallite_partionedS0(1:3,1:3,c,i,e) = crystallite_S0(1:3,1:3,c,i,e)
|
||||
crystallite_partitionedFp0(1:3,1:3,c,i,e) = crystallite_Fp0(1:3,1:3,c,i,e)
|
||||
crystallite_partitionedLp0(1:3,1:3,c,i,e) = crystallite_Lp0(1:3,1:3,c,i,e)
|
||||
crystallite_partitionedFi0(1:3,1:3,c,i,e) = crystallite_Fi0(1:3,1:3,c,i,e)
|
||||
crystallite_partitionedLi0(1:3,1:3,c,i,e) = crystallite_Li0(1:3,1:3,c,i,e)
|
||||
crystallite_partitionedF0(1:3,1:3,c,i,e) = crystallite_F0(1:3,1:3,c,i,e)
|
||||
crystallite_partitionedS0(1:3,1:3,c,i,e) = crystallite_S0(1:3,1:3,c,i,e)
|
||||
|
||||
plasticState(material_phaseAt(c,e))%partionedState0(:,material_phasememberAt(c,i,e)) = &
|
||||
plasticState(material_phaseAt(c,e))%partitionedState0(:,material_phasememberAt(c,i,e)) = &
|
||||
plasticState(material_phaseAt(c,e))%state0( :,material_phasememberAt(c,i,e))
|
||||
do s = 1, phase_Nsources(material_phaseAt(c,e))
|
||||
sourceState(material_phaseAt(c,e))%p(s)%partionedState0(:,material_phasememberAt(c,i,e)) = &
|
||||
sourceState(material_phaseAt(c,e))%p(s)%partitionedState0(:,material_phasememberAt(c,i,e)) = &
|
||||
sourceState(material_phaseAt(c,e))%p(s)%state0( :,material_phasememberAt(c,i,e))
|
||||
enddo
|
||||
enddo
|
||||
|
@ -506,17 +504,17 @@ subroutine crystallite_windForward(i,e)
|
|||
s
|
||||
|
||||
do c = 1,homogenization_Ngrains(material_homogenizationAt(e))
|
||||
crystallite_partionedF0 (1:3,1:3,c,i,e) = crystallite_partionedF(1:3,1:3,c,i,e)
|
||||
crystallite_partionedFp0(1:3,1:3,c,i,e) = crystallite_Fp (1:3,1:3,c,i,e)
|
||||
crystallite_partionedLp0(1:3,1:3,c,i,e) = crystallite_Lp (1:3,1:3,c,i,e)
|
||||
crystallite_partionedFi0(1:3,1:3,c,i,e) = crystallite_Fi (1:3,1:3,c,i,e)
|
||||
crystallite_partionedLi0(1:3,1:3,c,i,e) = crystallite_Li (1:3,1:3,c,i,e)
|
||||
crystallite_partionedS0 (1:3,1:3,c,i,e) = crystallite_S (1:3,1:3,c,i,e)
|
||||
crystallite_partitionedF0 (1:3,1:3,c,i,e) = crystallite_partitionedF(1:3,1:3,c,i,e)
|
||||
crystallite_partitionedFp0(1:3,1:3,c,i,e) = crystallite_Fp (1:3,1:3,c,i,e)
|
||||
crystallite_partitionedLp0(1:3,1:3,c,i,e) = crystallite_Lp (1:3,1:3,c,i,e)
|
||||
crystallite_partitionedFi0(1:3,1:3,c,i,e) = crystallite_Fi (1:3,1:3,c,i,e)
|
||||
crystallite_partitionedLi0(1:3,1:3,c,i,e) = crystallite_Li (1:3,1:3,c,i,e)
|
||||
crystallite_partitionedS0 (1:3,1:3,c,i,e) = crystallite_S (1:3,1:3,c,i,e)
|
||||
|
||||
plasticState (material_phaseAt(c,e))%partionedState0(:,material_phasememberAt(c,i,e)) = &
|
||||
plasticState (material_phaseAt(c,e))%partitionedState0(:,material_phasememberAt(c,i,e)) = &
|
||||
plasticState (material_phaseAt(c,e))%state (:,material_phasememberAt(c,i,e))
|
||||
do s = 1, phase_Nsources(material_phaseAt(c,e))
|
||||
sourceState(material_phaseAt(c,e))%p(s)%partionedState0(:,material_phasememberAt(c,i,e)) = &
|
||||
sourceState(material_phaseAt(c,e))%p(s)%partitionedState0(:,material_phasememberAt(c,i,e)) = &
|
||||
sourceState(material_phaseAt(c,e))%p(s)%state (:,material_phasememberAt(c,i,e))
|
||||
enddo
|
||||
enddo
|
||||
|
@ -540,18 +538,18 @@ subroutine crystallite_restore(i,e,includeL)
|
|||
|
||||
do c = 1,homogenization_Ngrains(material_homogenizationAt(e))
|
||||
if (includeL) then
|
||||
crystallite_Lp(1:3,1:3,c,i,e) = crystallite_partionedLp0(1:3,1:3,c,i,e)
|
||||
crystallite_Li(1:3,1:3,c,i,e) = crystallite_partionedLi0(1:3,1:3,c,i,e)
|
||||
crystallite_Lp(1:3,1:3,c,i,e) = crystallite_partitionedLp0(1:3,1:3,c,i,e)
|
||||
crystallite_Li(1:3,1:3,c,i,e) = crystallite_partitionedLi0(1:3,1:3,c,i,e)
|
||||
endif ! maybe protecting everything from overwriting makes more sense
|
||||
crystallite_Fp(1:3,1:3,c,i,e) = crystallite_partionedFp0(1:3,1:3,c,i,e)
|
||||
crystallite_Fi(1:3,1:3,c,i,e) = crystallite_partionedFi0(1:3,1:3,c,i,e)
|
||||
crystallite_S (1:3,1:3,c,i,e) = crystallite_partionedS0 (1:3,1:3,c,i,e)
|
||||
crystallite_Fp(1:3,1:3,c,i,e) = crystallite_partitionedFp0(1:3,1:3,c,i,e)
|
||||
crystallite_Fi(1:3,1:3,c,i,e) = crystallite_partitionedFi0(1:3,1:3,c,i,e)
|
||||
crystallite_S (1:3,1:3,c,i,e) = crystallite_partitionedS0 (1:3,1:3,c,i,e)
|
||||
|
||||
plasticState (material_phaseAt(c,e))%state( :,material_phasememberAt(c,i,e)) = &
|
||||
plasticState (material_phaseAt(c,e))%partionedState0(:,material_phasememberAt(c,i,e))
|
||||
plasticState (material_phaseAt(c,e))%partitionedState0(:,material_phasememberAt(c,i,e))
|
||||
do s = 1, phase_Nsources(material_phaseAt(c,e))
|
||||
sourceState(material_phaseAt(c,e))%p(s)%state( :,material_phasememberAt(c,i,e)) = &
|
||||
sourceState(material_phaseAt(c,e))%p(s)%partionedState0(:,material_phasememberAt(c,i,e))
|
||||
sourceState(material_phaseAt(c,e))%p(s)%partitionedState0(:,material_phasememberAt(c,i,e))
|
||||
enddo
|
||||
enddo
|
||||
|
||||
|
@ -758,7 +756,7 @@ subroutine crystallite_results
|
|||
do o = 1, size(output_constituent(p)%label)
|
||||
select case (output_constituent(p)%label(o))
|
||||
case('F')
|
||||
selected_tensors = select_tensors(crystallite_partionedF,p)
|
||||
selected_tensors = select_tensors(crystallite_partitionedF,p)
|
||||
call results_writeDataset(group,selected_tensors,output_constituent(p)%label(o),&
|
||||
'deformation gradient','1')
|
||||
case('Fe')
|
||||
|
@ -943,7 +941,7 @@ function integrateStress(ipc,ip,el,timeFraction) result(broken)
|
|||
F = crystallite_subF(1:3,1:3,ipc,ip,el)
|
||||
endif
|
||||
|
||||
call constitutive_dependentState(crystallite_partionedF(1:3,1:3,ipc,ip,el), &
|
||||
call constitutive_dependentState(crystallite_partitionedF(1:3,1:3,ipc,ip,el), &
|
||||
crystallite_Fp(1:3,1:3,ipc,ip,el),ipc,ip,el)
|
||||
|
||||
Lpguess = crystallite_Lp(1:3,1:3,ipc,ip,el) ! take as first guess
|
||||
|
@ -1120,9 +1118,9 @@ subroutine integrateStateFPI(g,i,e)
|
|||
c = material_phaseMemberAt(g,i,e)
|
||||
|
||||
broken = constitutive_collectDotState(crystallite_S(1:3,1:3,g,i,e), &
|
||||
crystallite_partionedF0, &
|
||||
crystallite_partitionedF0, &
|
||||
crystallite_Fi(1:3,1:3,g,i,e), &
|
||||
crystallite_partionedFp0, &
|
||||
crystallite_partitionedFp0, &
|
||||
crystallite_subdt(g,i,e), g,i,e,p,c)
|
||||
if(broken) return
|
||||
|
||||
|
@ -1152,9 +1150,9 @@ subroutine integrateStateFPI(g,i,e)
|
|||
if(broken) exit iteration
|
||||
|
||||
broken = constitutive_collectDotState(crystallite_S(1:3,1:3,g,i,e), &
|
||||
crystallite_partionedF0, &
|
||||
crystallite_partitionedF0, &
|
||||
crystallite_Fi(1:3,1:3,g,i,e), &
|
||||
crystallite_partionedFp0, &
|
||||
crystallite_partitionedFp0, &
|
||||
crystallite_subdt(g,i,e), g,i,e,p,c)
|
||||
if(broken) exit iteration
|
||||
|
||||
|
@ -1243,9 +1241,9 @@ subroutine integrateStateEuler(g,i,e)
|
|||
c = material_phaseMemberAt(g,i,e)
|
||||
|
||||
broken = constitutive_collectDotState(crystallite_S(1:3,1:3,g,i,e), &
|
||||
crystallite_partionedF0, &
|
||||
crystallite_partitionedF0, &
|
||||
crystallite_Fi(1:3,1:3,g,i,e), &
|
||||
crystallite_partionedFp0, &
|
||||
crystallite_partitionedFp0, &
|
||||
crystallite_subdt(g,i,e), g,i,e,p,c)
|
||||
if(broken) return
|
||||
|
||||
|
@ -1296,9 +1294,9 @@ subroutine integrateStateAdaptiveEuler(g,i,e)
|
|||
c = material_phaseMemberAt(g,i,e)
|
||||
|
||||
broken = constitutive_collectDotState(crystallite_S(1:3,1:3,g,i,e), &
|
||||
crystallite_partionedF0, &
|
||||
crystallite_partitionedF0, &
|
||||
crystallite_Fi(1:3,1:3,g,i,e), &
|
||||
crystallite_partionedFp0, &
|
||||
crystallite_partitionedFp0, &
|
||||
crystallite_subdt(g,i,e), g,i,e,p,c)
|
||||
if(broken) return
|
||||
|
||||
|
@ -1325,9 +1323,9 @@ subroutine integrateStateAdaptiveEuler(g,i,e)
|
|||
if(broken) return
|
||||
|
||||
broken = constitutive_collectDotState(crystallite_S(1:3,1:3,g,i,e), &
|
||||
crystallite_partionedF0, &
|
||||
crystallite_partitionedF0, &
|
||||
crystallite_Fi(1:3,1:3,g,i,e), &
|
||||
crystallite_partionedFp0, &
|
||||
crystallite_partitionedFp0, &
|
||||
crystallite_subdt(g,i,e), g,i,e,p,c)
|
||||
if(broken) return
|
||||
|
||||
|
@ -1434,9 +1432,9 @@ subroutine integrateStateRK(g,i,e,A,B,CC,DB)
|
|||
c = material_phaseMemberAt(g,i,e)
|
||||
|
||||
broken = constitutive_collectDotState(crystallite_S(1:3,1:3,g,i,e), &
|
||||
crystallite_partionedF0, &
|
||||
crystallite_partitionedF0, &
|
||||
crystallite_Fi(1:3,1:3,g,i,e), &
|
||||
crystallite_partionedFp0, &
|
||||
crystallite_partitionedFp0, &
|
||||
crystallite_subdt(g,i,e), g,i,e,p,c)
|
||||
if(broken) return
|
||||
|
||||
|
@ -1476,9 +1474,9 @@ subroutine integrateStateRK(g,i,e,A,B,CC,DB)
|
|||
if(broken) exit
|
||||
|
||||
broken = constitutive_collectDotState(crystallite_S(1:3,1:3,g,i,e), &
|
||||
crystallite_partionedF0, &
|
||||
crystallite_partitionedF0, &
|
||||
crystallite_Fi(1:3,1:3,g,i,e), &
|
||||
crystallite_partionedFp0, &
|
||||
crystallite_partitionedFp0, &
|
||||
crystallite_subdt(g,i,e)*CC(stage), g,i,e,p,c)
|
||||
if(broken) exit
|
||||
|
||||
|
@ -1526,38 +1524,6 @@ subroutine integrateStateRK(g,i,e,A,B,CC,DB)
|
|||
end subroutine integrateStateRK
|
||||
|
||||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
!> @brief sets convergence flag for nonlocal calculations
|
||||
!> @details one non-converged nonlocal sets all other nonlocals to non-converged to trigger cut back
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
subroutine nonlocalConvergenceCheck
|
||||
|
||||
integer :: e,i,p
|
||||
logical :: nonlocal_broken
|
||||
|
||||
nonlocal_broken = .false.
|
||||
!$OMP PARALLEL DO PRIVATE(p)
|
||||
do e = FEsolving_execElem(1),FEsolving_execElem(2)
|
||||
p = material_phaseAt(1,e)
|
||||
do i = FEsolving_execIP(1),FEsolving_execIP(2)
|
||||
if(plasticState(p)%nonlocal .and. .not. crystallite_converged(1,i,e)) nonlocal_broken = .true.
|
||||
enddo
|
||||
enddo
|
||||
!$OMP END PARALLEL DO
|
||||
|
||||
if(.not. nonlocal_broken) return
|
||||
!$OMP PARALLEL DO PRIVATE(p)
|
||||
do e = FEsolving_execElem(1),FEsolving_execElem(2)
|
||||
p = material_phaseAt(1,e)
|
||||
do i = FEsolving_execIP(1),FEsolving_execIP(2)
|
||||
if(plasticState(p)%nonlocal) crystallite_converged(1,i,e) = .false.
|
||||
enddo
|
||||
enddo
|
||||
!$OMP END PARALLEL DO
|
||||
|
||||
end subroutine nonlocalConvergenceCheck
|
||||
|
||||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
!> @brief determines whether a point is converged
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
|
@ -1590,7 +1556,7 @@ subroutine crystallite_restartWrite
|
|||
write(fileName,'(a,i0,a)') trim(getSolverJobName())//'_',worldrank,'.hdf5'
|
||||
fileHandle = HDF5_openFile(fileName,'a')
|
||||
|
||||
call HDF5_write(fileHandle,crystallite_partionedF,'F')
|
||||
call HDF5_write(fileHandle,crystallite_partitionedF,'F')
|
||||
call HDF5_write(fileHandle,crystallite_Fp, 'Fp')
|
||||
call HDF5_write(fileHandle,crystallite_Fi, 'Fi')
|
||||
call HDF5_write(fileHandle,crystallite_Lp, 'Lp')
|
||||
|
@ -1665,7 +1631,7 @@ subroutine crystallite_forward
|
|||
|
||||
integer :: i, j
|
||||
|
||||
crystallite_F0 = crystallite_partionedF
|
||||
crystallite_F0 = crystallite_partitionedF
|
||||
crystallite_Fp0 = crystallite_Fp
|
||||
crystallite_Lp0 = crystallite_Lp
|
||||
crystallite_Fi0 = crystallite_Fi
|
||||
|
|
|
@ -404,16 +404,16 @@ subroutine partitionDeformation(subF,ip,el)
|
|||
chosenHomogenization: select case(homogenization_type(material_homogenizationAt(el)))
|
||||
|
||||
case (HOMOGENIZATION_NONE_ID) chosenHomogenization
|
||||
crystallite_partionedF(1:3,1:3,1,ip,el) = subF
|
||||
crystallite_partitionedF(1:3,1:3,1,ip,el) = subF
|
||||
|
||||
case (HOMOGENIZATION_ISOSTRAIN_ID) chosenHomogenization
|
||||
call mech_isostrain_partitionDeformation(&
|
||||
crystallite_partionedF(1:3,1:3,1:homogenization_Ngrains(material_homogenizationAt(el)),ip,el), &
|
||||
crystallite_partitionedF(1:3,1:3,1:homogenization_Ngrains(material_homogenizationAt(el)),ip,el), &
|
||||
subF)
|
||||
|
||||
case (HOMOGENIZATION_RGC_ID) chosenHomogenization
|
||||
call mech_RGC_partitionDeformation(&
|
||||
crystallite_partionedF(1:3,1:3,1:homogenization_Ngrains(material_homogenizationAt(el)),ip,el), &
|
||||
crystallite_partitionedF(1:3,1:3,1:homogenization_Ngrains(material_homogenizationAt(el)),ip,el), &
|
||||
subF,&
|
||||
ip, &
|
||||
el)
|
||||
|
@ -448,8 +448,8 @@ function updateState(subdt,subF,ip,el)
|
|||
updateState = &
|
||||
updateState .and. &
|
||||
mech_RGC_updateState(crystallite_P(1:3,1:3,1:homogenization_Ngrains(material_homogenizationAt(el)),ip,el), &
|
||||
crystallite_partionedF(1:3,1:3,1:homogenization_Ngrains(material_homogenizationAt(el)),ip,el), &
|
||||
crystallite_partionedF0(1:3,1:3,1:homogenization_Ngrains(material_homogenizationAt(el)),ip,el),&
|
||||
crystallite_partitionedF(1:3,1:3,1:homogenization_Ngrains(material_homogenizationAt(el)),ip,el), &
|
||||
crystallite_partitionedF0(1:3,1:3,1:homogenization_Ngrains(material_homogenizationAt(el)),ip,el),&
|
||||
subF,&
|
||||
subdt, &
|
||||
dPdFs, &
|
||||
|
|
|
@ -212,7 +212,7 @@ end subroutine mech_RGC_init
|
|||
!--------------------------------------------------------------------------------------------------
|
||||
module subroutine mech_RGC_partitionDeformation(F,avgF,instance,of)
|
||||
|
||||
real(pReal), dimension (:,:,:), intent(out) :: F !< partioned F per grain
|
||||
real(pReal), dimension (:,:,:), intent(out) :: F !< partitioned F per grain
|
||||
|
||||
real(pReal), dimension (3,3), intent(in) :: avgF !< averaged F
|
||||
integer, intent(in) :: &
|
||||
|
@ -867,7 +867,7 @@ module procedure mech_RGC_updateState
|
|||
!--------------------------------------------------------------------------------------------------
|
||||
subroutine grainDeformation(F, avgF, instance, of)
|
||||
|
||||
real(pReal), dimension(:,:,:), intent(out) :: F !< partioned F per grain
|
||||
real(pReal), dimension(:,:,:), intent(out) :: F !< partitioned F per grain
|
||||
|
||||
real(pReal), dimension(:,:), intent(in) :: avgF !< averaged F
|
||||
integer, intent(in) :: &
|
||||
|
|
|
@ -47,7 +47,7 @@ module prec
|
|||
dotState, & !< rate of state change
|
||||
deltaState !< increment of state change
|
||||
real(pReal), allocatable, dimension(:,:) :: &
|
||||
partionedState0, &
|
||||
partitionedState0, &
|
||||
subState0
|
||||
end type
|
||||
|
||||
|
|
|
@ -737,13 +737,13 @@ pure function eu2om(eu) result(om)
|
|||
s = sin(eu)
|
||||
|
||||
om(1,1) = c(1)*c(3)-s(1)*s(3)*c(2)
|
||||
om(1,2) = s(1)*c(3)+c(1)*s(3)*c(2)
|
||||
om(1,3) = s(3)*s(2)
|
||||
om(2,1) = -c(1)*s(3)-s(1)*c(3)*c(2)
|
||||
om(2,2) = -s(1)*s(3)+c(1)*c(3)*c(2)
|
||||
om(2,3) = c(3)*s(2)
|
||||
om(3,1) = s(1)*s(2)
|
||||
om(1,2) = s(1)*c(3)+c(1)*s(3)*c(2)
|
||||
om(2,2) = -s(1)*s(3)+c(1)*c(3)*c(2)
|
||||
om(3,2) = -c(1)*s(2)
|
||||
om(1,3) = s(3)*s(2)
|
||||
om(2,3) = c(3)*s(2)
|
||||
om(3,3) = c(2)
|
||||
|
||||
where(abs(om)<1.0e-12_pReal) om = 0.0_pReal
|
||||
|
|
Loading…
Reference in New Issue