Merge branch 'development' into python-style
This commit is contained in:
commit
7a0c20b6de
|
@ -8,3 +8,10 @@
|
||||||
*.jpg binary
|
*.jpg binary
|
||||||
*.hdf5 binary
|
*.hdf5 binary
|
||||||
*.pdf binary
|
*.pdf binary
|
||||||
|
|
||||||
|
# ignore files from MSC.Marc in language statistics
|
||||||
|
installation/mods_MarcMentat/* linguist-vendored
|
||||||
|
src/MarcInclude/* linguist-vendored
|
||||||
|
|
||||||
|
# ignore reference files for tests in language statistics
|
||||||
|
python/tests/reference/* linguist-vendored
|
||||||
|
|
|
@ -104,7 +104,7 @@ checkout:
|
||||||
- release
|
- release
|
||||||
|
|
||||||
###################################################################################################
|
###################################################################################################
|
||||||
Pytest:
|
Pytest_python:
|
||||||
stage: python
|
stage: python
|
||||||
script:
|
script:
|
||||||
- cd $DAMASKROOT/python
|
- cd $DAMASKROOT/python
|
||||||
|
@ -142,13 +142,6 @@ Pre_General:
|
||||||
- master
|
- master
|
||||||
- release
|
- release
|
||||||
|
|
||||||
grid_geometryPacking:
|
|
||||||
stage: preprocessing
|
|
||||||
script: grid_geometryPacking/test.py
|
|
||||||
except:
|
|
||||||
- master
|
|
||||||
- release
|
|
||||||
|
|
||||||
###################################################################################################
|
###################################################################################################
|
||||||
Post_AverageDown:
|
Post_AverageDown:
|
||||||
stage: postprocessing
|
stage: postprocessing
|
||||||
|
@ -385,6 +378,15 @@ Phenopowerlaw_singleSlip:
|
||||||
- master
|
- master
|
||||||
- release
|
- release
|
||||||
|
|
||||||
|
Pytest_grid:
|
||||||
|
stage: grid
|
||||||
|
script:
|
||||||
|
- cd pytest
|
||||||
|
- pytest
|
||||||
|
except:
|
||||||
|
- master
|
||||||
|
- release
|
||||||
|
|
||||||
###################################################################################################
|
###################################################################################################
|
||||||
Marc_compileIfort:
|
Marc_compileIfort:
|
||||||
stage: compileMarc
|
stage: compileMarc
|
||||||
|
|
2
PRIVATE
2
PRIVATE
|
@ -1 +1 @@
|
||||||
Subproject commit ec615d249d39e5d01446b01ab9a5b7e7601340ad
|
Subproject commit 9573ce7bd2c1a7188c1aac5b83aa76d480c2bdb0
|
|
@ -1,49 +0,0 @@
|
||||||
[Aluminum]
|
|
||||||
elasticity hooke
|
|
||||||
plasticity phenopowerlaw
|
|
||||||
|
|
||||||
(output) resistance_slip
|
|
||||||
(output) shearrate_slip
|
|
||||||
(output) resolvedstress_slip
|
|
||||||
(output) accumulated_shear_slip
|
|
||||||
(output) resistance_twin
|
|
||||||
(output) shearrate_twin
|
|
||||||
(output) resolvedstress_twin
|
|
||||||
(output) accumulated_shear_twin
|
|
||||||
|
|
||||||
lattice_structure fcc
|
|
||||||
Nslip 12 # per family
|
|
||||||
Ntwin 0 # per family
|
|
||||||
|
|
||||||
c11 106.75e9
|
|
||||||
c12 60.41e9
|
|
||||||
c44 28.34e9
|
|
||||||
|
|
||||||
gdot0_slip 0.001
|
|
||||||
n_slip 20
|
|
||||||
tau0_slip 31e6 # per family
|
|
||||||
tausat_slip 63e6 # per family
|
|
||||||
a_slip 2.25
|
|
||||||
gdot0_twin 0.001
|
|
||||||
n_twin 20
|
|
||||||
tau0_twin 31e6 # per family
|
|
||||||
h0_slipslip 75e6
|
|
||||||
interaction_slipslip 1 1 1.4 1.4 1.4 1.4
|
|
||||||
atol_resistance 1
|
|
||||||
|
|
||||||
(stiffness_degradation) damage
|
|
||||||
(stiffness_degradation) porosity
|
|
||||||
{./Phase_Damage.config}
|
|
||||||
{./Phase_Thermal.config}
|
|
||||||
{./Phase_Vacancy.config}
|
|
||||||
{./Phase_Porosity.config}
|
|
||||||
{./Phase_Hydrogen.config}
|
|
||||||
{./Source_Damage_IsoBrittle.config}
|
|
||||||
{./Source_Thermal_Dissipation.config}
|
|
||||||
{./Source_Vacancy_PhenoPlasticity.config}
|
|
||||||
{./Source_Vacancy_Irradiation.config}
|
|
||||||
{./Kinematics_Thermal_Expansion.config}
|
|
||||||
{./Kinematics_Vacancy_Strain.config}
|
|
||||||
{./Kinematics_Hydrogen_Strain.config}
|
|
||||||
|
|
||||||
|
|
|
@ -52,15 +52,15 @@ for filename in options.filenames:
|
||||||
table = damask.Table(np.ones(np.product(results.grid),dtype=int)*int(inc[3:]),{'inc':(1,)})
|
table = damask.Table(np.ones(np.product(results.grid),dtype=int)*int(inc[3:]),{'inc':(1,)})
|
||||||
table.add('pos',coords.reshape((-1,3)))
|
table.add('pos',coords.reshape((-1,3)))
|
||||||
|
|
||||||
results.set_visible('materialpoints',False)
|
results.pick('materialpoints',False)
|
||||||
results.set_visible('constituents', True)
|
results.pick('constituents', True)
|
||||||
for label in options.con:
|
for label in options.con:
|
||||||
x = results.get_dataset_location(label)
|
x = results.get_dataset_location(label)
|
||||||
if len(x) != 0:
|
if len(x) != 0:
|
||||||
table.add(label,results.read_dataset(x,0,plain=True).reshape((results.grid.prod(),-1)))
|
table.add(label,results.read_dataset(x,0,plain=True).reshape((results.grid.prod(),-1)))
|
||||||
|
|
||||||
results.set_visible('constituents', False)
|
results.pick('constituents', False)
|
||||||
results.set_visible('materialpoints',True)
|
results.pick('materialpoints',True)
|
||||||
for label in options.mat:
|
for label in options.mat:
|
||||||
x = results.get_dataset_location(label)
|
x = results.get_dataset_location(label)
|
||||||
if len(x) != 0:
|
if len(x) != 0:
|
||||||
|
|
|
@ -42,8 +42,8 @@ for name in filenames:
|
||||||
|
|
||||||
table = damask.Table.from_ASCII(StringIO(''.join(sys.stdin.read())) if name is None else name)
|
table = damask.Table.from_ASCII(StringIO(''.join(sys.stdin.read())) if name is None else name)
|
||||||
table.add('Cauchy',
|
table.add('Cauchy',
|
||||||
damask.mechanics.Cauchy(table.get(options.defgrad).reshape(-1,3,3),
|
damask.mechanics.Cauchy(table.get(options.stress ).reshape(-1,3,3),
|
||||||
table.get(options.stress ).reshape(-1,3,3)).reshape(-1,9),
|
table.get(options.defgrad).reshape(-1,3,3)).reshape(-1,9),
|
||||||
scriptID+' '+' '.join(sys.argv[1:]))
|
scriptID+' '+' '.join(sys.argv[1:]))
|
||||||
|
|
||||||
table.to_ASCII(sys.stdout if name is None else name)
|
table.to_ASCII(sys.stdout if name is None else name)
|
||||||
|
|
|
@ -43,8 +43,8 @@ for name in filenames:
|
||||||
table = damask.Table.from_ASCII(StringIO(''.join(sys.stdin.read())) if name is None else name)
|
table = damask.Table.from_ASCII(StringIO(''.join(sys.stdin.read())) if name is None else name)
|
||||||
|
|
||||||
table.add('S',
|
table.add('S',
|
||||||
damask.mechanics.PK2(table.get(options.defgrad).reshape(-1,3,3),
|
damask.mechanics.PK2(table.get(options.stress ).reshape(-1,3,3),
|
||||||
table.get(options.stress ).reshape(-1,3,3)).reshape(-1,9),
|
table.get(options.defgrad).reshape(-1,3,3)).reshape(-1,9),
|
||||||
scriptID+' '+' '.join(sys.argv[1:]))
|
scriptID+' '+' '.join(sys.argv[1:]))
|
||||||
|
|
||||||
table.to_ASCII(sys.stdout if name is None else name)
|
table.to_ASCII(sys.stdout if name is None else name)
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
from io import StringIO
|
||||||
from optparse import OptionParser
|
from optparse import OptionParser
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
@ -33,69 +34,27 @@ parser.add_option('--no-check',
|
||||||
|
|
||||||
parser.set_defaults(rh = True,
|
parser.set_defaults(rh = True,
|
||||||
)
|
)
|
||||||
|
|
||||||
(options,filenames) = parser.parse_args()
|
(options,filenames) = parser.parse_args()
|
||||||
|
|
||||||
if options.tensor is None:
|
|
||||||
parser.error('no data column specified.')
|
|
||||||
|
|
||||||
# --- loop over input files -------------------------------------------------------------------------
|
|
||||||
|
|
||||||
if filenames == []: filenames = [None]
|
if filenames == []: filenames = [None]
|
||||||
|
|
||||||
for name in filenames:
|
for name in filenames:
|
||||||
try:
|
damask.util.report(scriptName,name)
|
||||||
table = damask.ASCIItable(name = name,
|
|
||||||
buffered = False)
|
|
||||||
except: continue
|
|
||||||
damask.util.report(scriptName,name)
|
|
||||||
|
|
||||||
# ------------------------------------------ read header ------------------------------------------
|
table = damask.Table.from_ASCII(StringIO(''.join(sys.stdin.read())) if name is None else name)
|
||||||
|
|
||||||
table.head_read()
|
for tensor in options.tensor:
|
||||||
|
|
||||||
|
t = table.get(tensor).reshape(-1,3,3)
|
||||||
|
(u,v) = np.linalg.eigh(damask.mechanics.symmetric(t))
|
||||||
|
if options.rh: v[np.linalg.det(v) < 0.0,:,2] *= -1.0
|
||||||
|
|
||||||
# ------------------------------------------ assemble header 1 ------------------------------------
|
for i,o in enumerate(['Min','Mid','Max']):
|
||||||
|
table.add('eigval{}({})'.format(o,tensor),u[:,i],
|
||||||
|
scriptID+' '+' '.join(sys.argv[1:]))
|
||||||
|
|
||||||
items = {
|
for i,o in enumerate(['Min','Mid','Max']):
|
||||||
'tensor': {'dim': 9, 'shape': [3,3], 'labels':options.tensor, 'column': []},
|
table.add('eigvec{}({})'.format(o,tensor),v[:,:,i],
|
||||||
}
|
scriptID+' '+' '.join(sys.argv[1:]))
|
||||||
errors = []
|
|
||||||
remarks = []
|
table.to_ASCII(sys.stdout if name is None else name)
|
||||||
|
|
||||||
for type, data in items.items():
|
|
||||||
for what in data['labels']:
|
|
||||||
dim = table.label_dimension(what)
|
|
||||||
if dim != data['dim']: remarks.append('column {} is not a {}...'.format(what,type))
|
|
||||||
else:
|
|
||||||
items[type]['column'].append(table.label_index(what))
|
|
||||||
for order in ['Min','Mid','Max']:
|
|
||||||
table.labels_append(['eigval{}({})'.format(order,what)]) # extend ASCII header with new labels
|
|
||||||
for order in ['Min','Mid','Max']:
|
|
||||||
table.labels_append(['{}_eigvec{}({})'.format(i+1,order,what) for i in range(3)]) # extend ASCII header with new labels
|
|
||||||
|
|
||||||
if remarks != []: damask.util.croak(remarks)
|
|
||||||
if errors != []:
|
|
||||||
damask.util.croak(errors)
|
|
||||||
table.close(dismiss = True)
|
|
||||||
continue
|
|
||||||
|
|
||||||
# ------------------------------------------ assemble header 2 ------------------------------------
|
|
||||||
|
|
||||||
table.info_append(scriptID + '\t' + ' '.join(sys.argv[1:]))
|
|
||||||
table.head_write()
|
|
||||||
|
|
||||||
# ------------------------------------------ process data -----------------------------------------
|
|
||||||
|
|
||||||
outputAlive = True
|
|
||||||
while outputAlive and table.data_read(): # read next data line of ASCII table
|
|
||||||
for type, data in items.items():
|
|
||||||
for column in data['column']:
|
|
||||||
(u,v) = np.linalg.eigh(np.array(list(map(float,table.data[column:column+data['dim']]))).reshape(data['shape']))
|
|
||||||
if options.rh and np.dot(np.cross(v[:,0], v[:,1]), v[:,2]) < 0.0 : v[:, 2] *= -1.0 # ensure right-handed eigenvector basis
|
|
||||||
table.data_append(list(u)) # vector of max,mid,min eigval
|
|
||||||
table.data_append(list(v.transpose().reshape(data['dim']))) # 3x3=9 combo vector of max,mid,min eigvec coordinates
|
|
||||||
outputAlive = table.data_write() # output processed line in accordance with column labeling
|
|
||||||
|
|
||||||
# ------------------------------------------ output finalization -----------------------------------
|
|
||||||
|
|
||||||
table.close() # close input ASCII table (works for stdin)
|
|
||||||
|
|
|
@ -83,7 +83,7 @@ for name in filenames:
|
||||||
|
|
||||||
# ------------------------------------------ assemble header ---------------------------------------
|
# ------------------------------------------ assemble header ---------------------------------------
|
||||||
|
|
||||||
randomSeed = int(os.urandom(4).encode('hex'), 16) if options.randomSeed is None else options.randomSeed # random seed per file
|
randomSeed = int(os.urandom(4).hex(), 16) if options.randomSeed is None else options.randomSeed # random seed per file
|
||||||
np.random.seed(randomSeed)
|
np.random.seed(randomSeed)
|
||||||
|
|
||||||
table.info_append([scriptID + '\t' + ' '.join(sys.argv[1:]),
|
table.info_append([scriptID + '\t' + ' '.join(sys.argv[1:]),
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,11 +1,9 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# -*- coding: UTF-8 no BOM -*-
|
|
||||||
|
|
||||||
import threading,time,os,sys,random
|
import threading,time,os,sys,random
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from optparse import OptionParser
|
from optparse import OptionParser
|
||||||
from io import StringIO
|
from io import StringIO
|
||||||
import binascii
|
|
||||||
import damask
|
import damask
|
||||||
|
|
||||||
scriptName = os.path.splitext(os.path.basename(__file__))[0]
|
scriptName = os.path.splitext(os.path.basename(__file__))[0]
|
||||||
|
@ -16,9 +14,10 @@ currentSeedsName = None
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------------------------
|
||||||
class myThread (threading.Thread):
|
class myThread (threading.Thread):
|
||||||
"""perturbes seed in seed file, performes Voronoi tessellation, evaluates, and updates best match"""
|
"""Perturb seed in seed file, performes Voronoi tessellation, evaluates, and updates best match."""
|
||||||
|
|
||||||
def __init__(self, threadID):
|
def __init__(self, threadID):
|
||||||
|
"""Threading class with thread ID."""
|
||||||
threading.Thread.__init__(self)
|
threading.Thread.__init__(self)
|
||||||
self.threadID = threadID
|
self.threadID = threadID
|
||||||
|
|
||||||
|
@ -215,20 +214,16 @@ options = parser.parse_args()[0]
|
||||||
damask.util.report(scriptName,options.seedFile)
|
damask.util.report(scriptName,options.seedFile)
|
||||||
|
|
||||||
if options.randomSeed is None:
|
if options.randomSeed is None:
|
||||||
options.randomSeed = int(binascii.hexlify(os.urandom(4)),16)
|
options.randomSeed = int(os.urandom(4).hex(),16)
|
||||||
damask.util.croak(options.randomSeed)
|
damask.util.croak(options.randomSeed)
|
||||||
delta = (options.scale/options.grid[0],options.scale/options.grid[1],options.scale/options.grid[2])
|
delta = (options.scale/options.grid[0],options.scale/options.grid[1],options.scale/options.grid[2])
|
||||||
baseFile=os.path.splitext(os.path.basename(options.seedFile))[0]
|
baseFile=os.path.splitext(os.path.basename(options.seedFile))[0]
|
||||||
points = np.array(options.grid).prod().astype('float')
|
points = np.array(options.grid).prod().astype('float')
|
||||||
|
|
||||||
# ----------- calculate target distribution and bin edges
|
# ----------- calculate target distribution and bin edges
|
||||||
targetGeomFile = os.path.splitext(os.path.basename(options.target))[0]+'.geom'
|
targetGeom = damask.Geom.from_file(os.path.splitext(os.path.basename(options.target))[0]+'.geom')
|
||||||
targetGeomTable = damask.ASCIItable(targetGeomFile,None,labeled=False,readonly=True)
|
nMicrostructures = len(np.unique(targetGeom.microstructure))
|
||||||
targetGeomTable.head_read()
|
targetVolFrac = np.bincount(targetGeom.microstructure.flatten())/targetGeom.grid.prod().astype(np.float)
|
||||||
info,devNull = targetGeomTable.head_getGeom()
|
|
||||||
nMicrostructures = info['microstructures']
|
|
||||||
targetVolFrac = np.bincount(targetGeomTable.microstructure_read(info['grid']))[1:nMicrostructures+1]/\
|
|
||||||
float(info['grid'].prod())
|
|
||||||
target=[]
|
target=[]
|
||||||
for i in range(1,nMicrostructures+1):
|
for i in range(1,nMicrostructures+1):
|
||||||
targetHist,targetBins = np.histogram(targetVolFrac,bins=i) #bin boundaries
|
targetHist,targetBins = np.histogram(targetVolFrac,bins=i) #bin boundaries
|
||||||
|
@ -252,13 +247,12 @@ initialGeomVFile = StringIO()
|
||||||
initialGeomVFile.write(damask.util.execute('geom_fromVoronoiTessellation '+
|
initialGeomVFile.write(damask.util.execute('geom_fromVoronoiTessellation '+
|
||||||
' -g '+' '.join(list(map(str, options.grid))),bestSeedsVFile)[0])
|
' -g '+' '.join(list(map(str, options.grid))),bestSeedsVFile)[0])
|
||||||
initialGeomVFile.seek(0)
|
initialGeomVFile.seek(0)
|
||||||
initialGeomTable = damask.ASCIItable(initialGeomVFile,None,labeled=False,readonly=True)
|
initialGeom = damask.Geom.from_file(initialGeomVFile)
|
||||||
initialGeomTable.head_read()
|
|
||||||
info,devNull = initialGeomTable.head_getGeom()
|
|
||||||
|
|
||||||
if info['microstructures'] != nMicrostructures: damask.util.croak('error. Microstructure count mismatch')
|
if len(np.unique(targetGeom.microstructure)) != nMicrostructures:
|
||||||
|
damask.util.croak('error. Microstructure count mismatch')
|
||||||
|
|
||||||
initialData = np.bincount(initialGeomTable.microstructure_read(info['grid']))/points
|
initialData = np.bincount(initialGeom.microstructure.flatten())/points
|
||||||
for i in range(nMicrostructures):
|
for i in range(nMicrostructures):
|
||||||
initialHist = np.histogram(initialData,bins=target[i]['bins'])[0]
|
initialHist = np.histogram(initialData,bins=target[i]['bins'])[0]
|
||||||
target[i]['error']=np.sqrt(np.square(np.array(target[i]['histogram']-initialHist)).sum())
|
target[i]['error']=np.sqrt(np.square(np.array(target[i]['histogram']-initialHist)).sum())
|
||||||
|
@ -274,7 +268,7 @@ for i in range(nMicrostructures):
|
||||||
|
|
||||||
|
|
||||||
if options.maxseeds < 1:
|
if options.maxseeds < 1:
|
||||||
maxSeeds = info['microstructures']
|
maxSeeds = len(np.unique(initialGeom.microstructure))
|
||||||
else:
|
else:
|
||||||
maxSeeds = options.maxseeds
|
maxSeeds = options.maxseeds
|
||||||
|
|
||||||
|
|
|
@ -1,13 +0,0 @@
|
||||||
DAMASK - The Düsseldorf Advanced Material Simulation Kit
|
|
||||||
Visit damask.mpie.de for installation and usage instructions
|
|
||||||
|
|
||||||
CONTACT INFORMATION
|
|
||||||
|
|
||||||
Max-Planck-Institut für Eisenforschung GmbH
|
|
||||||
Max-Planck-Str. 1
|
|
||||||
40237 Düsseldorf
|
|
||||||
Germany
|
|
||||||
|
|
||||||
Email: DAMASK@mpie.de
|
|
||||||
https://damask.mpie.de
|
|
||||||
https://magit1.mpie.de
|
|
|
@ -0,0 +1 @@
|
||||||
|
../README
|
|
@ -14,9 +14,10 @@ from .asciitable import ASCIItable # noqa
|
||||||
from .config import Material # noqa
|
from .config import Material # noqa
|
||||||
from .colormaps import Colormap, Color # noqa
|
from .colormaps import Colormap, Color # noqa
|
||||||
from .rotation import Rotation # noqa
|
from .rotation import Rotation # noqa
|
||||||
from .lattice import Symmetry, Lattice # noqa
|
from .lattice import Symmetry, Lattice# noqa
|
||||||
from .orientation import Orientation # noqa
|
from .orientation import Orientation # noqa
|
||||||
from .dadf5 import DADF5 # noqa
|
from .result import Result # noqa
|
||||||
|
from .result import Result as DADF5 # noqa
|
||||||
|
|
||||||
from .geom import Geom # noqa
|
from .geom import Geom # noqa
|
||||||
from .solver import Solver # noqa
|
from .solver import Solver # noqa
|
||||||
|
|
|
@ -11,12 +11,12 @@ class ASCIItable():
|
||||||
"""Read and write to ASCII tables."""
|
"""Read and write to ASCII tables."""
|
||||||
|
|
||||||
tmpext = '_tmp' # filename extension for in-place access
|
tmpext = '_tmp' # filename extension for in-place access
|
||||||
|
|
||||||
# ------------------------------------------------------------------
|
# ------------------------------------------------------------------
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
name = None,
|
name = None,
|
||||||
outname = None,
|
outname = None,
|
||||||
buffered = False, # flush writes
|
buffered = False, # is ignored, only exists for compatibility reasons
|
||||||
labeled = True, # assume table has labels
|
labeled = True, # assume table has labels
|
||||||
readonly = False, # no reading from file
|
readonly = False, # no reading from file
|
||||||
):
|
):
|
||||||
|
@ -52,7 +52,7 @@ class ASCIItable():
|
||||||
|
|
||||||
if self.__IO__['in'] is None \
|
if self.__IO__['in'] is None \
|
||||||
or self.__IO__['out'] is None: raise IOError # complain if any required file access not possible
|
or self.__IO__['out'] is None: raise IOError # complain if any required file access not possible
|
||||||
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------
|
# ------------------------------------------------------------------
|
||||||
def _removeCRLF(self,
|
def _removeCRLF(self,
|
||||||
|
@ -63,7 +63,6 @@ class ASCIItable():
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
return str(string)
|
return str(string)
|
||||||
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------
|
# ------------------------------------------------------------------
|
||||||
def _quote(self,
|
def _quote(self,
|
||||||
what):
|
what):
|
||||||
|
@ -71,6 +70,7 @@ class ASCIItable():
|
||||||
return '{quote}{content}{quote}'.format(
|
return '{quote}{content}{quote}'.format(
|
||||||
quote = ('"' if str(what)=='' or re.search(r"\s",str(what)) else ''),
|
quote = ('"' if str(what)=='' or re.search(r"\s",str(what)) else ''),
|
||||||
content = what)
|
content = what)
|
||||||
|
|
||||||
# ------------------------------------------------------------------
|
# ------------------------------------------------------------------
|
||||||
def close(self,
|
def close(self,
|
||||||
dismiss = False):
|
dismiss = False):
|
||||||
|
@ -110,7 +110,7 @@ class ASCIItable():
|
||||||
def head_read(self):
|
def head_read(self):
|
||||||
"""
|
"""
|
||||||
Get column labels.
|
Get column labels.
|
||||||
|
|
||||||
by either reading the first row or,
|
by either reading the first row or,
|
||||||
if keyword "head[*]" is present, the last line of the header
|
if keyword "head[*]" is present, the last line of the header
|
||||||
"""
|
"""
|
||||||
|
@ -121,7 +121,7 @@ class ASCIItable():
|
||||||
|
|
||||||
firstline = self.__IO__['in'].readline().strip()
|
firstline = self.__IO__['in'].readline().strip()
|
||||||
m = re.search(r'(\d+)\s+head', firstline.lower()) # search for "head" keyword
|
m = re.search(r'(\d+)\s+head', firstline.lower()) # search for "head" keyword
|
||||||
|
|
||||||
if m: # proper ASCIItable format
|
if m: # proper ASCIItable format
|
||||||
|
|
||||||
if self.__IO__['labeled']: # table features labels
|
if self.__IO__['labeled']: # table features labels
|
||||||
|
@ -145,7 +145,7 @@ class ASCIItable():
|
||||||
if self.__IO__['labeled']: # table features labels
|
if self.__IO__['labeled']: # table features labels
|
||||||
self.tags = self.data # get tags from last line in "header"...
|
self.tags = self.data # get tags from last line in "header"...
|
||||||
self.data_read() # ...and remove from buffer
|
self.data_read() # ...and remove from buffer
|
||||||
|
|
||||||
if self.__IO__['labeled']: # table features tags
|
if self.__IO__['labeled']: # table features tags
|
||||||
self.__IO__['tags'] = list(self.tags) # backup tags (make COPY, not link)
|
self.__IO__['tags'] = list(self.tags) # backup tags (make COPY, not link)
|
||||||
|
|
||||||
|
@ -163,7 +163,7 @@ class ASCIItable():
|
||||||
if self.__IO__['labeled']:
|
if self.__IO__['labeled']:
|
||||||
head.append('\t'.join(map(self._quote,self.tags)))
|
head.append('\t'.join(map(self._quote,self.tags)))
|
||||||
if len(self.tags) == 0: raise ValueError('no labels present.')
|
if len(self.tags) == 0: raise ValueError('no labels present.')
|
||||||
|
|
||||||
return self.output_write(head)
|
return self.output_write(head)
|
||||||
|
|
||||||
# ------------------------------------------------------------------
|
# ------------------------------------------------------------------
|
||||||
|
@ -178,15 +178,11 @@ class ASCIItable():
|
||||||
'grid': lambda x: int(x),
|
'grid': lambda x: int(x),
|
||||||
'size': lambda x: float(x),
|
'size': lambda x: float(x),
|
||||||
'origin': lambda x: float(x),
|
'origin': lambda x: float(x),
|
||||||
'homogenization': lambda x: int(x),
|
|
||||||
'microstructures': lambda x: int(x),
|
|
||||||
}
|
}
|
||||||
info = {
|
info = {
|
||||||
'grid': np.zeros(3,'i'),
|
'grid': np.zeros(3,'i'),
|
||||||
'size': np.zeros(3,'d'),
|
'size': np.zeros(3,'d'),
|
||||||
'origin': np.zeros(3,'d'),
|
'origin': np.zeros(3,'d'),
|
||||||
'homogenization': 0,
|
|
||||||
'microstructures': 0,
|
|
||||||
}
|
}
|
||||||
extra_header = []
|
extra_header = []
|
||||||
|
|
||||||
|
@ -234,7 +230,7 @@ class ASCIItable():
|
||||||
raw = False):
|
raw = False):
|
||||||
"""
|
"""
|
||||||
Tell abstract labels.
|
Tell abstract labels.
|
||||||
|
|
||||||
"x" for "1_x","2_x",... unless raw output is requested.
|
"x" for "1_x","2_x",... unless raw output is requested.
|
||||||
operates on object tags or given list.
|
operates on object tags or given list.
|
||||||
"""
|
"""
|
||||||
|
@ -347,7 +343,7 @@ class ASCIItable():
|
||||||
"""
|
"""
|
||||||
start = self.label_index(labels)
|
start = self.label_index(labels)
|
||||||
dim = self.label_dimension(labels)
|
dim = self.label_dimension(labels)
|
||||||
|
|
||||||
return np.hstack([range(s,s+d) for s,d in zip(start,dim)]).astype(int) \
|
return np.hstack([range(s,s+d) for s,d in zip(start,dim)]).astype(int) \
|
||||||
if isinstance(labels, Iterable) and not isinstance(labels, str) \
|
if isinstance(labels, Iterable) and not isinstance(labels, str) \
|
||||||
else range(start,start+dim)
|
else range(start,start+dim)
|
||||||
|
@ -375,15 +371,6 @@ class ASCIItable():
|
||||||
self.tags = list(self.__IO__['tags']) # restore label info found in header (as COPY, not link)
|
self.tags = list(self.__IO__['tags']) # restore label info found in header (as COPY, not link)
|
||||||
self.__IO__['labeled'] = len(self.tags) > 0
|
self.__IO__['labeled'] = len(self.tags) > 0
|
||||||
|
|
||||||
# ------------------------------------------------------------------
|
|
||||||
def data_skipLines(self,
|
|
||||||
count):
|
|
||||||
"""Wind forward by count number of lines."""
|
|
||||||
for i in range(count):
|
|
||||||
alive = self.data_read()
|
|
||||||
|
|
||||||
return alive
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------
|
# ------------------------------------------------------------------
|
||||||
def data_read(self,
|
def data_read(self,
|
||||||
advance = True,
|
advance = True,
|
||||||
|
@ -425,8 +412,8 @@ class ASCIItable():
|
||||||
columns = []
|
columns = []
|
||||||
for i,(c,d) in enumerate(zip(indices[present],dimensions[present])): # for all valid labels ...
|
for i,(c,d) in enumerate(zip(indices[present],dimensions[present])): # for all valid labels ...
|
||||||
# ... transparently add all components unless column referenced by number or with explicit dimension
|
# ... transparently add all components unless column referenced by number or with explicit dimension
|
||||||
columns += list(range(c,c +
|
columns += list(range(c,c +
|
||||||
(d if str(c) != str(labels[present[i]]) else
|
(d if str(c) != str(labels[present[i]]) else
|
||||||
1)))
|
1)))
|
||||||
use = np.array(columns) if len(columns) > 0 else None
|
use = np.array(columns) if len(columns) > 0 else None
|
||||||
|
|
||||||
|
@ -457,7 +444,7 @@ class ASCIItable():
|
||||||
output = [fmt % value for value in row] if fmt else list(map(repr,row))
|
output = [fmt % value for value in row] if fmt else list(map(repr,row))
|
||||||
except Exception:
|
except Exception:
|
||||||
output = [fmt % row] if fmt else [repr(row)]
|
output = [fmt % row] if fmt else [repr(row)]
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.__IO__['out'].write(delimiter.join(output) + '\n')
|
self.__IO__['out'].write(delimiter.join(output) + '\n')
|
||||||
except Exception:
|
except Exception:
|
||||||
|
@ -473,33 +460,3 @@ class ASCIItable():
|
||||||
for item in what: self.data_append(item)
|
for item in what: self.data_append(item)
|
||||||
except TypeError:
|
except TypeError:
|
||||||
self.data += [str(what)]
|
self.data += [str(what)]
|
||||||
|
|
||||||
# ------------------------------------------------------------------
|
|
||||||
def microstructure_read(self,
|
|
||||||
grid,
|
|
||||||
type = 'i',
|
|
||||||
strict = False):
|
|
||||||
"""Read microstructure data (from .geom format)."""
|
|
||||||
def datatype(item):
|
|
||||||
return int(item) if type.lower() == 'i' else float(item)
|
|
||||||
|
|
||||||
N = grid.prod() # expected number of microstructure indices in data
|
|
||||||
microstructure = np.zeros(N,type) # initialize as flat array
|
|
||||||
|
|
||||||
i = 0
|
|
||||||
while i < N and self.data_read():
|
|
||||||
items = self.data
|
|
||||||
if len(items) > 2:
|
|
||||||
if items[1].lower() == 'of':
|
|
||||||
items = np.ones(datatype(items[0]))*datatype(items[2])
|
|
||||||
elif items[1].lower() == 'to':
|
|
||||||
items = np.linspace(datatype(items[0]),datatype(items[2]),
|
|
||||||
abs(datatype(items[2])-datatype(items[0]))+1,dtype=int)
|
|
||||||
else: items = list(map(datatype,items))
|
|
||||||
else: items = list(map(datatype,items))
|
|
||||||
|
|
||||||
s = min(len(items), N-i) # prevent overflow of microstructure array
|
|
||||||
microstructure[i:i+s] = items[:s]
|
|
||||||
i += len(items)
|
|
||||||
|
|
||||||
return (microstructure, i == N and not self.data_read()) if strict else microstructure # check for proper point count and end of file
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -8,7 +8,7 @@ class Environment():
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
"""Read and provide values of DAMASK configuration."""
|
"""Read and provide values of DAMASK configuration."""
|
||||||
self.options = {}
|
self.options = {}
|
||||||
self.get_options()
|
self.__get_options()
|
||||||
|
|
||||||
def relPath(self,relative = '.'):
|
def relPath(self,relative = '.'):
|
||||||
return os.path.join(self.rootDir(),relative)
|
return os.path.join(self.rootDir(),relative)
|
||||||
|
@ -16,7 +16,7 @@ class Environment():
|
||||||
def rootDir(self):
|
def rootDir(self):
|
||||||
return os.path.normpath(os.path.join(os.path.realpath(__file__),'../../../'))
|
return os.path.normpath(os.path.join(os.path.realpath(__file__),'../../../'))
|
||||||
|
|
||||||
def get_options(self):
|
def __get_options(self):
|
||||||
for item in ['DAMASK_NUM_THREADS',
|
for item in ['DAMASK_NUM_THREADS',
|
||||||
'MSC_ROOT',
|
'MSC_ROOT',
|
||||||
'MARC_VERSION',
|
'MARC_VERSION',
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
def Cauchy(F,P):
|
def Cauchy(P,F):
|
||||||
"""
|
"""
|
||||||
Return Cauchy stress calculated from 1. Piola-Kirchhoff stress and deformation gradient.
|
Return Cauchy stress calculated from first Piola-Kirchhoff stress and deformation gradient.
|
||||||
|
|
||||||
Resulting tensor is symmetrized as the Cauchy stress needs to be symmetric.
|
Resulting tensor is symmetrized as the Cauchy stress needs to be symmetric.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
F : numpy.array of shape (:,3,3) or (3,3)
|
F : numpy.array of shape (:,3,3) or (3,3)
|
||||||
|
@ -21,32 +21,189 @@ def Cauchy(F,P):
|
||||||
return symmetric(sigma)
|
return symmetric(sigma)
|
||||||
|
|
||||||
|
|
||||||
def PK2(F,P):
|
def deviatoric_part(T):
|
||||||
"""
|
"""
|
||||||
Return 2. Piola-Kirchhoff stress calculated from 1. Piola-Kirchhoff stress and deformation gradient.
|
Return deviatoric part of a tensor.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
T : numpy.array of shape (:,3,3) or (3,3)
|
||||||
|
Tensor of which the deviatoric part is computed.
|
||||||
|
|
||||||
|
"""
|
||||||
|
return T - np.eye(3)*spherical_part(T) if np.shape(T) == (3,3) else \
|
||||||
|
T - np.einsum('ijk,i->ijk',np.broadcast_to(np.eye(3),[T.shape[0],3,3]),spherical_part(T))
|
||||||
|
|
||||||
|
|
||||||
|
def eigenvalues(T_sym):
|
||||||
|
"""
|
||||||
|
Return the eigenvalues, i.e. principal components, of a symmetric tensor.
|
||||||
|
|
||||||
|
The eigenvalues are sorted in ascending order, each repeated according to
|
||||||
|
its multiplicity.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
T_sym : numpy.array of shape (:,3,3) or (3,3)
|
||||||
|
Symmetric tensor of which the eigenvalues are computed.
|
||||||
|
|
||||||
|
"""
|
||||||
|
return np.linalg.eigvalsh(symmetric(T_sym))
|
||||||
|
|
||||||
|
|
||||||
|
def eigenvectors(T_sym,RHS=False):
|
||||||
|
"""
|
||||||
|
Return eigenvectors of a symmetric tensor.
|
||||||
|
|
||||||
|
The eigenvalues are sorted in ascending order of their associated eigenvalues.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
T_sym : numpy.array of shape (:,3,3) or (3,3)
|
||||||
|
Symmetric tensor of which the eigenvectors are computed.
|
||||||
|
RHS: bool, optional
|
||||||
|
Enforce right-handed coordinate system. Default is False.
|
||||||
|
|
||||||
|
"""
|
||||||
|
(u,v) = np.linalg.eigh(symmetric(T_sym))
|
||||||
|
|
||||||
|
if RHS:
|
||||||
|
if np.shape(T_sym) == (3,3):
|
||||||
|
if np.linalg.det(v) < 0.0: v[:,2] *= -1.0
|
||||||
|
else:
|
||||||
|
v[np.linalg.det(v) < 0.0,:,2] *= -1.0
|
||||||
|
return v
|
||||||
|
|
||||||
|
|
||||||
|
def left_stretch(T):
|
||||||
|
"""
|
||||||
|
Return the left stretch of a tensor.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
T : numpy.array of shape (:,3,3) or (3,3)
|
||||||
|
Tensor of which the left stretch is computed.
|
||||||
|
|
||||||
|
"""
|
||||||
|
return __polar_decomposition(T,'V')[0]
|
||||||
|
|
||||||
|
|
||||||
|
def maximum_shear(T_sym):
|
||||||
|
"""
|
||||||
|
Return the maximum shear component of a symmetric tensor.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
T_sym : numpy.array of shape (:,3,3) or (3,3)
|
||||||
|
Symmetric tensor of which the maximum shear is computed.
|
||||||
|
|
||||||
|
"""
|
||||||
|
w = eigenvalues(T_sym)
|
||||||
|
return (w[0] - w[2])*0.5 if np.shape(T_sym) == (3,3) else \
|
||||||
|
(w[:,0] - w[:,2])*0.5
|
||||||
|
|
||||||
|
|
||||||
|
def Mises_strain(epsilon):
|
||||||
|
"""
|
||||||
|
Return the Mises equivalent of a strain tensor.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
epsilon : numpy.array of shape (:,3,3) or (3,3)
|
||||||
|
Symmetric strain tensor of which the von Mises equivalent is computed.
|
||||||
|
|
||||||
|
"""
|
||||||
|
return __Mises(epsilon,2.0/3.0)
|
||||||
|
|
||||||
|
|
||||||
|
def Mises_stress(sigma):
|
||||||
|
"""
|
||||||
|
Return the Mises equivalent of a stress tensor.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
sigma : numpy.array of shape (:,3,3) or (3,3)
|
||||||
|
Symmetric stress tensor of which the von Mises equivalent is computed.
|
||||||
|
|
||||||
|
"""
|
||||||
|
return __Mises(sigma,3.0/2.0)
|
||||||
|
|
||||||
|
|
||||||
|
def PK2(P,F):
|
||||||
|
"""
|
||||||
|
Calculate second Piola-Kirchhoff stress from first Piola-Kirchhoff stress and deformation gradient.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
F : numpy.array of shape (:,3,3) or (3,3)
|
|
||||||
Deformation gradient.
|
|
||||||
P : numpy.array of shape (:,3,3) or (3,3)
|
P : numpy.array of shape (:,3,3) or (3,3)
|
||||||
1. Piola-Kirchhoff stress.
|
1. Piola-Kirchhoff stress.
|
||||||
|
F : numpy.array of shape (:,3,3) or (3,3)
|
||||||
|
Deformation gradient.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if np.shape(F) == np.shape(P) == (3,3):
|
if np.shape(F) == np.shape(P) == (3,3):
|
||||||
S = np.dot(np.linalg.inv(F),P)
|
S = np.dot(np.linalg.inv(F),P)
|
||||||
else:
|
else:
|
||||||
S = np.einsum('ijk,ikl->ijl',np.linalg.inv(F),P)
|
S = np.einsum('ijk,ikl->ijl',np.linalg.inv(F),P)
|
||||||
return S
|
return symmetric(S)
|
||||||
|
|
||||||
|
|
||||||
|
def right_stretch(T):
|
||||||
|
"""
|
||||||
|
Return the right stretch of a tensor.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
T : numpy.array of shape (:,3,3) or (3,3)
|
||||||
|
Tensor of which the right stretch is computed.
|
||||||
|
|
||||||
|
"""
|
||||||
|
return __polar_decomposition(T,'U')[0]
|
||||||
|
|
||||||
|
|
||||||
|
def rotational_part(T):
|
||||||
|
"""
|
||||||
|
Return the rotational part of a tensor.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
T : numpy.array of shape (:,3,3) or (3,3)
|
||||||
|
Tensor of which the rotational part is computed.
|
||||||
|
|
||||||
|
"""
|
||||||
|
return __polar_decomposition(T,'R')[0]
|
||||||
|
|
||||||
|
|
||||||
|
def spherical_part(T,tensor=False):
|
||||||
|
"""
|
||||||
|
Return spherical (hydrostatic) part of a tensor.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
T : numpy.array of shape (:,3,3) or (3,3)
|
||||||
|
Tensor of which the hydrostatic part is computed.
|
||||||
|
tensor : bool, optional
|
||||||
|
Map spherical part onto identity tensor. Default is false
|
||||||
|
|
||||||
|
"""
|
||||||
|
if T.shape == (3,3):
|
||||||
|
sph = np.trace(T)/3.0
|
||||||
|
return sph if not tensor else np.eye(3)*sph
|
||||||
|
else:
|
||||||
|
sph = np.trace(T,axis1=1,axis2=2)/3.0
|
||||||
|
if not tensor:
|
||||||
|
return sph
|
||||||
|
else:
|
||||||
|
return np.einsum('ijk,i->ijk',np.broadcast_to(np.eye(3),(T.shape[0],3,3)),sph)
|
||||||
|
|
||||||
|
|
||||||
def strain_tensor(F,t,m):
|
def strain_tensor(F,t,m):
|
||||||
"""
|
"""
|
||||||
Return strain tensor calculated from deformation gradient.
|
Return strain tensor calculated from deformation gradient.
|
||||||
|
|
||||||
For details refer to https://en.wikipedia.org/wiki/Finite_strain_theory and
|
For details refer to https://en.wikipedia.org/wiki/Finite_strain_theory and
|
||||||
https://de.wikipedia.org/wiki/Verzerrungstensor
|
https://de.wikipedia.org/wiki/Verzerrungstensor
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
F : numpy.array of shape (:,3,3) or (3,3)
|
F : numpy.array of shape (:,3,3) or (3,3)
|
||||||
|
@ -64,209 +221,87 @@ def strain_tensor(F,t,m):
|
||||||
elif t == 'U':
|
elif t == 'U':
|
||||||
C = np.matmul(transpose(F_),F_)
|
C = np.matmul(transpose(F_),F_)
|
||||||
w,n = np.linalg.eigh(C)
|
w,n = np.linalg.eigh(C)
|
||||||
|
|
||||||
if m > 0.0:
|
if m > 0.0:
|
||||||
eps = 1.0/(2.0*abs(m)) * (+ np.matmul(n,np.einsum('ij,ikj->ijk',w**m,n))
|
eps = 1.0/(2.0*abs(m)) * (+ np.matmul(n,np.einsum('ij,ikj->ijk',w**m,n))
|
||||||
- np.broadcast_to(np.eye(3),[F_.shape[0],3,3]))
|
- np.broadcast_to(np.eye(3),[F_.shape[0],3,3]))
|
||||||
elif m < 0.0:
|
elif m < 0.0:
|
||||||
eps = 1.0/(2.0*abs(m)) * (- np.matmul(n,np.einsum('ij,ikj->ijk',w**m,n))
|
eps = 1.0/(2.0*abs(m)) * (- np.matmul(n,np.einsum('ij,ikj->ijk',w**m,n))
|
||||||
+ np.broadcast_to(np.eye(3),[F_.shape[0],3,3]))
|
+ np.broadcast_to(np.eye(3),[F_.shape[0],3,3]))
|
||||||
else:
|
else:
|
||||||
eps = np.matmul(n,np.einsum('ij,ikj->ijk',0.5*np.log(w),n))
|
eps = np.matmul(n,np.einsum('ij,ikj->ijk',0.5*np.log(w),n))
|
||||||
|
|
||||||
return eps.reshape((3,3)) if np.shape(F) == (3,3) else \
|
return eps.reshape((3,3)) if np.shape(F) == (3,3) else \
|
||||||
eps
|
eps
|
||||||
|
|
||||||
|
|
||||||
def deviatoric_part(x):
|
def symmetric(T):
|
||||||
"""
|
|
||||||
Return deviatoric part of a tensor.
|
|
||||||
|
|
||||||
Parameters
|
|
||||||
----------
|
|
||||||
x : numpy.array of shape (:,3,3) or (3,3)
|
|
||||||
Tensor of which the deviatoric part is computed.
|
|
||||||
|
|
||||||
"""
|
|
||||||
return x - np.eye(3)*spherical_part(x) if np.shape(x) == (3,3) else \
|
|
||||||
x - np.einsum('ijk,i->ijk',np.broadcast_to(np.eye(3),[x.shape[0],3,3]),spherical_part(x))
|
|
||||||
|
|
||||||
|
|
||||||
def spherical_part(x,tensor=False):
|
|
||||||
"""
|
|
||||||
Return spherical (hydrostatic) part of a tensor.
|
|
||||||
|
|
||||||
Parameters
|
|
||||||
----------
|
|
||||||
x : numpy.array of shape (:,3,3) or (3,3)
|
|
||||||
Tensor of which the hydrostatic part is computed.
|
|
||||||
tensor : bool, optional
|
|
||||||
Map spherical part onto identity tensor. Default is false
|
|
||||||
|
|
||||||
"""
|
|
||||||
if x.shape == (3,3):
|
|
||||||
sph = np.trace(x)/3.0
|
|
||||||
return sph if not tensor else np.eye(3)*sph
|
|
||||||
else:
|
|
||||||
sph = np.trace(x,axis1=1,axis2=2)/3.0
|
|
||||||
if not tensor:
|
|
||||||
return sph
|
|
||||||
else:
|
|
||||||
return np.einsum('ijk,i->ijk',np.broadcast_to(np.eye(3),(x.shape[0],3,3)),sph)
|
|
||||||
|
|
||||||
|
|
||||||
def Mises_stress(sigma):
|
|
||||||
"""
|
|
||||||
Return the Mises equivalent of a stress tensor.
|
|
||||||
|
|
||||||
Parameters
|
|
||||||
----------
|
|
||||||
sigma : numpy.array of shape (:,3,3) or (3,3)
|
|
||||||
Symmetric stress tensor of which the von Mises equivalent is computed.
|
|
||||||
|
|
||||||
"""
|
|
||||||
s = deviatoric_part(sigma)
|
|
||||||
return np.sqrt(3.0/2.0*(np.sum(s**2.0))) if np.shape(sigma) == (3,3) else \
|
|
||||||
np.sqrt(3.0/2.0*np.einsum('ijk->i',s**2.0))
|
|
||||||
|
|
||||||
|
|
||||||
def Mises_strain(epsilon):
|
|
||||||
"""
|
|
||||||
Return the Mises equivalent of a strain tensor.
|
|
||||||
|
|
||||||
Parameters
|
|
||||||
----------
|
|
||||||
epsilon : numpy.array of shape (:,3,3) or (3,3)
|
|
||||||
Symmetric strain tensor of which the von Mises equivalent is computed.
|
|
||||||
|
|
||||||
"""
|
|
||||||
s = deviatoric_part(epsilon)
|
|
||||||
return np.sqrt(2.0/3.0*(np.sum(s**2.0))) if np.shape(epsilon) == (3,3) else \
|
|
||||||
np.sqrt(2.0/3.0*np.einsum('ijk->i',s**2.0))
|
|
||||||
|
|
||||||
|
|
||||||
def symmetric(x):
|
|
||||||
"""
|
"""
|
||||||
Return the symmetrized tensor.
|
Return the symmetrized tensor.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
x : numpy.array of shape (:,3,3) or (3,3)
|
T : numpy.array of shape (:,3,3) or (3,3)
|
||||||
Tensor of which the symmetrized values are computed.
|
Tensor of which the symmetrized values are computed.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return (x+transpose(x))*0.5
|
return (T+transpose(T))*0.5
|
||||||
|
|
||||||
|
|
||||||
def maximum_shear(x):
|
def transpose(T):
|
||||||
"""
|
|
||||||
Return the maximum shear component of a symmetric tensor.
|
|
||||||
|
|
||||||
Parameters
|
|
||||||
----------
|
|
||||||
x : numpy.array of shape (:,3,3) or (3,3)
|
|
||||||
Symmetric tensor of which the maximum shear is computed.
|
|
||||||
|
|
||||||
"""
|
|
||||||
w = np.linalg.eigvalsh(symmetric(x)) # eigenvalues in ascending order
|
|
||||||
return (w[2] - w[0])*0.5 if np.shape(x) == (3,3) else \
|
|
||||||
(w[:,2] - w[:,0])*0.5
|
|
||||||
|
|
||||||
|
|
||||||
def principal_components(x):
|
|
||||||
"""
|
|
||||||
Return the principal components of a symmetric tensor.
|
|
||||||
|
|
||||||
The principal components (eigenvalues) are sorted in descending order, each repeated according to
|
|
||||||
its multiplicity.
|
|
||||||
|
|
||||||
Parameters
|
|
||||||
----------
|
|
||||||
x : numpy.array of shape (:,3,3) or (3,3)
|
|
||||||
Symmetric tensor of which the principal compontents are computed.
|
|
||||||
|
|
||||||
"""
|
|
||||||
w = np.linalg.eigvalsh(symmetric(x)) # eigenvalues in ascending order
|
|
||||||
return w[::-1] if np.shape(x) == (3,3) else \
|
|
||||||
w[:,::-1]
|
|
||||||
|
|
||||||
|
|
||||||
def transpose(x):
|
|
||||||
"""
|
"""
|
||||||
Return the transpose of a tensor.
|
Return the transpose of a tensor.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
x : numpy.array of shape (:,3,3) or (3,3)
|
T : numpy.array of shape (:,3,3) or (3,3)
|
||||||
Tensor of which the transpose is computed.
|
Tensor of which the transpose is computed.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return x.T if np.shape(x) == (3,3) else \
|
return T.T if np.shape(T) == (3,3) else \
|
||||||
np.transpose(x,(0,2,1))
|
np.transpose(T,(0,2,1))
|
||||||
|
|
||||||
|
|
||||||
def rotational_part(x):
|
def __polar_decomposition(T,requested):
|
||||||
"""
|
|
||||||
Return the rotational part of a tensor.
|
|
||||||
|
|
||||||
Parameters
|
|
||||||
----------
|
|
||||||
x : numpy.array of shape (:,3,3) or (3,3)
|
|
||||||
Tensor of which the rotational part is computed.
|
|
||||||
|
|
||||||
"""
|
|
||||||
return __polar_decomposition(x,'R')[0]
|
|
||||||
|
|
||||||
|
|
||||||
def left_stretch(x):
|
|
||||||
"""
|
|
||||||
Return the left stretch of a tensor.
|
|
||||||
|
|
||||||
Parameters
|
|
||||||
----------
|
|
||||||
x : numpy.array of shape (:,3,3) or (3,3)
|
|
||||||
Tensor of which the left stretch is computed.
|
|
||||||
|
|
||||||
"""
|
|
||||||
return __polar_decomposition(x,'V')[0]
|
|
||||||
|
|
||||||
|
|
||||||
def right_stretch(x):
|
|
||||||
"""
|
|
||||||
Return the right stretch of a tensor.
|
|
||||||
|
|
||||||
Parameters
|
|
||||||
----------
|
|
||||||
x : numpy.array of shape (:,3,3) or (3,3)
|
|
||||||
Tensor of which the right stretch is computed.
|
|
||||||
|
|
||||||
"""
|
|
||||||
return __polar_decomposition(x,'U')[0]
|
|
||||||
|
|
||||||
|
|
||||||
def __polar_decomposition(x,requested):
|
|
||||||
"""
|
"""
|
||||||
Singular value decomposition.
|
Singular value decomposition.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
x : numpy.array of shape (:,3,3) or (3,3)
|
T : numpy.array of shape (:,3,3) or (3,3)
|
||||||
Tensor of which the singular values are computed.
|
Tensor of which the singular values are computed.
|
||||||
requested : iterable of str
|
requested : iterable of str
|
||||||
Requested outputs: ‘R’ for the rotation tensor,
|
Requested outputs: ‘R’ for the rotation tensor,
|
||||||
‘V’ for left stretch tensor and ‘U’ for right stretch tensor.
|
‘V’ for left stretch tensor and ‘U’ for right stretch tensor.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
u, s, vh = np.linalg.svd(x)
|
u, s, vh = np.linalg.svd(T)
|
||||||
R = np.dot(u,vh) if np.shape(x) == (3,3) else \
|
R = np.dot(u,vh) if np.shape(T) == (3,3) else \
|
||||||
np.einsum('ijk,ikl->ijl',u,vh)
|
np.einsum('ijk,ikl->ijl',u,vh)
|
||||||
|
|
||||||
output = []
|
output = []
|
||||||
if 'R' in requested:
|
if 'R' in requested:
|
||||||
output.append(R)
|
output.append(R)
|
||||||
if 'V' in requested:
|
if 'V' in requested:
|
||||||
output.append(np.dot(x,R.T) if np.shape(x) == (3,3) else np.einsum('ijk,ilk->ijl',x,R))
|
output.append(np.dot(T,R.T) if np.shape(T) == (3,3) else np.einsum('ijk,ilk->ijl',T,R))
|
||||||
if 'U' in requested:
|
if 'U' in requested:
|
||||||
output.append(np.dot(R.T,x) if np.shape(x) == (3,3) else np.einsum('ikj,ikl->ijl',R,x))
|
output.append(np.dot(R.T,T) if np.shape(T) == (3,3) else np.einsum('ikj,ikl->ijl',R,T))
|
||||||
|
|
||||||
return tuple(output)
|
return tuple(output)
|
||||||
|
|
||||||
|
|
||||||
|
def __Mises(T_sym,s):
|
||||||
|
"""
|
||||||
|
Base equation for Mises equivalent of a stres or strain tensor.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
T_sym : numpy.array of shape (:,3,3) or (3,3)
|
||||||
|
Symmetric tensor of which the von Mises equivalent is computed.
|
||||||
|
s : float
|
||||||
|
Scaling factor (2/3 for strain, 3/2 for stress).
|
||||||
|
|
||||||
|
"""
|
||||||
|
d = deviatoric_part(T_sym)
|
||||||
|
return np.sqrt(s*(np.sum(d**2.0))) if np.shape(T_sym) == (3,3) else \
|
||||||
|
np.sqrt(s*np.einsum('ijk->i',d**2.0))
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -32,7 +32,7 @@ class Table():
|
||||||
"""Label data individually, e.g. v v v ==> 1_v 2_v 3_v."""
|
"""Label data individually, e.g. v v v ==> 1_v 2_v 3_v."""
|
||||||
labels = []
|
labels = []
|
||||||
for label,shape in self.shapes.items():
|
for label,shape in self.shapes.items():
|
||||||
size = np.prod(shape)
|
size = int(np.prod(shape))
|
||||||
labels += ['{}{}'.format('' if size == 1 else '{}_'.format(i+1),label) for i in range(size)]
|
labels += ['{}{}'.format('' if size == 1 else '{}_'.format(i+1),label) for i in range(size)]
|
||||||
self.data.columns = labels
|
self.data.columns = labels
|
||||||
|
|
||||||
|
@ -41,14 +41,14 @@ class Table():
|
||||||
"""Label data condensed, e.g. 1_v 2_v 3_v ==> v v v."""
|
"""Label data condensed, e.g. 1_v 2_v 3_v ==> v v v."""
|
||||||
labels = []
|
labels = []
|
||||||
for label,shape in self.shapes.items():
|
for label,shape in self.shapes.items():
|
||||||
labels += [label] * np.prod(shape)
|
labels += [label] * int(np.prod(shape))
|
||||||
self.data.columns = labels
|
self.data.columns = labels
|
||||||
|
|
||||||
|
|
||||||
def __add_comment(self,label,shape,info):
|
def __add_comment(self,label,shape,info):
|
||||||
if info is not None:
|
if info is not None:
|
||||||
self.comments.append('{}{}: {}'.format(label,
|
self.comments.append('{}{}: {}'.format(label,
|
||||||
' '+str(shape) if np.prod(shape) > 1 else '',
|
' '+str(shape) if np.prod(shape,dtype=int) > 1 else '',
|
||||||
info))
|
info))
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -3,14 +3,16 @@ import time
|
||||||
import os
|
import os
|
||||||
import subprocess
|
import subprocess
|
||||||
import shlex
|
import shlex
|
||||||
|
from fractions import Fraction
|
||||||
|
from functools import reduce
|
||||||
from optparse import Option
|
from optparse import Option
|
||||||
from queue import Queue
|
|
||||||
from threading import Thread
|
import numpy as np
|
||||||
|
|
||||||
class bcolors:
|
class bcolors:
|
||||||
"""
|
"""
|
||||||
ASCII Colors (Blender code).
|
ASCII Colors (Blender code).
|
||||||
|
|
||||||
https://svn.blender.org/svnroot/bf-blender/trunk/blender/build_files/scons/tools/bcolors.py
|
https://svn.blender.org/svnroot/bf-blender/trunk/blender/build_files/scons/tools/bcolors.py
|
||||||
http://stackoverflow.com/questions/287871/print-in-terminal-with-colors-using-python
|
http://stackoverflow.com/questions/287871/print-in-terminal-with-colors-using-python
|
||||||
"""
|
"""
|
||||||
|
@ -104,6 +106,7 @@ def strikeout(what):
|
||||||
"""Formats string as strikeout."""
|
"""Formats string as strikeout."""
|
||||||
return bcolors.CROSSOUT+srepr(what)+bcolors.ENDC
|
return bcolors.CROSSOUT+srepr(what)+bcolors.ENDC
|
||||||
|
|
||||||
|
|
||||||
def execute(cmd,
|
def execute(cmd,
|
||||||
streamIn = None,
|
streamIn = None,
|
||||||
wd = './',
|
wd = './',
|
||||||
|
@ -207,6 +210,24 @@ def progressBar(iteration, total, prefix='', bar_length=50):
|
||||||
sys.stderr.flush()
|
sys.stderr.flush()
|
||||||
|
|
||||||
|
|
||||||
|
def scale_to_coprime(v):
|
||||||
|
"""Scale vector to co-prime (relatively prime) integers."""
|
||||||
|
MAX_DENOMINATOR = 1000
|
||||||
|
|
||||||
|
def get_square_denominator(x):
|
||||||
|
"""Denominator of the square of a number."""
|
||||||
|
return Fraction(x ** 2).limit_denominator(MAX_DENOMINATOR).denominator
|
||||||
|
|
||||||
|
def lcm(a, b):
|
||||||
|
"""Least common multiple."""
|
||||||
|
return a * b // np.gcd(a, b)
|
||||||
|
|
||||||
|
denominators = [int(get_square_denominator(i)) for i in v]
|
||||||
|
s = reduce(lcm, denominators) ** 0.5
|
||||||
|
m = (np.array(v)*s).astype(np.int)
|
||||||
|
return m//reduce(np.gcd,m)
|
||||||
|
|
||||||
|
|
||||||
class return_message():
|
class return_message():
|
||||||
"""Object with formatted return message."""
|
"""Object with formatted return message."""
|
||||||
|
|
||||||
|
@ -226,56 +247,3 @@ class return_message():
|
||||||
"""Return message suitable for interactive shells."""
|
"""Return message suitable for interactive shells."""
|
||||||
return srepr(self.message)
|
return srepr(self.message)
|
||||||
|
|
||||||
|
|
||||||
class ThreadPool:
|
|
||||||
"""Pool of threads consuming tasks from a queue."""
|
|
||||||
|
|
||||||
class Worker(Thread):
|
|
||||||
"""Thread executing tasks from a given tasks queue."""
|
|
||||||
|
|
||||||
def __init__(self, tasks):
|
|
||||||
"""Worker for tasks."""
|
|
||||||
Thread.__init__(self)
|
|
||||||
self.tasks = tasks
|
|
||||||
self.daemon = True
|
|
||||||
self.start()
|
|
||||||
|
|
||||||
def run(self):
|
|
||||||
while True:
|
|
||||||
func, args, kargs = self.tasks.get()
|
|
||||||
try:
|
|
||||||
func(*args, **kargs)
|
|
||||||
except Exception as e:
|
|
||||||
# An exception happened in this thread
|
|
||||||
print(e)
|
|
||||||
finally:
|
|
||||||
# Mark this task as done, whether an exception happened or not
|
|
||||||
self.tasks.task_done()
|
|
||||||
|
|
||||||
|
|
||||||
def __init__(self, num_threads):
|
|
||||||
"""
|
|
||||||
Thread pool.
|
|
||||||
|
|
||||||
Parameters
|
|
||||||
----------
|
|
||||||
num_threads : int
|
|
||||||
number of threads
|
|
||||||
|
|
||||||
"""
|
|
||||||
self.tasks = Queue(num_threads)
|
|
||||||
for _ in range(num_threads):
|
|
||||||
self.Worker(self.tasks)
|
|
||||||
|
|
||||||
def add_task(self, func, *args, **kargs):
|
|
||||||
"""Add a task to the queue."""
|
|
||||||
self.tasks.put((func, args, kargs))
|
|
||||||
|
|
||||||
def map(self, func, args_list):
|
|
||||||
"""Add a list of tasks to the queue."""
|
|
||||||
for args in args_list:
|
|
||||||
self.add_task(func, args)
|
|
||||||
|
|
||||||
def wait_completion(self):
|
|
||||||
"""Wait for completion of all the tasks in the queue."""
|
|
||||||
self.tasks.join()
|
|
||||||
|
|
|
@ -1,90 +0,0 @@
|
||||||
import shutil
|
|
||||||
import os
|
|
||||||
|
|
||||||
import pytest
|
|
||||||
import numpy as np
|
|
||||||
|
|
||||||
from damask import DADF5
|
|
||||||
from damask import mechanics
|
|
||||||
|
|
||||||
@pytest.fixture
|
|
||||||
def default(tmp_path,reference_dir):
|
|
||||||
"""Small DADF5 file in temp location for modification."""
|
|
||||||
fname = '12grains6x7x8_tensionY.hdf5'
|
|
||||||
shutil.copy(os.path.join(reference_dir,fname),tmp_path)
|
|
||||||
f = DADF5(os.path.join(tmp_path,fname))
|
|
||||||
f.set_by_time(20.0,20.0)
|
|
||||||
return f
|
|
||||||
|
|
||||||
@pytest.fixture
|
|
||||||
def reference_dir(reference_dir_base):
|
|
||||||
"""Directory containing reference results."""
|
|
||||||
return os.path.join(reference_dir_base,'DADF5')
|
|
||||||
|
|
||||||
|
|
||||||
class TestDADF5:
|
|
||||||
|
|
||||||
def test_time_increments(self,default):
|
|
||||||
shape = default.read_dataset(default.get_dataset_location('F'),0).shape
|
|
||||||
default.set_by_time(0.0,20.0)
|
|
||||||
for i in default.iter_visible('increments'):
|
|
||||||
assert shape == default.read_dataset(default.get_dataset_location('F'),0).shape
|
|
||||||
|
|
||||||
|
|
||||||
def test_add_absolute(self,default):
|
|
||||||
default.add_absolute('Fe')
|
|
||||||
loc = {'Fe': default.get_dataset_location('Fe'),
|
|
||||||
'|Fe|': default.get_dataset_location('|Fe|')}
|
|
||||||
in_memory = np.abs(default.read_dataset(loc['Fe'],0))
|
|
||||||
in_file = default.read_dataset(loc['|Fe|'],0)
|
|
||||||
assert np.allclose(in_memory,in_file)
|
|
||||||
|
|
||||||
def test_add_calculation(self,default):
|
|
||||||
default.add_calculation('2.0*np.abs(#F#)-1.0','x','-','test')
|
|
||||||
loc = {'F': default.get_dataset_location('F'),
|
|
||||||
'x': default.get_dataset_location('x')}
|
|
||||||
in_memory = 2.0*np.abs(default.read_dataset(loc['F'],0))-1.0
|
|
||||||
in_file = default.read_dataset(loc['x'],0)
|
|
||||||
assert np.allclose(in_memory,in_file)
|
|
||||||
|
|
||||||
def test_add_Cauchy(self,default):
|
|
||||||
default.add_Cauchy('P','F')
|
|
||||||
loc = {'F': default.get_dataset_location('F'),
|
|
||||||
'P': default.get_dataset_location('P'),
|
|
||||||
'sigma':default.get_dataset_location('sigma')}
|
|
||||||
in_memory = mechanics.Cauchy(default.read_dataset(loc['F'],0),
|
|
||||||
default.read_dataset(loc['P'],0))
|
|
||||||
in_file = default.read_dataset(loc['sigma'],0)
|
|
||||||
assert np.allclose(in_memory,in_file)
|
|
||||||
|
|
||||||
def test_add_determinant(self,default):
|
|
||||||
default.add_determinant('P')
|
|
||||||
loc = {'P': default.get_dataset_location('P'),
|
|
||||||
'det(P)':default.get_dataset_location('det(P)')}
|
|
||||||
in_memory = np.linalg.det(default.read_dataset(loc['P'],0)).reshape((-1,1))
|
|
||||||
in_file = default.read_dataset(loc['det(P)'],0)
|
|
||||||
assert np.allclose(in_memory,in_file)
|
|
||||||
|
|
||||||
def test_add_deviator(self,default):
|
|
||||||
default.add_deviator('P')
|
|
||||||
loc = {'P' :default.get_dataset_location('P'),
|
|
||||||
's_P':default.get_dataset_location('s_P')}
|
|
||||||
in_memory = mechanics.deviatoric_part(default.read_dataset(loc['P'],0))
|
|
||||||
in_file = default.read_dataset(loc['s_P'],0)
|
|
||||||
assert np.allclose(in_memory,in_file)
|
|
||||||
|
|
||||||
def test_add_norm(self,default):
|
|
||||||
default.add_norm('F',1)
|
|
||||||
loc = {'F': default.get_dataset_location('F'),
|
|
||||||
'|F|_1':default.get_dataset_location('|F|_1')}
|
|
||||||
in_memory = np.linalg.norm(default.read_dataset(loc['F'],0),ord=1,axis=(1,2),keepdims=True)
|
|
||||||
in_file = default.read_dataset(loc['|F|_1'],0)
|
|
||||||
assert np.allclose(in_memory,in_file)
|
|
||||||
|
|
||||||
def test_add_spherical(self,default):
|
|
||||||
default.add_spherical('P')
|
|
||||||
loc = {'P': default.get_dataset_location('P'),
|
|
||||||
'p_P': default.get_dataset_location('p_P')}
|
|
||||||
in_memory = mechanics.spherical_part(default.read_dataset(loc['P'],0)).reshape(-1,1)
|
|
||||||
in_file = default.read_dataset(loc['p_P'],0)
|
|
||||||
assert np.allclose(in_memory,in_file)
|
|
|
@ -0,0 +1,183 @@
|
||||||
|
import shutil
|
||||||
|
import os
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
from damask import Result
|
||||||
|
from damask import mechanics
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def default(tmp_path,reference_dir):
|
||||||
|
"""Small Result file in temp location for modification."""
|
||||||
|
fname = '12grains6x7x8_tensionY.hdf5'
|
||||||
|
shutil.copy(os.path.join(reference_dir,fname),tmp_path)
|
||||||
|
f = Result(os.path.join(tmp_path,fname))
|
||||||
|
f.set_by_time(20.0,20.0)
|
||||||
|
return f
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def reference_dir(reference_dir_base):
|
||||||
|
"""Directory containing reference results."""
|
||||||
|
return os.path.join(reference_dir_base,'Result')
|
||||||
|
|
||||||
|
|
||||||
|
class TestResult:
|
||||||
|
|
||||||
|
def test_time_increments(self,default):
|
||||||
|
shape = default.read_dataset(default.get_dataset_location('F'),0).shape
|
||||||
|
default.set_by_time(0.0,20.0)
|
||||||
|
for i in default.iter_visible('increments'):
|
||||||
|
assert shape == default.read_dataset(default.get_dataset_location('F'),0).shape
|
||||||
|
|
||||||
|
|
||||||
|
def test_add_absolute(self,default):
|
||||||
|
default.add_absolute('Fe')
|
||||||
|
loc = {'Fe': default.get_dataset_location('Fe'),
|
||||||
|
'|Fe|': default.get_dataset_location('|Fe|')}
|
||||||
|
in_memory = np.abs(default.read_dataset(loc['Fe'],0))
|
||||||
|
in_file = default.read_dataset(loc['|Fe|'],0)
|
||||||
|
assert np.allclose(in_memory,in_file)
|
||||||
|
|
||||||
|
def test_add_calculation(self,default):
|
||||||
|
default.add_calculation('x','2.0*np.abs(#F#)-1.0','-','my notes')
|
||||||
|
loc = {'F': default.get_dataset_location('F'),
|
||||||
|
'x': default.get_dataset_location('x')}
|
||||||
|
in_memory = 2.0*np.abs(default.read_dataset(loc['F'],0))-1.0
|
||||||
|
in_file = default.read_dataset(loc['x'],0)
|
||||||
|
assert np.allclose(in_memory,in_file)
|
||||||
|
|
||||||
|
def test_add_Cauchy(self,default):
|
||||||
|
default.add_Cauchy('P','F')
|
||||||
|
loc = {'F': default.get_dataset_location('F'),
|
||||||
|
'P': default.get_dataset_location('P'),
|
||||||
|
'sigma':default.get_dataset_location('sigma')}
|
||||||
|
in_memory = mechanics.Cauchy(default.read_dataset(loc['P'],0),
|
||||||
|
default.read_dataset(loc['F'],0))
|
||||||
|
in_file = default.read_dataset(loc['sigma'],0)
|
||||||
|
assert np.allclose(in_memory,in_file)
|
||||||
|
|
||||||
|
def test_add_determinant(self,default):
|
||||||
|
default.add_determinant('P')
|
||||||
|
loc = {'P': default.get_dataset_location('P'),
|
||||||
|
'det(P)':default.get_dataset_location('det(P)')}
|
||||||
|
in_memory = np.linalg.det(default.read_dataset(loc['P'],0)).reshape((-1,1))
|
||||||
|
in_file = default.read_dataset(loc['det(P)'],0)
|
||||||
|
assert np.allclose(in_memory,in_file)
|
||||||
|
|
||||||
|
def test_add_deviator(self,default):
|
||||||
|
default.add_deviator('P')
|
||||||
|
loc = {'P' :default.get_dataset_location('P'),
|
||||||
|
's_P':default.get_dataset_location('s_P')}
|
||||||
|
in_memory = mechanics.deviatoric_part(default.read_dataset(loc['P'],0))
|
||||||
|
in_file = default.read_dataset(loc['s_P'],0)
|
||||||
|
assert np.allclose(in_memory,in_file)
|
||||||
|
|
||||||
|
def test_add_eigenvalues(self,default):
|
||||||
|
default.add_Cauchy('P','F')
|
||||||
|
default.add_eigenvalues('sigma')
|
||||||
|
loc = {'sigma' :default.get_dataset_location('sigma'),
|
||||||
|
'lambda(sigma)':default.get_dataset_location('lambda(sigma)')}
|
||||||
|
in_memory = mechanics.eigenvalues(default.read_dataset(loc['sigma'],0))
|
||||||
|
in_file = default.read_dataset(loc['lambda(sigma)'],0)
|
||||||
|
assert np.allclose(in_memory,in_file)
|
||||||
|
|
||||||
|
def test_add_eigenvectors(self,default):
|
||||||
|
default.add_Cauchy('P','F')
|
||||||
|
default.add_eigenvectors('sigma')
|
||||||
|
loc = {'sigma' :default.get_dataset_location('sigma'),
|
||||||
|
'v(sigma)':default.get_dataset_location('v(sigma)')}
|
||||||
|
in_memory = mechanics.eigenvectors(default.read_dataset(loc['sigma'],0))
|
||||||
|
in_file = default.read_dataset(loc['v(sigma)'],0)
|
||||||
|
assert np.allclose(in_memory,in_file)
|
||||||
|
|
||||||
|
def test_add_maximum_shear(self,default):
|
||||||
|
default.add_Cauchy('P','F')
|
||||||
|
default.add_maximum_shear('sigma')
|
||||||
|
loc = {'sigma' :default.get_dataset_location('sigma'),
|
||||||
|
'max_shear(sigma)':default.get_dataset_location('max_shear(sigma)')}
|
||||||
|
in_memory = mechanics.maximum_shear(default.read_dataset(loc['sigma'],0)).reshape(-1,1)
|
||||||
|
in_file = default.read_dataset(loc['max_shear(sigma)'],0)
|
||||||
|
assert np.allclose(in_memory,in_file)
|
||||||
|
|
||||||
|
def test_add_Mises_strain(self,default):
|
||||||
|
t = ['V','U'][np.random.randint(0,2)]
|
||||||
|
m = np.random.random()*2.0 - 1.0
|
||||||
|
default.add_strain_tensor('F',t,m)
|
||||||
|
label = 'epsilon_{}^{}(F)'.format(t,m)
|
||||||
|
default.add_Mises(label)
|
||||||
|
loc = {label :default.get_dataset_location(label),
|
||||||
|
label+'_vM':default.get_dataset_location(label+'_vM')}
|
||||||
|
in_memory = mechanics.Mises_strain(default.read_dataset(loc[label],0)).reshape(-1,1)
|
||||||
|
in_file = default.read_dataset(loc[label+'_vM'],0)
|
||||||
|
assert np.allclose(in_memory,in_file)
|
||||||
|
|
||||||
|
def test_add_Mises_stress(self,default):
|
||||||
|
default.add_Cauchy('P','F')
|
||||||
|
default.add_Mises('sigma')
|
||||||
|
loc = {'sigma' :default.get_dataset_location('sigma'),
|
||||||
|
'sigma_vM':default.get_dataset_location('sigma_vM')}
|
||||||
|
in_memory = mechanics.Mises_stress(default.read_dataset(loc['sigma'],0)).reshape(-1,1)
|
||||||
|
in_file = default.read_dataset(loc['sigma_vM'],0)
|
||||||
|
assert np.allclose(in_memory,in_file)
|
||||||
|
|
||||||
|
def test_add_norm(self,default):
|
||||||
|
default.add_norm('F',1)
|
||||||
|
loc = {'F': default.get_dataset_location('F'),
|
||||||
|
'|F|_1':default.get_dataset_location('|F|_1')}
|
||||||
|
in_memory = np.linalg.norm(default.read_dataset(loc['F'],0),ord=1,axis=(1,2),keepdims=True)
|
||||||
|
in_file = default.read_dataset(loc['|F|_1'],0)
|
||||||
|
assert np.allclose(in_memory,in_file)
|
||||||
|
|
||||||
|
def test_add_PK2(self,default):
|
||||||
|
default.add_PK2('P','F')
|
||||||
|
loc = {'F':default.get_dataset_location('F'),
|
||||||
|
'P':default.get_dataset_location('P'),
|
||||||
|
'S':default.get_dataset_location('S')}
|
||||||
|
in_memory = mechanics.PK2(default.read_dataset(loc['P'],0),
|
||||||
|
default.read_dataset(loc['F'],0))
|
||||||
|
in_file = default.read_dataset(loc['S'],0)
|
||||||
|
assert np.allclose(in_memory,in_file)
|
||||||
|
|
||||||
|
def test_add_rotational_part(self,default):
|
||||||
|
default.add_rotational_part('F')
|
||||||
|
loc = {'F': default.get_dataset_location('F'),
|
||||||
|
'R(F)': default.get_dataset_location('R(F)')}
|
||||||
|
in_memory = mechanics.rotational_part(default.read_dataset(loc['F'],0))
|
||||||
|
in_file = default.read_dataset(loc['R(F)'],0)
|
||||||
|
assert np.allclose(in_memory,in_file)
|
||||||
|
|
||||||
|
def test_add_spherical(self,default):
|
||||||
|
default.add_spherical('P')
|
||||||
|
loc = {'P': default.get_dataset_location('P'),
|
||||||
|
'p_P': default.get_dataset_location('p_P')}
|
||||||
|
in_memory = mechanics.spherical_part(default.read_dataset(loc['P'],0)).reshape(-1,1)
|
||||||
|
in_file = default.read_dataset(loc['p_P'],0)
|
||||||
|
assert np.allclose(in_memory,in_file)
|
||||||
|
|
||||||
|
def test_add_strain(self,default):
|
||||||
|
t = ['V','U'][np.random.randint(0,2)]
|
||||||
|
m = np.random.random()*2.0 - 1.0
|
||||||
|
default.add_strain_tensor('F',t,m)
|
||||||
|
label = 'epsilon_{}^{}(F)'.format(t,m)
|
||||||
|
loc = {'F': default.get_dataset_location('F'),
|
||||||
|
label: default.get_dataset_location(label)}
|
||||||
|
in_memory = mechanics.strain_tensor(default.read_dataset(loc['F'],0),t,m)
|
||||||
|
in_file = default.read_dataset(loc[label],0)
|
||||||
|
assert np.allclose(in_memory,in_file)
|
||||||
|
|
||||||
|
def test_add_stretch_right(self,default):
|
||||||
|
default.add_stretch_tensor('F','U')
|
||||||
|
loc = {'F': default.get_dataset_location('F'),
|
||||||
|
'U(F)': default.get_dataset_location('U(F)')}
|
||||||
|
in_memory = mechanics.right_stretch(default.read_dataset(loc['F'],0))
|
||||||
|
in_file = default.read_dataset(loc['U(F)'],0)
|
||||||
|
assert np.allclose(in_memory,in_file)
|
||||||
|
|
||||||
|
def test_add_stretch_left(self,default):
|
||||||
|
default.add_stretch_tensor('F','V')
|
||||||
|
loc = {'F': default.get_dataset_location('F'),
|
||||||
|
'V(F)': default.get_dataset_location('V(F)')}
|
||||||
|
in_memory = mechanics.left_stretch(default.read_dataset(loc['F'],0))
|
||||||
|
in_file = default.read_dataset(loc['V(F)'],0)
|
||||||
|
assert np.allclose(in_memory,in_file)
|
|
@ -2,187 +2,224 @@ import numpy as np
|
||||||
from damask import mechanics
|
from damask import mechanics
|
||||||
|
|
||||||
class TestMechanics:
|
class TestMechanics:
|
||||||
|
|
||||||
n = 1000
|
n = 1000
|
||||||
c = np.random.randint(n)
|
c = np.random.randint(n)
|
||||||
|
|
||||||
|
|
||||||
def test_vectorize_Cauchy(self):
|
def test_vectorize_Cauchy(self):
|
||||||
P = np.random.random((self.n,3,3))
|
P = np.random.random((self.n,3,3))
|
||||||
F = np.random.random((self.n,3,3))
|
F = np.random.random((self.n,3,3))
|
||||||
assert np.allclose(mechanics.Cauchy(F,P)[self.c],
|
assert np.allclose(mechanics.Cauchy(P,F)[self.c],
|
||||||
mechanics.Cauchy(F[self.c],P[self.c]))
|
mechanics.Cauchy(P[self.c],F[self.c]))
|
||||||
|
|
||||||
|
|
||||||
def test_vectorize_strain_tensor(self):
|
|
||||||
F = np.random.random((self.n,3,3))
|
|
||||||
t = ['V','U'][np.random.randint(0,2)]
|
|
||||||
m = np.random.random()*10. -5.0
|
|
||||||
assert np.allclose(mechanics.strain_tensor(F,t,m)[self.c],
|
|
||||||
mechanics.strain_tensor(F[self.c],t,m))
|
|
||||||
|
|
||||||
|
|
||||||
def test_vectorize_deviatoric_part(self):
|
def test_vectorize_deviatoric_part(self):
|
||||||
x = np.random.random((self.n,3,3))
|
x = np.random.random((self.n,3,3))
|
||||||
assert np.allclose(mechanics.deviatoric_part(x)[self.c],
|
assert np.allclose(mechanics.deviatoric_part(x)[self.c],
|
||||||
mechanics.deviatoric_part(x[self.c]))
|
mechanics.deviatoric_part(x[self.c]))
|
||||||
|
|
||||||
|
def test_vectorize_eigenvalues(self):
|
||||||
|
x = np.random.random((self.n,3,3))
|
||||||
|
assert np.allclose(mechanics.eigenvalues(x)[self.c],
|
||||||
|
mechanics.eigenvalues(x[self.c]))
|
||||||
|
|
||||||
def test_vectorize_spherical_part(self):
|
def test_vectorize_eigenvectors(self):
|
||||||
x = np.random.random((self.n,3,3))
|
x = np.random.random((self.n,3,3))
|
||||||
assert np.allclose(mechanics.spherical_part(x,True)[self.c],
|
assert np.allclose(mechanics.eigenvectors(x)[self.c],
|
||||||
mechanics.spherical_part(x[self.c],True))
|
mechanics.eigenvectors(x[self.c]))
|
||||||
|
|
||||||
|
|
||||||
def test_vectorize_Mises_stress(self):
|
|
||||||
sigma = np.random.random((self.n,3,3))
|
|
||||||
assert np.allclose(mechanics.Mises_stress(sigma)[self.c],
|
|
||||||
mechanics.Mises_stress(sigma[self.c]))
|
|
||||||
|
|
||||||
|
|
||||||
def test_vectorize_Mises_strain(self):
|
|
||||||
epsilon = np.random.random((self.n,3,3))
|
|
||||||
assert np.allclose(mechanics.Mises_strain(epsilon)[self.c],
|
|
||||||
mechanics.Mises_strain(epsilon[self.c]))
|
|
||||||
|
|
||||||
|
|
||||||
def test_vectorize_symmetric(self):
|
|
||||||
x = np.random.random((self.n,3,3))
|
|
||||||
assert np.allclose(mechanics.symmetric(x)[self.c],
|
|
||||||
mechanics.symmetric(x[self.c]))
|
|
||||||
|
|
||||||
|
|
||||||
def test_vectorize_maximum_shear(self):
|
|
||||||
x = np.random.random((self.n,3,3))
|
|
||||||
assert np.allclose(mechanics.maximum_shear(x)[self.c],
|
|
||||||
mechanics.maximum_shear(x[self.c]))
|
|
||||||
|
|
||||||
|
|
||||||
def test_vectorize_principal_components(self):
|
|
||||||
x = np.random.random((self.n,3,3))
|
|
||||||
assert np.allclose(mechanics.principal_components(x)[self.c],
|
|
||||||
mechanics.principal_components(x[self.c]))
|
|
||||||
|
|
||||||
|
|
||||||
def test_vectorize_transpose(self):
|
|
||||||
x = np.random.random((self.n,3,3))
|
|
||||||
assert np.allclose(mechanics.transpose(x)[self.c],
|
|
||||||
mechanics.transpose(x[self.c]))
|
|
||||||
|
|
||||||
|
|
||||||
def test_vectorize_rotational_part(self):
|
|
||||||
x = np.random.random((self.n,3,3))
|
|
||||||
assert np.allclose(mechanics.rotational_part(x)[self.c],
|
|
||||||
mechanics.rotational_part(x[self.c]))
|
|
||||||
|
|
||||||
|
|
||||||
def test_vectorize_left_stretch(self):
|
def test_vectorize_left_stretch(self):
|
||||||
x = np.random.random((self.n,3,3))
|
x = np.random.random((self.n,3,3))
|
||||||
assert np.allclose(mechanics.left_stretch(x)[self.c],
|
assert np.allclose(mechanics.left_stretch(x)[self.c],
|
||||||
mechanics.left_stretch(x[self.c]))
|
mechanics.left_stretch(x[self.c]))
|
||||||
|
|
||||||
|
def test_vectorize_maximum_shear(self):
|
||||||
|
x = np.random.random((self.n,3,3))
|
||||||
|
assert np.allclose(mechanics.maximum_shear(x)[self.c],
|
||||||
|
mechanics.maximum_shear(x[self.c]))
|
||||||
|
|
||||||
|
def test_vectorize_Mises_strain(self):
|
||||||
|
epsilon = np.random.random((self.n,3,3))
|
||||||
|
assert np.allclose(mechanics.Mises_strain(epsilon)[self.c],
|
||||||
|
mechanics.Mises_strain(epsilon[self.c]))
|
||||||
|
|
||||||
|
def test_vectorize_Mises_stress(self):
|
||||||
|
sigma = np.random.random((self.n,3,3))
|
||||||
|
assert np.allclose(mechanics.Mises_stress(sigma)[self.c],
|
||||||
|
mechanics.Mises_stress(sigma[self.c]))
|
||||||
|
|
||||||
|
def test_vectorize_PK2(self):
|
||||||
|
F = np.random.random((self.n,3,3))
|
||||||
|
P = np.random.random((self.n,3,3))
|
||||||
|
assert np.allclose(mechanics.PK2(P,F)[self.c],
|
||||||
|
mechanics.PK2(P[self.c],F[self.c]))
|
||||||
|
|
||||||
def test_vectorize_right_stretch(self):
|
def test_vectorize_right_stretch(self):
|
||||||
x = np.random.random((self.n,3,3))
|
x = np.random.random((self.n,3,3))
|
||||||
assert np.allclose(mechanics.right_stretch(x)[self.c],
|
assert np.allclose(mechanics.right_stretch(x)[self.c],
|
||||||
mechanics.right_stretch(x[self.c]))
|
mechanics.right_stretch(x[self.c]))
|
||||||
|
|
||||||
|
def test_vectorize_rotational_part(self):
|
||||||
|
x = np.random.random((self.n,3,3))
|
||||||
|
assert np.allclose(mechanics.rotational_part(x)[self.c],
|
||||||
|
mechanics.rotational_part(x[self.c]))
|
||||||
|
|
||||||
|
def test_vectorize_spherical_part(self):
|
||||||
|
x = np.random.random((self.n,3,3))
|
||||||
|
assert np.allclose(mechanics.spherical_part(x,True)[self.c],
|
||||||
|
mechanics.spherical_part(x[self.c],True))
|
||||||
|
|
||||||
|
def test_vectorize_strain_tensor(self):
|
||||||
|
F = np.random.random((self.n,3,3))
|
||||||
|
t = ['V','U'][np.random.randint(0,2)]
|
||||||
|
m = np.random.random()*10. -5.0
|
||||||
|
assert np.allclose(mechanics.strain_tensor(F,t,m)[self.c],
|
||||||
|
mechanics.strain_tensor(F[self.c],t,m))
|
||||||
|
|
||||||
|
def test_vectorize_symmetric(self):
|
||||||
|
x = np.random.random((self.n,3,3))
|
||||||
|
assert np.allclose(mechanics.symmetric(x)[self.c],
|
||||||
|
mechanics.symmetric(x[self.c]))
|
||||||
|
|
||||||
|
def test_vectorize_transpose(self):
|
||||||
|
x = np.random.random((self.n,3,3))
|
||||||
|
assert np.allclose(mechanics.transpose(x)[self.c],
|
||||||
|
mechanics.transpose(x[self.c]))
|
||||||
|
|
||||||
|
|
||||||
def test_Cauchy(self):
|
def test_Cauchy(self):
|
||||||
"""Ensure Cauchy stress is symmetrized 1. Piola-Kirchhoff stress for no deformation."""
|
"""Ensure Cauchy stress is symmetrized 1. Piola-Kirchhoff stress for no deformation."""
|
||||||
P = np.random.random((self.n,3,3))
|
P = np.random.random((self.n,3,3))
|
||||||
assert np.allclose(mechanics.Cauchy(np.broadcast_to(np.eye(3),(self.n,3,3)),P),
|
assert np.allclose(mechanics.Cauchy(P,np.broadcast_to(np.eye(3),(self.n,3,3))),
|
||||||
mechanics.symmetric(P))
|
mechanics.symmetric(P))
|
||||||
|
|
||||||
|
|
||||||
def test_polar_decomposition(self):
|
def test_polar_decomposition(self):
|
||||||
"""F = RU = VR."""
|
"""F = RU = VR."""
|
||||||
F = np.broadcast_to(np.eye(3),[self.n,3,3])*np.random.random((self.n,3,3))
|
F = np.broadcast_to(np.eye(3),[self.n,3,3])*np.random.random((self.n,3,3))
|
||||||
R = mechanics.rotational_part(F)
|
R = mechanics.rotational_part(F)
|
||||||
V = mechanics.left_stretch(F)
|
V = mechanics.left_stretch(F)
|
||||||
U = mechanics.right_stretch(F)
|
U = mechanics.right_stretch(F)
|
||||||
assert np.allclose(np.matmul(R,U),
|
assert np.allclose(np.matmul(R,U),
|
||||||
np.matmul(V,R))
|
np.matmul(V,R))
|
||||||
|
|
||||||
|
|
||||||
|
def test_PK2(self):
|
||||||
|
"""Ensure 2. Piola-Kirchhoff stress is symmetrized 1. Piola-Kirchhoff stress for no deformation."""
|
||||||
|
P = np.random.random((self.n,3,3))
|
||||||
|
assert np.allclose(mechanics.PK2(P,np.broadcast_to(np.eye(3),(self.n,3,3))),
|
||||||
|
mechanics.symmetric(P))
|
||||||
|
|
||||||
|
|
||||||
def test_strain_tensor_no_rotation(self):
|
def test_strain_tensor_no_rotation(self):
|
||||||
"""Ensure that left and right stretch give same results for no rotation."""
|
"""Ensure that left and right stretch give same results for no rotation."""
|
||||||
F = np.broadcast_to(np.eye(3),[self.n,3,3])*np.random.random((self.n,3,3))
|
F = np.broadcast_to(np.eye(3),[self.n,3,3])*np.random.random((self.n,3,3))
|
||||||
m = np.random.random()*20.0-10.0
|
m = np.random.random()*20.0-10.0
|
||||||
assert np.allclose(mechanics.strain_tensor(F,'U',m),
|
assert np.allclose(mechanics.strain_tensor(F,'U',m),
|
||||||
mechanics.strain_tensor(F,'V',m))
|
mechanics.strain_tensor(F,'V',m))
|
||||||
|
|
||||||
def test_strain_tensor_rotation_equivalence(self):
|
def test_strain_tensor_rotation_equivalence(self):
|
||||||
"""Ensure that left and right strain differ only by a rotation."""
|
"""Ensure that left and right strain differ only by a rotation."""
|
||||||
F = np.broadcast_to(np.eye(3),[self.n,3,3]) + (np.random.random((self.n,3,3))*0.5 - 0.25)
|
F = np.broadcast_to(np.eye(3),[self.n,3,3]) + (np.random.random((self.n,3,3))*0.5 - 0.25)
|
||||||
m = np.random.random()*5.0-2.5
|
m = np.random.random()*5.0-2.5
|
||||||
assert np.allclose(np.linalg.det(mechanics.strain_tensor(F,'U',m)),
|
assert np.allclose(np.linalg.det(mechanics.strain_tensor(F,'U',m)),
|
||||||
np.linalg.det(mechanics.strain_tensor(F,'V',m)))
|
np.linalg.det(mechanics.strain_tensor(F,'V',m)))
|
||||||
|
|
||||||
def test_strain_tensor_rotation(self):
|
def test_strain_tensor_rotation(self):
|
||||||
"""Ensure that pure rotation results in no strain."""
|
"""Ensure that pure rotation results in no strain."""
|
||||||
F = mechanics.rotational_part(np.random.random((self.n,3,3)))
|
F = mechanics.rotational_part(np.random.random((self.n,3,3)))
|
||||||
t = ['V','U'][np.random.randint(0,2)]
|
t = ['V','U'][np.random.randint(0,2)]
|
||||||
m = np.random.random()*2.0 - 1.0
|
m = np.random.random()*2.0 - 1.0
|
||||||
assert np.allclose(mechanics.strain_tensor(F,t,m),
|
assert np.allclose(mechanics.strain_tensor(F,t,m),
|
||||||
0.0)
|
0.0)
|
||||||
|
|
||||||
def test_rotation_determinant(self):
|
|
||||||
"""
|
|
||||||
Ensure that the determinant of the rotational part is +- 1.
|
|
||||||
|
|
||||||
Should be +1, but random F might contain a reflection.
|
def test_rotation_determinant(self):
|
||||||
"""
|
"""
|
||||||
x = np.random.random((self.n,3,3))
|
Ensure that the determinant of the rotational part is +- 1.
|
||||||
assert np.allclose(np.abs(np.linalg.det(mechanics.rotational_part(x))),
|
|
||||||
1.0)
|
Should be +1, but random F might contain a reflection.
|
||||||
|
"""
|
||||||
|
x = np.random.random((self.n,3,3))
|
||||||
|
assert np.allclose(np.abs(np.linalg.det(mechanics.rotational_part(x))),
|
||||||
|
1.0)
|
||||||
|
|
||||||
|
|
||||||
def test_spherical_deviatoric_part(self):
|
def test_spherical_deviatoric_part(self):
|
||||||
"""Ensure that full tensor is sum of spherical and deviatoric part."""
|
"""Ensure that full tensor is sum of spherical and deviatoric part."""
|
||||||
x = np.random.random((self.n,3,3))
|
x = np.random.random((self.n,3,3))
|
||||||
sph = mechanics.spherical_part(x,True)
|
sph = mechanics.spherical_part(x,True)
|
||||||
assert np.allclose(sph + mechanics.deviatoric_part(x),
|
assert np.allclose(sph + mechanics.deviatoric_part(x),
|
||||||
x)
|
x)
|
||||||
|
|
||||||
def test_deviatoric_Mises(self):
|
def test_deviatoric_Mises(self):
|
||||||
"""Ensure that Mises equivalent stress depends only on deviatoric part."""
|
"""Ensure that Mises equivalent stress depends only on deviatoric part."""
|
||||||
x = np.random.random((self.n,3,3))
|
x = np.random.random((self.n,3,3))
|
||||||
full = mechanics.Mises_stress(x)
|
full = mechanics.Mises_stress(x)
|
||||||
dev = mechanics.Mises_stress(mechanics.deviatoric_part(x))
|
dev = mechanics.Mises_stress(mechanics.deviatoric_part(x))
|
||||||
assert np.allclose(full,
|
assert np.allclose(full,
|
||||||
dev)
|
dev)
|
||||||
|
|
||||||
def test_spherical_mapping(self):
|
def test_spherical_mapping(self):
|
||||||
"""Ensure that mapping to tensor is correct."""
|
"""Ensure that mapping to tensor is correct."""
|
||||||
x = np.random.random((self.n,3,3))
|
x = np.random.random((self.n,3,3))
|
||||||
tensor = mechanics.spherical_part(x,True)
|
tensor = mechanics.spherical_part(x,True)
|
||||||
scalar = mechanics.spherical_part(x)
|
scalar = mechanics.spherical_part(x)
|
||||||
assert np.allclose(np.linalg.det(tensor),
|
assert np.allclose(np.linalg.det(tensor),
|
||||||
scalar**3.0)
|
scalar**3.0)
|
||||||
|
|
||||||
def test_spherical_Mises(self):
|
def test_spherical_Mises(self):
|
||||||
"""Ensure that Mises equivalent strrain of spherical strain is 0."""
|
"""Ensure that Mises equivalent strrain of spherical strain is 0."""
|
||||||
x = np.random.random((self.n,3,3))
|
x = np.random.random((self.n,3,3))
|
||||||
sph = mechanics.spherical_part(x,True)
|
sph = mechanics.spherical_part(x,True)
|
||||||
assert np.allclose(mechanics.Mises_strain(sph),
|
assert np.allclose(mechanics.Mises_strain(sph),
|
||||||
0.0)
|
0.0)
|
||||||
|
|
||||||
def test_symmetric(self):
|
def test_symmetric(self):
|
||||||
"""Ensure that a symmetric tensor is half of the sum of a tensor and its transpose."""
|
"""Ensure that a symmetric tensor is half of the sum of a tensor and its transpose."""
|
||||||
x = np.random.random((self.n,3,3))
|
x = np.random.random((self.n,3,3))
|
||||||
assert np.allclose(mechanics.symmetric(x)*2.0,
|
assert np.allclose(mechanics.symmetric(x)*2.0,
|
||||||
mechanics.transpose(x)+x)
|
mechanics.transpose(x)+x)
|
||||||
|
|
||||||
|
|
||||||
def test_transpose(self):
|
def test_transpose(self):
|
||||||
"""Ensure that a symmetric tensor equals its transpose."""
|
"""Ensure that a symmetric tensor equals its transpose."""
|
||||||
x = mechanics.symmetric(np.random.random((self.n,3,3)))
|
x = mechanics.symmetric(np.random.random((self.n,3,3)))
|
||||||
assert np.allclose(mechanics.transpose(x),
|
assert np.allclose(mechanics.transpose(x),
|
||||||
x)
|
x)
|
||||||
|
|
||||||
|
|
||||||
def test_Mises(self):
|
def test_Mises(self):
|
||||||
"""Ensure that equivalent stress is 3/2 of equivalent strain."""
|
"""Ensure that equivalent stress is 3/2 of equivalent strain."""
|
||||||
x = np.random.random((self.n,3,3))
|
x = np.random.random((self.n,3,3))
|
||||||
assert np.allclose(mechanics.Mises_stress(x)/mechanics.Mises_strain(x),
|
assert np.allclose(mechanics.Mises_stress(x)/mechanics.Mises_strain(x),
|
||||||
1.5)
|
1.5)
|
||||||
|
|
||||||
|
|
||||||
|
def test_eigenvalues(self):
|
||||||
|
"""Ensure that the characteristic polynomial can be solved."""
|
||||||
|
A = mechanics.symmetric(np.random.random((self.n,3,3)))
|
||||||
|
lambd = mechanics.eigenvalues(A)
|
||||||
|
s = np.random.randint(self.n)
|
||||||
|
for i in range(3):
|
||||||
|
assert np.allclose(np.linalg.det(A[s]-lambd[s,i]*np.eye(3)),.0)
|
||||||
|
|
||||||
|
def test_eigenvalues_and_vectors(self):
|
||||||
|
"""Ensure that eigenvalues and -vectors are the solution to the characteristic polynomial."""
|
||||||
|
A = mechanics.symmetric(np.random.random((self.n,3,3)))
|
||||||
|
lambd = mechanics.eigenvalues(A)
|
||||||
|
x = mechanics.eigenvectors(A)
|
||||||
|
s = np.random.randint(self.n)
|
||||||
|
for i in range(3):
|
||||||
|
assert np.allclose(np.dot(A[s]-lambd[s,i]*np.eye(3),x[s,:,i]),.0)
|
||||||
|
|
||||||
|
def test_eigenvectors_RHS(self):
|
||||||
|
"""Ensure that RHS coordinate system does only change sign of determinant."""
|
||||||
|
A = mechanics.symmetric(np.random.random((self.n,3,3)))
|
||||||
|
LRHS = np.linalg.det(mechanics.eigenvectors(A,RHS=False))
|
||||||
|
RHS = np.linalg.det(mechanics.eigenvectors(A,RHS=True))
|
||||||
|
assert np.allclose(np.abs(LRHS),RHS)
|
||||||
|
|
||||||
|
def test_spherical_no_shear(self):
|
||||||
|
"""Ensure that sherical stress has max shear of 0.0."""
|
||||||
|
A = mechanics.spherical_part(mechanics.symmetric(np.random.random((self.n,3,3))),True)
|
||||||
|
assert np.allclose(mechanics.maximum_shear(A),0.0)
|
||||||
|
|
|
@ -400,6 +400,8 @@ subroutine IO_error(error_ID,el,ip,g,instance,ext_msg)
|
||||||
msg = 'number of values does not match'
|
msg = 'number of values does not match'
|
||||||
case (147)
|
case (147)
|
||||||
msg = 'not supported anymore'
|
msg = 'not supported anymore'
|
||||||
|
case (148)
|
||||||
|
msg = 'Nconstituents mismatch between homogenization and microstructure'
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! material error messages and related messages in mesh
|
! material error messages and related messages in mesh
|
||||||
|
|
|
@ -6,21 +6,10 @@
|
||||||
!> @brief crystal plasticity model for bcc metals, especially Tungsten
|
!> @brief crystal plasticity model for bcc metals, especially Tungsten
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
submodule(constitutive) plastic_disloUCLA
|
submodule(constitutive) plastic_disloUCLA
|
||||||
|
|
||||||
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
|
||||||
|
|
||||||
enum, bind(c)
|
|
||||||
enumerator :: &
|
|
||||||
undefined_ID, &
|
|
||||||
rho_mob_ID, &
|
|
||||||
rho_dip_ID, &
|
|
||||||
dot_gamma_sl_ID, &
|
|
||||||
gamma_sl_ID, &
|
|
||||||
Lambda_sl_ID, &
|
|
||||||
tau_pass_ID
|
|
||||||
end enum
|
|
||||||
|
|
||||||
type :: tParameters
|
type :: tParameters
|
||||||
real(pReal) :: &
|
real(pReal) :: &
|
||||||
aTol_rho, &
|
aTol_rho, &
|
||||||
|
@ -28,7 +17,7 @@ submodule(constitutive) plastic_disloUCLA
|
||||||
mu, &
|
mu, &
|
||||||
D_0, & !< prefactor for self-diffusion coefficient
|
D_0, & !< prefactor for self-diffusion coefficient
|
||||||
Q_cl !< activation energy for dislocation climb
|
Q_cl !< activation energy for dislocation climb
|
||||||
real(pReal), dimension(:), allocatable :: &
|
real(pReal), allocatable, dimension(:) :: &
|
||||||
rho_mob_0, & !< initial dislocation density
|
rho_mob_0, & !< initial dislocation density
|
||||||
rho_dip_0, & !< initial dipole density
|
rho_dip_0, & !< initial dipole density
|
||||||
b_sl, & !< magnitude of burgers vector [m]
|
b_sl, & !< magnitude of burgers vector [m]
|
||||||
|
@ -46,30 +35,30 @@ submodule(constitutive) plastic_disloUCLA
|
||||||
kink_height, & !< height of the kink pair
|
kink_height, & !< height of the kink pair
|
||||||
w, & !< width of the kink pair
|
w, & !< width of the kink pair
|
||||||
omega !< attempt frequency for kink pair nucleation
|
omega !< attempt frequency for kink pair nucleation
|
||||||
real(pReal), dimension(:,:), allocatable :: &
|
real(pReal), allocatable, dimension(:,:) :: &
|
||||||
h_sl_sl, & !< slip resistance from slip activity
|
h_sl_sl, & !< slip resistance from slip activity
|
||||||
forestProjectionEdge
|
forestProjectionEdge
|
||||||
real(pReal), dimension(:,:,:), allocatable :: &
|
real(pReal), allocatable, dimension(:,:,:) :: &
|
||||||
Schmid, &
|
Schmid, &
|
||||||
nonSchmid_pos, &
|
nonSchmid_pos, &
|
||||||
nonSchmid_neg
|
nonSchmid_neg
|
||||||
integer :: &
|
integer :: &
|
||||||
sum_N_sl !< total number of active slip system
|
sum_N_sl !< total number of active slip system
|
||||||
integer, dimension(:), allocatable :: &
|
integer, allocatable, dimension(:) :: &
|
||||||
N_sl !< number of active slip systems for each family
|
N_sl !< number of active slip systems for each family
|
||||||
integer(kind(undefined_ID)), dimension(:),allocatable :: &
|
character(len=pStringLen), allocatable, dimension(:) :: &
|
||||||
outputID !< ID of each post result output
|
output
|
||||||
logical :: &
|
logical :: &
|
||||||
dipoleFormation !< flag indicating consideration of dipole formation
|
dipoleFormation !< flag indicating consideration of dipole formation
|
||||||
end type !< container type for internal constitutive parameters
|
end type !< container type for internal constitutive parameters
|
||||||
|
|
||||||
type :: tDisloUCLAState
|
type :: tDisloUCLAState
|
||||||
real(pReal), dimension(:,:), pointer :: &
|
real(pReal), dimension(:,:), pointer :: &
|
||||||
rho_mob, &
|
rho_mob, &
|
||||||
rho_dip, &
|
rho_dip, &
|
||||||
gamma_sl
|
gamma_sl
|
||||||
end type tDisloUCLAState
|
end type tDisloUCLAState
|
||||||
|
|
||||||
type :: tDisloUCLAdependentState
|
type :: tDisloUCLAdependentState
|
||||||
real(pReal), dimension(:,:), allocatable :: &
|
real(pReal), dimension(:,:), allocatable :: &
|
||||||
Lambda_sl, &
|
Lambda_sl, &
|
||||||
|
@ -88,41 +77,36 @@ contains
|
||||||
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @brief module initialization
|
!> @brief Perform 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 subroutine plastic_disloUCLA_init
|
module subroutine plastic_disloUCLA_init
|
||||||
|
|
||||||
integer :: &
|
integer :: &
|
||||||
Ninstance, &
|
Ninstance, &
|
||||||
p, i, &
|
p, i, &
|
||||||
NipcMyPhase, &
|
NipcMyPhase, &
|
||||||
sizeState, sizeDotState, &
|
sizeState, sizeDotState, &
|
||||||
startIndex, endIndex
|
startIndex, endIndex
|
||||||
|
|
||||||
integer(kind(undefined_ID)) :: &
|
|
||||||
outputID
|
|
||||||
|
|
||||||
character(len=pStringLen) :: &
|
character(len=pStringLen) :: &
|
||||||
extmsg = ''
|
extmsg = ''
|
||||||
character(len=pStringLen), dimension(:), allocatable :: &
|
|
||||||
outputs
|
write(6,'(/,a)') ' <<<+- plastic_'//PLASTICITY_DISLOUCLA_label//' init -+>>>'; flush(6)
|
||||||
|
|
||||||
write(6,'(/,a)') ' <<<+- plastic_'//PLASTICITY_DISLOUCLA_label//' init -+>>>'
|
write(6,'(/,a)') ' Cereceda et al., International Journal of Plasticity 78:242–256, 2016'
|
||||||
|
write(6,'(a)') ' https://dx.doi.org/10.1016/j.ijplas.2015.09.002'
|
||||||
write(6,'(/,a)') ' Cereceda et al., International Journal of Plasticity 78:242–256, 2016'
|
|
||||||
write(6,'(a)') ' https://dx.doi.org/10.1016/j.ijplas.2015.09.002'
|
|
||||||
|
|
||||||
Ninstance = count(phase_plasticity == PLASTICITY_DISLOUCLA_ID)
|
Ninstance = count(phase_plasticity == PLASTICITY_DISLOUCLA_ID)
|
||||||
if (iand(debug_level(debug_constitutive),debug_levelBasic) /= 0) &
|
if (iand(debug_level(debug_constitutive),debug_levelBasic) /= 0) &
|
||||||
write(6,'(a16,1x,i5,/)') '# instances:',Ninstance
|
write(6,'(a16,1x,i5,/)') '# instances:',Ninstance
|
||||||
|
|
||||||
allocate(param(Ninstance))
|
allocate(param(Ninstance))
|
||||||
allocate(state(Ninstance))
|
allocate(state(Ninstance))
|
||||||
allocate(dotState(Ninstance))
|
allocate(dotState(Ninstance))
|
||||||
allocate(dependentState(Ninstance))
|
allocate(dependentState(Ninstance))
|
||||||
|
|
||||||
|
|
||||||
do p = 1, size(phase_plasticity)
|
do p = 1, size(phase_plasticity)
|
||||||
if (phase_plasticity(p) /= PLASTICITY_DISLOUCLA_ID) cycle
|
if (phase_plasticity(p) /= PLASTICITY_DISLOUCLA_ID) cycle
|
||||||
associate(prm => param(phase_plasticityInstance(p)), &
|
associate(prm => param(phase_plasticityInstance(p)), &
|
||||||
|
@ -134,9 +118,9 @@ module subroutine plastic_disloUCLA_init
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! optional parameters that need to be defined
|
! optional parameters that need to be defined
|
||||||
prm%mu = lattice_mu(p)
|
prm%mu = lattice_mu(p)
|
||||||
|
|
||||||
prm%aTol_rho = config%getFloat('atol_rho')
|
prm%aTol_rho = config%getFloat('atol_rho')
|
||||||
|
|
||||||
! sanity checks
|
! sanity checks
|
||||||
if (prm%aTol_rho <= 0.0_pReal) extmsg = trim(extmsg)//' atol_rho'
|
if (prm%aTol_rho <= 0.0_pReal) extmsg = trim(extmsg)//' atol_rho'
|
||||||
|
|
||||||
|
@ -147,7 +131,7 @@ module subroutine plastic_disloUCLA_init
|
||||||
slipActive: if (prm%sum_N_sl > 0) then
|
slipActive: if (prm%sum_N_sl > 0) then
|
||||||
prm%Schmid = lattice_SchmidMatrix_slip(prm%N_sl,config%getString('lattice_structure'),&
|
prm%Schmid = lattice_SchmidMatrix_slip(prm%N_sl,config%getString('lattice_structure'),&
|
||||||
config%getFloat('c/a',defaultVal=0.0_pReal))
|
config%getFloat('c/a',defaultVal=0.0_pReal))
|
||||||
|
|
||||||
if(trim(config%getString('lattice_structure')) == 'bcc') then
|
if(trim(config%getString('lattice_structure')) == 'bcc') then
|
||||||
prm%nonSchmidCoeff = config%getFloats('nonschmid_coefficients',&
|
prm%nonSchmidCoeff = config%getFloats('nonschmid_coefficients',&
|
||||||
defaultVal = emptyRealArray)
|
defaultVal = emptyRealArray)
|
||||||
|
@ -158,20 +142,20 @@ module subroutine plastic_disloUCLA_init
|
||||||
prm%nonSchmid_pos = prm%Schmid
|
prm%nonSchmid_pos = prm%Schmid
|
||||||
prm%nonSchmid_neg = prm%Schmid
|
prm%nonSchmid_neg = prm%Schmid
|
||||||
endif
|
endif
|
||||||
|
|
||||||
prm%h_sl_sl = lattice_interaction_SlipBySlip(prm%N_sl, &
|
prm%h_sl_sl = lattice_interaction_SlipBySlip(prm%N_sl, &
|
||||||
config%getFloats('interaction_slipslip'), &
|
config%getFloats('interaction_slipslip'), &
|
||||||
config%getString('lattice_structure'))
|
config%getString('lattice_structure'))
|
||||||
prm%forestProjectionEdge = lattice_forestProjection_edge(prm%N_sl,config%getString('lattice_structure'),&
|
prm%forestProjectionEdge = lattice_forestProjection_edge(prm%N_sl,config%getString('lattice_structure'),&
|
||||||
config%getFloat('c/a',defaultVal=0.0_pReal))
|
config%getFloat('c/a',defaultVal=0.0_pReal))
|
||||||
prm%forestProjectionEdge = transpose(prm%forestProjectionEdge)
|
prm%forestProjectionEdge = transpose(prm%forestProjectionEdge)
|
||||||
|
|
||||||
prm%rho_mob_0 = config%getFloats('rhoedge0', requiredSize=size(prm%N_sl))
|
prm%rho_mob_0 = config%getFloats('rhoedge0', requiredSize=size(prm%N_sl))
|
||||||
prm%rho_dip_0 = config%getFloats('rhoedgedip0', requiredSize=size(prm%N_sl))
|
prm%rho_dip_0 = config%getFloats('rhoedgedip0', requiredSize=size(prm%N_sl))
|
||||||
prm%v0 = config%getFloats('v0', requiredSize=size(prm%N_sl))
|
prm%v0 = config%getFloats('v0', requiredSize=size(prm%N_sl))
|
||||||
prm%b_sl = config%getFloats('slipburgers', requiredSize=size(prm%N_sl))
|
prm%b_sl = config%getFloats('slipburgers', requiredSize=size(prm%N_sl))
|
||||||
prm%delta_F = config%getFloats('qedge', requiredSize=size(prm%N_sl))
|
prm%delta_F = config%getFloats('qedge', requiredSize=size(prm%N_sl))
|
||||||
|
|
||||||
prm%i_sl = config%getFloats('clambdaslip', requiredSize=size(prm%N_sl))
|
prm%i_sl = config%getFloats('clambdaslip', requiredSize=size(prm%N_sl))
|
||||||
prm%tau_0 = config%getFloats('tau_peierls', requiredSize=size(prm%N_sl))
|
prm%tau_0 = config%getFloats('tau_peierls', requiredSize=size(prm%N_sl))
|
||||||
prm%p = config%getFloats('p_slip', requiredSize=size(prm%N_sl), &
|
prm%p = config%getFloats('p_slip', requiredSize=size(prm%N_sl), &
|
||||||
|
@ -182,14 +166,14 @@ module subroutine plastic_disloUCLA_init
|
||||||
prm%w = config%getFloats('kink_width', requiredSize=size(prm%N_sl))
|
prm%w = config%getFloats('kink_width', requiredSize=size(prm%N_sl))
|
||||||
prm%omega = config%getFloats('omega', requiredSize=size(prm%N_sl))
|
prm%omega = config%getFloats('omega', requiredSize=size(prm%N_sl))
|
||||||
prm%B = config%getFloats('friction_coeff', requiredSize=size(prm%N_sl))
|
prm%B = config%getFloats('friction_coeff', requiredSize=size(prm%N_sl))
|
||||||
|
|
||||||
prm%D = config%getFloat('grainsize')
|
prm%D = config%getFloat('grainsize')
|
||||||
prm%D_0 = config%getFloat('d0')
|
prm%D_0 = config%getFloat('d0')
|
||||||
prm%Q_cl = config%getFloat('qsd')
|
prm%Q_cl = config%getFloat('qsd')
|
||||||
prm%atomicVolume = config%getFloat('catomicvolume') * prm%b_sl**3.0_pReal
|
prm%atomicVolume = config%getFloat('catomicvolume') * prm%b_sl**3.0_pReal
|
||||||
prm%D_a = config%getFloat('cedgedipmindistance') * prm%b_sl
|
prm%D_a = config%getFloat('cedgedipmindistance') * prm%b_sl
|
||||||
prm%dipoleformation = config%getFloat('dipoleformationfactor') > 0.0_pReal !should be on by default, ToDo: change to /key/-type key
|
prm%dipoleformation = config%getFloat('dipoleformationfactor') > 0.0_pReal !should be on by default, ToDo: change to /key/-type key
|
||||||
|
|
||||||
! expand: family => system
|
! expand: family => system
|
||||||
prm%rho_mob_0 = math_expand(prm%rho_mob_0, prm%N_sl)
|
prm%rho_mob_0 = math_expand(prm%rho_mob_0, prm%N_sl)
|
||||||
prm%rho_dip_0 = math_expand(prm%rho_dip_0, prm%N_sl)
|
prm%rho_dip_0 = math_expand(prm%rho_dip_0, prm%N_sl)
|
||||||
|
@ -206,8 +190,8 @@ module subroutine plastic_disloUCLA_init
|
||||||
prm%i_sl = math_expand(prm%i_sl, prm%N_sl)
|
prm%i_sl = math_expand(prm%i_sl, prm%N_sl)
|
||||||
prm%atomicVolume = math_expand(prm%atomicVolume, prm%N_sl)
|
prm%atomicVolume = math_expand(prm%atomicVolume, prm%N_sl)
|
||||||
prm%D_a = math_expand(prm%D_a, prm%N_sl)
|
prm%D_a = math_expand(prm%D_a, prm%N_sl)
|
||||||
|
|
||||||
|
|
||||||
! sanity checks
|
! sanity checks
|
||||||
if ( prm%D_0 <= 0.0_pReal) extmsg = trim(extmsg)//' D_0'
|
if ( prm%D_0 <= 0.0_pReal) extmsg = trim(extmsg)//' D_0'
|
||||||
if ( prm%Q_cl <= 0.0_pReal) extmsg = trim(extmsg)//' Q_cl'
|
if ( prm%Q_cl <= 0.0_pReal) extmsg = trim(extmsg)//' Q_cl'
|
||||||
|
@ -219,7 +203,7 @@ module subroutine plastic_disloUCLA_init
|
||||||
if (any(prm%tau_0 < 0.0_pReal)) extmsg = trim(extmsg)//' tau_0'
|
if (any(prm%tau_0 < 0.0_pReal)) extmsg = trim(extmsg)//' tau_0'
|
||||||
if (any(prm%D_a <= 0.0_pReal)) extmsg = trim(extmsg)//' cedgedipmindistance or slipb_sl'
|
if (any(prm%D_a <= 0.0_pReal)) extmsg = trim(extmsg)//' cedgedipmindistance or slipb_sl'
|
||||||
if (any(prm%atomicVolume <= 0.0_pReal)) extmsg = trim(extmsg)//' catomicvolume or slipb_sl'
|
if (any(prm%atomicVolume <= 0.0_pReal)) extmsg = trim(extmsg)//' catomicvolume or slipb_sl'
|
||||||
|
|
||||||
else slipActive
|
else slipActive
|
||||||
allocate(prm%rho_mob_0(0))
|
allocate(prm%rho_mob_0(0))
|
||||||
allocate(prm%rho_dip_0(0))
|
allocate(prm%rho_dip_0(0))
|
||||||
|
@ -232,39 +216,14 @@ module subroutine plastic_disloUCLA_init
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! output pararameters
|
! output pararameters
|
||||||
outputs = config%getStrings('(output)',defaultVal=emptyStringArray)
|
prm%output = config%getStrings('(output)',defaultVal=emptyStringArray)
|
||||||
allocate(prm%outputID(0))
|
|
||||||
do i=1, size(outputs)
|
|
||||||
outputID = undefined_ID
|
|
||||||
select case(trim(outputs(i)))
|
|
||||||
|
|
||||||
case ('edge_density')
|
|
||||||
outputID = merge(rho_mob_ID,undefined_ID,prm%sum_N_sl>0)
|
|
||||||
case ('dipole_density')
|
|
||||||
outputID = merge(rho_dip_ID,undefined_ID,prm%sum_N_sl>0)
|
|
||||||
case ('shear_rate','shearrate','shear_rate_slip','shearrate_slip')
|
|
||||||
outputID = merge(dot_gamma_sl_ID,undefined_ID,prm%sum_N_sl>0)
|
|
||||||
case ('accumulated_shear','accumulatedshear','accumulated_shear_slip')
|
|
||||||
outputID = merge(gamma_sl_ID,undefined_ID,prm%sum_N_sl>0)
|
|
||||||
case ('mfp','mfp_slip')
|
|
||||||
outputID = merge(Lambda_sl_ID,undefined_ID,prm%sum_N_sl>0)
|
|
||||||
case ('threshold_stress','threshold_stress_slip')
|
|
||||||
outputID = merge(tau_pass_ID,undefined_ID,prm%sum_N_sl>0)
|
|
||||||
|
|
||||||
end select
|
|
||||||
|
|
||||||
if (outputID /= undefined_ID) then
|
|
||||||
prm%outputID = [prm%outputID, outputID]
|
|
||||||
endif
|
|
||||||
|
|
||||||
enddo
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! allocate state arrays
|
! allocate state arrays
|
||||||
NipcMyPhase = count(material_phaseAt == p) * discretization_nIP
|
NipcMyPhase = count(material_phaseAt == p) * discretization_nIP
|
||||||
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 material_allocatePlasticState(p,NipcMyPhase,sizeState,sizeDotState,0)
|
call material_allocatePlasticState(p,NipcMyPhase,sizeState,sizeDotState,0)
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
@ -275,14 +234,14 @@ module subroutine plastic_disloUCLA_init
|
||||||
stt%rho_mob= spread(prm%rho_mob_0,2,NipcMyPhase)
|
stt%rho_mob= spread(prm%rho_mob_0,2,NipcMyPhase)
|
||||||
dot%rho_mob=>plasticState(p)%dotState(startIndex:endIndex,:)
|
dot%rho_mob=>plasticState(p)%dotState(startIndex:endIndex,:)
|
||||||
plasticState(p)%aTolState(startIndex:endIndex) = prm%aTol_rho
|
plasticState(p)%aTolState(startIndex:endIndex) = prm%aTol_rho
|
||||||
|
|
||||||
startIndex = endIndex + 1
|
startIndex = endIndex + 1
|
||||||
endIndex = endIndex + prm%sum_N_sl
|
endIndex = endIndex + prm%sum_N_sl
|
||||||
stt%rho_dip=>plasticState(p)%state(startIndex:endIndex,:)
|
stt%rho_dip=>plasticState(p)%state(startIndex:endIndex,:)
|
||||||
stt%rho_dip= spread(prm%rho_dip_0,2,NipcMyPhase)
|
stt%rho_dip= spread(prm%rho_dip_0,2,NipcMyPhase)
|
||||||
dot%rho_dip=>plasticState(p)%dotState(startIndex:endIndex,:)
|
dot%rho_dip=>plasticState(p)%dotState(startIndex:endIndex,:)
|
||||||
plasticState(p)%aTolState(startIndex:endIndex) = prm%aTol_rho
|
plasticState(p)%aTolState(startIndex:endIndex) = prm%aTol_rho
|
||||||
|
|
||||||
startIndex = endIndex + 1
|
startIndex = endIndex + 1
|
||||||
endIndex = endIndex + prm%sum_N_sl
|
endIndex = endIndex + prm%sum_N_sl
|
||||||
stt%gamma_sl=>plasticState(p)%state(startIndex:endIndex,:)
|
stt%gamma_sl=>plasticState(p)%state(startIndex:endIndex,:)
|
||||||
|
@ -290,21 +249,21 @@ module subroutine plastic_disloUCLA_init
|
||||||
plasticState(p)%aTolState(startIndex:endIndex) = 1.0e6_pReal ! Don't use for convergence check
|
plasticState(p)%aTolState(startIndex:endIndex) = 1.0e6_pReal ! Don't use for convergence check
|
||||||
! global alias
|
! global alias
|
||||||
plasticState(p)%slipRate => plasticState(p)%dotState(startIndex:endIndex,:)
|
plasticState(p)%slipRate => plasticState(p)%dotState(startIndex:endIndex,:)
|
||||||
|
|
||||||
allocate(dst%Lambda_sl(prm%sum_N_sl,NipcMyPhase), source=0.0_pReal)
|
allocate(dst%Lambda_sl(prm%sum_N_sl,NipcMyPhase), source=0.0_pReal)
|
||||||
allocate(dst%threshold_stress(prm%sum_N_sl,NipcMyPhase), source=0.0_pReal)
|
allocate(dst%threshold_stress(prm%sum_N_sl,NipcMyPhase), source=0.0_pReal)
|
||||||
|
|
||||||
plasticState(p)%state0 = plasticState(p)%state ! ToDo: this could be done centrally
|
plasticState(p)%state0 = plasticState(p)%state ! ToDo: this could be done centrally
|
||||||
|
|
||||||
end associate
|
end associate
|
||||||
|
|
||||||
enddo
|
enddo
|
||||||
|
|
||||||
end subroutine plastic_disloUCLA_init
|
end subroutine plastic_disloUCLA_init
|
||||||
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @brief calculates plastic velocity gradient and its tangent
|
!> @brief Calculate plastic velocity gradient and its tangent.
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
pure module subroutine plastic_disloUCLA_LpAndItsTangent(Lp,dLp_dMp, &
|
pure module subroutine plastic_disloUCLA_LpAndItsTangent(Lp,dLp_dMp, &
|
||||||
Mp,T,instance,of)
|
Mp,T,instance,of)
|
||||||
|
@ -312,7 +271,7 @@ pure module subroutine plastic_disloUCLA_LpAndItsTangent(Lp,dLp_dMp, &
|
||||||
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 !< derivative of Lp with respect to the Mandel stress
|
dLp_dMp !< derivative of Lp with respect to the Mandel stress
|
||||||
|
|
||||||
real(pReal), dimension(3,3), intent(in) :: &
|
real(pReal), dimension(3,3), intent(in) :: &
|
||||||
Mp !< Mandel stress
|
Mp !< Mandel stress
|
||||||
real(pReal), intent(in) :: &
|
real(pReal), intent(in) :: &
|
||||||
|
@ -320,18 +279,18 @@ pure module subroutine plastic_disloUCLA_LpAndItsTangent(Lp,dLp_dMp, &
|
||||||
integer, intent(in) :: &
|
integer, intent(in) :: &
|
||||||
instance, &
|
instance, &
|
||||||
of
|
of
|
||||||
|
|
||||||
integer :: &
|
integer :: &
|
||||||
i,k,l,m,n
|
i,k,l,m,n
|
||||||
real(pReal), dimension(param(instance)%sum_N_sl) :: &
|
real(pReal), dimension(param(instance)%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(instance))
|
associate(prm => param(instance))
|
||||||
|
|
||||||
call kinetics(Mp,T,instance,of,dot_gamma_pos,dot_gamma_neg,ddot_gamma_dtau_pos,ddot_gamma_dtau_neg)
|
call kinetics(Mp,T,instance,of,dot_gamma_pos,dot_gamma_neg,ddot_gamma_dtau_pos,ddot_gamma_dtau_neg)
|
||||||
do i = 1, prm%sum_N_sl
|
do i = 1, prm%sum_N_sl
|
||||||
Lp = Lp + (dot_gamma_pos(i)+dot_gamma_neg(i))*prm%Schmid(1:3,1:3,i)
|
Lp = Lp + (dot_gamma_pos(i)+dot_gamma_neg(i))*prm%Schmid(1:3,1:3,i)
|
||||||
|
@ -340,17 +299,17 @@ pure module subroutine plastic_disloUCLA_LpAndItsTangent(Lp,dLp_dMp, &
|
||||||
+ ddot_gamma_dtau_pos(i) * prm%Schmid(k,l,i) * prm%nonSchmid_pos(m,n,i) &
|
+ ddot_gamma_dtau_pos(i) * prm%Schmid(k,l,i) * prm%nonSchmid_pos(m,n,i) &
|
||||||
+ ddot_gamma_dtau_neg(i) * prm%Schmid(k,l,i) * prm%nonSchmid_neg(m,n,i)
|
+ ddot_gamma_dtau_neg(i) * prm%Schmid(k,l,i) * prm%nonSchmid_neg(m,n,i)
|
||||||
enddo
|
enddo
|
||||||
|
|
||||||
end associate
|
end associate
|
||||||
|
|
||||||
end subroutine plastic_disloUCLA_LpAndItsTangent
|
end subroutine plastic_disloUCLA_LpAndItsTangent
|
||||||
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @brief calculates the rate of change of microstructure
|
!> @brief Calculate the rate of change of microstructure.
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
module subroutine plastic_disloUCLA_dotState(Mp,T,instance,of)
|
module subroutine plastic_disloUCLA_dotState(Mp,T,instance,of)
|
||||||
|
|
||||||
real(pReal), dimension(3,3), intent(in) :: &
|
real(pReal), dimension(3,3), intent(in) :: &
|
||||||
Mp !< Mandel stress
|
Mp !< Mandel stress
|
||||||
real(pReal), intent(in) :: &
|
real(pReal), intent(in) :: &
|
||||||
|
@ -358,7 +317,7 @@ module subroutine plastic_disloUCLA_dotState(Mp,T,instance,of)
|
||||||
integer, intent(in) :: &
|
integer, intent(in) :: &
|
||||||
instance, &
|
instance, &
|
||||||
of
|
of
|
||||||
|
|
||||||
real(pReal) :: &
|
real(pReal) :: &
|
||||||
VacancyDiffusion
|
VacancyDiffusion
|
||||||
real(pReal), dimension(param(instance)%sum_N_sl) :: &
|
real(pReal), dimension(param(instance)%sum_N_sl) :: &
|
||||||
|
@ -369,16 +328,16 @@ module subroutine plastic_disloUCLA_dotState(Mp,T,instance,of)
|
||||||
dot_rho_dip_formation, &
|
dot_rho_dip_formation, &
|
||||||
dot_rho_dip_climb, &
|
dot_rho_dip_climb, &
|
||||||
dip_distance
|
dip_distance
|
||||||
|
|
||||||
associate(prm => param(instance), stt => state(instance),dot => dotState(instance), dst => dependentState(instance))
|
associate(prm => param(instance), stt => state(instance),dot => dotState(instance), dst => dependentState(instance))
|
||||||
|
|
||||||
call kinetics(Mp,T,instance,of,&
|
call kinetics(Mp,T,instance,of,&
|
||||||
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)
|
||||||
|
|
||||||
dot%gamma_sl(:,of) = (gdot_pos+gdot_neg) ! ToDo: needs to be abs
|
dot%gamma_sl(:,of) = (gdot_pos+gdot_neg) ! ToDo: needs to be abs
|
||||||
VacancyDiffusion = prm%D_0*exp(-prm%Q_cl/(kB*T))
|
VacancyDiffusion = prm%D_0*exp(-prm%Q_cl/(kB*T))
|
||||||
|
|
||||||
where(dEq0(tau_pos)) ! ToDo: use avg of pos and neg
|
where(dEq0(tau_pos)) ! ToDo: use avg of pos and neg
|
||||||
dot_rho_dip_formation = 0.0_pReal
|
dot_rho_dip_formation = 0.0_pReal
|
||||||
dot_rho_dip_climb = 0.0_pReal
|
dot_rho_dip_climb = 0.0_pReal
|
||||||
|
@ -393,73 +352,73 @@ module subroutine plastic_disloUCLA_dotState(Mp,T,instance,of)
|
||||||
* (1.0_pReal/(dip_distance+prm%D_a))
|
* (1.0_pReal/(dip_distance+prm%D_a))
|
||||||
dot_rho_dip_climb = (4.0_pReal*v_cl*stt%rho_dip(:,of))/(dip_distance-prm%D_a) ! ToDo: Discuss with Franz: Stress dependency?
|
dot_rho_dip_climb = (4.0_pReal*v_cl*stt%rho_dip(:,of))/(dip_distance-prm%D_a) ! ToDo: Discuss with Franz: Stress dependency?
|
||||||
end where
|
end where
|
||||||
|
|
||||||
dot%rho_mob(:,of) = abs(dot%gamma_sl(:,of))/(prm%b_sl*dst%Lambda_sl(:,of)) & ! multiplication
|
dot%rho_mob(:,of) = abs(dot%gamma_sl(:,of))/(prm%b_sl*dst%Lambda_sl(:,of)) & ! multiplication
|
||||||
- dot_rho_dip_formation &
|
- dot_rho_dip_formation &
|
||||||
- (2.0_pReal*prm%D_a)/prm%b_sl*stt%rho_mob(:,of)*abs(dot%gamma_sl(:,of)) ! Spontaneous annihilation of 2 single edge dislocations
|
- (2.0_pReal*prm%D_a)/prm%b_sl*stt%rho_mob(:,of)*abs(dot%gamma_sl(:,of)) ! Spontaneous annihilation of 2 single edge dislocations
|
||||||
dot%rho_dip(:,of) = dot_rho_dip_formation &
|
dot%rho_dip(:,of) = dot_rho_dip_formation &
|
||||||
- (2.0_pReal*prm%D_a)/prm%b_sl*stt%rho_dip(:,of)*abs(dot%gamma_sl(:,of)) & ! Spontaneous annihilation of a single edge dislocation with a dipole constituent
|
- (2.0_pReal*prm%D_a)/prm%b_sl*stt%rho_dip(:,of)*abs(dot%gamma_sl(:,of)) & ! Spontaneous annihilation of a single edge dislocation with a dipole constituent
|
||||||
- dot_rho_dip_climb
|
- dot_rho_dip_climb
|
||||||
|
|
||||||
end associate
|
end associate
|
||||||
|
|
||||||
end subroutine plastic_disloUCLA_dotState
|
end subroutine plastic_disloUCLA_dotState
|
||||||
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @brief calculates derived quantities from state
|
!> @brief Calculate derived quantities from state.
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
module subroutine plastic_disloUCLA_dependentState(instance,of)
|
module subroutine plastic_disloUCLA_dependentState(instance,of)
|
||||||
|
|
||||||
integer, intent(in) :: &
|
integer, intent(in) :: &
|
||||||
instance, &
|
instance, &
|
||||||
of
|
of
|
||||||
|
|
||||||
real(pReal), dimension(param(instance)%sum_N_sl) :: &
|
real(pReal), dimension(param(instance)%sum_N_sl) :: &
|
||||||
dislocationSpacing
|
dislocationSpacing
|
||||||
|
|
||||||
associate(prm => param(instance), stt => state(instance),dst => dependentState(instance))
|
associate(prm => param(instance), stt => state(instance),dst => dependentState(instance))
|
||||||
|
|
||||||
dislocationSpacing = sqrt(matmul(prm%forestProjectionEdge, &
|
dislocationSpacing = sqrt(matmul(prm%forestProjectionEdge, &
|
||||||
stt%rho_mob(:,of)+stt%rho_dip(:,of)))
|
stt%rho_mob(:,of)+stt%rho_dip(:,of)))
|
||||||
dst%threshold_stress(:,of) = prm%mu*prm%b_sl &
|
dst%threshold_stress(:,of) = prm%mu*prm%b_sl &
|
||||||
* sqrt(matmul(prm%h_sl_sl,stt%rho_mob(:,of)+stt%rho_dip(:,of)))
|
* sqrt(matmul(prm%h_sl_sl,stt%rho_mob(:,of)+stt%rho_dip(:,of)))
|
||||||
|
|
||||||
dst%Lambda_sl(:,of) = prm%D/(1.0_pReal+prm%D*dislocationSpacing/prm%i_sl)
|
dst%Lambda_sl(:,of) = prm%D/(1.0_pReal+prm%D*dislocationSpacing/prm%i_sl)
|
||||||
|
|
||||||
end associate
|
end associate
|
||||||
|
|
||||||
end subroutine plastic_disloUCLA_dependentState
|
end subroutine plastic_disloUCLA_dependentState
|
||||||
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @brief writes results to HDF5 output file
|
!> @brief Write results to HDF5 output file.
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
module subroutine plastic_disloUCLA_results(instance,group)
|
module subroutine plastic_disloUCLA_results(instance,group)
|
||||||
|
|
||||||
integer, intent(in) :: instance
|
integer, intent(in) :: instance
|
||||||
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(instance), stt => state(instance), dst => dependentState(instance))
|
||||||
outputsLoop: do o = 1,size(prm%outputID)
|
outputsLoop: do o = 1,size(prm%output)
|
||||||
select case(prm%outputID(o))
|
select case(trim(prm%output(o)))
|
||||||
case (rho_mob_ID)
|
case('edge_density') ! ToDo: should be rho_mob
|
||||||
call results_writeDataset(group,stt%rho_mob,'rho_mob',&
|
if(prm%sum_N_sl>0) call results_writeDataset(group,stt%rho_mob,'rho_mob',&
|
||||||
'mobile dislocation density','1/m²')
|
'mobile dislocation density','1/m²')
|
||||||
case (rho_dip_ID)
|
case('dipole_density') ! ToDo: should be rho_dip
|
||||||
call results_writeDataset(group,stt%rho_dip,'rho_dip',&
|
if(prm%sum_N_sl>0) call results_writeDataset(group,stt%rho_dip,'rho_dip',&
|
||||||
'dislocation dipole density''1/m²')
|
'dislocation dipole density''1/m²')
|
||||||
case (dot_gamma_sl_ID)
|
case('shear_rate_slip') ! should be gamma
|
||||||
call results_writeDataset(group,stt%gamma_sl,'dot_gamma_sl',& ! this is not dot!!
|
if(prm%sum_N_sl>0) call results_writeDataset(group,stt%gamma_sl,'dot_gamma_sl',& ! this is not dot!!
|
||||||
'plastic shear','1')
|
'plastic shear','1')
|
||||||
case (Lambda_sl_ID)
|
case('mfp_slip') !ToDo: should be Lambda
|
||||||
call results_writeDataset(group,dst%Lambda_sl,'Lambda_sl',&
|
if(prm%sum_N_sl>0) call results_writeDataset(group,dst%Lambda_sl,'Lambda_sl',&
|
||||||
'mean free path for slip','m')
|
'mean free path for slip','m')
|
||||||
case (tau_pass_ID)
|
case('threshold_stress_slip') !ToDo: should be tau_pass
|
||||||
call results_writeDataset(group,dst%threshold_stress,'tau_pass',&
|
if(prm%sum_N_sl>0) call results_writeDataset(group,dst%threshold_stress,'tau_pass',&
|
||||||
'threshold stress for slip','Pa')
|
'threshold stress for slip','Pa')
|
||||||
end select
|
end select
|
||||||
enddo outputsLoop
|
enddo outputsLoop
|
||||||
end associate
|
end associate
|
||||||
|
@ -468,15 +427,15 @@ end subroutine plastic_disloUCLA_results
|
||||||
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @brief Shear rates on slip systems, their derivatives with respect to resolved stress and the
|
!> @brief Calculate shear rates on slip systems, their derivatives with respect to resolved
|
||||||
! resolved stresss
|
! stress, and the resolved stress.
|
||||||
!> @details Derivatives and resolved stress are calculated only optionally.
|
!> @details Derivatives and resolved stress are calculated only optionally.
|
||||||
! 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,of, &
|
pure subroutine kinetics(Mp,T,instance,of, &
|
||||||
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) :: &
|
||||||
Mp !< Mandel stress
|
Mp !< Mandel stress
|
||||||
real(pReal), intent(in) :: &
|
real(pReal), intent(in) :: &
|
||||||
|
@ -484,7 +443,7 @@ pure subroutine kinetics(Mp,T,instance,of, &
|
||||||
integer, intent(in) :: &
|
integer, intent(in) :: &
|
||||||
instance, &
|
instance, &
|
||||||
of
|
of
|
||||||
|
|
||||||
real(pReal), intent(out), dimension(param(instance)%sum_N_sl) :: &
|
real(pReal), intent(out), dimension(param(instance)%sum_N_sl) :: &
|
||||||
dot_gamma_pos, &
|
dot_gamma_pos, &
|
||||||
dot_gamma_neg
|
dot_gamma_neg
|
||||||
|
@ -501,82 +460,82 @@ pure subroutine kinetics(Mp,T,instance,of, &
|
||||||
t_n, t_k, dtk,dtn, &
|
t_n, t_k, dtk,dtn, &
|
||||||
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(instance), stt => state(instance), dst => dependentState(instance))
|
||||||
|
|
||||||
do j = 1, prm%sum_N_sl
|
do j = 1, prm%sum_N_sl
|
||||||
tau_pos(j) = math_mul33xx33(Mp,prm%nonSchmid_pos(1:3,1:3,j))
|
tau_pos(j) = math_mul33xx33(Mp,prm%nonSchmid_pos(1:3,1:3,j))
|
||||||
tau_neg(j) = math_mul33xx33(Mp,prm%nonSchmid_neg(1:3,1:3,j))
|
tau_neg(j) = math_mul33xx33(Mp,prm%nonSchmid_neg(1:3,1:3,j))
|
||||||
enddo
|
enddo
|
||||||
|
|
||||||
|
|
||||||
if (present(tau_pos_out)) tau_pos_out = tau_pos
|
if (present(tau_pos_out)) tau_pos_out = tau_pos
|
||||||
if (present(tau_neg_out)) tau_neg_out = tau_neg
|
if (present(tau_neg_out)) tau_neg_out = tau_neg
|
||||||
|
|
||||||
associate(BoltzmannRatio => prm%delta_F/(kB*T), &
|
associate(BoltzmannRatio => prm%delta_F/(kB*T), &
|
||||||
dot_gamma_0 => stt%rho_mob(:,of)*prm%b_sl*prm%v0, &
|
dot_gamma_0 => stt%rho_mob(:,of)*prm%b_sl*prm%v0, &
|
||||||
effectiveLength => dst%Lambda_sl(:,of) - prm%w)
|
effectiveLength => dst%Lambda_sl(:,of) - prm%w)
|
||||||
|
|
||||||
significantPositiveTau: where(abs(tau_pos)-dst%threshold_stress(:,of) > tol_math_check)
|
significantPositiveTau: where(abs(tau_pos)-dst%threshold_stress(:,of) > tol_math_check)
|
||||||
StressRatio = (abs(tau_pos)-dst%threshold_stress(:,of))/prm%tau_0
|
StressRatio = (abs(tau_pos)-dst%threshold_stress(:,of))/prm%tau_0
|
||||||
StressRatio_p = StressRatio** prm%p
|
StressRatio_p = StressRatio** prm%p
|
||||||
StressRatio_pminus1 = StressRatio**(prm%p-1.0_pReal)
|
StressRatio_pminus1 = StressRatio**(prm%p-1.0_pReal)
|
||||||
needsGoodName = exp(-BoltzmannRatio*(1-StressRatio_p) ** prm%q)
|
needsGoodName = exp(-BoltzmannRatio*(1-StressRatio_p) ** prm%q)
|
||||||
|
|
||||||
t_n = prm%b_sl/(needsGoodName*prm%omega*effectiveLength)
|
t_n = prm%b_sl/(needsGoodName*prm%omega*effectiveLength)
|
||||||
t_k = effectiveLength * prm%B /(2.0_pReal*prm%b_sl*tau_pos)
|
t_k = effectiveLength * prm%B /(2.0_pReal*prm%b_sl*tau_pos)
|
||||||
|
|
||||||
vel = prm%kink_height/(t_n + t_k)
|
vel = prm%kink_height/(t_n + t_k)
|
||||||
|
|
||||||
dot_gamma_pos = dot_gamma_0 * sign(vel,tau_pos) * 0.5_pReal
|
dot_gamma_pos = dot_gamma_0 * sign(vel,tau_pos) * 0.5_pReal
|
||||||
else where significantPositiveTau
|
else where significantPositiveTau
|
||||||
dot_gamma_pos = 0.0_pReal
|
dot_gamma_pos = 0.0_pReal
|
||||||
end where significantPositiveTau
|
end where significantPositiveTau
|
||||||
|
|
||||||
if (present(ddot_gamma_dtau_pos)) then
|
if (present(ddot_gamma_dtau_pos)) then
|
||||||
significantPositiveTau2: where(abs(tau_pos)-dst%threshold_stress(:,of) > tol_math_check)
|
significantPositiveTau2: where(abs(tau_pos)-dst%threshold_stress(:,of) > tol_math_check)
|
||||||
dtn = -1.0_pReal * t_n * BoltzmannRatio * prm%p * prm%q * (1.0_pReal-StressRatio_p)**(prm%q - 1.0_pReal) &
|
dtn = -1.0_pReal * t_n * BoltzmannRatio * prm%p * prm%q * (1.0_pReal-StressRatio_p)**(prm%q - 1.0_pReal) &
|
||||||
* (StressRatio)**(prm%p - 1.0_pReal) / prm%tau_0
|
* (StressRatio)**(prm%p - 1.0_pReal) / prm%tau_0
|
||||||
dtk = -1.0_pReal * t_k / tau_pos
|
dtk = -1.0_pReal * t_k / tau_pos
|
||||||
|
|
||||||
dvel = -1.0_pReal * prm%kink_height * (dtk + dtn) / (t_n + t_k)**2.0_pReal
|
dvel = -1.0_pReal * prm%kink_height * (dtk + dtn) / (t_n + t_k)**2.0_pReal
|
||||||
|
|
||||||
ddot_gamma_dtau_pos = dot_gamma_0 * dvel* 0.5_pReal
|
ddot_gamma_dtau_pos = dot_gamma_0 * dvel* 0.5_pReal
|
||||||
else where significantPositiveTau2
|
else where significantPositiveTau2
|
||||||
ddot_gamma_dtau_pos = 0.0_pReal
|
ddot_gamma_dtau_pos = 0.0_pReal
|
||||||
end where significantPositiveTau2
|
end where significantPositiveTau2
|
||||||
endif
|
endif
|
||||||
|
|
||||||
significantNegativeTau: where(abs(tau_neg)-dst%threshold_stress(:,of) > tol_math_check)
|
significantNegativeTau: where(abs(tau_neg)-dst%threshold_stress(:,of) > tol_math_check)
|
||||||
StressRatio = (abs(tau_neg)-dst%threshold_stress(:,of))/prm%tau_0
|
StressRatio = (abs(tau_neg)-dst%threshold_stress(:,of))/prm%tau_0
|
||||||
StressRatio_p = StressRatio** prm%p
|
StressRatio_p = StressRatio** prm%p
|
||||||
StressRatio_pminus1 = StressRatio**(prm%p-1.0_pReal)
|
StressRatio_pminus1 = StressRatio**(prm%p-1.0_pReal)
|
||||||
needsGoodName = exp(-BoltzmannRatio*(1-StressRatio_p) ** prm%q)
|
needsGoodName = exp(-BoltzmannRatio*(1-StressRatio_p) ** prm%q)
|
||||||
|
|
||||||
t_n = prm%b_sl/(needsGoodName*prm%omega*effectiveLength)
|
t_n = prm%b_sl/(needsGoodName*prm%omega*effectiveLength)
|
||||||
t_k = effectiveLength * prm%B /(2.0_pReal*prm%b_sl*tau_pos)
|
t_k = effectiveLength * prm%B /(2.0_pReal*prm%b_sl*tau_pos)
|
||||||
|
|
||||||
vel = prm%kink_height/(t_n + t_k)
|
vel = prm%kink_height/(t_n + t_k)
|
||||||
|
|
||||||
dot_gamma_neg = dot_gamma_0 * sign(vel,tau_neg) * 0.5_pReal
|
dot_gamma_neg = dot_gamma_0 * sign(vel,tau_neg) * 0.5_pReal
|
||||||
else where significantNegativeTau
|
else where significantNegativeTau
|
||||||
dot_gamma_neg = 0.0_pReal
|
dot_gamma_neg = 0.0_pReal
|
||||||
end where significantNegativeTau
|
end where significantNegativeTau
|
||||||
|
|
||||||
if (present(ddot_gamma_dtau_neg)) then
|
if (present(ddot_gamma_dtau_neg)) then
|
||||||
significantNegativeTau2: where(abs(tau_neg)-dst%threshold_stress(:,of) > tol_math_check)
|
significantNegativeTau2: where(abs(tau_neg)-dst%threshold_stress(:,of) > tol_math_check)
|
||||||
dtn = -1.0_pReal * t_n * BoltzmannRatio * prm%p * prm%q * (1.0_pReal-StressRatio_p)**(prm%q - 1.0_pReal) &
|
dtn = -1.0_pReal * t_n * BoltzmannRatio * prm%p * prm%q * (1.0_pReal-StressRatio_p)**(prm%q - 1.0_pReal) &
|
||||||
* (StressRatio)**(prm%p - 1.0_pReal) / prm%tau_0
|
* (StressRatio)**(prm%p - 1.0_pReal) / prm%tau_0
|
||||||
dtk = -1.0_pReal * t_k / tau_neg
|
dtk = -1.0_pReal * t_k / tau_neg
|
||||||
|
|
||||||
dvel = -1.0_pReal * prm%kink_height * (dtk + dtn) / (t_n + t_k)**2.0_pReal
|
dvel = -1.0_pReal * prm%kink_height * (dtk + dtn) / (t_n + t_k)**2.0_pReal
|
||||||
|
|
||||||
ddot_gamma_dtau_neg = dot_gamma_0 * dvel * 0.5_pReal
|
ddot_gamma_dtau_neg = dot_gamma_0 * dvel * 0.5_pReal
|
||||||
else where significantNegativeTau2
|
else where significantNegativeTau2
|
||||||
ddot_gamma_dtau_neg = 0.0_pReal
|
ddot_gamma_dtau_neg = 0.0_pReal
|
||||||
end where significantNegativeTau2
|
end where significantNegativeTau2
|
||||||
end if
|
end if
|
||||||
|
|
||||||
end associate
|
end associate
|
||||||
end associate
|
end associate
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -8,14 +8,7 @@
|
||||||
!! untextured polycrystal
|
!! untextured polycrystal
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
submodule(constitutive) plastic_isotropic
|
submodule(constitutive) plastic_isotropic
|
||||||
|
|
||||||
enum, bind(c)
|
|
||||||
enumerator :: &
|
|
||||||
undefined_ID, &
|
|
||||||
xi_ID, &
|
|
||||||
dot_gamma_ID
|
|
||||||
end enum
|
|
||||||
|
|
||||||
type :: tParameters
|
type :: tParameters
|
||||||
real(pReal) :: &
|
real(pReal) :: &
|
||||||
M, & !< Taylor factor
|
M, & !< Taylor factor
|
||||||
|
@ -34,12 +27,12 @@ submodule(constitutive) plastic_isotropic
|
||||||
aTol_gamma
|
aTol_gamma
|
||||||
integer :: &
|
integer :: &
|
||||||
of_debug = 0
|
of_debug = 0
|
||||||
integer(kind(undefined_ID)), allocatable, dimension(:) :: &
|
|
||||||
outputID
|
|
||||||
logical :: &
|
logical :: &
|
||||||
dilatation
|
dilatation
|
||||||
|
character(len=pStringLen), allocatable, dimension(:) :: &
|
||||||
|
output
|
||||||
end type tParameters
|
end type tParameters
|
||||||
|
|
||||||
type :: tIsotropicState
|
type :: tIsotropicState
|
||||||
real(pReal), pointer, dimension(:) :: &
|
real(pReal), pointer, dimension(:) :: &
|
||||||
xi, &
|
xi, &
|
||||||
|
@ -56,50 +49,45 @@ submodule(constitutive) plastic_isotropic
|
||||||
contains
|
contains
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @brief module initialization
|
!> @brief Perform 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 subroutine plastic_isotropic_init
|
module subroutine plastic_isotropic_init
|
||||||
|
|
||||||
integer :: &
|
integer :: &
|
||||||
Ninstance, &
|
Ninstance, &
|
||||||
p, i, &
|
p, &
|
||||||
NipcMyPhase, &
|
NipcMyPhase, &
|
||||||
sizeState, sizeDotState
|
sizeState, sizeDotState
|
||||||
|
|
||||||
integer(kind(undefined_ID)) :: &
|
|
||||||
outputID
|
|
||||||
|
|
||||||
character(len=pStringLen) :: &
|
character(len=pStringLen) :: &
|
||||||
extmsg = ''
|
extmsg = ''
|
||||||
character(len=pStringLen), dimension(:), allocatable :: &
|
|
||||||
outputs
|
write(6,'(/,a)') ' <<<+- plastic_'//PLASTICITY_ISOTROPIC_label//' init -+>>>'; flush(6)
|
||||||
|
|
||||||
write(6,'(/,a)') ' <<<+- plastic_'//PLASTICITY_ISOTROPIC_label//' init -+>>>'
|
write(6,'(/,a)') ' Maiti and Eisenlohr, Scripta Materialia 145:37–40, 2018'
|
||||||
|
write(6,'(a)') ' https://doi.org/10.1016/j.scriptamat.2017.09.047'
|
||||||
write(6,'(/,a)') ' Maiti and Eisenlohr, Scripta Materialia 145:37–40, 2018'
|
|
||||||
write(6,'(a)') ' https://doi.org/10.1016/j.scriptamat.2017.09.047'
|
|
||||||
|
|
||||||
Ninstance = count(phase_plasticity == PLASTICITY_ISOTROPIC_ID)
|
Ninstance = count(phase_plasticity == PLASTICITY_ISOTROPIC_ID)
|
||||||
if (iand(debug_level(debug_constitutive),debug_levelBasic) /= 0) &
|
if (iand(debug_level(debug_constitutive),debug_levelBasic) /= 0) &
|
||||||
write(6,'(a16,1x,i5,/)') '# instances:',Ninstance
|
write(6,'(a16,1x,i5,/)') '# instances:',Ninstance
|
||||||
|
|
||||||
allocate(param(Ninstance))
|
allocate(param(Ninstance))
|
||||||
allocate(state(Ninstance))
|
allocate(state(Ninstance))
|
||||||
allocate(dotState(Ninstance))
|
allocate(dotState(Ninstance))
|
||||||
|
|
||||||
do p = 1, size(phase_plasticity)
|
do p = 1, size(phase_plasticity)
|
||||||
if (phase_plasticity(p) /= PLASTICITY_ISOTROPIC_ID) cycle
|
if (phase_plasticity(p) /= PLASTICITY_ISOTROPIC_ID) cycle
|
||||||
associate(prm => param(phase_plasticityInstance(p)), &
|
associate(prm => param(phase_plasticityInstance(p)), &
|
||||||
dot => dotState(phase_plasticityInstance(p)), &
|
dot => dotState(phase_plasticityInstance(p)), &
|
||||||
stt => state(phase_plasticityInstance(p)), &
|
stt => state(phase_plasticityInstance(p)), &
|
||||||
config => config_phase(p))
|
config => config_phase(p))
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
if (p==material_phaseAt(debug_g,debug_e)) &
|
if (p==material_phaseAt(debug_g,debug_e)) &
|
||||||
prm%of_debug = material_phasememberAt(debug_g,debug_i,debug_e)
|
prm%of_debug = material_phasememberAt(debug_g,debug_i,debug_e)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
prm%xi_0 = config%getFloat('tau0')
|
prm%xi_0 = config%getFloat('tau0')
|
||||||
prm%xi_inf = config%getFloat('tausat')
|
prm%xi_inf = config%getFloat('tausat')
|
||||||
prm%dot_gamma_0 = config%getFloat('gdot0')
|
prm%dot_gamma_0 = config%getFloat('gdot0')
|
||||||
|
@ -114,9 +102,9 @@ module subroutine plastic_isotropic_init
|
||||||
prm%a = config%getFloat('a')
|
prm%a = config%getFloat('a')
|
||||||
prm%aTol_xi = config%getFloat('atol_flowstress',defaultVal=1.0_pReal)
|
prm%aTol_xi = config%getFloat('atol_flowstress',defaultVal=1.0_pReal)
|
||||||
prm%aTol_gamma = config%getFloat('atol_shear', defaultVal=1.0e-6_pReal)
|
prm%aTol_gamma = config%getFloat('atol_shear', defaultVal=1.0e-6_pReal)
|
||||||
|
|
||||||
prm%dilatation = config%keyExists('/dilatation/')
|
prm%dilatation = config%keyExists('/dilatation/')
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! sanity checks
|
! sanity checks
|
||||||
extmsg = ''
|
extmsg = ''
|
||||||
|
@ -128,79 +116,62 @@ module subroutine plastic_isotropic_init
|
||||||
if (prm%M <= 0.0_pReal) extmsg = trim(extmsg)//' m'
|
if (prm%M <= 0.0_pReal) extmsg = trim(extmsg)//' m'
|
||||||
if (prm%aTol_xi <= 0.0_pReal) extmsg = trim(extmsg)//' atol_xi'
|
if (prm%aTol_xi <= 0.0_pReal) extmsg = trim(extmsg)//' atol_xi'
|
||||||
if (prm%aTol_gamma <= 0.0_pReal) extmsg = trim(extmsg)//' atol_shear'
|
if (prm%aTol_gamma <= 0.0_pReal) extmsg = trim(extmsg)//' atol_shear'
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! exit if any parameter is out of range
|
! exit if any parameter is out of range
|
||||||
if (extmsg /= '') &
|
if (extmsg /= '') &
|
||||||
call IO_error(211,ext_msg=trim(extmsg)//'('//PLASTICITY_ISOTROPIC_label//')')
|
call IO_error(211,ext_msg=trim(extmsg)//'('//PLASTICITY_ISOTROPIC_label//')')
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! output pararameters
|
! output pararameters
|
||||||
outputs = config%getStrings('(output)',defaultVal=emptyStringArray)
|
prm%output = config%getStrings('(output)',defaultVal=emptyStringArray)
|
||||||
allocate(prm%outputID(0))
|
|
||||||
do i=1, size(outputs)
|
|
||||||
outputID = undefined_ID
|
|
||||||
select case(outputs(i))
|
|
||||||
|
|
||||||
case ('flowstress')
|
|
||||||
outputID = xi_ID
|
|
||||||
case ('strainrate')
|
|
||||||
outputID = dot_gamma_ID
|
|
||||||
|
|
||||||
end select
|
|
||||||
|
|
||||||
if (outputID /= undefined_ID) then
|
|
||||||
prm%outputID = [prm%outputID, outputID]
|
|
||||||
endif
|
|
||||||
|
|
||||||
enddo
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! allocate state arrays
|
! allocate state arrays
|
||||||
NipcMyPhase = count(material_phaseAt == p) * discretization_nIP
|
NipcMyPhase = count(material_phaseAt == p) * discretization_nIP
|
||||||
sizeDotState = size(['xi ','accumulated_shear'])
|
sizeDotState = size(['xi ','accumulated_shear'])
|
||||||
sizeState = sizeDotState
|
sizeState = sizeDotState
|
||||||
|
|
||||||
call material_allocatePlasticState(p,NipcMyPhase,sizeState,sizeDotState,0)
|
call material_allocatePlasticState(p,NipcMyPhase,sizeState,sizeDotState,0)
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! locally defined state aliases and initialization of state0 and aTolState
|
! locally defined state aliases and initialization of state0 and aTolState
|
||||||
stt%xi => plasticState(p)%state (1,:)
|
stt%xi => plasticState(p)%state (1,:)
|
||||||
stt%xi = prm%xi_0
|
stt%xi = prm%xi_0
|
||||||
dot%xi => plasticState(p)%dotState(1,:)
|
dot%xi => plasticState(p)%dotState(1,:)
|
||||||
plasticState(p)%aTolState(1) = prm%aTol_xi
|
plasticState(p)%aTolState(1) = prm%aTol_xi
|
||||||
|
|
||||||
stt%gamma => plasticState(p)%state (2,:)
|
stt%gamma => plasticState(p)%state (2,:)
|
||||||
dot%gamma => plasticState(p)%dotState(2,:)
|
dot%gamma => plasticState(p)%dotState(2,:)
|
||||||
plasticState(p)%aTolState(2) = prm%aTol_gamma
|
plasticState(p)%aTolState(2) = prm%aTol_gamma
|
||||||
! global alias
|
! global alias
|
||||||
plasticState(p)%slipRate => plasticState(p)%dotState(2:2,:)
|
plasticState(p)%slipRate => plasticState(p)%dotState(2:2,:)
|
||||||
|
|
||||||
plasticState(p)%state0 = plasticState(p)%state ! ToDo: this could be done centrally
|
plasticState(p)%state0 = plasticState(p)%state ! ToDo: this could be done centrally
|
||||||
|
|
||||||
end associate
|
end associate
|
||||||
|
|
||||||
enddo
|
enddo
|
||||||
|
|
||||||
end subroutine plastic_isotropic_init
|
end subroutine plastic_isotropic_init
|
||||||
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @brief calculates plastic velocity gradient and its tangent
|
!> @brief Calculate plastic velocity gradient and its tangent.
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
module subroutine plastic_isotropic_LpAndItsTangent(Lp,dLp_dMp,Mp,instance,of)
|
module subroutine plastic_isotropic_LpAndItsTangent(Lp,dLp_dMp,Mp,instance,of)
|
||||||
|
|
||||||
real(pReal), dimension(3,3), intent(out) :: &
|
real(pReal), dimension(3,3), intent(out) :: &
|
||||||
Lp !< plastic velocity gradient
|
Lp !< plastic velocity gradient
|
||||||
real(pReal), dimension(3,3,3,3), intent(out) :: &
|
real(pReal), dimension(3,3,3,3), intent(out) :: &
|
||||||
dLp_dMp !< derivative of Lp with respect to the Mandel stress
|
dLp_dMp !< derivative of Lp with respect to the Mandel stress
|
||||||
|
|
||||||
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, &
|
instance, &
|
||||||
of
|
of
|
||||||
|
|
||||||
real(pReal), dimension(3,3) :: &
|
real(pReal), dimension(3,3) :: &
|
||||||
Mp_dev !< deviatoric part of the Mandel stress
|
Mp_dev !< deviatoric part of the Mandel stress
|
||||||
real(pReal) :: &
|
real(pReal) :: &
|
||||||
|
@ -209,16 +180,16 @@ module subroutine plastic_isotropic_LpAndItsTangent(Lp,dLp_dMp,Mp,instance,of)
|
||||||
squarenorm_Mp_dev !< square of the norm of the deviatoric part of the Mandel stress
|
squarenorm_Mp_dev !< square of the norm of the deviatoric part of the Mandel stress
|
||||||
integer :: &
|
integer :: &
|
||||||
k, l, m, n
|
k, l, m, n
|
||||||
|
|
||||||
associate(prm => param(instance), stt => state(instance))
|
associate(prm => param(instance), stt => state(instance))
|
||||||
|
|
||||||
Mp_dev = math_deviatoric33(Mp)
|
Mp_dev = math_deviatoric33(Mp)
|
||||||
squarenorm_Mp_dev = math_mul33xx33(Mp_dev,Mp_dev)
|
squarenorm_Mp_dev = math_mul33xx33(Mp_dev,Mp_dev)
|
||||||
norm_Mp_dev = sqrt(squarenorm_Mp_dev)
|
norm_Mp_dev = sqrt(squarenorm_Mp_dev)
|
||||||
|
|
||||||
if (norm_Mp_dev > 0.0_pReal) then
|
if (norm_Mp_dev > 0.0_pReal) then
|
||||||
dot_gamma = prm%dot_gamma_0 * (sqrt(1.5_pReal) * norm_Mp_dev/(prm%M*stt%xi(of))) **prm%n
|
dot_gamma = prm%dot_gamma_0 * (sqrt(1.5_pReal) * norm_Mp_dev/(prm%M*stt%xi(of))) **prm%n
|
||||||
|
|
||||||
Lp = dot_gamma/prm%M * Mp_dev/norm_Mp_dev
|
Lp = dot_gamma/prm%M * Mp_dev/norm_Mp_dev
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
if (iand(debug_level(debug_constitutive), debug_levelExtensive) /= 0 &
|
if (iand(debug_level(debug_constitutive), debug_levelExtensive) /= 0 &
|
||||||
|
@ -240,42 +211,42 @@ module subroutine plastic_isotropic_LpAndItsTangent(Lp,dLp_dMp,Mp,instance,of)
|
||||||
Lp = 0.0_pReal
|
Lp = 0.0_pReal
|
||||||
dLp_dMp = 0.0_pReal
|
dLp_dMp = 0.0_pReal
|
||||||
end if
|
end if
|
||||||
|
|
||||||
end associate
|
end associate
|
||||||
|
|
||||||
end subroutine plastic_isotropic_LpAndItsTangent
|
end subroutine plastic_isotropic_LpAndItsTangent
|
||||||
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @brief calculates plastic velocity gradient and its tangent
|
!> @brief Calculate inelastic velocity gradient and its tangent.
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
module subroutine plastic_isotropic_LiAndItsTangent(Li,dLi_dMi,Mi,instance,of)
|
module subroutine plastic_isotropic_LiAndItsTangent(Li,dLi_dMi,Mi,instance,of)
|
||||||
|
|
||||||
real(pReal), dimension(3,3), intent(out) :: &
|
real(pReal), dimension(3,3), intent(out) :: &
|
||||||
Li !< inleastic velocity gradient
|
Li !< inleastic velocity gradient
|
||||||
real(pReal), dimension(3,3,3,3), intent(out) :: &
|
real(pReal), dimension(3,3,3,3), intent(out) :: &
|
||||||
dLi_dMi !< derivative of Li with respect to Mandel stress
|
dLi_dMi !< derivative of Li with respect to Mandel stress
|
||||||
|
|
||||||
real(pReal), dimension(3,3), intent(in) :: &
|
real(pReal), dimension(3,3), intent(in) :: &
|
||||||
Mi !< Mandel stress
|
Mi !< Mandel stress
|
||||||
integer, intent(in) :: &
|
integer, intent(in) :: &
|
||||||
instance, &
|
instance, &
|
||||||
of
|
of
|
||||||
|
|
||||||
real(pReal) :: &
|
real(pReal) :: &
|
||||||
tr !< trace of spherical part of Mandel stress (= 3 x pressure)
|
tr !< trace of spherical part of Mandel stress (= 3 x pressure)
|
||||||
integer :: &
|
integer :: &
|
||||||
k, l, m, n
|
k, l, m, n
|
||||||
|
|
||||||
associate(prm => param(instance), stt => state(instance))
|
associate(prm => param(instance), stt => state(instance))
|
||||||
|
|
||||||
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(of))**(-prm%n) &
|
* prm%dot_gamma_0/prm%M * (3.0_pReal*prm%M*stt%xi(of))**(-prm%n) &
|
||||||
* tr * abs(tr)**(prm%n-1.0_pReal)
|
* tr * abs(tr)**(prm%n-1.0_pReal)
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
if (iand(debug_level(debug_constitutive), debug_levelExtensive) /= 0 &
|
if (iand(debug_level(debug_constitutive), debug_levelExtensive) /= 0 &
|
||||||
.and. (of == prm%of_debug .or. .not. iand(debug_level(debug_constitutive),debug_levelSelective) /= 0)) then
|
.and. (of == prm%of_debug .or. .not. iand(debug_level(debug_constitutive),debug_levelSelective) /= 0)) then
|
||||||
|
@ -292,38 +263,38 @@ module subroutine plastic_isotropic_LiAndItsTangent(Li,dLi_dMi,Mi,instance,of)
|
||||||
Li = 0.0_pReal
|
Li = 0.0_pReal
|
||||||
dLi_dMi = 0.0_pReal
|
dLi_dMi = 0.0_pReal
|
||||||
endif
|
endif
|
||||||
|
|
||||||
end associate
|
end associate
|
||||||
|
|
||||||
end subroutine plastic_isotropic_LiAndItsTangent
|
end subroutine plastic_isotropic_LiAndItsTangent
|
||||||
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @brief calculates the rate of change of microstructure
|
!> @brief Calculate the rate of change of microstructure.
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
module subroutine plastic_isotropic_dotState(Mp,instance,of)
|
module subroutine plastic_isotropic_dotState(Mp,instance,of)
|
||||||
|
|
||||||
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, &
|
instance, &
|
||||||
of
|
of
|
||||||
|
|
||||||
real(pReal) :: &
|
real(pReal) :: &
|
||||||
dot_gamma, & !< strainrate
|
dot_gamma, & !< strainrate
|
||||||
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(instance), stt => state(instance), dot => dotState(instance))
|
associate(prm => param(instance), stt => state(instance), dot => dotState(instance))
|
||||||
|
|
||||||
if (prm%dilatation) then
|
if (prm%dilatation) then
|
||||||
norm_Mp = sqrt(math_mul33xx33(Mp,Mp))
|
norm_Mp = sqrt(math_mul33xx33(Mp,Mp))
|
||||||
else
|
else
|
||||||
norm_Mp = sqrt(math_mul33xx33(math_deviatoric33(Mp),math_deviatoric33(Mp)))
|
norm_Mp = sqrt(math_mul33xx33(math_deviatoric33(Mp),math_deviatoric33(Mp)))
|
||||||
endif
|
endif
|
||||||
|
|
||||||
dot_gamma = prm%dot_gamma_0 * (sqrt(1.5_pReal) * norm_Mp /(prm%M*stt%xi(of))) **prm%n
|
dot_gamma = prm%dot_gamma_0 * (sqrt(1.5_pReal) * norm_Mp /(prm%M*stt%xi(of))) **prm%n
|
||||||
|
|
||||||
if (dot_gamma > 1e-12_pReal) then
|
if (dot_gamma > 1e-12_pReal) then
|
||||||
if (dEq0(prm%c_1)) then
|
if (dEq0(prm%c_1)) then
|
||||||
xi_inf_star = prm%xi_inf
|
xi_inf_star = prm%xi_inf
|
||||||
|
@ -339,28 +310,28 @@ module subroutine plastic_isotropic_dotState(Mp,instance,of)
|
||||||
else
|
else
|
||||||
dot%xi(of) = 0.0_pReal
|
dot%xi(of) = 0.0_pReal
|
||||||
endif
|
endif
|
||||||
|
|
||||||
dot%gamma(of) = dot_gamma ! ToDo: not really used
|
dot%gamma(of) = dot_gamma ! ToDo: not really used
|
||||||
|
|
||||||
end associate
|
end associate
|
||||||
|
|
||||||
end subroutine plastic_isotropic_dotState
|
end subroutine plastic_isotropic_dotState
|
||||||
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @brief writes results to HDF5 output file
|
!> @brief Write results to HDF5 output file.
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
module subroutine plastic_isotropic_results(instance,group)
|
module subroutine plastic_isotropic_results(instance,group)
|
||||||
|
|
||||||
integer, intent(in) :: instance
|
integer, intent(in) :: instance
|
||||||
character(len=*), intent(in) :: group
|
character(len=*), intent(in) :: group
|
||||||
|
|
||||||
integer :: o
|
integer :: o
|
||||||
|
|
||||||
associate(prm => param(instance), stt => state(instance))
|
associate(prm => param(instance), stt => state(instance))
|
||||||
outputsLoop: do o = 1,size(prm%outputID)
|
outputsLoop: do o = 1,size(prm%output)
|
||||||
select case(prm%outputID(o))
|
select case(trim(prm%output(o)))
|
||||||
case (xi_ID)
|
case ('flowstress') ! ToDo: should be 'xi'
|
||||||
call results_writeDataset(group,stt%xi,'xi','resistance against plastic flow','Pa')
|
call results_writeDataset(group,stt%xi,'xi','resistance against plastic flow','Pa')
|
||||||
end select
|
end select
|
||||||
enddo outputsLoop
|
enddo outputsLoop
|
||||||
|
|
|
@ -7,26 +7,13 @@
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
submodule(constitutive) plastic_kinehardening
|
submodule(constitutive) plastic_kinehardening
|
||||||
|
|
||||||
enum, bind(c)
|
|
||||||
enumerator :: &
|
|
||||||
undefined_ID, &
|
|
||||||
crss_ID, & !< critical resolved stress
|
|
||||||
crss_back_ID, & !< critical resolved back stress
|
|
||||||
sense_ID, & !< sense of acting shear stress (-1 or +1)
|
|
||||||
chi0_ID, & !< backstress at last switch of stress sense (positive?)
|
|
||||||
gamma0_ID, & !< accumulated shear at last switch of stress sense (at current switch?)
|
|
||||||
accshear_ID, &
|
|
||||||
shearrate_ID, &
|
|
||||||
resolvedstress_ID
|
|
||||||
end enum
|
|
||||||
|
|
||||||
type :: tParameters
|
type :: tParameters
|
||||||
real(pReal) :: &
|
real(pReal) :: &
|
||||||
gdot0, & !< reference shear strain rate for slip
|
gdot0, & !< reference shear strain rate for slip
|
||||||
n, & !< stress exponent for slip
|
n, & !< stress exponent for slip
|
||||||
aTolResistance, &
|
aTolResistance, &
|
||||||
aTolShear
|
aTolShear
|
||||||
real(pReal), allocatable, dimension(:) :: &
|
real(pReal), allocatable, dimension(:) :: &
|
||||||
crss0, & !< initial critical shear stress for slip
|
crss0, & !< initial critical shear stress for slip
|
||||||
theta0, & !< initial hardening rate of forward stress for each slip
|
theta0, & !< initial hardening rate of forward stress for each slip
|
||||||
theta1, & !< asymptotic hardening rate of forward stress for each slip
|
theta1, & !< asymptotic hardening rate of forward stress for each slip
|
||||||
|
@ -35,21 +22,21 @@ submodule(constitutive) plastic_kinehardening
|
||||||
tau1, &
|
tau1, &
|
||||||
tau1_b, &
|
tau1_b, &
|
||||||
nonSchmidCoeff
|
nonSchmidCoeff
|
||||||
real(pReal), allocatable, dimension(:,:) :: &
|
real(pReal), allocatable, dimension(:,:) :: &
|
||||||
interaction_slipslip !< slip resistance from slip activity
|
interaction_slipslip !< slip resistance from slip activity
|
||||||
real(pReal), allocatable, dimension(:,:,:) :: &
|
real(pReal), allocatable, dimension(:,:,:) :: &
|
||||||
Schmid, &
|
Schmid, &
|
||||||
nonSchmid_pos, &
|
nonSchmid_pos, &
|
||||||
nonSchmid_neg
|
nonSchmid_neg
|
||||||
integer :: &
|
integer :: &
|
||||||
totalNslip, & !< total number of active slip system
|
totalNslip, & !< total number of active slip system
|
||||||
of_debug = 0
|
of_debug = 0
|
||||||
integer, allocatable, dimension(:) :: &
|
integer, allocatable, dimension(:) :: &
|
||||||
Nslip !< number of active slip systems for each family
|
Nslip !< number of active slip systems for each family
|
||||||
integer(kind(undefined_ID)), allocatable, dimension(:) :: &
|
character(len=pStringLen), allocatable, dimension(:) :: &
|
||||||
outputID !< ID of each post result output
|
output
|
||||||
end type tParameters
|
end type tParameters
|
||||||
|
|
||||||
type :: tKinehardeningState
|
type :: tKinehardeningState
|
||||||
real(pReal), pointer, dimension(:,:) :: & !< vectors along NipcMyInstance
|
real(pReal), pointer, dimension(:,:) :: & !< vectors along NipcMyInstance
|
||||||
crss, & !< critical resolved stress
|
crss, & !< critical resolved stress
|
||||||
|
@ -59,7 +46,7 @@ submodule(constitutive) plastic_kinehardening
|
||||||
gamma0, & !< accumulated shear at last switch of stress sense
|
gamma0, & !< accumulated shear at last switch of stress sense
|
||||||
accshear !< accumulated (absolute) shear
|
accshear !< accumulated (absolute) shear
|
||||||
end type tKinehardeningState
|
end type tKinehardeningState
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! containers for parameters and state
|
! containers for parameters and state
|
||||||
type(tParameters), allocatable, dimension(:) :: param
|
type(tParameters), allocatable, dimension(:) :: param
|
||||||
|
@ -72,37 +59,32 @@ contains
|
||||||
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @brief module initialization
|
!> @brief Perform 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 subroutine plastic_kinehardening_init
|
module subroutine plastic_kinehardening_init
|
||||||
|
|
||||||
integer :: &
|
integer :: &
|
||||||
Ninstance, &
|
Ninstance, &
|
||||||
p, i, o, &
|
p, o, &
|
||||||
NipcMyPhase, &
|
NipcMyPhase, &
|
||||||
sizeState, sizeDeltaState, sizeDotState, &
|
sizeState, sizeDeltaState, sizeDotState, &
|
||||||
startIndex, endIndex
|
startIndex, endIndex
|
||||||
|
|
||||||
integer(kind(undefined_ID)) :: &
|
|
||||||
outputID
|
|
||||||
|
|
||||||
character(len=pStringLen) :: &
|
character(len=pStringLen) :: &
|
||||||
extmsg = ''
|
extmsg = ''
|
||||||
character(len=pStringLen), dimension(:), allocatable :: &
|
|
||||||
outputs
|
write(6,'(/,a)') ' <<<+- plastic_'//PLASTICITY_KINEHARDENING_label//' init -+>>>'; flush(6)
|
||||||
|
|
||||||
write(6,'(/,a)') ' <<<+- plastic_'//PLASTICITY_KINEHARDENING_label//' init -+>>>'
|
|
||||||
|
|
||||||
Ninstance = count(phase_plasticity == PLASTICITY_KINEHARDENING_ID)
|
Ninstance = count(phase_plasticity == PLASTICITY_KINEHARDENING_ID)
|
||||||
if (iand(debug_level(debug_constitutive),debug_levelBasic) /= 0) &
|
if (iand(debug_level(debug_constitutive),debug_levelBasic) /= 0) &
|
||||||
write(6,'(a16,1x,i5,/)') '# instances:',Ninstance
|
write(6,'(a16,1x,i5,/)') '# instances:',Ninstance
|
||||||
|
|
||||||
allocate(param(Ninstance))
|
allocate(param(Ninstance))
|
||||||
allocate(state(Ninstance))
|
allocate(state(Ninstance))
|
||||||
allocate(dotState(Ninstance))
|
allocate(dotState(Ninstance))
|
||||||
allocate(deltaState(Ninstance))
|
allocate(deltaState(Ninstance))
|
||||||
|
|
||||||
do p = 1, size(phase_plasticityInstance)
|
do p = 1, size(phase_plasticityInstance)
|
||||||
if (phase_plasticity(p) /= PLASTICITY_KINEHARDENING_ID) cycle
|
if (phase_plasticity(p) /= PLASTICITY_KINEHARDENING_ID) cycle
|
||||||
associate(prm => param(phase_plasticityInstance(p)), &
|
associate(prm => param(phase_plasticityInstance(p)), &
|
||||||
|
@ -110,22 +92,22 @@ module subroutine plastic_kinehardening_init
|
||||||
dlt => deltaState(phase_plasticityInstance(p)), &
|
dlt => deltaState(phase_plasticityInstance(p)), &
|
||||||
stt => state(phase_plasticityInstance(p)),&
|
stt => state(phase_plasticityInstance(p)),&
|
||||||
config => config_phase(p))
|
config => config_phase(p))
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
if (p==material_phaseAt(debug_g,debug_e)) then
|
if (p==material_phaseAt(debug_g,debug_e)) then
|
||||||
prm%of_debug = material_phasememberAt(debug_g,debug_i,debug_e)
|
prm%of_debug = material_phasememberAt(debug_g,debug_i,debug_e)
|
||||||
endif
|
endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! optional parameters that need to be defined
|
! optional parameters that need to be defined
|
||||||
prm%aTolResistance = config%getFloat('atol_resistance',defaultVal=1.0_pReal)
|
prm%aTolResistance = config%getFloat('atol_resistance',defaultVal=1.0_pReal)
|
||||||
prm%aTolShear = config%getFloat('atol_shear', defaultVal=1.0e-6_pReal)
|
prm%aTolShear = config%getFloat('atol_shear', defaultVal=1.0e-6_pReal)
|
||||||
|
|
||||||
! sanity checks
|
! sanity checks
|
||||||
if (prm%aTolResistance <= 0.0_pReal) extmsg = trim(extmsg)//' aTolresistance'
|
if (prm%aTolResistance <= 0.0_pReal) extmsg = trim(extmsg)//' aTolresistance'
|
||||||
if (prm%aTolShear <= 0.0_pReal) extmsg = trim(extmsg)//' aTolShear'
|
if (prm%aTolShear <= 0.0_pReal) extmsg = trim(extmsg)//' aTolShear'
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! slip related parameters
|
! slip related parameters
|
||||||
prm%Nslip = config%getInts('nslip',defaultVal=emptyIntArray)
|
prm%Nslip = config%getInts('nslip',defaultVal=emptyIntArray)
|
||||||
|
@ -133,7 +115,7 @@ module subroutine plastic_kinehardening_init
|
||||||
slipActive: if (prm%totalNslip > 0) then
|
slipActive: if (prm%totalNslip > 0) then
|
||||||
prm%Schmid = lattice_SchmidMatrix_slip(prm%Nslip,config%getString('lattice_structure'),&
|
prm%Schmid = lattice_SchmidMatrix_slip(prm%Nslip,config%getString('lattice_structure'),&
|
||||||
config%getFloat('c/a',defaultVal=0.0_pReal))
|
config%getFloat('c/a',defaultVal=0.0_pReal))
|
||||||
|
|
||||||
if(trim(config%getString('lattice_structure')) == 'bcc') then
|
if(trim(config%getString('lattice_structure')) == 'bcc') then
|
||||||
prm%nonSchmidCoeff = config%getFloats('nonschmid_coefficients',&
|
prm%nonSchmidCoeff = config%getFloats('nonschmid_coefficients',&
|
||||||
defaultVal = emptyRealArray)
|
defaultVal = emptyRealArray)
|
||||||
|
@ -146,7 +128,7 @@ module subroutine plastic_kinehardening_init
|
||||||
prm%interaction_SlipSlip = lattice_interaction_SlipBySlip(prm%Nslip, &
|
prm%interaction_SlipSlip = lattice_interaction_SlipBySlip(prm%Nslip, &
|
||||||
config%getFloats('interaction_slipslip'), &
|
config%getFloats('interaction_slipslip'), &
|
||||||
config%getString('lattice_structure'))
|
config%getString('lattice_structure'))
|
||||||
|
|
||||||
prm%crss0 = config%getFloats('crss0', requiredSize=size(prm%Nslip))
|
prm%crss0 = config%getFloats('crss0', requiredSize=size(prm%Nslip))
|
||||||
prm%tau1 = config%getFloats('tau1', requiredSize=size(prm%Nslip))
|
prm%tau1 = config%getFloats('tau1', requiredSize=size(prm%Nslip))
|
||||||
prm%tau1_b = config%getFloats('tau1_b', requiredSize=size(prm%Nslip))
|
prm%tau1_b = config%getFloats('tau1_b', requiredSize=size(prm%Nslip))
|
||||||
|
@ -154,10 +136,10 @@ module subroutine plastic_kinehardening_init
|
||||||
prm%theta1 = config%getFloats('theta1', requiredSize=size(prm%Nslip))
|
prm%theta1 = config%getFloats('theta1', requiredSize=size(prm%Nslip))
|
||||||
prm%theta0_b = config%getFloats('theta0_b', requiredSize=size(prm%Nslip))
|
prm%theta0_b = config%getFloats('theta0_b', requiredSize=size(prm%Nslip))
|
||||||
prm%theta1_b = config%getFloats('theta1_b', requiredSize=size(prm%Nslip))
|
prm%theta1_b = config%getFloats('theta1_b', requiredSize=size(prm%Nslip))
|
||||||
|
|
||||||
prm%gdot0 = config%getFloat('gdot0')
|
prm%gdot0 = config%getFloat('gdot0')
|
||||||
prm%n = config%getFloat('n_slip')
|
prm%n = config%getFloat('n_slip')
|
||||||
|
|
||||||
! expand: family => system
|
! expand: family => system
|
||||||
prm%crss0 = math_expand(prm%crss0, prm%Nslip)
|
prm%crss0 = math_expand(prm%crss0, prm%Nslip)
|
||||||
prm%tau1 = math_expand(prm%tau1, prm%Nslip)
|
prm%tau1 = math_expand(prm%tau1, prm%Nslip)
|
||||||
|
@ -166,9 +148,9 @@ module subroutine plastic_kinehardening_init
|
||||||
prm%theta1 = math_expand(prm%theta1, prm%Nslip)
|
prm%theta1 = math_expand(prm%theta1, prm%Nslip)
|
||||||
prm%theta0_b = math_expand(prm%theta0_b,prm%Nslip)
|
prm%theta0_b = math_expand(prm%theta0_b,prm%Nslip)
|
||||||
prm%theta1_b = math_expand(prm%theta1_b,prm%Nslip)
|
prm%theta1_b = math_expand(prm%theta1_b,prm%Nslip)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! sanity checks
|
! sanity checks
|
||||||
if ( prm%gdot0 <= 0.0_pReal) extmsg = trim(extmsg)//' gdot0'
|
if ( prm%gdot0 <= 0.0_pReal) extmsg = trim(extmsg)//' gdot0'
|
||||||
|
@ -176,58 +158,29 @@ module subroutine plastic_kinehardening_init
|
||||||
if (any(prm%crss0 <= 0.0_pReal)) extmsg = trim(extmsg)//' crss0'
|
if (any(prm%crss0 <= 0.0_pReal)) extmsg = trim(extmsg)//' crss0'
|
||||||
if (any(prm%tau1 <= 0.0_pReal)) extmsg = trim(extmsg)//' tau1'
|
if (any(prm%tau1 <= 0.0_pReal)) extmsg = trim(extmsg)//' tau1'
|
||||||
if (any(prm%tau1_b <= 0.0_pReal)) extmsg = trim(extmsg)//' tau1_b'
|
if (any(prm%tau1_b <= 0.0_pReal)) extmsg = trim(extmsg)//' tau1_b'
|
||||||
|
|
||||||
!ToDo: Any sensible checks for theta?
|
!ToDo: Any sensible checks for theta?
|
||||||
|
|
||||||
endif slipActive
|
endif slipActive
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! exit if any parameter is out of range
|
! exit if any parameter is out of range
|
||||||
if (extmsg /= '') &
|
if (extmsg /= '') &
|
||||||
call IO_error(211,ext_msg=trim(extmsg)//'('//PLASTICITY_KINEHARDENING_label//')')
|
call IO_error(211,ext_msg=trim(extmsg)//'('//PLASTICITY_KINEHARDENING_label//')')
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! output pararameters
|
! output pararameters
|
||||||
outputs = config%getStrings('(output)',defaultVal=emptyStringArray)
|
prm%output = config%getStrings('(output)',defaultVal=emptyStringArray)
|
||||||
allocate(prm%outputID(0))
|
|
||||||
do i=1, size(outputs)
|
|
||||||
outputID = undefined_ID
|
|
||||||
select case(outputs(i))
|
|
||||||
|
|
||||||
case ('resistance')
|
|
||||||
outputID = merge(crss_ID,undefined_ID,prm%totalNslip>0)
|
|
||||||
case ('accumulatedshear')
|
|
||||||
outputID = merge(accshear_ID,undefined_ID,prm%totalNslip>0)
|
|
||||||
case ('shearrate')
|
|
||||||
outputID = merge(shearrate_ID,undefined_ID,prm%totalNslip>0)
|
|
||||||
case ('resolvedstress')
|
|
||||||
outputID = merge(resolvedstress_ID,undefined_ID,prm%totalNslip>0)
|
|
||||||
case ('backstress')
|
|
||||||
outputID = merge(crss_back_ID,undefined_ID,prm%totalNslip>0)
|
|
||||||
case ('sense')
|
|
||||||
outputID = merge(sense_ID,undefined_ID,prm%totalNslip>0)
|
|
||||||
case ('chi0')
|
|
||||||
outputID = merge(chi0_ID,undefined_ID,prm%totalNslip>0)
|
|
||||||
case ('gamma0')
|
|
||||||
outputID = merge(gamma0_ID,undefined_ID,prm%totalNslip>0)
|
|
||||||
|
|
||||||
end select
|
|
||||||
|
|
||||||
if (outputID /= undefined_ID) then
|
|
||||||
prm%outputID = [prm%outputID , outputID]
|
|
||||||
endif
|
|
||||||
|
|
||||||
enddo
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! allocate state arrays
|
! allocate state arrays
|
||||||
NipcMyPhase = count(material_phaseAt == p) * discretization_nIP
|
NipcMyPhase = count(material_phaseAt == p) * discretization_nIP
|
||||||
sizeDotState = size(['crss ','crss_back', 'accshear ']) * prm%totalNslip
|
sizeDotState = size(['crss ','crss_back', 'accshear ']) * prm%totalNslip
|
||||||
sizeDeltaState = size(['sense ', 'chi0 ', 'gamma0' ]) * prm%totalNslip
|
sizeDeltaState = size(['sense ', 'chi0 ', 'gamma0' ]) * prm%totalNslip
|
||||||
sizeState = sizeDotState + sizeDeltaState
|
sizeState = sizeDotState + sizeDeltaState
|
||||||
|
|
||||||
call material_allocatePlasticState(p,NipcMyPhase,sizeState,sizeDotState,sizeDeltaState)
|
call material_allocatePlasticState(p,NipcMyPhase,sizeState,sizeDotState,sizeDeltaState)
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! locally defined state aliases and initialization of state0 and aTolState
|
! locally defined state aliases and initialization of state0 and aTolState
|
||||||
startIndex = 1
|
startIndex = 1
|
||||||
|
@ -236,13 +189,13 @@ module subroutine plastic_kinehardening_init
|
||||||
stt%crss = spread(prm%crss0, 2, NipcMyPhase)
|
stt%crss = spread(prm%crss0, 2, NipcMyPhase)
|
||||||
dot%crss => plasticState(p)%dotState(startIndex:endIndex,:)
|
dot%crss => plasticState(p)%dotState(startIndex:endIndex,:)
|
||||||
plasticState(p)%aTolState(startIndex:endIndex) = prm%aTolResistance
|
plasticState(p)%aTolState(startIndex:endIndex) = prm%aTolResistance
|
||||||
|
|
||||||
startIndex = endIndex + 1
|
startIndex = endIndex + 1
|
||||||
endIndex = endIndex + prm%totalNslip
|
endIndex = endIndex + prm%totalNslip
|
||||||
stt%crss_back => plasticState(p)%state (startIndex:endIndex,:)
|
stt%crss_back => plasticState(p)%state (startIndex:endIndex,:)
|
||||||
dot%crss_back => plasticState(p)%dotState(startIndex:endIndex,:)
|
dot%crss_back => plasticState(p)%dotState(startIndex:endIndex,:)
|
||||||
plasticState(p)%aTolState(startIndex:endIndex) = prm%aTolResistance
|
plasticState(p)%aTolState(startIndex:endIndex) = prm%aTolResistance
|
||||||
|
|
||||||
startIndex = endIndex + 1
|
startIndex = endIndex + 1
|
||||||
endIndex = endIndex + prm%totalNslip
|
endIndex = endIndex + prm%totalNslip
|
||||||
stt%accshear => plasticState(p)%state (startIndex:endIndex,:)
|
stt%accshear => plasticState(p)%state (startIndex:endIndex,:)
|
||||||
|
@ -250,34 +203,34 @@ module subroutine plastic_kinehardening_init
|
||||||
plasticState(p)%aTolState(startIndex:endIndex) = prm%aTolShear
|
plasticState(p)%aTolState(startIndex:endIndex) = prm%aTolShear
|
||||||
! global alias
|
! global alias
|
||||||
plasticState(p)%slipRate => plasticState(p)%dotState(startIndex:endIndex,:)
|
plasticState(p)%slipRate => plasticState(p)%dotState(startIndex:endIndex,:)
|
||||||
|
|
||||||
o = plasticState(p)%offsetDeltaState
|
o = plasticState(p)%offsetDeltaState
|
||||||
startIndex = endIndex + 1
|
startIndex = endIndex + 1
|
||||||
endIndex = endIndex + prm%totalNslip
|
endIndex = endIndex + prm%totalNslip
|
||||||
stt%sense => plasticState(p)%state (startIndex :endIndex ,:)
|
stt%sense => plasticState(p)%state (startIndex :endIndex ,:)
|
||||||
dlt%sense => plasticState(p)%deltaState(startIndex-o:endIndex-o,:)
|
dlt%sense => plasticState(p)%deltaState(startIndex-o:endIndex-o,:)
|
||||||
|
|
||||||
startIndex = endIndex + 1
|
startIndex = endIndex + 1
|
||||||
endIndex = endIndex + prm%totalNslip
|
endIndex = endIndex + prm%totalNslip
|
||||||
stt%chi0 => plasticState(p)%state (startIndex :endIndex ,:)
|
stt%chi0 => plasticState(p)%state (startIndex :endIndex ,:)
|
||||||
dlt%chi0 => plasticState(p)%deltaState(startIndex-o:endIndex-o,:)
|
dlt%chi0 => plasticState(p)%deltaState(startIndex-o:endIndex-o,:)
|
||||||
|
|
||||||
startIndex = endIndex + 1
|
startIndex = endIndex + 1
|
||||||
endIndex = endIndex + prm%totalNslip
|
endIndex = endIndex + prm%totalNslip
|
||||||
stt%gamma0 => plasticState(p)%state (startIndex :endIndex ,:)
|
stt%gamma0 => plasticState(p)%state (startIndex :endIndex ,:)
|
||||||
dlt%gamma0 => plasticState(p)%deltaState(startIndex-o:endIndex-o,:)
|
dlt%gamma0 => plasticState(p)%deltaState(startIndex-o:endIndex-o,:)
|
||||||
|
|
||||||
plasticState(p)%state0 = plasticState(p)%state ! ToDo: this could be done centrally
|
plasticState(p)%state0 = plasticState(p)%state ! ToDo: this could be done centrally
|
||||||
|
|
||||||
end associate
|
end associate
|
||||||
|
|
||||||
enddo
|
enddo
|
||||||
|
|
||||||
end subroutine plastic_kinehardening_init
|
end subroutine plastic_kinehardening_init
|
||||||
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @brief calculates plastic velocity gradient and its tangent
|
!> @brief Calculate plastic velocity gradient and its tangent.
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
pure module subroutine plastic_kinehardening_LpAndItsTangent(Lp,dLp_dMp,Mp,instance,of)
|
pure module subroutine plastic_kinehardening_LpAndItsTangent(Lp,dLp_dMp,Mp,instance,of)
|
||||||
|
|
||||||
|
@ -285,26 +238,26 @@ pure module subroutine plastic_kinehardening_LpAndItsTangent(Lp,dLp_dMp,Mp,insta
|
||||||
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 !< derivative of Lp with respect to the Mandel stress
|
dLp_dMp !< derivative of Lp with respect to the Mandel stress
|
||||||
|
|
||||||
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, &
|
instance, &
|
||||||
of
|
of
|
||||||
|
|
||||||
integer :: &
|
integer :: &
|
||||||
i,k,l,m,n
|
i,k,l,m,n
|
||||||
real(pReal), dimension(param(instance)%totalNslip) :: &
|
real(pReal), dimension(param(instance)%totalNslip) :: &
|
||||||
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(instance))
|
associate(prm => param(instance))
|
||||||
|
|
||||||
call kinetics(Mp,instance,of,gdot_pos,gdot_neg,dgdot_dtau_pos,dgdot_dtau_neg)
|
call kinetics(Mp,instance,of,gdot_pos,gdot_neg,dgdot_dtau_pos,dgdot_dtau_neg)
|
||||||
|
|
||||||
do i = 1, prm%totalNslip
|
do i = 1, prm%totalNslip
|
||||||
Lp = Lp + (gdot_pos(i)+gdot_neg(i))*prm%Schmid(1:3,1:3,i)
|
Lp = Lp + (gdot_pos(i)+gdot_neg(i))*prm%Schmid(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) &
|
||||||
|
@ -312,14 +265,14 @@ pure module subroutine plastic_kinehardening_LpAndItsTangent(Lp,dLp_dMp,Mp,insta
|
||||||
+ dgdot_dtau_pos(i) * prm%Schmid(k,l,i) * prm%nonSchmid_pos(m,n,i) &
|
+ dgdot_dtau_pos(i) * prm%Schmid(k,l,i) * prm%nonSchmid_pos(m,n,i) &
|
||||||
+ dgdot_dtau_neg(i) * prm%Schmid(k,l,i) * prm%nonSchmid_neg(m,n,i)
|
+ dgdot_dtau_neg(i) * prm%Schmid(k,l,i) * prm%nonSchmid_neg(m,n,i)
|
||||||
enddo
|
enddo
|
||||||
|
|
||||||
end associate
|
end associate
|
||||||
|
|
||||||
end subroutine plastic_kinehardening_LpAndItsTangent
|
end subroutine plastic_kinehardening_LpAndItsTangent
|
||||||
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @brief calculates the rate of change of microstructure
|
!> @brief Calculate the rate of change of microstructure.
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
module subroutine plastic_kinehardening_dotState(Mp,instance,of)
|
module subroutine plastic_kinehardening_dotState(Mp,instance,of)
|
||||||
|
|
||||||
|
@ -328,40 +281,40 @@ module subroutine plastic_kinehardening_dotState(Mp,instance,of)
|
||||||
integer, intent(in) :: &
|
integer, intent(in) :: &
|
||||||
instance, &
|
instance, &
|
||||||
of
|
of
|
||||||
|
|
||||||
real(pReal) :: &
|
real(pReal) :: &
|
||||||
sumGamma
|
sumGamma
|
||||||
real(pReal), dimension(param(instance)%totalNslip) :: &
|
real(pReal), dimension(param(instance)%totalNslip) :: &
|
||||||
gdot_pos,gdot_neg
|
gdot_pos,gdot_neg
|
||||||
|
|
||||||
|
|
||||||
associate(prm => param(instance), stt => state(instance), dot => dotState(instance))
|
associate(prm => param(instance), stt => state(instance), dot => dotState(instance))
|
||||||
|
|
||||||
call kinetics(Mp,instance,of,gdot_pos,gdot_neg)
|
call kinetics(Mp,instance,of,gdot_pos,gdot_neg)
|
||||||
dot%accshear(:,of) = abs(gdot_pos+gdot_neg)
|
dot%accshear(:,of) = abs(gdot_pos+gdot_neg)
|
||||||
sumGamma = sum(stt%accshear(:,of))
|
sumGamma = sum(stt%accshear(:,of))
|
||||||
|
|
||||||
|
|
||||||
dot%crss(:,of) = matmul(prm%interaction_SlipSlip,dot%accshear(:,of)) &
|
dot%crss(:,of) = matmul(prm%interaction_SlipSlip,dot%accshear(:,of)) &
|
||||||
* ( prm%theta1 &
|
* ( prm%theta1 &
|
||||||
+ (prm%theta0 - prm%theta1 + prm%theta0*prm%theta1*sumGamma/prm%tau1) &
|
+ (prm%theta0 - prm%theta1 + prm%theta0*prm%theta1*sumGamma/prm%tau1) &
|
||||||
* exp(-sumGamma*prm%theta0/prm%tau1) &
|
* exp(-sumGamma*prm%theta0/prm%tau1) &
|
||||||
)
|
)
|
||||||
|
|
||||||
dot%crss_back(:,of) = stt%sense(:,of)*dot%accshear(:,of) * &
|
dot%crss_back(:,of) = stt%sense(:,of)*dot%accshear(:,of) * &
|
||||||
( prm%theta1_b + &
|
( prm%theta1_b + &
|
||||||
(prm%theta0_b - prm%theta1_b &
|
(prm%theta0_b - prm%theta1_b &
|
||||||
+ prm%theta0_b*prm%theta1_b/(prm%tau1_b+stt%chi0(:,of))*(stt%accshear(:,of)-stt%gamma0(:,of))&
|
+ prm%theta0_b*prm%theta1_b/(prm%tau1_b+stt%chi0(:,of))*(stt%accshear(:,of)-stt%gamma0(:,of))&
|
||||||
) *exp(-(stt%accshear(:,of)-stt%gamma0(:,of)) *prm%theta0_b/(prm%tau1_b+stt%chi0(:,of))) &
|
) *exp(-(stt%accshear(:,of)-stt%gamma0(:,of)) *prm%theta0_b/(prm%tau1_b+stt%chi0(:,of))) &
|
||||||
)
|
)
|
||||||
|
|
||||||
end associate
|
end associate
|
||||||
|
|
||||||
end subroutine plastic_kinehardening_dotState
|
end subroutine plastic_kinehardening_dotState
|
||||||
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @brief calculates (instantaneous) incremental change of microstructure
|
!> @brief Calculate (instantaneous) incremental change of microstructure.
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
module subroutine plastic_kinehardening_deltaState(Mp,instance,of)
|
module subroutine plastic_kinehardening_deltaState(Mp,instance,of)
|
||||||
|
|
||||||
|
@ -370,18 +323,18 @@ module subroutine plastic_kinehardening_deltaState(Mp,instance,of)
|
||||||
integer, intent(in) :: &
|
integer, intent(in) :: &
|
||||||
instance, &
|
instance, &
|
||||||
of
|
of
|
||||||
|
|
||||||
real(pReal), dimension(param(instance)%totalNslip) :: &
|
real(pReal), dimension(param(instance)%totalNslip) :: &
|
||||||
gdot_pos,gdot_neg, &
|
gdot_pos,gdot_neg, &
|
||||||
sense
|
sense
|
||||||
|
|
||||||
associate(prm => param(instance), stt => state(instance), dlt => deltaState(instance))
|
associate(prm => param(instance), stt => state(instance), dlt => deltaState(instance))
|
||||||
|
|
||||||
call kinetics(Mp,instance,of,gdot_pos,gdot_neg)
|
call kinetics(Mp,instance,of,gdot_pos,gdot_neg)
|
||||||
sense = merge(state(instance)%sense(:,of), & ! keep existing...
|
sense = merge(state(instance)%sense(:,of), & ! 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
|
#ifdef DEBUG
|
||||||
if (iand(debug_level(debug_constitutive), debug_levelExtensive) /= 0 &
|
if (iand(debug_level(debug_constitutive), debug_levelExtensive) /= 0 &
|
||||||
.and. (of == prm%of_debug &
|
.and. (of == prm%of_debug &
|
||||||
|
@ -390,7 +343,7 @@ module subroutine plastic_kinehardening_deltaState(Mp,instance,of)
|
||||||
write(6,*) sense,state(instance)%sense(:,of)
|
write(6,*) sense,state(instance)%sense(:,of)
|
||||||
endif
|
endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! switch in sense of shear?
|
! switch in sense of shear?
|
||||||
where(dNeq(sense,stt%sense(:,of),0.1_pReal))
|
where(dNeq(sense,stt%sense(:,of),0.1_pReal))
|
||||||
|
@ -402,45 +355,43 @@ module subroutine plastic_kinehardening_deltaState(Mp,instance,of)
|
||||||
dlt%chi0 (:,of) = 0.0_pReal
|
dlt%chi0 (:,of) = 0.0_pReal
|
||||||
dlt%gamma0(:,of) = 0.0_pReal
|
dlt%gamma0(:,of) = 0.0_pReal
|
||||||
end where
|
end where
|
||||||
|
|
||||||
end associate
|
end associate
|
||||||
|
|
||||||
end subroutine plastic_kinehardening_deltaState
|
end subroutine plastic_kinehardening_deltaState
|
||||||
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @brief writes results to HDF5 output file
|
!> @brief Write results to HDF5 output file.
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
module subroutine plastic_kinehardening_results(instance,group)
|
module subroutine plastic_kinehardening_results(instance,group)
|
||||||
|
|
||||||
integer, intent(in) :: instance
|
integer, intent(in) :: instance
|
||||||
character(len=*), intent(in) :: group
|
character(len=*), intent(in) :: group
|
||||||
|
|
||||||
integer :: o
|
integer :: o
|
||||||
|
|
||||||
associate(prm => param(instance), stt => state(instance))
|
associate(prm => param(instance), stt => state(instance))
|
||||||
outputsLoop: do o = 1,size(prm%outputID)
|
outputsLoop: do o = 1,size(prm%output)
|
||||||
select case(prm%outputID(o))
|
select case(trim(prm%output(o)))
|
||||||
case (crss_ID)
|
case('resistance')
|
||||||
call results_writeDataset(group,stt%crss,'xi_sl', &
|
if(prm%totalNslip>0) call results_writeDataset(group,stt%crss,'xi_sl', &
|
||||||
'resistance against plastic slip','Pa')
|
'resistance against plastic slip','Pa')
|
||||||
|
case('backstress') ! ToDo: should be 'tau_back'
|
||||||
case(crss_back_ID)
|
if(prm%totalNslip>0) call results_writeDataset(group,stt%crss_back,'tau_back', &
|
||||||
call results_writeDataset(group,stt%crss_back,'tau_back', &
|
'back stress against plastic slip','Pa')
|
||||||
'back stress against plastic slip','Pa')
|
case ('sense')
|
||||||
|
if(prm%totalNslip>0) call results_writeDataset(group,stt%sense,'sense_of_shear', &
|
||||||
case (sense_ID)
|
'tbd','1')
|
||||||
call results_writeDataset(group,stt%sense,'sense_of_shear','tbd','1')
|
case ('chi0')
|
||||||
|
if(prm%totalNslip>0) call results_writeDataset(group,stt%chi0,'chi0', &
|
||||||
case (chi0_ID)
|
'tbd','Pa')
|
||||||
call results_writeDataset(group,stt%chi0,'chi0','tbd','Pa')
|
case ('gamma0')
|
||||||
|
if(prm%totalNslip>0) call results_writeDataset(group,stt%gamma0,'gamma0', &
|
||||||
case (gamma0_ID)
|
'tbd','1')
|
||||||
call results_writeDataset(group,stt%gamma0,'gamma0','tbd','1')
|
case ('accumulatedshear')
|
||||||
|
if(prm%totalNslip>0) call results_writeDataset(group,stt%accshear,'gamma_sl', &
|
||||||
case (accshear_ID)
|
'plastic shear','1')
|
||||||
call results_writeDataset(group,stt%accshear,'gamma_sl', &
|
|
||||||
'plastic shear','1')
|
|
||||||
|
|
||||||
end select
|
end select
|
||||||
enddo outputsLoop
|
enddo outputsLoop
|
||||||
end associate
|
end associate
|
||||||
|
@ -449,10 +400,11 @@ end subroutine plastic_kinehardening_results
|
||||||
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @brief calculates shear rates on slip systems and derivatives with respect to resolved stress
|
!> @brief Calculate shear rates on slip systems and their derivatives with respect to resolved
|
||||||
!> @details: Shear rates are calculated only optionally.
|
! stress.
|
||||||
|
!> @details: Derivatives are calculated only optionally.
|
||||||
! 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,of, &
|
pure subroutine kinetics(Mp,instance,of, &
|
||||||
gdot_pos,gdot_neg,dgdot_dtau_pos,dgdot_dtau_neg)
|
gdot_pos,gdot_neg,dgdot_dtau_pos,dgdot_dtau_neg)
|
||||||
|
@ -462,44 +414,44 @@ pure subroutine kinetics(Mp,instance,of, &
|
||||||
integer, intent(in) :: &
|
integer, intent(in) :: &
|
||||||
instance, &
|
instance, &
|
||||||
of
|
of
|
||||||
|
|
||||||
real(pReal), intent(out), dimension(param(instance)%totalNslip) :: &
|
real(pReal), intent(out), dimension(param(instance)%totalNslip) :: &
|
||||||
gdot_pos, &
|
gdot_pos, &
|
||||||
gdot_neg
|
gdot_neg
|
||||||
real(pReal), intent(out), optional, dimension(param(instance)%totalNslip) :: &
|
real(pReal), intent(out), optional, dimension(param(instance)%totalNslip) :: &
|
||||||
dgdot_dtau_pos, &
|
dgdot_dtau_pos, &
|
||||||
dgdot_dtau_neg
|
dgdot_dtau_neg
|
||||||
|
|
||||||
real(pReal), dimension(param(instance)%totalNslip) :: &
|
real(pReal), dimension(param(instance)%totalNslip) :: &
|
||||||
tau_pos, &
|
tau_pos, &
|
||||||
tau_neg
|
tau_neg
|
||||||
integer :: i
|
integer :: i
|
||||||
logical :: nonSchmidActive
|
logical :: nonSchmidActive
|
||||||
|
|
||||||
associate(prm => param(instance), stt => state(instance))
|
associate(prm => param(instance), stt => state(instance))
|
||||||
|
|
||||||
nonSchmidActive = size(prm%nonSchmidCoeff) > 0
|
nonSchmidActive = size(prm%nonSchmidCoeff) > 0
|
||||||
|
|
||||||
do i = 1, prm%totalNslip
|
do i = 1, prm%totalNslip
|
||||||
tau_pos(i) = math_mul33xx33(Mp,prm%nonSchmid_pos(1:3,1:3,i)) - stt%crss_back(i,of)
|
tau_pos(i) = math_mul33xx33(Mp,prm%nonSchmid_pos(1:3,1:3,i)) - stt%crss_back(i,of)
|
||||||
tau_neg(i) = merge(math_mul33xx33(Mp,prm%nonSchmid_neg(1:3,1:3,i)) - stt%crss_back(i,of), &
|
tau_neg(i) = merge(math_mul33xx33(Mp,prm%nonSchmid_neg(1:3,1:3,i)) - stt%crss_back(i,of), &
|
||||||
0.0_pReal, nonSchmidActive)
|
0.0_pReal, nonSchmidActive)
|
||||||
enddo
|
enddo
|
||||||
|
|
||||||
where(dNeq0(tau_pos))
|
where(dNeq0(tau_pos))
|
||||||
gdot_pos = prm%gdot0 * merge(0.5_pReal,1.0_pReal, nonSchmidActive) & ! 1/2 if non-Schmid active
|
gdot_pos = prm%gdot0 * merge(0.5_pReal,1.0_pReal, nonSchmidActive) & ! 1/2 if non-Schmid active
|
||||||
* sign(abs(tau_pos/stt%crss(:,of))**prm%n, tau_pos)
|
* sign(abs(tau_pos/stt%crss(:,of))**prm%n, tau_pos)
|
||||||
else where
|
else where
|
||||||
gdot_pos = 0.0_pReal
|
gdot_pos = 0.0_pReal
|
||||||
end where
|
end where
|
||||||
|
|
||||||
where(dNeq0(tau_neg))
|
where(dNeq0(tau_neg))
|
||||||
gdot_neg = prm%gdot0 * 0.5_pReal & ! only used if non-Schmid active, always 1/2
|
gdot_neg = prm%gdot0 * 0.5_pReal & ! only used if non-Schmid active, always 1/2
|
||||||
* sign(abs(tau_neg/stt%crss(:,of))**prm%n, tau_neg)
|
* sign(abs(tau_neg/stt%crss(:,of))**prm%n, tau_neg)
|
||||||
else where
|
else where
|
||||||
gdot_neg = 0.0_pReal
|
gdot_neg = 0.0_pReal
|
||||||
end where
|
end where
|
||||||
|
|
||||||
if (present(dgdot_dtau_pos)) then
|
if (present(dgdot_dtau_pos)) then
|
||||||
where(dNeq0(gdot_pos))
|
where(dNeq0(gdot_pos))
|
||||||
dgdot_dtau_pos = gdot_pos*prm%n/tau_pos
|
dgdot_dtau_pos = gdot_pos*prm%n/tau_pos
|
||||||
|
|
|
@ -18,19 +18,19 @@ module subroutine plastic_none_init
|
||||||
Ninstance, &
|
Ninstance, &
|
||||||
p, &
|
p, &
|
||||||
NipcMyPhase
|
NipcMyPhase
|
||||||
|
|
||||||
write(6,'(/,a)') ' <<<+- plastic_'//PLASTICITY_NONE_label//' init -+>>>'
|
write(6,'(/,a)') ' <<<+- plastic_'//PLASTICITY_NONE_label//' init -+>>>'; flush(6)
|
||||||
|
|
||||||
Ninstance = count(phase_plasticity == PLASTICITY_NONE_ID)
|
Ninstance = count(phase_plasticity == PLASTICITY_NONE_ID)
|
||||||
if (iand(debug_level(debug_constitutive),debug_levelBasic) /= 0) &
|
if (iand(debug_level(debug_constitutive),debug_levelBasic) /= 0) &
|
||||||
write(6,'(a16,1x,i5,/)') '# instances:',Ninstance
|
write(6,'(a16,1x,i5,/)') '# instances:',Ninstance
|
||||||
|
|
||||||
do p = 1, size(phase_plasticity)
|
do p = 1, size(phase_plasticity)
|
||||||
if (phase_plasticity(p) /= PLASTICITY_NONE_ID) cycle
|
if (phase_plasticity(p) /= PLASTICITY_NONE_ID) cycle
|
||||||
|
|
||||||
NipcMyPhase = count(material_phaseAt == p) * discretization_nIP
|
NipcMyPhase = count(material_phaseAt == p) * discretization_nIP
|
||||||
call material_allocatePlasticState(p,NipcMyPhase,0,0,0)
|
call material_allocatePlasticState(p,NipcMyPhase,0,0,0)
|
||||||
|
|
||||||
enddo
|
enddo
|
||||||
|
|
||||||
end subroutine plastic_none_init
|
end subroutine plastic_none_init
|
||||||
|
|
|
@ -48,32 +48,6 @@ submodule(constitutive) plastic_nonlocal
|
||||||
real(pReal), dimension(:,:,:,:,:,:), allocatable :: &
|
real(pReal), dimension(:,:,:,:,:,:), allocatable :: &
|
||||||
compatibility !< slip system compatibility between me and my neighbors
|
compatibility !< slip system compatibility between me and my neighbors
|
||||||
|
|
||||||
enum, bind(c)
|
|
||||||
enumerator :: &
|
|
||||||
undefined_ID, &
|
|
||||||
rho_sgl_mob_edg_pos_ID, &
|
|
||||||
rho_sgl_mob_edg_neg_ID, &
|
|
||||||
rho_sgl_mob_scr_pos_ID, &
|
|
||||||
rho_sgl_mob_scr_neg_ID, &
|
|
||||||
rho_sgl_imm_edg_pos_ID, &
|
|
||||||
rho_sgl_imm_edg_neg_ID, &
|
|
||||||
rho_sgl_imm_scr_pos_ID, &
|
|
||||||
rho_sgl_imm_scr_neg_ID, &
|
|
||||||
rho_dip_edg_ID, &
|
|
||||||
rho_dip_scr_ID, &
|
|
||||||
rho_forest_ID, &
|
|
||||||
resolvedstress_back_ID, &
|
|
||||||
tau_pass_ID, &
|
|
||||||
rho_dot_sgl_ID, &
|
|
||||||
rho_dot_sgl_mobile_ID, &
|
|
||||||
rho_dot_dip_ID, &
|
|
||||||
v_edg_pos_ID, &
|
|
||||||
v_edg_neg_ID, &
|
|
||||||
v_scr_pos_ID, &
|
|
||||||
v_scr_neg_ID, &
|
|
||||||
gamma_ID
|
|
||||||
end enum
|
|
||||||
|
|
||||||
type :: tParameters !< container type for internal constitutive parameters
|
type :: tParameters !< container type for internal constitutive parameters
|
||||||
real(pReal) :: &
|
real(pReal) :: &
|
||||||
atomicVolume, & !< atomic volume
|
atomicVolume, & !< atomic volume
|
||||||
|
@ -135,14 +109,12 @@ submodule(constitutive) plastic_nonlocal
|
||||||
integer, dimension(:) ,allocatable :: &
|
integer, dimension(:) ,allocatable :: &
|
||||||
Nslip,&
|
Nslip,&
|
||||||
colinearSystem !< colinear system to the active slip system (only valid for fcc!)
|
colinearSystem !< colinear system to the active slip system (only valid for fcc!)
|
||||||
|
character(len=pStringLen), allocatable, dimension(:) :: &
|
||||||
|
output
|
||||||
logical :: &
|
logical :: &
|
||||||
shortRangeStressCorrection, & !< flag indicating the use of the short range stress correction by a excess density gradient term
|
shortRangeStressCorrection, & !< flag indicating the use of the short range stress correction by a excess density gradient term
|
||||||
probabilisticMultiplication
|
probabilisticMultiplication
|
||||||
|
|
||||||
integer(kind(undefined_ID)), dimension(:), allocatable :: &
|
|
||||||
outputID !< ID of each post result output
|
|
||||||
|
|
||||||
end type tParameters
|
end type tParameters
|
||||||
|
|
||||||
type :: tNonlocalMicrostructure
|
type :: tNonlocalMicrostructure
|
||||||
|
@ -198,22 +170,19 @@ module subroutine plastic_nonlocal_init
|
||||||
integer :: &
|
integer :: &
|
||||||
sizeState, sizeDotState,sizeDependentState, sizeDeltaState, &
|
sizeState, sizeDotState,sizeDependentState, sizeDeltaState, &
|
||||||
maxNinstances, &
|
maxNinstances, &
|
||||||
p, i, &
|
p, &
|
||||||
l, &
|
l, &
|
||||||
s1, s2, &
|
s1, s2, &
|
||||||
s, &
|
s, &
|
||||||
t, &
|
t, &
|
||||||
c
|
c
|
||||||
|
|
||||||
integer(kind(undefined_ID)) :: &
|
|
||||||
outputID
|
|
||||||
character(len=pStringLen) :: &
|
character(len=pStringLen) :: &
|
||||||
extmsg = '', &
|
extmsg = '', &
|
||||||
structure
|
structure
|
||||||
character(len=pStringLen), dimension(:), allocatable :: outputs
|
|
||||||
integer :: NofMyPhase
|
integer :: NofMyPhase
|
||||||
|
|
||||||
write(6,'(/,a)') ' <<<+- constitutive_'//PLASTICITY_NONLOCAL_label//' init -+>>>'
|
write(6,'(/,a)') ' <<<+- constitutive_'//PLASTICITY_NONLOCAL_label//' init -+>>>'; flush(6)
|
||||||
|
|
||||||
write(6,'(/,a)') ' Reuber et al., Acta Materialia 71:333–348, 2014'
|
write(6,'(/,a)') ' Reuber et al., Acta Materialia 71:333–348, 2014'
|
||||||
write(6,'(a)') ' https://doi.org/10.1016/j.actamat.2014.03.012'
|
write(6,'(a)') ' https://doi.org/10.1016/j.actamat.2014.03.012'
|
||||||
|
@ -407,60 +376,7 @@ module subroutine plastic_nonlocal_init
|
||||||
|
|
||||||
endif slipActive
|
endif slipActive
|
||||||
|
|
||||||
outputs = config%getStrings('(output)',defaultVal=emptyStringArray)
|
prm%output = config%getStrings('(output)',defaultVal=emptyStringArray)
|
||||||
allocate(prm%outputID(0))
|
|
||||||
do i=1, size(outputs)
|
|
||||||
outputID = undefined_ID
|
|
||||||
select case(trim(outputs(i)))
|
|
||||||
case ('rho_sgl_mob_edg_pos')
|
|
||||||
outputID = merge(rho_sgl_mob_edg_pos_ID,undefined_ID,prm%totalNslip>0)
|
|
||||||
case ('rho_sgl_mob_edg_neg')
|
|
||||||
outputID = merge(rho_sgl_mob_edg_neg_ID,undefined_ID,prm%totalNslip>0)
|
|
||||||
case ('rho_sgl_mob_scr_pos')
|
|
||||||
outputID = merge(rho_sgl_mob_scr_pos_ID,undefined_ID,prm%totalNslip>0)
|
|
||||||
case ('rho_sgl_mob_scr_neg')
|
|
||||||
outputID = merge(rho_sgl_mob_scr_neg_ID,undefined_ID,prm%totalNslip>0)
|
|
||||||
case ('rho_sgl_imm_edg_pos')
|
|
||||||
outputID = merge(rho_sgl_imm_edg_pos_ID,undefined_ID,prm%totalNslip>0)
|
|
||||||
case ('rho_sgl_imm_edg_neg')
|
|
||||||
outputID = merge(rho_sgl_imm_edg_neg_ID,undefined_ID,prm%totalNslip>0)
|
|
||||||
case ('rho_sgl_imm_scr_pos')
|
|
||||||
outputID = merge(rho_sgl_imm_scr_pos_ID,undefined_ID,prm%totalNslip>0)
|
|
||||||
case ('rho_sgl_imm_scr_neg')
|
|
||||||
outputID = merge(rho_sgl_imm_scr_neg_ID,undefined_ID,prm%totalNslip>0)
|
|
||||||
case ('rho_dip_edg')
|
|
||||||
outputID = merge(rho_dip_edg_ID,undefined_ID,prm%totalNslip>0)
|
|
||||||
case ('rho_dip_scr')
|
|
||||||
outputID = merge(rho_dip_scr_ID,undefined_ID,prm%totalNslip>0)
|
|
||||||
case ('rho_forest')
|
|
||||||
outputID = merge(rho_forest_ID,undefined_ID,prm%totalNslip>0)
|
|
||||||
case ('resolvedstress_back')
|
|
||||||
outputID = merge(resolvedstress_back_ID,undefined_ID,prm%totalNslip>0)
|
|
||||||
case ('tau_pass')
|
|
||||||
outputID = merge(tau_pass_ID,undefined_ID,prm%totalNslip>0)
|
|
||||||
case ('rho_dot_sgl')
|
|
||||||
outputID = merge(rho_dot_sgl_ID,undefined_ID,prm%totalNslip>0)
|
|
||||||
case ('rho_dot_sgl_mobile')
|
|
||||||
outputID = merge(rho_dot_sgl_mobile_ID,undefined_ID,prm%totalNslip>0)
|
|
||||||
case ('rho_dot_dip')
|
|
||||||
outputID = merge(rho_dot_dip_ID,undefined_ID,prm%totalNslip>0)
|
|
||||||
case ('v_edg_pos')
|
|
||||||
outputID = merge(v_edg_pos_ID,undefined_ID,prm%totalNslip>0)
|
|
||||||
case ('v_edg_neg')
|
|
||||||
outputID = merge(v_edg_neg_ID,undefined_ID,prm%totalNslip>0)
|
|
||||||
case ('v_scr_pos')
|
|
||||||
outputID = merge(v_scr_pos_ID,undefined_ID,prm%totalNslip>0)
|
|
||||||
case ('v_scr_neg')
|
|
||||||
outputID = merge(v_scr_neg_ID,undefined_ID,prm%totalNslip>0)
|
|
||||||
case ('gamma')
|
|
||||||
outputID = merge(gamma_ID,undefined_ID,prm%totalNslip>0)
|
|
||||||
end select
|
|
||||||
|
|
||||||
if (outputID /= undefined_ID) then
|
|
||||||
prm%outputID = [prm%outputID , outputID]
|
|
||||||
endif
|
|
||||||
|
|
||||||
enddo
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! allocate state arrays
|
! allocate state arrays
|
||||||
|
@ -561,7 +477,7 @@ module subroutine plastic_nonlocal_init
|
||||||
stt%v_scr_neg => plasticState(p)%state (15*prm%totalNslip + 1:16*prm%totalNslip ,1:NofMyPhase)
|
stt%v_scr_neg => plasticState(p)%state (15*prm%totalNslip + 1:16*prm%totalNslip ,1:NofMyPhase)
|
||||||
|
|
||||||
allocate(dst%tau_pass(prm%totalNslip,NofMyPhase),source=0.0_pReal)
|
allocate(dst%tau_pass(prm%totalNslip,NofMyPhase),source=0.0_pReal)
|
||||||
allocate(dst%tau_Back(prm%totalNslip,NofMyPhase), source=0.0_pReal)
|
allocate(dst%tau_back(prm%totalNslip,NofMyPhase),source=0.0_pReal)
|
||||||
end associate
|
end associate
|
||||||
|
|
||||||
if (NofMyPhase > 0) call stateInit(p,NofMyPhase)
|
if (NofMyPhase > 0) call stateInit(p,NofMyPhase)
|
||||||
|
@ -1968,62 +1884,63 @@ module subroutine plastic_nonlocal_results(instance,group)
|
||||||
|
|
||||||
integer, intent(in) :: instance
|
integer, intent(in) :: instance
|
||||||
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(instance),dst => microstructure(instance),stt=>state(instance))
|
||||||
outputsLoop: do o = 1,size(prm%outputID)
|
outputsLoop: do o = 1,size(prm%output)
|
||||||
select case(prm%outputID(o))
|
select case(trim(prm%output(o)))
|
||||||
case (rho_sgl_mob_edg_pos_ID)
|
case('rho_sgl_mob_edg_pos')
|
||||||
call results_writeDataset(group,stt%rho_sgl_mob_edg_pos, 'rho_sgl_mob_edg_pos', &
|
if(prm%totalNslip>0) call results_writeDataset(group,stt%rho_sgl_mob_edg_pos, 'rho_sgl_mob_edg_pos', &
|
||||||
'positive mobile edge density','1/m²')
|
'positive mobile edge density','1/m²')
|
||||||
case (rho_sgl_imm_edg_pos_ID)
|
case('rho_sgl_imm_edg_pos')
|
||||||
call results_writeDataset(group,stt%rho_sgl_imm_edg_pos, 'rho_sgl_imm_edg_pos',&
|
if(prm%totalNslip>0) call results_writeDataset(group,stt%rho_sgl_imm_edg_pos, 'rho_sgl_imm_edg_pos',&
|
||||||
'positive immobile edge density','1/m²')
|
'positive immobile edge density','1/m²')
|
||||||
case (rho_sgl_mob_edg_neg_ID)
|
case('rho_sgl_mob_edg_neg')
|
||||||
call results_writeDataset(group,stt%rho_sgl_mob_edg_neg, 'rho_sgl_mob_edg_neg',&
|
if(prm%totalNslip>0) call results_writeDataset(group,stt%rho_sgl_mob_edg_neg, 'rho_sgl_mob_edg_neg',&
|
||||||
'negative mobile edge density','1/m²')
|
'negative mobile edge density','1/m²')
|
||||||
case (rho_sgl_imm_edg_neg_ID)
|
case('rho_sgl_imm_edg_neg')
|
||||||
call results_writeDataset(group,stt%rho_sgl_imm_edg_neg, 'rho_sgl_imm_edg_neg',&
|
if(prm%totalNslip>0) call results_writeDataset(group,stt%rho_sgl_imm_edg_neg, 'rho_sgl_imm_edg_neg',&
|
||||||
'negative immobile edge density','1/m²')
|
'negative immobile edge density','1/m²')
|
||||||
case (rho_dip_edg_ID)
|
case('rho_dip_edg')
|
||||||
call results_writeDataset(group,stt%rho_dip_edg, 'rho_dip_edg',&
|
if(prm%totalNslip>0) call results_writeDataset(group,stt%rho_dip_edg, 'rho_dip_edg',&
|
||||||
'edge dipole density','1/m²')
|
'edge dipole density','1/m²')
|
||||||
case (rho_sgl_mob_scr_pos_ID)
|
case('rho_sgl_mob_scr_pos')
|
||||||
call results_writeDataset(group,stt%rho_sgl_mob_scr_pos, 'rho_sgl_mob_scr_pos',&
|
if(prm%totalNslip>0) call results_writeDataset(group,stt%rho_sgl_mob_scr_pos, 'rho_sgl_mob_scr_pos',&
|
||||||
'positive mobile screw density','1/m²')
|
'positive mobile screw density','1/m²')
|
||||||
case (rho_sgl_imm_scr_pos_ID)
|
case('rho_sgl_imm_scr_pos')
|
||||||
call results_writeDataset(group,stt%rho_sgl_imm_scr_pos, 'rho_sgl_imm_scr_pos',&
|
if(prm%totalNslip>0) call results_writeDataset(group,stt%rho_sgl_imm_scr_pos, 'rho_sgl_imm_scr_pos',&
|
||||||
'positive immobile screw density','1/m²')
|
'positive immobile screw density','1/m²')
|
||||||
case (rho_sgl_mob_scr_neg_ID)
|
case('rho_sgl_mob_scr_neg')
|
||||||
call results_writeDataset(group,stt%rho_sgl_mob_scr_neg, 'rho_sgl_mob_scr_neg',&
|
if(prm%totalNslip>0) call results_writeDataset(group,stt%rho_sgl_mob_scr_neg, 'rho_sgl_mob_scr_neg',&
|
||||||
'negative mobile screw density','1/m²')
|
'negative mobile screw density','1/m²')
|
||||||
case (rho_sgl_imm_scr_neg_ID)
|
case('rho_sgl_imm_scr_neg')
|
||||||
call results_writeDataset(group,stt%rho_sgl_imm_scr_neg, 'rho_sgl_imm_scr_neg',&
|
if(prm%totalNslip>0) call results_writeDataset(group,stt%rho_sgl_imm_scr_neg, 'rho_sgl_imm_scr_neg',&
|
||||||
'negative immobile screw density','1/m²')
|
'negative immobile screw density','1/m²')
|
||||||
case (rho_dip_scr_ID)
|
case('rho_dip_scr')
|
||||||
call results_writeDataset(group,stt%rho_dip_scr, 'rho_dip_scr',&
|
if(prm%totalNslip>0) call results_writeDataset(group,stt%rho_dip_scr, 'rho_dip_scr',&
|
||||||
'screw dipole density','1/m²')
|
'screw dipole density','1/m²')
|
||||||
case (rho_forest_ID)
|
case('rho_forest')
|
||||||
call results_writeDataset(group,stt%rho_forest, 'rho_forest',&
|
if(prm%totalNslip>0) call results_writeDataset(group,stt%rho_forest, 'rho_forest',&
|
||||||
'forest density','1/m²')
|
'forest density','1/m²')
|
||||||
case (v_edg_pos_ID)
|
case('v_edg_pos')
|
||||||
call results_writeDataset(group,stt%v_edg_pos, 'v_edg_pos',&
|
if(prm%totalNslip>0) call results_writeDataset(group,stt%v_edg_pos, 'v_edg_pos',&
|
||||||
'positive edge velocity','m/s')
|
'positive edge velocity','m/s')
|
||||||
case (v_edg_neg_ID)
|
case('v_edg_neg')
|
||||||
call results_writeDataset(group,stt%v_edg_neg, 'v_edg_neg',&
|
if(prm%totalNslip>0) call results_writeDataset(group,stt%v_edg_neg, 'v_edg_neg',&
|
||||||
'negative edge velocity','m/s')
|
'negative edge velocity','m/s')
|
||||||
case (v_scr_pos_ID)
|
case('v_scr_pos')
|
||||||
call results_writeDataset(group,stt%v_scr_pos, 'v_scr_pos',&
|
if(prm%totalNslip>0) call results_writeDataset(group,stt%v_scr_pos, 'v_scr_pos',&
|
||||||
'positive srew velocity','m/s')
|
'positive srew velocity','m/s')
|
||||||
case (v_scr_neg_ID)
|
case('v_scr_neg')
|
||||||
call results_writeDataset(group,stt%v_scr_neg, 'v_scr_neg',&
|
if(prm%totalNslip>0) call results_writeDataset(group,stt%v_scr_neg, 'v_scr_neg',&
|
||||||
'negative screw velocity','m/s')
|
'negative screw velocity','m/s')
|
||||||
case(gamma_ID)
|
case('gamma')
|
||||||
call results_writeDataset(group,stt%gamma,'gamma',&
|
if(prm%totalNslip>0) call results_writeDataset(group,stt%gamma,'gamma',&
|
||||||
'plastic shear','1')
|
'plastic shear','1')
|
||||||
case (tau_pass_ID)
|
case('tau_pass')
|
||||||
call results_writeDataset(group,dst%tau_pass,'tau_pass',&
|
if(prm%totalNslip>0) call results_writeDataset(group,dst%tau_pass,'tau_pass',&
|
||||||
'passing stress for slip','Pa')
|
'passing stress for slip','Pa')
|
||||||
end select
|
end select
|
||||||
enddo outputsLoop
|
enddo outputsLoop
|
||||||
end associate
|
end associate
|
||||||
|
|
|
@ -6,19 +6,6 @@
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
submodule(constitutive) plastic_phenopowerlaw
|
submodule(constitutive) plastic_phenopowerlaw
|
||||||
|
|
||||||
enum, bind(c)
|
|
||||||
enumerator :: &
|
|
||||||
undefined_ID, &
|
|
||||||
resistance_slip_ID, &
|
|
||||||
accumulatedshear_slip_ID, &
|
|
||||||
shearrate_slip_ID, &
|
|
||||||
resolvedstress_slip_ID, &
|
|
||||||
resistance_twin_ID, &
|
|
||||||
accumulatedshear_twin_ID, &
|
|
||||||
shearrate_twin_ID, &
|
|
||||||
resolvedstress_twin_ID
|
|
||||||
end enum
|
|
||||||
|
|
||||||
type :: tParameters
|
type :: tParameters
|
||||||
real(pReal) :: &
|
real(pReal) :: &
|
||||||
gdot0_slip, & !< reference shear strain rate for slip
|
gdot0_slip, & !< reference shear strain rate for slip
|
||||||
|
@ -37,19 +24,19 @@ submodule(constitutive) plastic_phenopowerlaw
|
||||||
aTolResistance, & !< absolute tolerance for integration of xi
|
aTolResistance, & !< absolute tolerance for integration of xi
|
||||||
aTolShear, & !< absolute tolerance for integration of gamma
|
aTolShear, & !< absolute tolerance for integration of gamma
|
||||||
aTolTwinfrac !< absolute tolerance for integration of f
|
aTolTwinfrac !< absolute tolerance for integration of f
|
||||||
real(pReal), allocatable, dimension(:) :: &
|
real(pReal), allocatable, dimension(:) :: &
|
||||||
xi_slip_0, & !< initial critical shear stress for slip
|
xi_slip_0, & !< initial critical shear stress for slip
|
||||||
xi_twin_0, & !< initial critical shear stress for twin
|
xi_twin_0, & !< initial critical shear stress for twin
|
||||||
xi_slip_sat, & !< maximum critical shear stress for slip
|
xi_slip_sat, & !< maximum critical shear stress for slip
|
||||||
nonSchmidCoeff, &
|
nonSchmidCoeff, &
|
||||||
H_int, & !< per family hardening activity (optional)
|
H_int, & !< per family hardening activity (optional)
|
||||||
gamma_twin_char !< characteristic shear for twins
|
gamma_twin_char !< characteristic shear for twins
|
||||||
real(pReal), allocatable, dimension(:,:) :: &
|
real(pReal), allocatable, dimension(:,:) :: &
|
||||||
interaction_SlipSlip, & !< slip resistance from slip activity
|
interaction_SlipSlip, & !< slip resistance from slip activity
|
||||||
interaction_SlipTwin, & !< slip resistance from twin activity
|
interaction_SlipTwin, & !< slip resistance from twin activity
|
||||||
interaction_TwinSlip, & !< twin resistance from slip activity
|
interaction_TwinSlip, & !< twin resistance from slip activity
|
||||||
interaction_TwinTwin !< twin resistance from twin activity
|
interaction_TwinTwin !< twin resistance from twin activity
|
||||||
real(pReal), allocatable, dimension(:,:,:) :: &
|
real(pReal), allocatable, dimension(:,:,:) :: &
|
||||||
Schmid_slip, &
|
Schmid_slip, &
|
||||||
Schmid_twin, &
|
Schmid_twin, &
|
||||||
nonSchmid_pos, &
|
nonSchmid_pos, &
|
||||||
|
@ -57,13 +44,13 @@ submodule(constitutive) plastic_phenopowerlaw
|
||||||
integer :: &
|
integer :: &
|
||||||
totalNslip, & !< total number of active slip system
|
totalNslip, & !< total number of active slip system
|
||||||
totalNtwin !< total number of active twin systems
|
totalNtwin !< total number of active twin systems
|
||||||
integer, allocatable, dimension(:) :: &
|
integer, allocatable, dimension(:) :: &
|
||||||
Nslip, & !< number of active slip systems for each family
|
Nslip, & !< number of active slip systems for each family
|
||||||
Ntwin !< number of active twin systems for each family
|
Ntwin !< number of active twin systems for each family
|
||||||
integer(kind(undefined_ID)), allocatable, dimension(:) :: &
|
character(len=pStringLen), allocatable, dimension(:) :: &
|
||||||
outputID !< ID of each post result output
|
output
|
||||||
end type tParameters
|
end type tParameters
|
||||||
|
|
||||||
type :: tPhenopowerlawState
|
type :: tPhenopowerlawState
|
||||||
real(pReal), pointer, dimension(:,:) :: &
|
real(pReal), pointer, dimension(:,:) :: &
|
||||||
xi_slip, &
|
xi_slip, &
|
||||||
|
@ -71,7 +58,7 @@ submodule(constitutive) plastic_phenopowerlaw
|
||||||
gamma_slip, &
|
gamma_slip, &
|
||||||
gamma_twin
|
gamma_twin
|
||||||
end type tPhenopowerlawState
|
end type tPhenopowerlawState
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! containers for parameters and state
|
! containers for parameters and state
|
||||||
type(tParameters), allocatable, dimension(:) :: param
|
type(tParameters), allocatable, dimension(:) :: param
|
||||||
|
@ -83,7 +70,7 @@ contains
|
||||||
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @brief module initialization
|
!> @brief Perform 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 subroutine plastic_phenopowerlaw_init
|
module subroutine plastic_phenopowerlaw_init
|
||||||
|
@ -91,51 +78,46 @@ module subroutine plastic_phenopowerlaw_init
|
||||||
integer :: &
|
integer :: &
|
||||||
Ninstance, &
|
Ninstance, &
|
||||||
p, i, &
|
p, i, &
|
||||||
NipcMyPhase, outputSize, &
|
NipcMyPhase, &
|
||||||
sizeState, sizeDotState, &
|
sizeState, sizeDotState, &
|
||||||
startIndex, endIndex
|
startIndex, endIndex
|
||||||
|
|
||||||
integer(kind(undefined_ID)) :: &
|
|
||||||
outputID
|
|
||||||
|
|
||||||
character(len=pStringLen) :: &
|
character(len=pStringLen) :: &
|
||||||
extmsg = ''
|
extmsg = ''
|
||||||
character(len=pStringLen), dimension(:), allocatable :: &
|
|
||||||
outputs
|
write(6,'(/,a)') ' <<<+- plastic_'//PLASTICITY_PHENOPOWERLAW_label//' init -+>>>'; flush(6)
|
||||||
|
|
||||||
write(6,'(/,a)') ' <<<+- plastic_'//PLASTICITY_PHENOPOWERLAW_label//' init -+>>>'
|
|
||||||
|
|
||||||
Ninstance = count(phase_plasticity == PLASTICITY_PHENOPOWERLAW_ID)
|
Ninstance = count(phase_plasticity == PLASTICITY_PHENOPOWERLAW_ID)
|
||||||
if (iand(debug_level(debug_constitutive),debug_levelBasic) /= 0) &
|
if (iand(debug_level(debug_constitutive),debug_levelBasic) /= 0) &
|
||||||
write(6,'(a16,1x,i5,/)') '# instances:',Ninstance
|
write(6,'(a16,1x,i5,/)') '# instances:',Ninstance
|
||||||
|
|
||||||
allocate(param(Ninstance))
|
allocate(param(Ninstance))
|
||||||
allocate(state(Ninstance))
|
allocate(state(Ninstance))
|
||||||
allocate(dotState(Ninstance))
|
allocate(dotState(Ninstance))
|
||||||
|
|
||||||
do p = 1, size(phase_plasticity)
|
do p = 1, size(phase_plasticity)
|
||||||
if (phase_plasticity(p) /= PLASTICITY_PHENOPOWERLAW_ID) cycle
|
if (phase_plasticity(p) /= PLASTICITY_PHENOPOWERLAW_ID) cycle
|
||||||
associate(prm => param(phase_plasticityInstance(p)), &
|
associate(prm => param(phase_plasticityInstance(p)), &
|
||||||
dot => dotState(phase_plasticityInstance(p)), &
|
dot => dotState(phase_plasticityInstance(p)), &
|
||||||
stt => state(phase_plasticityInstance(p)), &
|
stt => state(phase_plasticityInstance(p)), &
|
||||||
config => config_phase(p))
|
config => config_phase(p))
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! optional parameters that need to be defined
|
! optional parameters that need to be defined
|
||||||
prm%c_1 = config%getFloat('twin_c',defaultVal=0.0_pReal)
|
prm%c_1 = config%getFloat('twin_c',defaultVal=0.0_pReal)
|
||||||
prm%c_2 = config%getFloat('twin_b',defaultVal=1.0_pReal)
|
prm%c_2 = config%getFloat('twin_b',defaultVal=1.0_pReal)
|
||||||
prm%c_3 = config%getFloat('twin_e',defaultVal=0.0_pReal)
|
prm%c_3 = config%getFloat('twin_e',defaultVal=0.0_pReal)
|
||||||
prm%c_4 = config%getFloat('twin_d',defaultVal=0.0_pReal)
|
prm%c_4 = config%getFloat('twin_d',defaultVal=0.0_pReal)
|
||||||
|
|
||||||
prm%aTolResistance = config%getFloat('atol_resistance',defaultVal=1.0_pReal)
|
prm%aTolResistance = config%getFloat('atol_resistance',defaultVal=1.0_pReal)
|
||||||
prm%aTolShear = config%getFloat('atol_shear', defaultVal=1.0e-6_pReal)
|
prm%aTolShear = config%getFloat('atol_shear', defaultVal=1.0e-6_pReal)
|
||||||
prm%aTolTwinfrac = config%getFloat('atol_twinfrac', defaultVal=1.0e-6_pReal)
|
prm%aTolTwinfrac = config%getFloat('atol_twinfrac', defaultVal=1.0e-6_pReal)
|
||||||
|
|
||||||
! sanity checks
|
! sanity checks
|
||||||
if (prm%aTolResistance <= 0.0_pReal) extmsg = trim(extmsg)//' aTolresistance'
|
if (prm%aTolResistance <= 0.0_pReal) extmsg = trim(extmsg)//' aTolresistance'
|
||||||
if (prm%aTolShear <= 0.0_pReal) extmsg = trim(extmsg)//' aTolShear'
|
if (prm%aTolShear <= 0.0_pReal) extmsg = trim(extmsg)//' aTolShear'
|
||||||
if (prm%aTolTwinfrac <= 0.0_pReal) extmsg = trim(extmsg)//' atoltwinfrac'
|
if (prm%aTolTwinfrac <= 0.0_pReal) extmsg = trim(extmsg)//' atoltwinfrac'
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! slip related parameters
|
! slip related parameters
|
||||||
prm%Nslip = config%getInts('nslip',defaultVal=emptyIntArray)
|
prm%Nslip = config%getInts('nslip',defaultVal=emptyIntArray)
|
||||||
|
@ -143,7 +125,7 @@ module subroutine plastic_phenopowerlaw_init
|
||||||
slipActive: if (prm%totalNslip > 0) then
|
slipActive: if (prm%totalNslip > 0) then
|
||||||
prm%Schmid_slip = lattice_SchmidMatrix_slip(prm%Nslip,config%getString('lattice_structure'),&
|
prm%Schmid_slip = lattice_SchmidMatrix_slip(prm%Nslip,config%getString('lattice_structure'),&
|
||||||
config%getFloat('c/a',defaultVal=0.0_pReal))
|
config%getFloat('c/a',defaultVal=0.0_pReal))
|
||||||
|
|
||||||
if(trim(config%getString('lattice_structure')) == 'bcc') then
|
if(trim(config%getString('lattice_structure')) == 'bcc') then
|
||||||
prm%nonSchmidCoeff = config%getFloats('nonschmid_coefficients',&
|
prm%nonSchmidCoeff = config%getFloats('nonschmid_coefficients',&
|
||||||
defaultVal = emptyRealArray)
|
defaultVal = emptyRealArray)
|
||||||
|
@ -157,22 +139,22 @@ module subroutine plastic_phenopowerlaw_init
|
||||||
prm%interaction_SlipSlip = lattice_interaction_SlipBySlip(prm%Nslip, &
|
prm%interaction_SlipSlip = lattice_interaction_SlipBySlip(prm%Nslip, &
|
||||||
config%getFloats('interaction_slipslip'), &
|
config%getFloats('interaction_slipslip'), &
|
||||||
config%getString('lattice_structure'))
|
config%getString('lattice_structure'))
|
||||||
|
|
||||||
prm%xi_slip_0 = config%getFloats('tau0_slip', requiredSize=size(prm%Nslip))
|
prm%xi_slip_0 = config%getFloats('tau0_slip', requiredSize=size(prm%Nslip))
|
||||||
prm%xi_slip_sat = config%getFloats('tausat_slip', requiredSize=size(prm%Nslip))
|
prm%xi_slip_sat = config%getFloats('tausat_slip', requiredSize=size(prm%Nslip))
|
||||||
prm%H_int = config%getFloats('h_int', requiredSize=size(prm%Nslip), &
|
prm%H_int = config%getFloats('h_int', requiredSize=size(prm%Nslip), &
|
||||||
defaultVal=[(0.0_pReal,i=1,size(prm%Nslip))])
|
defaultVal=[(0.0_pReal,i=1,size(prm%Nslip))])
|
||||||
|
|
||||||
prm%gdot0_slip = config%getFloat('gdot0_slip')
|
prm%gdot0_slip = config%getFloat('gdot0_slip')
|
||||||
prm%n_slip = config%getFloat('n_slip')
|
prm%n_slip = config%getFloat('n_slip')
|
||||||
prm%a_slip = config%getFloat('a_slip')
|
prm%a_slip = config%getFloat('a_slip')
|
||||||
prm%h0_SlipSlip = config%getFloat('h0_slipslip')
|
prm%h0_SlipSlip = config%getFloat('h0_slipslip')
|
||||||
|
|
||||||
! expand: family => system
|
! expand: family => system
|
||||||
prm%xi_slip_0 = math_expand(prm%xi_slip_0, prm%Nslip)
|
prm%xi_slip_0 = math_expand(prm%xi_slip_0, prm%Nslip)
|
||||||
prm%xi_slip_sat = math_expand(prm%xi_slip_sat,prm%Nslip)
|
prm%xi_slip_sat = math_expand(prm%xi_slip_sat,prm%Nslip)
|
||||||
prm%H_int = math_expand(prm%H_int, prm%Nslip)
|
prm%H_int = math_expand(prm%H_int, prm%Nslip)
|
||||||
|
|
||||||
! sanity checks
|
! sanity checks
|
||||||
if ( prm%gdot0_slip <= 0.0_pReal) extmsg = trim(extmsg)//' gdot0_slip'
|
if ( prm%gdot0_slip <= 0.0_pReal) extmsg = trim(extmsg)//' gdot0_slip'
|
||||||
if ( prm%a_slip <= 0.0_pReal) extmsg = trim(extmsg)//' a_slip'
|
if ( prm%a_slip <= 0.0_pReal) extmsg = trim(extmsg)//' a_slip'
|
||||||
|
@ -183,7 +165,7 @@ module subroutine plastic_phenopowerlaw_init
|
||||||
allocate(prm%interaction_SlipSlip(0,0))
|
allocate(prm%interaction_SlipSlip(0,0))
|
||||||
allocate(prm%xi_slip_0(0))
|
allocate(prm%xi_slip_0(0))
|
||||||
endif slipActive
|
endif slipActive
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! twin related parameters
|
! twin related parameters
|
||||||
prm%Ntwin = config%getInts('ntwin', defaultVal=emptyIntArray)
|
prm%Ntwin = config%getInts('ntwin', defaultVal=emptyIntArray)
|
||||||
|
@ -196,17 +178,17 @@ module subroutine plastic_phenopowerlaw_init
|
||||||
config%getString('lattice_structure'))
|
config%getString('lattice_structure'))
|
||||||
prm%gamma_twin_char = lattice_characteristicShear_twin(prm%Ntwin,config%getString('lattice_structure'),&
|
prm%gamma_twin_char = lattice_characteristicShear_twin(prm%Ntwin,config%getString('lattice_structure'),&
|
||||||
config%getFloat('c/a'))
|
config%getFloat('c/a'))
|
||||||
|
|
||||||
prm%xi_twin_0 = config%getFloats('tau0_twin',requiredSize=size(prm%Ntwin))
|
prm%xi_twin_0 = config%getFloats('tau0_twin',requiredSize=size(prm%Ntwin))
|
||||||
|
|
||||||
prm%gdot0_twin = config%getFloat('gdot0_twin')
|
prm%gdot0_twin = config%getFloat('gdot0_twin')
|
||||||
prm%n_twin = config%getFloat('n_twin')
|
prm%n_twin = config%getFloat('n_twin')
|
||||||
prm%spr = config%getFloat('s_pr')
|
prm%spr = config%getFloat('s_pr')
|
||||||
prm%h0_TwinTwin = config%getFloat('h0_twintwin')
|
prm%h0_TwinTwin = config%getFloat('h0_twintwin')
|
||||||
|
|
||||||
! expand: family => system
|
! expand: family => system
|
||||||
prm%xi_twin_0 = math_expand(prm%xi_twin_0, prm%Ntwin)
|
prm%xi_twin_0 = math_expand(prm%xi_twin_0, prm%Ntwin)
|
||||||
|
|
||||||
! sanity checks
|
! sanity checks
|
||||||
if (prm%gdot0_twin <= 0.0_pReal) extmsg = trim(extmsg)//' gdot0_twin'
|
if (prm%gdot0_twin <= 0.0_pReal) extmsg = trim(extmsg)//' gdot0_twin'
|
||||||
if (prm%n_twin <= 0.0_pReal) extmsg = trim(extmsg)//' n_twin'
|
if (prm%n_twin <= 0.0_pReal) extmsg = trim(extmsg)//' n_twin'
|
||||||
|
@ -215,7 +197,7 @@ module subroutine plastic_phenopowerlaw_init
|
||||||
allocate(prm%xi_twin_0(0))
|
allocate(prm%xi_twin_0(0))
|
||||||
allocate(prm%gamma_twin_char(0))
|
allocate(prm%gamma_twin_char(0))
|
||||||
endif twinActive
|
endif twinActive
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! slip-twin related parameters
|
! slip-twin related parameters
|
||||||
slipAndTwinActive: if (prm%totalNslip > 0 .and. prm%totalNtwin > 0) then
|
slipAndTwinActive: if (prm%totalNslip > 0 .and. prm%totalNtwin > 0) then
|
||||||
|
@ -231,63 +213,25 @@ module subroutine plastic_phenopowerlaw_init
|
||||||
allocate(prm%interaction_TwinSlip(prm%TotalNtwin,prm%TotalNslip)) ! at least one dimension is 0
|
allocate(prm%interaction_TwinSlip(prm%TotalNtwin,prm%TotalNslip)) ! at least one dimension is 0
|
||||||
prm%h0_TwinSlip = 0.0_pReal
|
prm%h0_TwinSlip = 0.0_pReal
|
||||||
endif slipAndTwinActive
|
endif slipAndTwinActive
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! exit if any parameter is out of range
|
! exit if any parameter is out of range
|
||||||
if (extmsg /= '') &
|
if (extmsg /= '') &
|
||||||
call IO_error(211,ext_msg=trim(extmsg)//'('//PLASTICITY_PHENOPOWERLAW_label//')')
|
call IO_error(211,ext_msg=trim(extmsg)//'('//PLASTICITY_PHENOPOWERLAW_label//')')
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! output pararameters
|
! output pararameters
|
||||||
outputs = config%getStrings('(output)',defaultVal=emptyStringArray)
|
prm%output = config%getStrings('(output)',defaultVal=emptyStringArray)
|
||||||
allocate(prm%outputID(0))
|
|
||||||
do i=1, size(outputs)
|
|
||||||
outputID = undefined_ID
|
|
||||||
select case(outputs(i))
|
|
||||||
|
|
||||||
case ('resistance_slip')
|
|
||||||
outputID = merge(resistance_slip_ID,undefined_ID,prm%totalNslip>0)
|
|
||||||
outputSize = prm%totalNslip
|
|
||||||
case ('accumulatedshear_slip')
|
|
||||||
outputID = merge(accumulatedshear_slip_ID,undefined_ID,prm%totalNslip>0)
|
|
||||||
outputSize = prm%totalNslip
|
|
||||||
case ('shearrate_slip')
|
|
||||||
outputID = merge(shearrate_slip_ID,undefined_ID,prm%totalNslip>0)
|
|
||||||
outputSize = prm%totalNslip
|
|
||||||
case ('resolvedstress_slip')
|
|
||||||
outputID = merge(resolvedstress_slip_ID,undefined_ID,prm%totalNslip>0)
|
|
||||||
outputSize = prm%totalNslip
|
|
||||||
|
|
||||||
case ('resistance_twin')
|
|
||||||
outputID = merge(resistance_twin_ID,undefined_ID,prm%totalNtwin>0)
|
|
||||||
outputSize = prm%totalNtwin
|
|
||||||
case ('accumulatedshear_twin')
|
|
||||||
outputID = merge(accumulatedshear_twin_ID,undefined_ID,prm%totalNtwin>0)
|
|
||||||
outputSize = prm%totalNtwin
|
|
||||||
case ('shearrate_twin')
|
|
||||||
outputID = merge(shearrate_twin_ID,undefined_ID,prm%totalNtwin>0)
|
|
||||||
outputSize = prm%totalNtwin
|
|
||||||
case ('resolvedstress_twin')
|
|
||||||
outputID = merge(resolvedstress_twin_ID,undefined_ID,prm%totalNtwin>0)
|
|
||||||
outputSize = prm%totalNtwin
|
|
||||||
|
|
||||||
end select
|
|
||||||
|
|
||||||
if (outputID /= undefined_ID) then
|
|
||||||
prm%outputID = [prm%outputID, outputID]
|
|
||||||
endif
|
|
||||||
|
|
||||||
enddo
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! allocate state arrays
|
! allocate state arrays
|
||||||
NipcMyPhase = count(material_phaseAt == p) * discretization_nIP
|
NipcMyPhase = count(material_phaseAt == p) * discretization_nIP
|
||||||
sizeDotState = size(['tau_slip ','gamma_slip']) * prm%totalNslip &
|
sizeDotState = size(['tau_slip ','gamma_slip']) * prm%totalNslip &
|
||||||
+ size(['tau_twin ','gamma_twin']) * prm%totalNtwin
|
+ size(['tau_twin ','gamma_twin']) * prm%totalNtwin
|
||||||
sizeState = sizeDotState
|
sizeState = sizeDotState
|
||||||
|
|
||||||
call material_allocatePlasticState(p,NipcMyPhase,sizeState,sizeDotState,0)
|
call material_allocatePlasticState(p,NipcMyPhase,sizeState,sizeDotState,0)
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! locally defined state aliases and initialization of state0 and aTolState
|
! locally defined state aliases and initialization of state0 and aTolState
|
||||||
startIndex = 1
|
startIndex = 1
|
||||||
|
@ -296,14 +240,14 @@ module subroutine plastic_phenopowerlaw_init
|
||||||
stt%xi_slip = spread(prm%xi_slip_0, 2, NipcMyPhase)
|
stt%xi_slip = spread(prm%xi_slip_0, 2, NipcMyPhase)
|
||||||
dot%xi_slip => plasticState(p)%dotState(startIndex:endIndex,:)
|
dot%xi_slip => plasticState(p)%dotState(startIndex:endIndex,:)
|
||||||
plasticState(p)%aTolState(startIndex:endIndex) = prm%aTolResistance
|
plasticState(p)%aTolState(startIndex:endIndex) = prm%aTolResistance
|
||||||
|
|
||||||
startIndex = endIndex + 1
|
startIndex = endIndex + 1
|
||||||
endIndex = endIndex + prm%totalNtwin
|
endIndex = endIndex + prm%totalNtwin
|
||||||
stt%xi_twin => plasticState(p)%state (startIndex:endIndex,:)
|
stt%xi_twin => plasticState(p)%state (startIndex:endIndex,:)
|
||||||
stt%xi_twin = spread(prm%xi_twin_0, 2, NipcMyPhase)
|
stt%xi_twin = spread(prm%xi_twin_0, 2, NipcMyPhase)
|
||||||
dot%xi_twin => plasticState(p)%dotState(startIndex:endIndex,:)
|
dot%xi_twin => plasticState(p)%dotState(startIndex:endIndex,:)
|
||||||
plasticState(p)%aTolState(startIndex:endIndex) = prm%aTolResistance
|
plasticState(p)%aTolState(startIndex:endIndex) = prm%aTolResistance
|
||||||
|
|
||||||
startIndex = endIndex + 1
|
startIndex = endIndex + 1
|
||||||
endIndex = endIndex + prm%totalNslip
|
endIndex = endIndex + prm%totalNslip
|
||||||
stt%gamma_slip => plasticState(p)%state (startIndex:endIndex,:)
|
stt%gamma_slip => plasticState(p)%state (startIndex:endIndex,:)
|
||||||
|
@ -317,18 +261,18 @@ module subroutine plastic_phenopowerlaw_init
|
||||||
stt%gamma_twin => plasticState(p)%state (startIndex:endIndex,:)
|
stt%gamma_twin => plasticState(p)%state (startIndex:endIndex,:)
|
||||||
dot%gamma_twin => plasticState(p)%dotState(startIndex:endIndex,:)
|
dot%gamma_twin => plasticState(p)%dotState(startIndex:endIndex,:)
|
||||||
plasticState(p)%aTolState(startIndex:endIndex) = prm%aTolShear
|
plasticState(p)%aTolState(startIndex:endIndex) = prm%aTolShear
|
||||||
|
|
||||||
plasticState(p)%state0 = plasticState(p)%state ! ToDo: this could be done centrally
|
plasticState(p)%state0 = plasticState(p)%state ! ToDo: this could be done centrally
|
||||||
|
|
||||||
end associate
|
end associate
|
||||||
|
|
||||||
enddo
|
enddo
|
||||||
|
|
||||||
end subroutine plastic_phenopowerlaw_init
|
end subroutine plastic_phenopowerlaw_init
|
||||||
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @brief calculates plastic velocity gradient and its tangent
|
!> @brief Calculate plastic velocity gradient and its tangent.
|
||||||
!> @details asummes that deformation by dislocation glide affects twinned and untwinned volume
|
!> @details asummes that deformation by dislocation glide affects twinned and untwinned volume
|
||||||
! equally (Taylor assumption). Twinning happens only in untwinned volume
|
! equally (Taylor assumption). Twinning happens only in untwinned volume
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
@ -338,13 +282,13 @@ pure module subroutine plastic_phenopowerlaw_LpAndItsTangent(Lp,dLp_dMp,Mp,insta
|
||||||
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 !< derivative of Lp with respect to the Mandel stress
|
dLp_dMp !< derivative of Lp with respect to the Mandel stress
|
||||||
|
|
||||||
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, &
|
instance, &
|
||||||
of
|
of
|
||||||
|
|
||||||
integer :: &
|
integer :: &
|
||||||
i,k,l,m,n
|
i,k,l,m,n
|
||||||
real(pReal), dimension(param(instance)%totalNslip) :: &
|
real(pReal), dimension(param(instance)%totalNslip) :: &
|
||||||
|
@ -352,12 +296,12 @@ pure module subroutine plastic_phenopowerlaw_LpAndItsTangent(Lp,dLp_dMp,Mp,insta
|
||||||
dgdot_dtauslip_pos,dgdot_dtauslip_neg
|
dgdot_dtauslip_pos,dgdot_dtauslip_neg
|
||||||
real(pReal), dimension(param(instance)%totalNtwin) :: &
|
real(pReal), dimension(param(instance)%totalNtwin) :: &
|
||||||
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(instance))
|
associate(prm => param(instance))
|
||||||
|
|
||||||
call kinetics_slip(Mp,instance,of,gdot_slip_pos,gdot_slip_neg,dgdot_dtauslip_pos,dgdot_dtauslip_neg)
|
call kinetics_slip(Mp,instance,of,gdot_slip_pos,gdot_slip_neg,dgdot_dtauslip_pos,dgdot_dtauslip_neg)
|
||||||
slipSystems: do i = 1, prm%totalNslip
|
slipSystems: do i = 1, prm%totalNslip
|
||||||
Lp = Lp + (gdot_slip_pos(i)+gdot_slip_neg(i))*prm%Schmid_slip(1:3,1:3,i)
|
Lp = Lp + (gdot_slip_pos(i)+gdot_slip_neg(i))*prm%Schmid_slip(1:3,1:3,i)
|
||||||
|
@ -366,7 +310,7 @@ pure module subroutine plastic_phenopowerlaw_LpAndItsTangent(Lp,dLp_dMp,Mp,insta
|
||||||
+ dgdot_dtauslip_pos(i) * prm%Schmid_slip(k,l,i) * prm%nonSchmid_pos(m,n,i) &
|
+ dgdot_dtauslip_pos(i) * prm%Schmid_slip(k,l,i) * prm%nonSchmid_pos(m,n,i) &
|
||||||
+ dgdot_dtauslip_neg(i) * prm%Schmid_slip(k,l,i) * prm%nonSchmid_neg(m,n,i)
|
+ dgdot_dtauslip_neg(i) * prm%Schmid_slip(k,l,i) * prm%nonSchmid_neg(m,n,i)
|
||||||
enddo slipSystems
|
enddo slipSystems
|
||||||
|
|
||||||
call kinetics_twin(Mp,instance,of,gdot_twin,dgdot_dtautwin)
|
call kinetics_twin(Mp,instance,of,gdot_twin,dgdot_dtautwin)
|
||||||
twinSystems: do i = 1, prm%totalNtwin
|
twinSystems: do i = 1, prm%totalNtwin
|
||||||
Lp = Lp + gdot_twin(i)*prm%Schmid_twin(1:3,1:3,i)
|
Lp = Lp + gdot_twin(i)*prm%Schmid_twin(1:3,1:3,i)
|
||||||
|
@ -374,14 +318,14 @@ pure module subroutine plastic_phenopowerlaw_LpAndItsTangent(Lp,dLp_dMp,Mp,insta
|
||||||
dLp_dMp(k,l,m,n) = dLp_dMp(k,l,m,n) &
|
dLp_dMp(k,l,m,n) = dLp_dMp(k,l,m,n) &
|
||||||
+ dgdot_dtautwin(i)*prm%Schmid_twin(k,l,i)*prm%Schmid_twin(m,n,i)
|
+ dgdot_dtautwin(i)*prm%Schmid_twin(k,l,i)*prm%Schmid_twin(m,n,i)
|
||||||
enddo twinSystems
|
enddo twinSystems
|
||||||
|
|
||||||
end associate
|
end associate
|
||||||
|
|
||||||
end subroutine plastic_phenopowerlaw_LpAndItsTangent
|
end subroutine plastic_phenopowerlaw_LpAndItsTangent
|
||||||
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @brief calculates the rate of change of microstructure
|
!> @brief Calculate the rate of change of microstructure.
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
module subroutine plastic_phenopowerlaw_dotState(Mp,instance,of)
|
module subroutine plastic_phenopowerlaw_dotState(Mp,instance,of)
|
||||||
|
|
||||||
|
@ -390,7 +334,7 @@ module subroutine plastic_phenopowerlaw_dotState(Mp,instance,of)
|
||||||
integer, intent(in) :: &
|
integer, intent(in) :: &
|
||||||
instance, &
|
instance, &
|
||||||
of
|
of
|
||||||
|
|
||||||
real(pReal) :: &
|
real(pReal) :: &
|
||||||
c_SlipSlip,c_TwinSlip,c_TwinTwin, &
|
c_SlipSlip,c_TwinSlip,c_TwinTwin, &
|
||||||
xi_slip_sat_offset,&
|
xi_slip_sat_offset,&
|
||||||
|
@ -398,9 +342,9 @@ module subroutine plastic_phenopowerlaw_dotState(Mp,instance,of)
|
||||||
real(pReal), dimension(param(instance)%totalNslip) :: &
|
real(pReal), dimension(param(instance)%totalNslip) :: &
|
||||||
left_SlipSlip,right_SlipSlip, &
|
left_SlipSlip,right_SlipSlip, &
|
||||||
gdot_slip_pos,gdot_slip_neg
|
gdot_slip_pos,gdot_slip_neg
|
||||||
|
|
||||||
associate(prm => param(instance), stt => state(instance), dot => dotState(instance))
|
associate(prm => param(instance), stt => state(instance), dot => dotState(instance))
|
||||||
|
|
||||||
sumGamma = sum(stt%gamma_slip(:,of))
|
sumGamma = sum(stt%gamma_slip(:,of))
|
||||||
sumF = sum(stt%gamma_twin(:,of)/prm%gamma_twin_char)
|
sumF = sum(stt%gamma_twin(:,of)/prm%gamma_twin_char)
|
||||||
|
|
||||||
|
@ -409,26 +353,26 @@ module subroutine plastic_phenopowerlaw_dotState(Mp,instance,of)
|
||||||
c_SlipSlip = prm%h0_slipslip * (1.0_pReal + prm%c_1*sumF** prm%c_2)
|
c_SlipSlip = prm%h0_slipslip * (1.0_pReal + prm%c_1*sumF** prm%c_2)
|
||||||
c_TwinSlip = prm%h0_TwinSlip * sumGamma**prm%c_3
|
c_TwinSlip = prm%h0_TwinSlip * sumGamma**prm%c_3
|
||||||
c_TwinTwin = prm%h0_TwinTwin * sumF**prm%c_4
|
c_TwinTwin = prm%h0_TwinTwin * sumF**prm%c_4
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! calculate left and right vectors
|
! calculate left and right vectors
|
||||||
left_SlipSlip = 1.0_pReal + prm%H_int
|
left_SlipSlip = 1.0_pReal + prm%H_int
|
||||||
xi_slip_sat_offset = prm%spr*sqrt(sumF)
|
xi_slip_sat_offset = prm%spr*sqrt(sumF)
|
||||||
right_SlipSlip = abs(1.0_pReal-stt%xi_slip(:,of) / (prm%xi_slip_sat+xi_slip_sat_offset)) **prm%a_slip &
|
right_SlipSlip = abs(1.0_pReal-stt%xi_slip(:,of) / (prm%xi_slip_sat+xi_slip_sat_offset)) **prm%a_slip &
|
||||||
* sign(1.0_pReal,1.0_pReal-stt%xi_slip(:,of) / (prm%xi_slip_sat+xi_slip_sat_offset))
|
* sign(1.0_pReal,1.0_pReal-stt%xi_slip(:,of) / (prm%xi_slip_sat+xi_slip_sat_offset))
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! shear rates
|
! shear rates
|
||||||
call kinetics_slip(Mp,instance,of,gdot_slip_pos,gdot_slip_neg)
|
call kinetics_slip(Mp,instance,of,gdot_slip_pos,gdot_slip_neg)
|
||||||
dot%gamma_slip(:,of) = abs(gdot_slip_pos+gdot_slip_neg)
|
dot%gamma_slip(:,of) = abs(gdot_slip_pos+gdot_slip_neg)
|
||||||
call kinetics_twin(Mp,instance,of,dot%gamma_twin(:,of))
|
call kinetics_twin(Mp,instance,of,dot%gamma_twin(:,of))
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! hardening
|
! hardening
|
||||||
dot%xi_slip(:,of) = c_SlipSlip * left_SlipSlip * &
|
dot%xi_slip(:,of) = c_SlipSlip * left_SlipSlip * &
|
||||||
matmul(prm%interaction_SlipSlip,dot%gamma_slip(:,of)*right_SlipSlip) &
|
matmul(prm%interaction_SlipSlip,dot%gamma_slip(:,of)*right_SlipSlip) &
|
||||||
+ matmul(prm%interaction_SlipTwin,dot%gamma_twin(:,of))
|
+ matmul(prm%interaction_SlipTwin,dot%gamma_twin(:,of))
|
||||||
|
|
||||||
dot%xi_twin(:,of) = c_TwinSlip * matmul(prm%interaction_TwinSlip,dot%gamma_slip(:,of)) &
|
dot%xi_twin(:,of) = c_TwinSlip * matmul(prm%interaction_TwinSlip,dot%gamma_slip(:,of)) &
|
||||||
+ c_TwinTwin * matmul(prm%interaction_TwinTwin,dot%gamma_twin(:,of))
|
+ c_TwinTwin * matmul(prm%interaction_TwinTwin,dot%gamma_twin(:,of))
|
||||||
end associate
|
end associate
|
||||||
|
@ -437,33 +381,33 @@ end subroutine plastic_phenopowerlaw_dotState
|
||||||
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @brief writes results to HDF5 output file
|
!> @brief Write results to HDF5 output file.
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
module subroutine plastic_phenopowerlaw_results(instance,group)
|
module subroutine plastic_phenopowerlaw_results(instance,group)
|
||||||
|
|
||||||
integer, intent(in) :: instance
|
integer, intent(in) :: instance
|
||||||
character(len=*), intent(in) :: group
|
character(len=*), intent(in) :: group
|
||||||
|
|
||||||
integer :: o
|
integer :: o
|
||||||
|
|
||||||
associate(prm => param(instance), stt => state(instance))
|
associate(prm => param(instance), stt => state(instance))
|
||||||
outputsLoop: do o = 1,size(prm%outputID)
|
outputsLoop: do o = 1,size(prm%output)
|
||||||
select case(prm%outputID(o))
|
select case(trim(prm%output(o)))
|
||||||
|
|
||||||
|
case('resistance_slip')
|
||||||
|
if(prm%totalNslip>0) call results_writeDataset(group,stt%xi_slip, 'xi_sl', &
|
||||||
|
'resistance against plastic slip','Pa')
|
||||||
|
case('accumulatedshear_slip')
|
||||||
|
if(prm%totalNslip>0) call results_writeDataset(group,stt%gamma_slip,'gamma_sl', &
|
||||||
|
'plastic shear','1')
|
||||||
|
|
||||||
|
case('resistance_twin')
|
||||||
|
if(prm%totalNtwin>0) call results_writeDataset(group,stt%xi_twin, 'xi_tw', &
|
||||||
|
'resistance against twinning','Pa')
|
||||||
|
case('accumulatedshear_twin')
|
||||||
|
if(prm%totalNtwin>0) call results_writeDataset(group,stt%gamma_twin,'gamma_tw', &
|
||||||
|
'twinning shear','1')
|
||||||
|
|
||||||
case (resistance_slip_ID)
|
|
||||||
call results_writeDataset(group,stt%xi_slip, 'xi_sl', &
|
|
||||||
'resistance against plastic slip','Pa')
|
|
||||||
case (accumulatedshear_slip_ID)
|
|
||||||
call results_writeDataset(group,stt%gamma_slip,'gamma_sl', &
|
|
||||||
'plastic shear','1')
|
|
||||||
|
|
||||||
case (resistance_twin_ID)
|
|
||||||
call results_writeDataset(group,stt%xi_twin, 'xi_tw', &
|
|
||||||
'resistance against twinning','Pa')
|
|
||||||
case (accumulatedshear_twin_ID)
|
|
||||||
call results_writeDataset(group,stt%gamma_twin,'gamma_tw', &
|
|
||||||
'twinning shear','1')
|
|
||||||
|
|
||||||
end select
|
end select
|
||||||
enddo outputsLoop
|
enddo outputsLoop
|
||||||
end associate
|
end associate
|
||||||
|
@ -472,10 +416,11 @@ end subroutine plastic_phenopowerlaw_results
|
||||||
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @brief Shear rates on slip systems and their derivatives with respect to resolved stress
|
!> @brief Calculate shear rates on slip systems and their derivatives with respect to resolved
|
||||||
|
! stress.
|
||||||
!> @details Derivatives are calculated only optionally.
|
!> @details Derivatives are calculated only optionally.
|
||||||
! 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,of, &
|
pure subroutine kinetics_slip(Mp,instance,of, &
|
||||||
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)
|
||||||
|
@ -485,44 +430,44 @@ pure subroutine kinetics_slip(Mp,instance,of, &
|
||||||
integer, intent(in) :: &
|
integer, intent(in) :: &
|
||||||
instance, &
|
instance, &
|
||||||
of
|
of
|
||||||
|
|
||||||
real(pReal), intent(out), dimension(param(instance)%totalNslip) :: &
|
real(pReal), intent(out), dimension(param(instance)%totalNslip) :: &
|
||||||
gdot_slip_pos, &
|
gdot_slip_pos, &
|
||||||
gdot_slip_neg
|
gdot_slip_neg
|
||||||
real(pReal), intent(out), optional, dimension(param(instance)%totalNslip) :: &
|
real(pReal), intent(out), optional, dimension(param(instance)%totalNslip) :: &
|
||||||
dgdot_dtau_slip_pos, &
|
dgdot_dtau_slip_pos, &
|
||||||
dgdot_dtau_slip_neg
|
dgdot_dtau_slip_neg
|
||||||
|
|
||||||
real(pReal), dimension(param(instance)%totalNslip) :: &
|
real(pReal), dimension(param(instance)%totalNslip) :: &
|
||||||
tau_slip_pos, &
|
tau_slip_pos, &
|
||||||
tau_slip_neg
|
tau_slip_neg
|
||||||
integer :: i
|
integer :: i
|
||||||
logical :: nonSchmidActive
|
logical :: nonSchmidActive
|
||||||
|
|
||||||
associate(prm => param(instance), stt => state(instance))
|
associate(prm => param(instance), stt => state(instance))
|
||||||
|
|
||||||
nonSchmidActive = size(prm%nonSchmidCoeff) > 0
|
nonSchmidActive = size(prm%nonSchmidCoeff) > 0
|
||||||
|
|
||||||
do i = 1, prm%totalNslip
|
do i = 1, prm%totalNslip
|
||||||
tau_slip_pos(i) = math_mul33xx33(Mp,prm%nonSchmid_pos(1:3,1:3,i))
|
tau_slip_pos(i) = math_mul33xx33(Mp,prm%nonSchmid_pos(1:3,1:3,i))
|
||||||
tau_slip_neg(i) = merge(math_mul33xx33(Mp,prm%nonSchmid_neg(1:3,1:3,i)), &
|
tau_slip_neg(i) = merge(math_mul33xx33(Mp,prm%nonSchmid_neg(1:3,1:3,i)), &
|
||||||
0.0_pReal, nonSchmidActive)
|
0.0_pReal, nonSchmidActive)
|
||||||
enddo
|
enddo
|
||||||
|
|
||||||
where(dNeq0(tau_slip_pos))
|
where(dNeq0(tau_slip_pos))
|
||||||
gdot_slip_pos = prm%gdot0_slip * merge(0.5_pReal,1.0_pReal, nonSchmidActive) & ! 1/2 if non-Schmid active
|
gdot_slip_pos = prm%gdot0_slip * merge(0.5_pReal,1.0_pReal, nonSchmidActive) & ! 1/2 if non-Schmid active
|
||||||
* sign(abs(tau_slip_pos/stt%xi_slip(:,of))**prm%n_slip, tau_slip_pos)
|
* sign(abs(tau_slip_pos/stt%xi_slip(:,of))**prm%n_slip, tau_slip_pos)
|
||||||
else where
|
else where
|
||||||
gdot_slip_pos = 0.0_pReal
|
gdot_slip_pos = 0.0_pReal
|
||||||
end where
|
end where
|
||||||
|
|
||||||
where(dNeq0(tau_slip_neg))
|
where(dNeq0(tau_slip_neg))
|
||||||
gdot_slip_neg = prm%gdot0_slip * 0.5_pReal & ! only used if non-Schmid active, always 1/2
|
gdot_slip_neg = prm%gdot0_slip * 0.5_pReal & ! only used if non-Schmid active, always 1/2
|
||||||
* sign(abs(tau_slip_neg/stt%xi_slip(:,of))**prm%n_slip, tau_slip_neg)
|
* sign(abs(tau_slip_neg/stt%xi_slip(:,of))**prm%n_slip, tau_slip_neg)
|
||||||
else where
|
else where
|
||||||
gdot_slip_neg = 0.0_pReal
|
gdot_slip_neg = 0.0_pReal
|
||||||
end where
|
end where
|
||||||
|
|
||||||
if (present(dgdot_dtau_slip_pos)) then
|
if (present(dgdot_dtau_slip_pos)) then
|
||||||
where(dNeq0(gdot_slip_pos))
|
where(dNeq0(gdot_slip_pos))
|
||||||
dgdot_dtau_slip_pos = gdot_slip_pos*prm%n_slip/tau_slip_pos
|
dgdot_dtau_slip_pos = gdot_slip_pos*prm%n_slip/tau_slip_pos
|
||||||
|
@ -543,9 +488,9 @@ end subroutine kinetics_slip
|
||||||
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @brief Shear rates on twin systems and their derivatives with respect to resolved stress.
|
!> @brief Calculate shear rates on twin systems and their derivatives with respect to resolved
|
||||||
! twinning is assumed to take place only in untwinned volume.
|
! stress. Twinning is assumed to take place only in untwinned volume.
|
||||||
!> @details Derivates are calculated only optionally.
|
!> @details Derivatives are calculated only optionally.
|
||||||
! 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.
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
@ -557,29 +502,29 @@ pure subroutine kinetics_twin(Mp,instance,of,&
|
||||||
integer, intent(in) :: &
|
integer, intent(in) :: &
|
||||||
instance, &
|
instance, &
|
||||||
of
|
of
|
||||||
|
|
||||||
real(pReal), dimension(param(instance)%totalNtwin), intent(out) :: &
|
real(pReal), dimension(param(instance)%totalNtwin), intent(out) :: &
|
||||||
gdot_twin
|
gdot_twin
|
||||||
real(pReal), dimension(param(instance)%totalNtwin), intent(out), optional :: &
|
real(pReal), dimension(param(instance)%totalNtwin), intent(out), optional :: &
|
||||||
dgdot_dtau_twin
|
dgdot_dtau_twin
|
||||||
|
|
||||||
real(pReal), dimension(param(instance)%totalNtwin) :: &
|
real(pReal), dimension(param(instance)%totalNtwin) :: &
|
||||||
tau_twin
|
tau_twin
|
||||||
integer :: i
|
integer :: i
|
||||||
|
|
||||||
associate(prm => param(instance), stt => state(instance))
|
associate(prm => param(instance), stt => state(instance))
|
||||||
|
|
||||||
do i = 1, prm%totalNtwin
|
do i = 1, prm%totalNtwin
|
||||||
tau_twin(i) = math_mul33xx33(Mp,prm%Schmid_twin(1:3,1:3,i))
|
tau_twin(i) = math_mul33xx33(Mp,prm%Schmid_twin(1:3,1:3,i))
|
||||||
enddo
|
enddo
|
||||||
|
|
||||||
where(tau_twin > 0.0_pReal)
|
where(tau_twin > 0.0_pReal)
|
||||||
gdot_twin = (1.0_pReal-sum(stt%gamma_twin(:,of)/prm%gamma_twin_char)) & ! only twin in untwinned volume fraction
|
gdot_twin = (1.0_pReal-sum(stt%gamma_twin(:,of)/prm%gamma_twin_char)) & ! only twin in untwinned volume fraction
|
||||||
* prm%gdot0_twin*(abs(tau_twin)/stt%xi_twin(:,of))**prm%n_twin
|
* prm%gdot0_twin*(abs(tau_twin)/stt%xi_twin(:,of))**prm%n_twin
|
||||||
else where
|
else where
|
||||||
gdot_twin = 0.0_pReal
|
gdot_twin = 0.0_pReal
|
||||||
end where
|
end where
|
||||||
|
|
||||||
if (present(dgdot_dtau_twin)) then
|
if (present(dgdot_dtau_twin)) then
|
||||||
where(dNeq0(gdot_twin))
|
where(dNeq0(gdot_twin))
|
||||||
dgdot_dtau_twin = gdot_twin*prm%n_twin/tau_twin
|
dgdot_dtau_twin = gdot_twin*prm%n_twin/tau_twin
|
||||||
|
@ -587,7 +532,7 @@ pure subroutine kinetics_twin(Mp,instance,of,&
|
||||||
dgdot_dtau_twin = 0.0_pReal
|
dgdot_dtau_twin = 0.0_pReal
|
||||||
end where
|
end where
|
||||||
endif
|
endif
|
||||||
|
|
||||||
end associate
|
end associate
|
||||||
|
|
||||||
end subroutine kinetics_twin
|
end subroutine kinetics_twin
|
||||||
|
|
|
@ -57,9 +57,7 @@ module crystallite
|
||||||
crystallite_Li0, & !< intermediate velocitiy grad at start of FE inc
|
crystallite_Li0, & !< intermediate velocitiy grad at start of FE inc
|
||||||
crystallite_partionedLi0 !< intermediate velocity grad at start of homog inc
|
crystallite_partionedLi0 !< intermediate velocity grad at start of homog inc
|
||||||
real(pReal), dimension(:,:,:,:,:), allocatable :: &
|
real(pReal), dimension(:,:,:,:,:), allocatable :: &
|
||||||
crystallite_invFp, & !< inverse of current plastic def grad (end of converged time step)
|
|
||||||
crystallite_subFp0,& !< plastic def grad at start of crystallite inc
|
crystallite_subFp0,& !< plastic def grad at start of crystallite inc
|
||||||
crystallite_invFi, & !< inverse of current intermediate def grad (end of converged time step)
|
|
||||||
crystallite_subFi0,& !< intermediate def grad at start of crystallite inc
|
crystallite_subFi0,& !< intermediate def grad at start of crystallite inc
|
||||||
crystallite_subF, & !< def grad to be reached at end of crystallite inc
|
crystallite_subF, & !< def grad to be reached at end of crystallite inc
|
||||||
crystallite_subF0, & !< def grad at start of crystallite inc
|
crystallite_subF0, & !< def grad at start of crystallite inc
|
||||||
|
@ -145,12 +143,10 @@ subroutine crystallite_init
|
||||||
allocate(crystallite_partionedFp0(3,3,cMax,iMax,eMax), source=0.0_pReal)
|
allocate(crystallite_partionedFp0(3,3,cMax,iMax,eMax), source=0.0_pReal)
|
||||||
allocate(crystallite_subFp0(3,3,cMax,iMax,eMax), source=0.0_pReal)
|
allocate(crystallite_subFp0(3,3,cMax,iMax,eMax), source=0.0_pReal)
|
||||||
allocate(crystallite_Fp(3,3,cMax,iMax,eMax), source=0.0_pReal)
|
allocate(crystallite_Fp(3,3,cMax,iMax,eMax), source=0.0_pReal)
|
||||||
allocate(crystallite_invFp(3,3,cMax,iMax,eMax), source=0.0_pReal)
|
|
||||||
allocate(crystallite_Fi0(3,3,cMax,iMax,eMax), source=0.0_pReal)
|
allocate(crystallite_Fi0(3,3,cMax,iMax,eMax), source=0.0_pReal)
|
||||||
allocate(crystallite_partionedFi0(3,3,cMax,iMax,eMax), source=0.0_pReal)
|
allocate(crystallite_partionedFi0(3,3,cMax,iMax,eMax), source=0.0_pReal)
|
||||||
allocate(crystallite_subFi0(3,3,cMax,iMax,eMax), source=0.0_pReal)
|
allocate(crystallite_subFi0(3,3,cMax,iMax,eMax), source=0.0_pReal)
|
||||||
allocate(crystallite_Fi(3,3,cMax,iMax,eMax), source=0.0_pReal)
|
allocate(crystallite_Fi(3,3,cMax,iMax,eMax), source=0.0_pReal)
|
||||||
allocate(crystallite_invFi(3,3,cMax,iMax,eMax), source=0.0_pReal)
|
|
||||||
allocate(crystallite_Fe(3,3,cMax,iMax,eMax), source=0.0_pReal)
|
allocate(crystallite_Fe(3,3,cMax,iMax,eMax), source=0.0_pReal)
|
||||||
allocate(crystallite_Lp0(3,3,cMax,iMax,eMax), source=0.0_pReal)
|
allocate(crystallite_Lp0(3,3,cMax,iMax,eMax), source=0.0_pReal)
|
||||||
allocate(crystallite_partionedLp0(3,3,cMax,iMax,eMax), source=0.0_pReal)
|
allocate(crystallite_partionedLp0(3,3,cMax,iMax,eMax), source=0.0_pReal)
|
||||||
|
@ -408,9 +404,7 @@ function crystallite_stress(dummyArgumentToPreventInternalCompilerErrorWithGCC)
|
||||||
else
|
else
|
||||||
crystallite_subStep(c,i,e) = num%subStepSizeCryst * crystallite_subStep(c,i,e)
|
crystallite_subStep(c,i,e) = num%subStepSizeCryst * crystallite_subStep(c,i,e)
|
||||||
crystallite_Fp (1:3,1:3,c,i,e) = crystallite_subFp0(1:3,1:3,c,i,e)
|
crystallite_Fp (1:3,1:3,c,i,e) = crystallite_subFp0(1:3,1:3,c,i,e)
|
||||||
crystallite_invFp(1:3,1:3,c,i,e) = math_inv33(crystallite_Fp (1:3,1:3,c,i,e))
|
|
||||||
crystallite_Fi (1:3,1:3,c,i,e) = crystallite_subFi0(1:3,1:3,c,i,e)
|
crystallite_Fi (1:3,1:3,c,i,e) = crystallite_subFi0(1:3,1:3,c,i,e)
|
||||||
crystallite_invFi(1:3,1:3,c,i,e) = math_inv33(crystallite_Fi (1:3,1:3,c,i,e))
|
|
||||||
crystallite_S (1:3,1:3,c,i,e) = crystallite_S0 (1:3,1:3,c,i,e)
|
crystallite_S (1:3,1:3,c,i,e) = crystallite_S0 (1:3,1:3,c,i,e)
|
||||||
if (crystallite_subStep(c,i,e) < 1.0_pReal) then ! actual (not initial) cutback
|
if (crystallite_subStep(c,i,e) < 1.0_pReal) then ! actual (not initial) cutback
|
||||||
crystallite_Lp (1:3,1:3,c,i,e) = crystallite_subLp0(1:3,1:3,c,i,e)
|
crystallite_Lp (1:3,1:3,c,i,e) = crystallite_subLp0(1:3,1:3,c,i,e)
|
||||||
|
@ -431,11 +425,11 @@ function crystallite_stress(dummyArgumentToPreventInternalCompilerErrorWithGCC)
|
||||||
! prepare for integration
|
! prepare for integration
|
||||||
if (crystallite_todo(c,i,e)) then
|
if (crystallite_todo(c,i,e)) then
|
||||||
crystallite_subF(1:3,1:3,c,i,e) = crystallite_subF0(1:3,1:3,c,i,e) &
|
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_subStep(c,i,e) *( crystallite_partionedF (1:3,1:3,c,i,e) &
|
||||||
- crystallite_partionedF0(1:3,1:3,c,i,e))
|
-crystallite_partionedF0(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), &
|
crystallite_Fe(1:3,1:3,c,i,e) = matmul(matmul(crystallite_subF(1:3,1:3,c,i,e), &
|
||||||
crystallite_invFp(1:3,1:3,c,i,e)), &
|
math_inv33(crystallite_Fp(1:3,1:3,c,i,e))), &
|
||||||
crystallite_invFi(1:3,1:3,c,i,e))
|
math_inv33(crystallite_Fi(1:3,1:3,c,i,e)))
|
||||||
crystallite_subdt(c,i,e) = crystallite_subStep(c,i,e) * crystallite_dt(c,i,e)
|
crystallite_subdt(c,i,e) = crystallite_subStep(c,i,e) * crystallite_dt(c,i,e)
|
||||||
crystallite_converged(c,i,e) = .false.
|
crystallite_converged(c,i,e) = .false.
|
||||||
endif
|
endif
|
||||||
|
@ -477,7 +471,9 @@ subroutine crystallite_stressTangent
|
||||||
o, &
|
o, &
|
||||||
p
|
p
|
||||||
|
|
||||||
real(pReal), dimension(3,3) :: temp_33_1, devNull,invSubFi0, temp_33_2, temp_33_3, temp_33_4
|
real(pReal), dimension(3,3) :: devNull, &
|
||||||
|
invSubFp0,invSubFi0,invFp,invFi, &
|
||||||
|
temp_33_1, temp_33_2, temp_33_3, temp_33_4
|
||||||
real(pReal), dimension(3,3,3,3) :: dSdFe, &
|
real(pReal), dimension(3,3,3,3) :: dSdFe, &
|
||||||
dSdF, &
|
dSdF, &
|
||||||
dSdFi, &
|
dSdFi, &
|
||||||
|
@ -493,7 +489,8 @@ subroutine crystallite_stressTangent
|
||||||
real(pReal), dimension(9,9):: temp_99
|
real(pReal), dimension(9,9):: temp_99
|
||||||
logical :: error
|
logical :: error
|
||||||
|
|
||||||
!$OMP PARALLEL DO PRIVATE(dSdF,dSdFe,dSdFi,dLpdS,dLpdFi,dFpinvdF,dLidS,dLidFi,dFidS,invSubFi0,o,p, &
|
!$OMP PARALLEL DO PRIVATE(dSdF,dSdFe,dSdFi,dLpdS,dLpdFi,dFpinvdF,dLidS,dLidFi,dFidS,o,p, &
|
||||||
|
!$OMP invSubFp0,invSubFi0,invFp,invFi, &
|
||||||
!$OMP rhs_3333,lhs_3333,temp_99,temp_33_1,temp_33_2,temp_33_3,temp_33_4,temp_3333,error)
|
!$OMP rhs_3333,lhs_3333,temp_99,temp_33_1,temp_33_2,temp_33_3,temp_33_4,temp_3333,error)
|
||||||
elementLooping: do e = FEsolving_execElem(1),FEsolving_execElem(2)
|
elementLooping: do e = FEsolving_execElem(1),FEsolving_execElem(2)
|
||||||
do i = FEsolving_execIP(1),FEsolving_execIP(2)
|
do i = FEsolving_execIP(1),FEsolving_execIP(2)
|
||||||
|
@ -507,16 +504,20 @@ subroutine crystallite_stressTangent
|
||||||
crystallite_Fi(1:3,1:3,c,i,e), &
|
crystallite_Fi(1:3,1:3,c,i,e), &
|
||||||
c,i,e)
|
c,i,e)
|
||||||
|
|
||||||
|
invFp = math_inv33(crystallite_Fp(1:3,1:3,c,i,e))
|
||||||
|
invFi = math_inv33(crystallite_Fi(1:3,1:3,c,i,e))
|
||||||
|
invSubFp0 = math_inv33(crystallite_subFp0(1:3,1:3,c,i,e))
|
||||||
|
invSubFi0 = math_inv33(crystallite_subFi0(1:3,1:3,c,i,e))
|
||||||
|
|
||||||
if (sum(abs(dLidS)) < tol_math_check) then
|
if (sum(abs(dLidS)) < tol_math_check) then
|
||||||
dFidS = 0.0_pReal
|
dFidS = 0.0_pReal
|
||||||
else
|
else
|
||||||
invSubFi0 = math_inv33(crystallite_subFi0(1:3,1:3,c,i,e))
|
|
||||||
lhs_3333 = 0.0_pReal; rhs_3333 = 0.0_pReal
|
lhs_3333 = 0.0_pReal; rhs_3333 = 0.0_pReal
|
||||||
do o=1,3; do p=1,3
|
do o=1,3; do p=1,3
|
||||||
lhs_3333(1:3,1:3,o,p) = lhs_3333(1:3,1:3,o,p) &
|
lhs_3333(1:3,1:3,o,p) = lhs_3333(1:3,1:3,o,p) &
|
||||||
+ crystallite_subdt(c,i,e)*matmul(invSubFi0,dLidFi(1:3,1:3,o,p))
|
+ crystallite_subdt(c,i,e)*matmul(invSubFi0,dLidFi(1:3,1:3,o,p))
|
||||||
lhs_3333(1:3,o,1:3,p) = lhs_3333(1:3,o,1:3,p) &
|
lhs_3333(1:3,o,1:3,p) = lhs_3333(1:3,o,1:3,p) &
|
||||||
+ crystallite_invFi(1:3,1:3,c,i,e)*crystallite_invFi(p,o,c,i,e)
|
+ invFi*invFi(p,o)
|
||||||
rhs_3333(1:3,1:3,o,p) = rhs_3333(1:3,1:3,o,p) &
|
rhs_3333(1:3,1:3,o,p) = rhs_3333(1:3,1:3,o,p) &
|
||||||
- crystallite_subdt(c,i,e)*matmul(invSubFi0,dLidS(1:3,1:3,o,p))
|
- crystallite_subdt(c,i,e)*matmul(invSubFi0,dLidS(1:3,1:3,o,p))
|
||||||
enddo; enddo
|
enddo; enddo
|
||||||
|
@ -538,18 +539,13 @@ subroutine crystallite_stressTangent
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! calculate dSdF
|
! calculate dSdF
|
||||||
temp_33_1 = transpose(matmul(crystallite_invFp(1:3,1:3,c,i,e), &
|
temp_33_1 = transpose(matmul(invFp,invFi))
|
||||||
crystallite_invFi(1:3,1:3,c,i,e)))
|
temp_33_2 = matmul(crystallite_subF(1:3,1:3,c,i,e),invSubFp0)
|
||||||
temp_33_2 = matmul(crystallite_subF(1:3,1:3,c,i,e), &
|
temp_33_3 = matmul(matmul(crystallite_subF(1:3,1:3,c,i,e),invFp), invSubFi0)
|
||||||
math_inv33(crystallite_subFp0(1:3,1:3,c,i,e)))
|
|
||||||
temp_33_3 = matmul(matmul(crystallite_subF(1:3,1:3,c,i,e), &
|
|
||||||
crystallite_invFp (1:3,1:3,c,i,e)), &
|
|
||||||
math_inv33(crystallite_subFi0(1:3,1:3,c,i,e)))
|
|
||||||
|
|
||||||
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)
|
||||||
temp_3333(1:3,1:3,p,o) = matmul(matmul(temp_33_2,dLpdS(1:3,1:3,p,o)), &
|
temp_3333(1:3,1:3,p,o) = matmul(matmul(temp_33_2,dLpdS(1:3,1:3,p,o)), invFi) &
|
||||||
crystallite_invFi(1:3,1:3,c,i,e)) &
|
|
||||||
+ matmul(temp_33_3,dLidS(1:3,1:3,p,o))
|
+ matmul(temp_33_3,dLidS(1:3,1:3,p,o))
|
||||||
enddo; enddo
|
enddo; enddo
|
||||||
lhs_3333 = crystallite_subdt(c,i,e)*math_mul3333xx3333(dSdFe,temp_3333) &
|
lhs_3333 = crystallite_subdt(c,i,e)*math_mul3333xx3333(dSdFe,temp_3333) &
|
||||||
|
@ -569,15 +565,14 @@ subroutine crystallite_stressTangent
|
||||||
temp_3333 = math_mul3333xx3333(dLpdS,dSdF)
|
temp_3333 = math_mul3333xx3333(dLpdS,dSdF)
|
||||||
do o=1,3; do p=1,3
|
do o=1,3; do p=1,3
|
||||||
dFpinvdF(1:3,1:3,p,o) = -crystallite_subdt(c,i,e) &
|
dFpinvdF(1:3,1:3,p,o) = -crystallite_subdt(c,i,e) &
|
||||||
* matmul(math_inv33(crystallite_subFp0(1:3,1:3,c,i,e)), &
|
* matmul(invSubFp0, matmul(temp_3333(1:3,1:3,p,o),invFi))
|
||||||
matmul(temp_3333(1:3,1:3,p,o),crystallite_invFi(1:3,1:3,c,i,e)))
|
|
||||||
enddo; enddo
|
enddo; enddo
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! assemble dPdF
|
! assemble dPdF
|
||||||
temp_33_1 = matmul(crystallite_S(1:3,1:3,c,i,e),transpose(crystallite_invFp(1:3,1:3,c,i,e)))
|
temp_33_1 = matmul(crystallite_S(1:3,1:3,c,i,e),transpose(invFp))
|
||||||
temp_33_2 = matmul(crystallite_invFp(1:3,1:3,c,i,e),temp_33_1)
|
temp_33_2 = matmul(invFp,temp_33_1)
|
||||||
temp_33_3 = matmul(crystallite_subF(1:3,1:3,c,i,e),crystallite_invFp(1:3,1:3,c,i,e))
|
temp_33_3 = matmul(crystallite_subF(1:3,1:3,c,i,e),invFp)
|
||||||
temp_33_4 = matmul(temp_33_3,crystallite_S(1:3,1:3,c,i,e))
|
temp_33_4 = matmul(temp_33_3,crystallite_S(1:3,1:3,c,i,e))
|
||||||
|
|
||||||
crystallite_dPdF(1:3,1:3,1:3,1:3,c,i,e) = 0.0_pReal
|
crystallite_dPdF(1:3,1:3,1:3,1:3,c,i,e) = 0.0_pReal
|
||||||
|
@ -589,7 +584,7 @@ subroutine crystallite_stressTangent
|
||||||
+ matmul(matmul(crystallite_subF(1:3,1:3,c,i,e), &
|
+ matmul(matmul(crystallite_subF(1:3,1:3,c,i,e), &
|
||||||
dFpinvdF(1:3,1:3,p,o)),temp_33_1) &
|
dFpinvdF(1:3,1:3,p,o)),temp_33_1) &
|
||||||
+ matmul(matmul(temp_33_3,dSdF(1:3,1:3,p,o)), &
|
+ matmul(matmul(temp_33_3,dSdF(1:3,1:3,p,o)), &
|
||||||
transpose(crystallite_invFp(1:3,1:3,c,i,e))) &
|
transpose(invFp)) &
|
||||||
+ matmul(temp_33_4,transpose(dFpinvdF(1:3,1:3,p,o)))
|
+ matmul(temp_33_4,transpose(dFpinvdF(1:3,1:3,p,o)))
|
||||||
enddo; enddo
|
enddo; enddo
|
||||||
|
|
||||||
|
@ -734,7 +729,7 @@ subroutine crystallite_results
|
||||||
real(pReal), allocatable, dimension(:,:,:) :: select_tensors
|
real(pReal), allocatable, dimension(:,:,:) :: select_tensors
|
||||||
integer :: e,i,c,j
|
integer :: e,i,c,j
|
||||||
|
|
||||||
allocate(select_tensors(3,3,count(material_phaseAt==instance)*homogenization_maxNgrains*discretization_nIP))
|
allocate(select_tensors(3,3,count(material_phaseAt==instance)*discretization_nIP))
|
||||||
|
|
||||||
j=0
|
j=0
|
||||||
do e = 1, size(material_phaseAt,2)
|
do e = 1, size(material_phaseAt,2)
|
||||||
|
@ -793,28 +788,28 @@ logical function integrateStress(ipc,ip,el,timeFraction)
|
||||||
|
|
||||||
real(pReal), dimension(3,3):: F, & ! deformation gradient at end of timestep
|
real(pReal), dimension(3,3):: F, & ! deformation gradient at end of timestep
|
||||||
Fp_new, & ! plastic deformation gradient at end of timestep
|
Fp_new, & ! plastic deformation gradient at end of timestep
|
||||||
Fe_new, & ! elastic deformation gradient at end of timestep
|
|
||||||
invFp_new, & ! inverse of Fp_new
|
invFp_new, & ! inverse of Fp_new
|
||||||
Fi_new, & ! gradient of intermediate deformation stages
|
|
||||||
invFi_new, &
|
|
||||||
invFp_current, & ! inverse of Fp_current
|
invFp_current, & ! inverse of Fp_current
|
||||||
invFi_current, & ! inverse of Fp_current
|
|
||||||
Lpguess, & ! current guess for plastic velocity gradient
|
Lpguess, & ! current guess for plastic velocity gradient
|
||||||
Lpguess_old, & ! known last good guess for plastic velocity gradient
|
Lpguess_old, & ! known last good guess for plastic velocity gradient
|
||||||
Lp_constitutive, & ! plastic velocity gradient resulting from constitutive law
|
Lp_constitutive, & ! plastic velocity gradient resulting from constitutive law
|
||||||
residuumLp, & ! current residuum of plastic velocity gradient
|
residuumLp, & ! current residuum of plastic velocity gradient
|
||||||
residuumLp_old, & ! last residuum of plastic velocity gradient
|
residuumLp_old, & ! last residuum of plastic velocity gradient
|
||||||
deltaLp, & ! direction of next guess
|
deltaLp, & ! direction of next guess
|
||||||
|
Fi_new, & ! gradient of intermediate deformation stages
|
||||||
|
invFi_new, &
|
||||||
|
invFi_current, & ! inverse of Fi_current
|
||||||
Liguess, & ! current guess for intermediate velocity gradient
|
Liguess, & ! current guess for intermediate velocity gradient
|
||||||
Liguess_old, & ! known last good guess for intermediate velocity gradient
|
Liguess_old, & ! known last good guess for intermediate velocity gradient
|
||||||
Li_constitutive, & ! intermediate velocity gradient resulting from constitutive law
|
Li_constitutive, & ! intermediate velocity gradient resulting from constitutive law
|
||||||
residuumLi, & ! current residuum of intermediate velocity gradient
|
residuumLi, & ! current residuum of intermediate velocity gradient
|
||||||
residuumLi_old, & ! last residuum of intermediate velocity gradient
|
residuumLi_old, & ! last residuum of intermediate velocity gradient
|
||||||
deltaLi, & ! direction of next guess
|
deltaLi, & ! direction of next guess
|
||||||
|
Fe, & ! elastic deformation gradient
|
||||||
|
Fe_new, &
|
||||||
S, & ! 2nd Piola-Kirchhoff Stress in plastic (lattice) configuration
|
S, & ! 2nd Piola-Kirchhoff Stress in plastic (lattice) configuration
|
||||||
A, &
|
A, &
|
||||||
B, &
|
B, &
|
||||||
Fe, & ! elastic deformation gradient
|
|
||||||
temp_33
|
temp_33
|
||||||
real(pReal), dimension(9) :: temp_9 ! needed for matrix inversion by LAPACK
|
real(pReal), dimension(9) :: temp_9 ! needed for matrix inversion by LAPACK
|
||||||
integer, dimension(9) :: devNull_9 ! needed for matrix inversion by LAPACK
|
integer, dimension(9) :: devNull_9 ! needed for matrix inversion by LAPACK
|
||||||
|
@ -993,16 +988,13 @@ logical function integrateStress(ipc,ip,el,timeFraction)
|
||||||
Fe_new = matmul(matmul(F,invFp_new),invFi_new)
|
Fe_new = matmul(matmul(F,invFp_new),invFi_new)
|
||||||
|
|
||||||
integrateStress = .true.
|
integrateStress = .true.
|
||||||
crystallite_P (1:3,1:3,ipc,ip,el) = matmul(matmul(F,invFp_new),matmul(S,transpose(invFp_new))) ! ToDo: We propably do not need to store P!
|
crystallite_P (1:3,1:3,ipc,ip,el) = matmul(matmul(F,invFp_new),matmul(S,transpose(invFp_new)))
|
||||||
crystallite_S (1:3,1:3,ipc,ip,el) = S
|
crystallite_S (1:3,1:3,ipc,ip,el) = S
|
||||||
crystallite_Lp (1:3,1:3,ipc,ip,el) = Lpguess
|
crystallite_Lp (1:3,1:3,ipc,ip,el) = Lpguess
|
||||||
crystallite_Li (1:3,1:3,ipc,ip,el) = Liguess
|
crystallite_Li (1:3,1:3,ipc,ip,el) = Liguess
|
||||||
crystallite_Fp (1:3,1:3,ipc,ip,el) = Fp_new
|
crystallite_Fp (1:3,1:3,ipc,ip,el) = Fp_new
|
||||||
crystallite_Fi (1:3,1:3,ipc,ip,el) = Fi_new
|
crystallite_Fi (1:3,1:3,ipc,ip,el) = Fi_new
|
||||||
crystallite_Fe (1:3,1:3,ipc,ip,el) = Fe_new
|
crystallite_Fe (1:3,1:3,ipc,ip,el) = Fe_new
|
||||||
crystallite_invFp(1:3,1:3,ipc,ip,el) = invFp_new
|
|
||||||
crystallite_invFi(1:3,1:3,ipc,ip,el) = invFi_new
|
|
||||||
|
|
||||||
|
|
||||||
end function integrateStress
|
end function integrateStress
|
||||||
|
|
||||||
|
|
|
@ -21,10 +21,10 @@ module grid_mech_FEM
|
||||||
use discretization
|
use discretization
|
||||||
use mesh_grid
|
use mesh_grid
|
||||||
use debug
|
use debug
|
||||||
|
|
||||||
implicit none
|
implicit none
|
||||||
private
|
private
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! derived types
|
! derived types
|
||||||
type(tSolutionParams), private :: params
|
type(tSolutionParams), private :: params
|
||||||
|
@ -52,20 +52,20 @@ module grid_mech_FEM
|
||||||
F_aim_lastIter = math_I3, &
|
F_aim_lastIter = math_I3, &
|
||||||
F_aim_lastInc = math_I3, & !< previous average deformation gradient
|
F_aim_lastInc = math_I3, & !< previous average deformation gradient
|
||||||
P_av = 0.0_pReal !< average 1st Piola--Kirchhoff stress
|
P_av = 0.0_pReal !< average 1st Piola--Kirchhoff stress
|
||||||
|
|
||||||
character(len=pStringLen), private :: incInfo !< time and increment information
|
character(len=pStringLen), private :: incInfo !< time and increment information
|
||||||
|
|
||||||
real(pReal), private, dimension(3,3,3,3) :: &
|
real(pReal), private, dimension(3,3,3,3) :: &
|
||||||
C_volAvg = 0.0_pReal, & !< current volume average stiffness
|
C_volAvg = 0.0_pReal, & !< current volume average stiffness
|
||||||
C_volAvgLastInc = 0.0_pReal, & !< previous volume average stiffness
|
C_volAvgLastInc = 0.0_pReal, & !< previous volume average stiffness
|
||||||
S = 0.0_pReal !< current compliance (filled up with zeros)
|
S = 0.0_pReal !< current compliance (filled up with zeros)
|
||||||
|
|
||||||
real(pReal), private :: &
|
real(pReal), private :: &
|
||||||
err_BC !< deviation from stress BC
|
err_BC !< deviation from stress BC
|
||||||
|
|
||||||
integer, private :: &
|
integer, private :: &
|
||||||
totalIter = 0 !< total iteration in current increment
|
totalIter = 0 !< total iteration in current increment
|
||||||
|
|
||||||
public :: &
|
public :: &
|
||||||
grid_mech_FEM_init, &
|
grid_mech_FEM_init, &
|
||||||
grid_mech_FEM_solution, &
|
grid_mech_FEM_solution, &
|
||||||
|
@ -79,7 +79,7 @@ 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_mech_FEM_init
|
||||||
|
|
||||||
real(pReal) :: HGCoeff = 0.0e-2_pReal
|
real(pReal) :: HGCoeff = 0.0e-2_pReal
|
||||||
PetscInt, dimension(0:worldsize-1) :: localK
|
PetscInt, dimension(0:worldsize-1) :: localK
|
||||||
real(pReal), dimension(3,3) :: &
|
real(pReal), dimension(3,3) :: &
|
||||||
|
@ -99,9 +99,9 @@ subroutine grid_mech_FEM_init
|
||||||
real(pReal), dimension(3,3,3,3) :: devNull
|
real(pReal), dimension(3,3,3,3) :: devNull
|
||||||
PetscScalar, pointer, dimension(:,:,:,:) :: &
|
PetscScalar, pointer, dimension(:,:,:,:) :: &
|
||||||
u_current,u_lastInc
|
u_current,u_lastInc
|
||||||
|
|
||||||
write(6,'(/,a)') ' <<<+- grid_mech_FEM init -+>>>'; flush(6)
|
write(6,'(/,a)') ' <<<+- grid_mech_FEM init -+>>>'; flush(6)
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! 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_snes_type newtonls -mech_ksp_type fgmres &
|
||||||
|
@ -115,11 +115,11 @@ subroutine grid_mech_FEM_init
|
||||||
allocate(F (3,3,grid(1),grid(2),grid3),source = 0.0_pReal)
|
allocate(F (3,3,grid(1),grid(2),grid3),source = 0.0_pReal)
|
||||||
allocate(P_current (3,3,grid(1),grid(2),grid3),source = 0.0_pReal)
|
allocate(P_current (3,3,grid(1),grid(2),grid3),source = 0.0_pReal)
|
||||||
allocate(F_lastInc (3,3,grid(1),grid(2),grid3),source = 0.0_pReal)
|
allocate(F_lastInc (3,3,grid(1),grid(2),grid3),source = 0.0_pReal)
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! 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,mech_snes,ierr); CHKERRQ(ierr)
|
||||||
call SNESSetOptionsPrefix(mech_snes,'mech_',ierr);CHKERRQ(ierr)
|
call SNESSetOptionsPrefix(mech_snes,'mech_',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)
|
||||||
|
@ -141,12 +141,12 @@ subroutine grid_mech_FEM_init
|
||||||
call DMCreateGlobalVector(mech_grid,solution_lastInc,ierr); CHKERRQ(ierr)
|
call DMCreateGlobalVector(mech_grid,solution_lastInc,ierr); CHKERRQ(ierr)
|
||||||
call DMCreateGlobalVector(mech_grid,solution_rate ,ierr); CHKERRQ(ierr)
|
call DMCreateGlobalVector(mech_grid,solution_rate ,ierr); CHKERRQ(ierr)
|
||||||
call DMSNESSetFunctionLocal(mech_grid,formResidual,PETSC_NULL_SNES,ierr)
|
call DMSNESSetFunctionLocal(mech_grid,formResidual,PETSC_NULL_SNES,ierr)
|
||||||
CHKERRQ(ierr)
|
CHKERRQ(ierr)
|
||||||
call DMSNESSetJacobianLocal(mech_grid,formJacobian,PETSC_NULL_SNES,ierr)
|
call DMSNESSetJacobianLocal(mech_grid,formJacobian,PETSC_NULL_SNES,ierr)
|
||||||
CHKERRQ(ierr)
|
CHKERRQ(ierr)
|
||||||
call SNESSetConvergenceTest(mech_snes,converged,PETSC_NULL_SNES,PETSC_NULL_FUNCTION,ierr) ! specify custom convergence check function "_converged"
|
call SNESSetConvergenceTest(mech_snes,converged,PETSC_NULL_SNES,PETSC_NULL_FUNCTION,ierr) ! specify custom convergence check function "_converged"
|
||||||
CHKERRQ(ierr)
|
CHKERRQ(ierr)
|
||||||
call SNESSetMaxLinearSolveFailures(mech_snes, huge(1), ierr); CHKERRQ(ierr) ! ignore linear solve failures
|
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
|
call SNESSetFromOptions(mech_snes,ierr); CHKERRQ(ierr) ! pull it all together with additional cli arguments
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
@ -156,15 +156,15 @@ subroutine grid_mech_FEM_init
|
||||||
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(mech_grid,solution_current,u_current,ierr); CHKERRQ(ierr)
|
||||||
call DMDAVecGetArrayF90(mech_grid,solution_lastInc,u_lastInc,ierr); CHKERRQ(ierr)
|
call DMDAVecGetArrayF90(mech_grid,solution_lastInc,u_lastInc,ierr); CHKERRQ(ierr)
|
||||||
|
|
||||||
call DMDAGetCorners(mech_grid,xstart,ystart,zstart,xend,yend,zend,ierr) ! local grid extent
|
call DMDAGetCorners(mech_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
|
||||||
zend = zstart+zend-1
|
zend = zstart+zend-1
|
||||||
delta = geomSize/real(grid,pReal) ! grid spacing
|
delta = geomSize/real(grid,pReal) ! grid spacing
|
||||||
detJ = product(delta) ! cell volume
|
detJ = product(delta) ! cell volume
|
||||||
|
|
||||||
BMat = reshape(real([-1.0_pReal/delta(1),-1.0_pReal/delta(2),-1.0_pReal/delta(3), &
|
BMat = reshape(real([-1.0_pReal/delta(1),-1.0_pReal/delta(2),-1.0_pReal/delta(3), &
|
||||||
1.0_pReal/delta(1),-1.0_pReal/delta(2),-1.0_pReal/delta(3), &
|
1.0_pReal/delta(1),-1.0_pReal/delta(2),-1.0_pReal/delta(3), &
|
||||||
-1.0_pReal/delta(1), 1.0_pReal/delta(2),-1.0_pReal/delta(3), &
|
-1.0_pReal/delta(1), 1.0_pReal/delta(2),-1.0_pReal/delta(3), &
|
||||||
|
@ -173,7 +173,7 @@ subroutine grid_mech_FEM_init
|
||||||
1.0_pReal/delta(1),-1.0_pReal/delta(2), 1.0_pReal/delta(3), &
|
1.0_pReal/delta(1),-1.0_pReal/delta(2), 1.0_pReal/delta(3), &
|
||||||
-1.0_pReal/delta(1), 1.0_pReal/delta(2), 1.0_pReal/delta(3), &
|
-1.0_pReal/delta(1), 1.0_pReal/delta(2), 1.0_pReal/delta(3), &
|
||||||
1.0_pReal/delta(1), 1.0_pReal/delta(2), 1.0_pReal/delta(3)],pReal), [3,8])/4.0_pReal ! shape function derivative matrix
|
1.0_pReal/delta(1), 1.0_pReal/delta(2), 1.0_pReal/delta(3)],pReal), [3,8])/4.0_pReal ! shape function derivative matrix
|
||||||
|
|
||||||
HGMat = matmul(transpose(HGcomp),HGcomp) &
|
HGMat = matmul(transpose(HGcomp),HGcomp) &
|
||||||
* HGCoeff*(delta(1)*delta(2) + delta(2)*delta(3) + delta(3)*delta(1))/16.0_pReal ! hourglass stabilization matrix
|
* HGCoeff*(delta(1)*delta(2) + delta(2)*delta(3) + delta(3)*delta(1))/16.0_pReal ! hourglass stabilization matrix
|
||||||
|
|
||||||
|
@ -181,11 +181,11 @@ subroutine grid_mech_FEM_init
|
||||||
! init fields
|
! init fields
|
||||||
restartRead: if (interface_restartInc > 0) then
|
restartRead: if (interface_restartInc > 0) then
|
||||||
write(6,'(/,a,i0,a)') ' reading restart data of increment ', interface_restartInc, ' from file'
|
write(6,'(/,a,i0,a)') ' reading restart data of increment ', interface_restartInc, ' from file'
|
||||||
|
|
||||||
write(fileName,'(a,a,i0,a)') trim(getSolverJobName()),'_',worldrank,'.hdf5'
|
write(fileName,'(a,a,i0,a)') trim(getSolverJobName()),'_',worldrank,'.hdf5'
|
||||||
fileHandle = HDF5_openFile(fileName)
|
fileHandle = HDF5_openFile(fileName)
|
||||||
groupHandle = HDF5_openGroup(fileHandle,'solver')
|
groupHandle = HDF5_openGroup(fileHandle,'solver')
|
||||||
|
|
||||||
call HDF5_read(groupHandle,F_aim, 'F_aim')
|
call HDF5_read(groupHandle,F_aim, 'F_aim')
|
||||||
call HDF5_read(groupHandle,F_aim_lastInc,'F_aim_lastInc')
|
call HDF5_read(groupHandle,F_aim_lastInc,'F_aim_lastInc')
|
||||||
call HDF5_read(groupHandle,F_aimDot, 'F_aimDot')
|
call HDF5_read(groupHandle,F_aimDot, 'F_aimDot')
|
||||||
|
@ -193,7 +193,7 @@ subroutine grid_mech_FEM_init
|
||||||
call HDF5_read(groupHandle,F_lastInc, 'F_lastInc')
|
call HDF5_read(groupHandle,F_lastInc, 'F_lastInc')
|
||||||
call HDF5_read(groupHandle,u_current, 'u')
|
call HDF5_read(groupHandle,u_current, 'u')
|
||||||
call HDF5_read(groupHandle,u_lastInc, 'u_lastInc')
|
call HDF5_read(groupHandle,u_lastInc, 'u_lastInc')
|
||||||
|
|
||||||
elseif (interface_restartInc == 0) then restartRead
|
elseif (interface_restartInc == 0) then restartRead
|
||||||
F_lastInc = spread(spread(spread(math_I3,3,grid(1)),4,grid(2)),5,grid3) ! initialize to identity
|
F_lastInc = spread(spread(spread(math_I3,3,grid(1)),4,grid(2)),5,grid3) ! initialize to identity
|
||||||
F = spread(spread(spread(math_I3,3,grid(1)),4,grid(2)),5,grid3)
|
F = spread(spread(spread(math_I3,3,grid(1)),4,grid(2)),5,grid3)
|
||||||
|
@ -207,12 +207,12 @@ subroutine grid_mech_FEM_init
|
||||||
CHKERRQ(ierr)
|
CHKERRQ(ierr)
|
||||||
call DMDAVecRestoreArrayF90(mech_grid,solution_lastInc,u_lastInc,ierr)
|
call DMDAVecRestoreArrayF90(mech_grid,solution_lastInc,u_lastInc,ierr)
|
||||||
CHKERRQ(ierr)
|
CHKERRQ(ierr)
|
||||||
|
|
||||||
restartRead2: if (interface_restartInc > 0) then
|
restartRead2: if (interface_restartInc > 0) then
|
||||||
write(6,'(/,a,i0,a)') ' reading more restart data of increment ', interface_restartInc, ' from file'
|
write(6,'(/,a,i0,a)') ' reading more restart data of increment ', interface_restartInc, ' from file'
|
||||||
call HDF5_read(groupHandle,C_volAvg, 'C_volAvg')
|
call HDF5_read(groupHandle,C_volAvg, 'C_volAvg')
|
||||||
call HDF5_read(groupHandle,C_volAvgLastInc,'C_volAvgLastInc')
|
call HDF5_read(groupHandle,C_volAvgLastInc,'C_volAvgLastInc')
|
||||||
|
|
||||||
call HDF5_closeGroup(groupHandle)
|
call HDF5_closeGroup(groupHandle)
|
||||||
call HDF5_closeFile(fileHandle)
|
call HDF5_closeFile(fileHandle)
|
||||||
|
|
||||||
|
@ -243,14 +243,14 @@ function grid_mech_FEM_solution(incInfoIn,timeinc,timeinc_old,stress_BC,rotation
|
||||||
! PETSc Data
|
! PETSc Data
|
||||||
PetscErrorCode :: ierr
|
PetscErrorCode :: ierr
|
||||||
SNESConvergedReason :: reason
|
SNESConvergedReason :: reason
|
||||||
|
|
||||||
incInfo = incInfoIn
|
incInfo = incInfoIn
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! update stiffness (and gamma operator)
|
! update stiffness (and gamma operator)
|
||||||
S = utilities_maskedCompliance(rotation_BC,stress_BC%maskLogical,C_volAvg)
|
S = utilities_maskedCompliance(rotation_BC,stress_BC%maskLogical,C_volAvg)
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! set module wide available data
|
! set module wide available data
|
||||||
params%stress_mask = stress_BC%maskFloat
|
params%stress_mask = stress_BC%maskFloat
|
||||||
params%stress_BC = stress_BC%values
|
params%stress_BC = stress_BC%values
|
||||||
params%rotation_BC = rotation_BC
|
params%rotation_BC = rotation_BC
|
||||||
|
@ -258,13 +258,13 @@ function grid_mech_FEM_solution(incInfoIn,timeinc,timeinc_old,stress_BC,rotation
|
||||||
params%timeincOld = timeinc_old
|
params%timeincOld = timeinc_old
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! solve BVP
|
! solve BVP
|
||||||
call SNESsolve(mech_snes,PETSC_NULL_VEC,solution_current,ierr);CHKERRQ(ierr)
|
call SNESsolve(mech_snes,PETSC_NULL_VEC,solution_current,ierr);CHKERRQ(ierr)
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! check convergence
|
! check convergence
|
||||||
call SNESGetConvergedReason(mech_snes,reason,ierr);CHKERRQ(ierr)
|
call SNESGetConvergedReason(mech_snes,reason,ierr);CHKERRQ(ierr)
|
||||||
|
|
||||||
solution%converged = reason > 0
|
solution%converged = reason > 0
|
||||||
solution%iterationsNeeded = totalIter
|
solution%iterationsNeeded = totalIter
|
||||||
solution%termIll = terminallyIll
|
solution%termIll = terminallyIll
|
||||||
|
@ -296,15 +296,15 @@ subroutine grid_mech_FEM_forward(cutBack,guess,timeinc,timeinc_old,loadCaseTime,
|
||||||
PetscErrorCode :: ierr
|
PetscErrorCode :: ierr
|
||||||
PetscScalar, pointer, dimension(:,:,:,:) :: &
|
PetscScalar, pointer, dimension(:,:,:,:) :: &
|
||||||
u_current,u_lastInc
|
u_current,u_lastInc
|
||||||
|
|
||||||
call DMDAVecGetArrayF90(mech_grid,solution_current,u_current,ierr); CHKERRQ(ierr)
|
call DMDAVecGetArrayF90(mech_grid,solution_current,u_current,ierr); CHKERRQ(ierr)
|
||||||
call DMDAVecGetArrayF90(mech_grid,solution_lastInc,u_lastInc,ierr); CHKERRQ(ierr)
|
call DMDAVecGetArrayF90(mech_grid,solution_lastInc,u_lastInc,ierr); CHKERRQ(ierr)
|
||||||
|
|
||||||
if (cutBack) then
|
if (cutBack) then
|
||||||
C_volAvg = C_volAvgLastInc
|
C_volAvg = C_volAvgLastInc
|
||||||
else
|
else
|
||||||
C_volAvgLastInc = C_volAvg
|
C_volAvgLastInc = C_volAvg
|
||||||
|
|
||||||
F_aimDot = merge(stress_BC%maskFloat*(F_aim-F_aim_lastInc)/timeinc_old, 0.0_pReal, guess)
|
F_aimDot = merge(stress_BC%maskFloat*(F_aim-F_aim_lastInc)/timeinc_old, 0.0_pReal, guess)
|
||||||
F_aim_lastInc = F_aim
|
F_aim_lastInc = F_aim
|
||||||
|
|
||||||
|
@ -329,10 +329,10 @@ subroutine grid_mech_FEM_forward(cutBack,guess,timeinc,timeinc_old,loadCaseTime,
|
||||||
call VecSet(solution_rate,0.0_pReal,ierr); CHKERRQ(ierr)
|
call VecSet(solution_rate,0.0_pReal,ierr); CHKERRQ(ierr)
|
||||||
endif
|
endif
|
||||||
call VecCopy(solution_current,solution_lastInc,ierr); CHKERRQ(ierr)
|
call VecCopy(solution_current,solution_lastInc,ierr); CHKERRQ(ierr)
|
||||||
|
|
||||||
F_lastInc = F
|
F_lastInc = F
|
||||||
|
|
||||||
materialpoint_F0 = reshape(F, [3,3,1,product(grid(1:2))*grid3])
|
materialpoint_F0 = reshape(F, [3,3,1,product(grid(1:2))*grid3])
|
||||||
endif
|
endif
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
@ -365,12 +365,12 @@ subroutine grid_mech_FEM_restartWrite
|
||||||
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(mech_grid,solution_current,u_current,ierr); CHKERRQ(ierr)
|
||||||
call DMDAVecGetArrayF90(mech_grid,solution_lastInc,u_lastInc,ierr); CHKERRQ(ierr)
|
call DMDAVecGetArrayF90(mech_grid,solution_lastInc,u_lastInc,ierr); CHKERRQ(ierr)
|
||||||
|
|
||||||
write(6,'(a)') ' writing solver data required for restart to file'; flush(6)
|
write(6,'(a)') ' writing solver data required for restart to file'; flush(6)
|
||||||
|
|
||||||
write(fileName,'(a,a,i0,a)') trim(getSolverJobName()),'_',worldrank,'.hdf5'
|
write(fileName,'(a,a,i0,a)') trim(getSolverJobName()),'_',worldrank,'.hdf5'
|
||||||
fileHandle = HDF5_openFile(fileName,'w')
|
fileHandle = HDF5_openFile(fileName,'w')
|
||||||
groupHandle = HDF5_addGroup(fileHandle,'solver')
|
groupHandle = HDF5_addGroup(fileHandle,'solver')
|
||||||
|
@ -388,7 +388,7 @@ 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(mech_grid,solution_current,u_current,ierr);CHKERRQ(ierr)
|
||||||
call DMDAVecRestoreArrayF90(mech_grid,solution_lastInc,u_lastInc,ierr);CHKERRQ(ierr)
|
call DMDAVecRestoreArrayF90(mech_grid,solution_lastInc,u_lastInc,ierr);CHKERRQ(ierr)
|
||||||
|
|
||||||
|
@ -405,7 +405,7 @@ subroutine converged(snes_local,PETScIter,devNull1,devNull2,fnorm,reason,dummy,i
|
||||||
PetscReal, intent(in) :: &
|
PetscReal, intent(in) :: &
|
||||||
devNull1, &
|
devNull1, &
|
||||||
devNull2, &
|
devNull2, &
|
||||||
fnorm
|
fnorm
|
||||||
SNESConvergedReason :: reason
|
SNESConvergedReason :: reason
|
||||||
PetscObject :: dummy
|
PetscObject :: dummy
|
||||||
PetscErrorCode :: ierr
|
PetscErrorCode :: ierr
|
||||||
|
@ -421,7 +421,7 @@ subroutine converged(snes_local,PETScIter,devNull1,devNull2,fnorm,reason,dummy,i
|
||||||
if ((totalIter >= itmin .and. &
|
if ((totalIter >= itmin .and. &
|
||||||
all([ err_div/divTol, &
|
all([ err_div/divTol, &
|
||||||
err_BC /BCTol ] < 1.0_pReal)) &
|
err_BC /BCTol ] < 1.0_pReal)) &
|
||||||
.or. terminallyIll) then
|
.or. terminallyIll) then
|
||||||
reason = 1
|
reason = 1
|
||||||
elseif (totalIter >= itmax) then
|
elseif (totalIter >= itmax) then
|
||||||
reason = -1
|
reason = -1
|
||||||
|
@ -435,10 +435,10 @@ subroutine converged(snes_local,PETScIter,devNull1,devNull2,fnorm,reason,dummy,i
|
||||||
write(6,'(1/,a,f12.2,a,es8.2,a,es9.2,a)') ' error divergence = ', &
|
write(6,'(1/,a,f12.2,a,es8.2,a,es9.2,a)') ' error divergence = ', &
|
||||||
err_div/divTol, ' (',err_div,' / m, tol = ',divTol,')'
|
err_div/divTol, ' (',err_div,' / m, tol = ',divTol,')'
|
||||||
write(6,'(a,f12.2,a,es8.2,a,es9.2,a)') ' error stress BC = ', &
|
write(6,'(a,f12.2,a,es8.2,a,es9.2,a)') ' error stress BC = ', &
|
||||||
err_BC/BCTol, ' (',err_BC, ' Pa, tol = ',BCTol,')'
|
err_BC/BCTol, ' (',err_BC, ' Pa, tol = ',BCTol,')'
|
||||||
write(6,'(/,a)') ' ==========================================================================='
|
write(6,'(/,a)') ' ==========================================================================='
|
||||||
flush(6)
|
flush(6)
|
||||||
|
|
||||||
end subroutine converged
|
end subroutine converged
|
||||||
|
|
||||||
|
|
||||||
|
@ -475,7 +475,7 @@ subroutine formResidual(da_local,x_local, &
|
||||||
write(6,'(1x,a,3(a,i0))') trim(incInfo), ' @ Iteration ', itmin, '≤',totalIter+1, '≤', itmax
|
write(6,'(1x,a,3(a,i0))') trim(incInfo), ' @ Iteration ', itmin, '≤',totalIter+1, '≤', itmax
|
||||||
if (iand(debug_level(debug_spectral),debug_spectralRotation) /= 0) &
|
if (iand(debug_level(debug_spectral),debug_spectralRotation) /= 0) &
|
||||||
write(6,'(/,a,/,3(3(f12.7,1x)/))',advance='no') &
|
write(6,'(/,a,/,3(3(f12.7,1x)/))',advance='no') &
|
||||||
' deformation gradient aim (lab) =', transpose(params%rotation_BC%rotTensor2(F_aim,active=.true.))
|
' deformation gradient aim (lab) =', transpose(params%rotation_BC%rotate(F_aim,active=.true.))
|
||||||
write(6,'(/,a,/,3(3(f12.7,1x)/))',advance='no') &
|
write(6,'(/,a,/,3(3(f12.7,1x)/))',advance='no') &
|
||||||
' deformation gradient aim =', transpose(F_aim)
|
' deformation gradient aim =', transpose(F_aim)
|
||||||
flush(6)
|
flush(6)
|
||||||
|
@ -491,7 +491,7 @@ subroutine formResidual(da_local,x_local, &
|
||||||
x_elem(ctr,1:3) = x_scal(0:2,i+ii,j+jj,k+kk)
|
x_elem(ctr,1:3) = x_scal(0:2,i+ii,j+jj,k+kk)
|
||||||
enddo; enddo; enddo
|
enddo; enddo; enddo
|
||||||
ii = i-xstart+1; jj = j-ystart+1; kk = k-zstart+1
|
ii = i-xstart+1; jj = j-ystart+1; kk = k-zstart+1
|
||||||
F(1:3,1:3,ii,jj,kk) = params%rotation_BC%rotTensor2(F_aim,active=.true.) + transpose(matmul(BMat,x_elem))
|
F(1:3,1:3,ii,jj,kk) = params%rotation_BC%rotate(F_aim,active=.true.) + transpose(matmul(BMat,x_elem))
|
||||||
enddo; enddo; enddo
|
enddo; enddo; enddo
|
||||||
call DMDAVecRestoreArrayF90(da_local,x_local,x_scal,ierr);CHKERRQ(ierr)
|
call DMDAVecRestoreArrayF90(da_local,x_local,x_scal,ierr);CHKERRQ(ierr)
|
||||||
|
|
||||||
|
@ -501,7 +501,7 @@ subroutine formResidual(da_local,x_local, &
|
||||||
P_av,C_volAvg,devNull, &
|
P_av,C_volAvg,devNull, &
|
||||||
F,params%timeinc,params%rotation_BC)
|
F,params%timeinc,params%rotation_BC)
|
||||||
call MPI_Allreduce(MPI_IN_PLACE,terminallyIll,1,MPI_LOGICAL,MPI_LOR,PETSC_COMM_WORLD,ierr)
|
call MPI_Allreduce(MPI_IN_PLACE,terminallyIll,1,MPI_LOGICAL,MPI_LOR,PETSC_COMM_WORLD,ierr)
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! stress BC handling
|
! stress BC handling
|
||||||
F_aim_lastIter = F_aim
|
F_aim_lastIter = F_aim
|
||||||
|
@ -535,24 +535,24 @@ subroutine formResidual(da_local,x_local, &
|
||||||
enddo; enddo; enddo
|
enddo; enddo; enddo
|
||||||
call DMDAVecRestoreArrayF90(da_local,x_local,x_scal,ierr);CHKERRQ(ierr)
|
call DMDAVecRestoreArrayF90(da_local,x_local,x_scal,ierr);CHKERRQ(ierr)
|
||||||
call DMDAVecRestoreArrayF90(da_local,f_local,f_scal,ierr);CHKERRQ(ierr)
|
call DMDAVecRestoreArrayF90(da_local,f_local,f_scal,ierr);CHKERRQ(ierr)
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! applying boundary conditions
|
! applying boundary conditions
|
||||||
call DMDAVecGetArrayF90(da_local,f_local,f_scal,ierr);CHKERRQ(ierr)
|
call DMDAVecGetArrayF90(da_local,f_local,f_scal,ierr);CHKERRQ(ierr)
|
||||||
if (zstart == 0) then
|
if (zstart == 0) then
|
||||||
f_scal(0:2,xstart,ystart,zstart) = 0.0
|
f_scal(0:2,xstart,ystart,zstart) = 0.0
|
||||||
f_scal(0:2,xend+1,ystart,zstart) = 0.0
|
f_scal(0:2,xend+1,ystart,zstart) = 0.0
|
||||||
f_scal(0:2,xstart,yend+1,zstart) = 0.0
|
f_scal(0:2,xstart,yend+1,zstart) = 0.0
|
||||||
f_scal(0:2,xend+1,yend+1,zstart) = 0.0
|
f_scal(0:2,xend+1,yend+1,zstart) = 0.0
|
||||||
endif
|
endif
|
||||||
if (zend + 1 == grid(3)) then
|
if (zend + 1 == grid(3)) then
|
||||||
f_scal(0:2,xstart,ystart,zend+1) = 0.0
|
f_scal(0:2,xstart,ystart,zend+1) = 0.0
|
||||||
f_scal(0:2,xend+1,ystart,zend+1) = 0.0
|
f_scal(0:2,xend+1,ystart,zend+1) = 0.0
|
||||||
f_scal(0:2,xstart,yend+1,zend+1) = 0.0
|
f_scal(0:2,xstart,yend+1,zend+1) = 0.0
|
||||||
f_scal(0:2,xend+1,yend+1,zend+1) = 0.0
|
f_scal(0:2,xend+1,yend+1,zend+1) = 0.0
|
||||||
endif
|
endif
|
||||||
call DMDAVecRestoreArrayF90(da_local,f_local,f_scal,ierr);CHKERRQ(ierr)
|
call DMDAVecRestoreArrayF90(da_local,f_local,f_scal,ierr);CHKERRQ(ierr)
|
||||||
|
|
||||||
end subroutine formResidual
|
end subroutine formResidual
|
||||||
|
|
||||||
|
|
||||||
|
@ -574,7 +574,7 @@ subroutine formJacobian(da_local,x_local,Jac_pre,Jac,dummy,ierr)
|
||||||
PetscObject :: dummy
|
PetscObject :: dummy
|
||||||
MatNullSpace :: matnull
|
MatNullSpace :: matnull
|
||||||
PetscErrorCode :: ierr
|
PetscErrorCode :: ierr
|
||||||
|
|
||||||
BMatFull = 0.0
|
BMatFull = 0.0
|
||||||
BMatFull(1:3,1 :8 ) = BMat
|
BMatFull(1:3,1 :8 ) = BMat
|
||||||
BMatFull(4:6,9 :16) = BMat
|
BMatFull(4:6,9 :16) = BMat
|
||||||
|
@ -623,7 +623,7 @@ subroutine formJacobian(da_local,x_local,Jac_pre,Jac,dummy,ierr)
|
||||||
call MatAssemblyEnd(Jac,MAT_FINAL_ASSEMBLY,ierr); CHKERRQ(ierr)
|
call MatAssemblyEnd(Jac,MAT_FINAL_ASSEMBLY,ierr); CHKERRQ(ierr)
|
||||||
call MatAssemblyBegin(Jac_pre,MAT_FINAL_ASSEMBLY,ierr); CHKERRQ(ierr)
|
call MatAssemblyBegin(Jac_pre,MAT_FINAL_ASSEMBLY,ierr); CHKERRQ(ierr)
|
||||||
call MatAssemblyEnd(Jac_pre,MAT_FINAL_ASSEMBLY,ierr); CHKERRQ(ierr)
|
call MatAssemblyEnd(Jac_pre,MAT_FINAL_ASSEMBLY,ierr); CHKERRQ(ierr)
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! applying boundary conditions
|
! applying boundary conditions
|
||||||
diag = (C_volAvg(1,1,1,1)/delta(1)**2.0_pReal + &
|
diag = (C_volAvg(1,1,1,1)/delta(1)**2.0_pReal + &
|
||||||
|
|
|
@ -28,11 +28,11 @@ module grid_mech_spectral_basic
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! derived types
|
! derived types
|
||||||
type(tSolutionParams), private :: params
|
type(tSolutionParams), private :: params
|
||||||
|
|
||||||
type, private :: tNumerics
|
type, private :: tNumerics
|
||||||
logical :: update_gamma !< update gamma operator with current stiffness
|
logical :: update_gamma !< update gamma operator with current stiffness
|
||||||
end type tNumerics
|
end type tNumerics
|
||||||
|
|
||||||
type(tNumerics) :: num ! numerics parameters. Better name?
|
type(tNumerics) :: num ! numerics parameters. Better name?
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
@ -55,21 +55,21 @@ module grid_mech_spectral_basic
|
||||||
F_aim_lastInc = math_I3, & !< previous average deformation gradient
|
F_aim_lastInc = math_I3, & !< previous average deformation gradient
|
||||||
P_av = 0.0_pReal !< average 1st Piola--Kirchhoff stress
|
P_av = 0.0_pReal !< average 1st Piola--Kirchhoff stress
|
||||||
|
|
||||||
character(len=pStringLen), private :: incInfo !< time and increment information
|
character(len=pStringLen), private :: incInfo !< time and increment information
|
||||||
real(pReal), private, dimension(3,3,3,3) :: &
|
real(pReal), private, dimension(3,3,3,3) :: &
|
||||||
C_volAvg = 0.0_pReal, & !< current volume average stiffness
|
C_volAvg = 0.0_pReal, & !< current volume average stiffness
|
||||||
C_volAvgLastInc = 0.0_pReal, & !< previous volume average stiffness
|
C_volAvgLastInc = 0.0_pReal, & !< previous volume average stiffness
|
||||||
C_minMaxAvg = 0.0_pReal, & !< current (min+max)/2 stiffness
|
C_minMaxAvg = 0.0_pReal, & !< current (min+max)/2 stiffness
|
||||||
C_minMaxAvgLastInc = 0.0_pReal, & !< previous (min+max)/2 stiffness
|
C_minMaxAvgLastInc = 0.0_pReal, & !< previous (min+max)/2 stiffness
|
||||||
S = 0.0_pReal !< current compliance (filled up with zeros)
|
S = 0.0_pReal !< current compliance (filled up with zeros)
|
||||||
|
|
||||||
real(pReal), private :: &
|
real(pReal), private :: &
|
||||||
err_BC, & !< deviation from stress BC
|
err_BC, & !< deviation from stress BC
|
||||||
err_div !< RMS of div of P
|
err_div !< RMS of div of P
|
||||||
|
|
||||||
integer, private :: &
|
integer, private :: &
|
||||||
totalIter = 0 !< total iteration in current increment
|
totalIter = 0 !< total iteration in current increment
|
||||||
|
|
||||||
public :: &
|
public :: &
|
||||||
grid_mech_spectral_basic_init, &
|
grid_mech_spectral_basic_init, &
|
||||||
grid_mech_spectral_basic_solution, &
|
grid_mech_spectral_basic_solution, &
|
||||||
|
@ -83,27 +83,27 @@ 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_mech_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
|
||||||
real(pReal), dimension(3,3) :: &
|
real(pReal), dimension(3,3) :: &
|
||||||
temp33_Real = 0.0_pReal
|
temp33_Real = 0.0_pReal
|
||||||
|
|
||||||
PetscErrorCode :: ierr
|
PetscErrorCode :: ierr
|
||||||
PetscScalar, pointer, dimension(:,:,:,:) :: &
|
PetscScalar, pointer, dimension(:,:,:,:) :: &
|
||||||
F ! pointer to solution data
|
F ! pointer to solution data
|
||||||
PetscInt, dimension(worldsize) :: localK
|
PetscInt, dimension(worldsize) :: localK
|
||||||
integer(HID_T) :: fileHandle, groupHandle
|
integer(HID_T) :: fileHandle, groupHandle
|
||||||
integer :: fileUnit
|
integer :: fileUnit
|
||||||
character(len=pStringLen) :: fileName
|
character(len=pStringLen) :: fileName
|
||||||
|
|
||||||
write(6,'(/,a)') ' <<<+- grid_mech_spectral_basic init -+>>>'; flush(6)
|
write(6,'(/,a)') ' <<<+- grid_mech_spectral_basic init -+>>>'; flush(6)
|
||||||
|
|
||||||
write(6,'(/,a)') ' Eisenlohr et al., International Journal of Plasticity 46:37–53, 2013'
|
write(6,'(/,a)') ' Eisenlohr et al., International Journal of Plasticity 46:37–53, 2013'
|
||||||
write(6,'(a)') ' https://doi.org/10.1016/j.ijplas.2012.09.012'
|
write(6,'(a)') ' https://doi.org/10.1016/j.ijplas.2012.09.012'
|
||||||
|
|
||||||
write(6,'(/,a)') ' Shanthraj et al., International Journal of Plasticity 66:31–45, 2015'
|
write(6,'(/,a)') ' Shanthraj et al., International Journal of Plasticity 66:31–45, 2015'
|
||||||
write(6,'(a)') ' https://doi.org/10.1016/j.ijplas.2014.02.006'
|
write(6,'(a)') ' https://doi.org/10.1016/j.ijplas.2014.02.006'
|
||||||
|
|
||||||
num%update_gamma = config_numerics%getInt('update_gamma',defaultVal=0) > 0
|
num%update_gamma = config_numerics%getInt('update_gamma',defaultVal=0) > 0
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
@ -117,11 +117,11 @@ subroutine grid_mech_spectral_basic_init
|
||||||
! allocate global fields
|
! allocate global fields
|
||||||
allocate (F_lastInc(3,3,grid(1),grid(2),grid3),source = 0.0_pReal)
|
allocate (F_lastInc(3,3,grid(1),grid(2),grid3),source = 0.0_pReal)
|
||||||
allocate (Fdot (3,3,grid(1),grid(2),grid3),source = 0.0_pReal)
|
allocate (Fdot (3,3,grid(1),grid(2),grid3),source = 0.0_pReal)
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! 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,'mech_',ierr);CHKERRQ(ierr)
|
||||||
localK = 0
|
localK = 0
|
||||||
localK(worldrank+1) = grid3
|
localK(worldrank+1) = 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)
|
||||||
|
@ -139,45 +139,45 @@ subroutine grid_mech_spectral_basic_init
|
||||||
call DMsetUp(da,ierr); CHKERRQ(ierr)
|
call DMsetUp(da,ierr); CHKERRQ(ierr)
|
||||||
call DMcreateGlobalVector(da,solution_vec,ierr); CHKERRQ(ierr) ! global solution vector (grid x 9, i.e. every def grad tensor)
|
call DMcreateGlobalVector(da,solution_vec,ierr); CHKERRQ(ierr) ! global solution vector (grid x 9, i.e. every def grad tensor)
|
||||||
call DMDASNESsetFunctionLocal(da,INSERT_VALUES,formResidual,PETSC_NULL_SNES,ierr) ! residual vector of same shape as solution vector
|
call DMDASNESsetFunctionLocal(da,INSERT_VALUES,formResidual,PETSC_NULL_SNES,ierr) ! residual vector of same shape as solution vector
|
||||||
CHKERRQ(ierr)
|
CHKERRQ(ierr)
|
||||||
call SNESsetConvergenceTest(snes,converged,PETSC_NULL_SNES,PETSC_NULL_FUNCTION,ierr) ! specify custom convergence check function "converged"
|
call SNESsetConvergenceTest(snes,converged,PETSC_NULL_SNES,PETSC_NULL_FUNCTION,ierr) ! specify custom convergence check function "converged"
|
||||||
CHKERRQ(ierr)
|
CHKERRQ(ierr)
|
||||||
call SNESsetFromOptions(snes,ierr); CHKERRQ(ierr) ! pull it all together with additional CLI arguments
|
call SNESsetFromOptions(snes,ierr); CHKERRQ(ierr) ! pull it all together with additional CLI arguments
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! init fields
|
! init fields
|
||||||
call DMDAVecGetArrayF90(da,solution_vec,F,ierr); CHKERRQ(ierr) ! places pointer on PETSc data
|
call DMDAVecGetArrayF90(da,solution_vec,F,ierr); CHKERRQ(ierr) ! places pointer on PETSc data
|
||||||
|
|
||||||
restartRead: if (interface_restartInc > 0) then
|
restartRead: if (interface_restartInc > 0) then
|
||||||
write(6,'(/,a,i0,a)') ' reading restart data of increment ', interface_restartInc, ' from file'
|
write(6,'(/,a,i0,a)') ' reading restart data of increment ', interface_restartInc, ' from file'
|
||||||
|
|
||||||
write(fileName,'(a,a,i0,a)') trim(getSolverJobName()),'_',worldrank,'.hdf5'
|
write(fileName,'(a,a,i0,a)') trim(getSolverJobName()),'_',worldrank,'.hdf5'
|
||||||
fileHandle = HDF5_openFile(fileName)
|
fileHandle = HDF5_openFile(fileName)
|
||||||
groupHandle = HDF5_openGroup(fileHandle,'solver')
|
groupHandle = HDF5_openGroup(fileHandle,'solver')
|
||||||
|
|
||||||
call HDF5_read(groupHandle,F_aim, 'F_aim')
|
call HDF5_read(groupHandle,F_aim, 'F_aim')
|
||||||
call HDF5_read(groupHandle,F_aim_lastInc,'F_aim_lastInc')
|
call HDF5_read(groupHandle,F_aim_lastInc,'F_aim_lastInc')
|
||||||
call HDF5_read(groupHandle,F_aimDot, 'F_aimDot')
|
call HDF5_read(groupHandle,F_aimDot, 'F_aimDot')
|
||||||
call HDF5_read(groupHandle,F, 'F')
|
call HDF5_read(groupHandle,F, 'F')
|
||||||
call HDF5_read(groupHandle,F_lastInc, 'F_lastInc')
|
call HDF5_read(groupHandle,F_lastInc, 'F_lastInc')
|
||||||
|
|
||||||
elseif (interface_restartInc == 0) then restartRead
|
elseif (interface_restartInc == 0) then restartRead
|
||||||
F_lastInc = spread(spread(spread(math_I3,3,grid(1)),4,grid(2)),5,grid3) ! initialize to identity
|
F_lastInc = spread(spread(spread(math_I3,3,grid(1)),4,grid(2)),5,grid3) ! initialize to identity
|
||||||
F = reshape(F_lastInc,[9,grid(1),grid(2),grid3])
|
F = reshape(F_lastInc,[9,grid(1),grid(2),grid3])
|
||||||
endif restartRead
|
endif restartRead
|
||||||
|
|
||||||
materialpoint_F0 = reshape(F_lastInc, [3,3,1,product(grid(1:2))*grid3]) ! set starting condition for materialpoint_stressAndItsTangent
|
materialpoint_F0 = reshape(F_lastInc, [3,3,1,product(grid(1:2))*grid3]) ! set starting condition for materialpoint_stressAndItsTangent
|
||||||
call Utilities_updateCoords(reshape(F,shape(F_lastInc)))
|
call Utilities_updateCoords(reshape(F,shape(F_lastInc)))
|
||||||
call Utilities_constitutiveResponse(P,temp33_Real,C_volAvg,C_minMaxAvg, & ! stress field, stress avg, global average of stiffness and (min+max)/2
|
call Utilities_constitutiveResponse(P,temp33_Real,C_volAvg,C_minMaxAvg, & ! stress field, stress avg, global average of stiffness and (min+max)/2
|
||||||
reshape(F,shape(F_lastInc)), & ! target F
|
reshape(F,shape(F_lastInc)), & ! target F
|
||||||
0.0_pReal) ! time increment
|
0.0_pReal) ! time increment
|
||||||
call DMDAVecRestoreArrayF90(da,solution_vec,F,ierr); CHKERRQ(ierr) ! deassociate pointer
|
call DMDAVecRestoreArrayF90(da,solution_vec,F,ierr); CHKERRQ(ierr) ! deassociate pointer
|
||||||
|
|
||||||
restartRead2: if (interface_restartInc > 0) then
|
restartRead2: if (interface_restartInc > 0) then
|
||||||
write(6,'(/,a,i0,a)') ' reading more restart data of increment ', interface_restartInc, ' from file'
|
write(6,'(/,a,i0,a)') ' reading more restart data of increment ', interface_restartInc, ' from file'
|
||||||
call HDF5_read(groupHandle,C_volAvg, 'C_volAvg')
|
call HDF5_read(groupHandle,C_volAvg, 'C_volAvg')
|
||||||
call HDF5_read(groupHandle,C_volAvgLastInc,'C_volAvgLastInc')
|
call HDF5_read(groupHandle,C_volAvgLastInc,'C_volAvgLastInc')
|
||||||
|
|
||||||
call HDF5_closeGroup(groupHandle)
|
call HDF5_closeGroup(groupHandle)
|
||||||
call HDF5_closeFile(fileHandle)
|
call HDF5_closeFile(fileHandle)
|
||||||
|
|
||||||
|
@ -197,7 +197,7 @@ end subroutine grid_mech_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,timeinc,timeinc_old,stress_BC,rotation_BC) result(solution)
|
function grid_mech_spectral_basic_solution(incInfoIn,timeinc,timeinc_old,stress_BC,rotation_BC) result(solution)
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! input data for solution
|
! input data for solution
|
||||||
character(len=*), intent(in) :: &
|
character(len=*), intent(in) :: &
|
||||||
|
@ -215,7 +215,7 @@ function grid_mech_spectral_basic_solution(incInfoIn,timeinc,timeinc_old,stress_
|
||||||
! PETSc Data
|
! PETSc Data
|
||||||
PetscErrorCode :: ierr
|
PetscErrorCode :: ierr
|
||||||
SNESConvergedReason :: reason
|
SNESConvergedReason :: reason
|
||||||
|
|
||||||
incInfo = incInfoIn
|
incInfo = incInfoIn
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
@ -224,7 +224,7 @@ function grid_mech_spectral_basic_solution(incInfoIn,timeinc,timeinc_old,stress_
|
||||||
if(num%update_gamma) call utilities_updateGamma(C_minMaxAvg)
|
if(num%update_gamma) call utilities_updateGamma(C_minMaxAvg)
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! set module wide available data
|
! set module wide available data
|
||||||
params%stress_mask = stress_BC%maskFloat
|
params%stress_mask = stress_BC%maskFloat
|
||||||
params%stress_BC = stress_BC%values
|
params%stress_BC = stress_BC%values
|
||||||
params%rotation_BC = rotation_BC
|
params%rotation_BC = rotation_BC
|
||||||
|
@ -232,13 +232,13 @@ function grid_mech_spectral_basic_solution(incInfoIn,timeinc,timeinc_old,stress_
|
||||||
params%timeincOld = timeinc_old
|
params%timeincOld = timeinc_old
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! solve BVP
|
! solve BVP
|
||||||
call SNESsolve(snes,PETSC_NULL_VEC,solution_vec,ierr); CHKERRQ(ierr)
|
call SNESsolve(snes,PETSC_NULL_VEC,solution_vec,ierr); CHKERRQ(ierr)
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! check convergence
|
! check convergence
|
||||||
call SNESGetConvergedReason(snes,reason,ierr); CHKERRQ(ierr)
|
call SNESGetConvergedReason(snes,reason,ierr); CHKERRQ(ierr)
|
||||||
|
|
||||||
solution%converged = reason > 0
|
solution%converged = reason > 0
|
||||||
solution%iterationsNeeded = totalIter
|
solution%iterationsNeeded = totalIter
|
||||||
solution%termIll = terminallyIll
|
solution%termIll = terminallyIll
|
||||||
|
@ -271,14 +271,14 @@ subroutine grid_mech_spectral_basic_forward(cutBack,guess,timeinc,timeinc_old,lo
|
||||||
PetscScalar, dimension(:,:,:,:), pointer :: F
|
PetscScalar, dimension(:,:,:,:), pointer :: F
|
||||||
|
|
||||||
call DMDAVecGetArrayF90(da,solution_vec,F,ierr); CHKERRQ(ierr)
|
call DMDAVecGetArrayF90(da,solution_vec,F,ierr); CHKERRQ(ierr)
|
||||||
|
|
||||||
if (cutBack) then
|
if (cutBack) then
|
||||||
C_volAvg = C_volAvgLastInc
|
C_volAvg = C_volAvgLastInc
|
||||||
C_minMaxAvg = C_minMaxAvgLastInc
|
C_minMaxAvg = C_minMaxAvgLastInc
|
||||||
else
|
else
|
||||||
C_volAvgLastInc = C_volAvg
|
C_volAvgLastInc = C_volAvg
|
||||||
C_minMaxAvgLastInc = C_minMaxAvg
|
C_minMaxAvgLastInc = C_minMaxAvg
|
||||||
|
|
||||||
F_aimDot = merge(stress_BC%maskFloat*(F_aim-F_aim_lastInc)/timeinc_old, 0.0_pReal, guess)
|
F_aimDot = merge(stress_BC%maskFloat*(F_aim-F_aim_lastInc)/timeinc_old, 0.0_pReal, guess)
|
||||||
F_aim_lastInc = F_aim
|
F_aim_lastInc = F_aim
|
||||||
|
|
||||||
|
@ -297,9 +297,9 @@ subroutine grid_mech_spectral_basic_forward(cutBack,guess,timeinc,timeinc_old,lo
|
||||||
|
|
||||||
Fdot = utilities_calculateRate(guess, &
|
Fdot = utilities_calculateRate(guess, &
|
||||||
F_lastInc,reshape(F,[3,3,grid(1),grid(2),grid3]),timeinc_old, &
|
F_lastInc,reshape(F,[3,3,grid(1),grid(2),grid3]),timeinc_old, &
|
||||||
rotation_BC%rotTensor2(F_aimDot,active=.true.))
|
rotation_BC%rotate(F_aimDot,active=.true.))
|
||||||
F_lastInc = reshape(F,[3,3,grid(1),grid(2),grid3])
|
F_lastInc = reshape(F,[3,3,grid(1),grid(2),grid3])
|
||||||
|
|
||||||
materialpoint_F0 = reshape(F, [3,3,1,product(grid(1:2))*grid3])
|
materialpoint_F0 = reshape(F, [3,3,1,product(grid(1:2))*grid3])
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
@ -307,9 +307,9 @@ subroutine grid_mech_spectral_basic_forward(cutBack,guess,timeinc,timeinc_old,lo
|
||||||
! update average and local deformation gradients
|
! update average and local deformation gradients
|
||||||
F_aim = F_aim_lastInc + F_aimDot * timeinc
|
F_aim = F_aim_lastInc + F_aimDot * timeinc
|
||||||
F = reshape(Utilities_forwardField(timeinc,F_lastInc,Fdot, & ! estimate of F at end of time+timeinc that matches rotated F_aim on average
|
F = reshape(Utilities_forwardField(timeinc,F_lastInc,Fdot, & ! estimate of F at end of time+timeinc that matches rotated F_aim on average
|
||||||
rotation_BC%rotTensor2(F_aim,active=.true.)),[9,grid(1),grid(2),grid3])
|
rotation_BC%rotate(F_aim,active=.true.)),[9,grid(1),grid(2),grid3])
|
||||||
call DMDAVecRestoreArrayF90(da,solution_vec,F,ierr); CHKERRQ(ierr)
|
call DMDAVecRestoreArrayF90(da,solution_vec,F,ierr); CHKERRQ(ierr)
|
||||||
|
|
||||||
end subroutine grid_mech_spectral_basic_forward
|
end subroutine grid_mech_spectral_basic_forward
|
||||||
|
|
||||||
|
|
||||||
|
@ -341,11 +341,11 @@ subroutine grid_mech_spectral_basic_restartWrite
|
||||||
call DMDAVecGetArrayF90(da,solution_vec,F,ierr); CHKERRQ(ierr)
|
call DMDAVecGetArrayF90(da,solution_vec,F,ierr); CHKERRQ(ierr)
|
||||||
|
|
||||||
write(6,'(a)') ' writing solver data required for restart to file'; flush(6)
|
write(6,'(a)') ' writing solver data required for restart to file'; flush(6)
|
||||||
|
|
||||||
write(fileName,'(a,a,i0,a)') trim(getSolverJobName()),'_',worldrank,'.hdf5'
|
write(fileName,'(a,a,i0,a)') trim(getSolverJobName()),'_',worldrank,'.hdf5'
|
||||||
fileHandle = HDF5_openFile(fileName,'w')
|
fileHandle = HDF5_openFile(fileName,'w')
|
||||||
groupHandle = HDF5_addGroup(fileHandle,'solver')
|
groupHandle = HDF5_addGroup(fileHandle,'solver')
|
||||||
|
|
||||||
call HDF5_write(groupHandle,F_aim, 'F_aim')
|
call HDF5_write(groupHandle,F_aim, 'F_aim')
|
||||||
call HDF5_write(groupHandle,F_aim_lastInc,'F_aim_lastInc')
|
call HDF5_write(groupHandle,F_aim_lastInc,'F_aim_lastInc')
|
||||||
call HDF5_write(groupHandle,F_aimDot, 'F_aimDot')
|
call HDF5_write(groupHandle,F_aimDot, 'F_aimDot')
|
||||||
|
@ -358,7 +358,7 @@ subroutine grid_mech_spectral_basic_restartWrite
|
||||||
|
|
||||||
call HDF5_closeGroup(groupHandle)
|
call HDF5_closeGroup(groupHandle)
|
||||||
call HDF5_closeFile(fileHandle)
|
call HDF5_closeFile(fileHandle)
|
||||||
|
|
||||||
if (num%update_gamma) call utilities_saveReferenceStiffness
|
if (num%update_gamma) call utilities_saveReferenceStiffness
|
||||||
|
|
||||||
call DMDAVecRestoreArrayF90(da,solution_vec,F,ierr); CHKERRQ(ierr)
|
call DMDAVecRestoreArrayF90(da,solution_vec,F,ierr); CHKERRQ(ierr)
|
||||||
|
@ -376,7 +376,7 @@ subroutine converged(snes_local,PETScIter,devNull1,devNull2,devNull3,reason,dumm
|
||||||
PetscReal, intent(in) :: &
|
PetscReal, intent(in) :: &
|
||||||
devNull1, &
|
devNull1, &
|
||||||
devNull2, &
|
devNull2, &
|
||||||
devNull3
|
devNull3
|
||||||
SNESConvergedReason :: reason
|
SNESConvergedReason :: reason
|
||||||
PetscObject :: dummy
|
PetscObject :: dummy
|
||||||
PetscErrorCode :: ierr
|
PetscErrorCode :: ierr
|
||||||
|
@ -390,7 +390,7 @@ subroutine converged(snes_local,PETScIter,devNull1,devNull2,devNull3,reason,dumm
|
||||||
if ((totalIter >= itmin .and. &
|
if ((totalIter >= itmin .and. &
|
||||||
all([ err_div/divTol, &
|
all([ err_div/divTol, &
|
||||||
err_BC /BCTol ] < 1.0_pReal)) &
|
err_BC /BCTol ] < 1.0_pReal)) &
|
||||||
.or. terminallyIll) then
|
.or. terminallyIll) then
|
||||||
reason = 1
|
reason = 1
|
||||||
elseif (totalIter >= itmax) then
|
elseif (totalIter >= itmax) then
|
||||||
reason = -1
|
reason = -1
|
||||||
|
@ -404,10 +404,10 @@ subroutine converged(snes_local,PETScIter,devNull1,devNull2,devNull3,reason,dumm
|
||||||
write(6,'(1/,a,f12.2,a,es8.2,a,es9.2,a)') ' error divergence = ', &
|
write(6,'(1/,a,f12.2,a,es8.2,a,es9.2,a)') ' error divergence = ', &
|
||||||
err_div/divTol, ' (',err_div,' / m, tol = ',divTol,')'
|
err_div/divTol, ' (',err_div,' / m, tol = ',divTol,')'
|
||||||
write(6,'(a,f12.2,a,es8.2,a,es9.2,a)') ' error stress BC = ', &
|
write(6,'(a,f12.2,a,es8.2,a,es9.2,a)') ' error stress BC = ', &
|
||||||
err_BC/BCTol, ' (',err_BC, ' Pa, tol = ',BCTol,')'
|
err_BC/BCTol, ' (',err_BC, ' Pa, tol = ',BCTol,')'
|
||||||
write(6,'(/,a)') ' ==========================================================================='
|
write(6,'(/,a)') ' ==========================================================================='
|
||||||
flush(6)
|
flush(6)
|
||||||
|
|
||||||
end subroutine converged
|
end subroutine converged
|
||||||
|
|
||||||
|
|
||||||
|
@ -441,7 +441,7 @@ subroutine formResidual(in, F, &
|
||||||
write(6,'(1x,a,3(a,i0))') trim(incInfo), ' @ Iteration ', itmin, '≤',totalIter, '≤', itmax
|
write(6,'(1x,a,3(a,i0))') trim(incInfo), ' @ Iteration ', itmin, '≤',totalIter, '≤', itmax
|
||||||
if (iand(debug_level(debug_spectral),debug_spectralRotation) /= 0) &
|
if (iand(debug_level(debug_spectral),debug_spectralRotation) /= 0) &
|
||||||
write(6,'(/,a,/,3(3(f12.7,1x)/))',advance='no') &
|
write(6,'(/,a,/,3(3(f12.7,1x)/))',advance='no') &
|
||||||
' deformation gradient aim (lab) =', transpose(params%rotation_BC%rotTensor2(F_aim,active=.true.))
|
' deformation gradient aim (lab) =', transpose(params%rotation_BC%rotate(F_aim,active=.true.))
|
||||||
write(6,'(/,a,/,3(3(f12.7,1x)/))',advance='no') &
|
write(6,'(/,a,/,3(3(f12.7,1x)/))',advance='no') &
|
||||||
' deformation gradient aim =', transpose(F_aim)
|
' deformation gradient aim =', transpose(F_aim)
|
||||||
flush(6)
|
flush(6)
|
||||||
|
@ -453,7 +453,7 @@ subroutine formResidual(in, F, &
|
||||||
P_av,C_volAvg,C_minMaxAvg, &
|
P_av,C_volAvg,C_minMaxAvg, &
|
||||||
F,params%timeinc,params%rotation_BC)
|
F,params%timeinc,params%rotation_BC)
|
||||||
call MPI_Allreduce(MPI_IN_PLACE,terminallyIll,1,MPI_LOGICAL,MPI_LOR,PETSC_COMM_WORLD,ierr)
|
call MPI_Allreduce(MPI_IN_PLACE,terminallyIll,1,MPI_LOGICAL,MPI_LOR,PETSC_COMM_WORLD,ierr)
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! stress BC handling
|
! stress BC handling
|
||||||
deltaF_aim = math_mul3333xx33(S, P_av - params%stress_BC)
|
deltaF_aim = math_mul3333xx33(S, P_av - params%stress_BC)
|
||||||
|
@ -466,9 +466,9 @@ subroutine formResidual(in, F, &
|
||||||
tensorField_real(1:3,1:3,1:grid(1),1:grid(2),1:grid3) = residuum ! store fPK field for subsequent FFT forward transform
|
tensorField_real(1:3,1:3,1:grid(1),1:grid(2),1:grid3) = residuum ! store fPK field for subsequent FFT forward transform
|
||||||
call utilities_FFTtensorForward ! FFT forward of global "tensorField_real"
|
call utilities_FFTtensorForward ! FFT forward of global "tensorField_real"
|
||||||
err_div = Utilities_divergenceRMS() ! divRMS of tensorField_fourier for later use
|
err_div = Utilities_divergenceRMS() ! divRMS of tensorField_fourier for later use
|
||||||
call utilities_fourierGammaConvolution(params%rotation_BC%rotTensor2(deltaF_aim,active=.true.)) ! convolution of Gamma and tensorField_fourier
|
call utilities_fourierGammaConvolution(params%rotation_BC%rotate(deltaF_aim,active=.true.)) ! convolution of Gamma and tensorField_fourier
|
||||||
call utilities_FFTtensorBackward ! FFT backward of global tensorField_fourier
|
call utilities_FFTtensorBackward ! FFT backward of global tensorField_fourier
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! constructing residual
|
! constructing residual
|
||||||
residuum = tensorField_real(1:3,1:3,1:grid(1),1:grid(2),1:grid3) ! Gamma*P gives correction towards div(P) = 0, so needs to be zero, too
|
residuum = tensorField_real(1:3,1:3,1:grid(1),1:grid(2),1:grid3) ! Gamma*P gives correction towards div(P) = 0, so needs to be zero, too
|
||||||
|
|
|
@ -22,20 +22,20 @@ module grid_mech_spectral_polarisation
|
||||||
use homogenization
|
use homogenization
|
||||||
use mesh_grid
|
use mesh_grid
|
||||||
use debug
|
use debug
|
||||||
|
|
||||||
implicit none
|
implicit none
|
||||||
private
|
private
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! derived types
|
! derived types
|
||||||
type(tSolutionParams), private :: params
|
type(tSolutionParams), private :: params
|
||||||
|
|
||||||
type, private :: tNumerics
|
type, private :: tNumerics
|
||||||
logical :: update_gamma !< update gamma operator with current stiffness
|
logical :: update_gamma !< update gamma operator with current stiffness
|
||||||
end type tNumerics
|
end type tNumerics
|
||||||
|
|
||||||
type(tNumerics) :: num ! numerics parameters. Better name?
|
type(tNumerics) :: num ! numerics parameters. Better name?
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! PETSc data
|
! PETSc data
|
||||||
DM, private :: da
|
DM, private :: da
|
||||||
|
@ -46,7 +46,7 @@ module grid_mech_spectral_polarisation
|
||||||
! common pointwise data
|
! common pointwise data
|
||||||
real(pReal), private, dimension(:,:,:,:,:), allocatable :: &
|
real(pReal), private, dimension(:,:,:,:,:), allocatable :: &
|
||||||
F_lastInc, & !< field of previous compatible deformation gradients
|
F_lastInc, & !< field of previous compatible deformation gradients
|
||||||
F_tau_lastInc, & !< field of previous incompatible deformation gradient
|
F_tau_lastInc, & !< field of previous incompatible deformation gradient
|
||||||
Fdot, & !< field of assumed rate of compatible deformation gradient
|
Fdot, & !< field of assumed rate of compatible deformation gradient
|
||||||
F_tauDot !< field of assumed rate of incopatible deformation gradient
|
F_tauDot !< field of assumed rate of incopatible deformation gradient
|
||||||
|
|
||||||
|
@ -58,25 +58,25 @@ module grid_mech_spectral_polarisation
|
||||||
F_aim_lastInc = math_I3, & !< previous average deformation gradient
|
F_aim_lastInc = math_I3, & !< previous average deformation gradient
|
||||||
F_av = 0.0_pReal, & !< average incompatible def grad field
|
F_av = 0.0_pReal, & !< average incompatible def grad field
|
||||||
P_av = 0.0_pReal !< average 1st Piola--Kirchhoff stress
|
P_av = 0.0_pReal !< average 1st Piola--Kirchhoff stress
|
||||||
|
|
||||||
character(len=pStringLen), private :: incInfo !< time and increment information
|
character(len=pStringLen), private :: incInfo !< time and increment information
|
||||||
real(pReal), private, dimension(3,3,3,3) :: &
|
real(pReal), private, dimension(3,3,3,3) :: &
|
||||||
C_volAvg = 0.0_pReal, & !< current volume average stiffness
|
C_volAvg = 0.0_pReal, & !< current volume average stiffness
|
||||||
C_volAvgLastInc = 0.0_pReal, & !< previous volume average stiffness
|
C_volAvgLastInc = 0.0_pReal, & !< previous volume average stiffness
|
||||||
C_minMaxAvg = 0.0_pReal, & !< current (min+max)/2 stiffness
|
C_minMaxAvg = 0.0_pReal, & !< current (min+max)/2 stiffness
|
||||||
C_minMaxAvgLastInc = 0.0_pReal, & !< previous (min+max)/2 stiffness
|
C_minMaxAvgLastInc = 0.0_pReal, & !< previous (min+max)/2 stiffness
|
||||||
S = 0.0_pReal, & !< current compliance (filled up with zeros)
|
S = 0.0_pReal, & !< current compliance (filled up with zeros)
|
||||||
C_scale = 0.0_pReal, &
|
C_scale = 0.0_pReal, &
|
||||||
S_scale = 0.0_pReal
|
S_scale = 0.0_pReal
|
||||||
|
|
||||||
real(pReal), private :: &
|
real(pReal), private :: &
|
||||||
err_BC, & !< deviation from stress BC
|
err_BC, & !< deviation from stress BC
|
||||||
err_curl, & !< RMS of curl of F
|
err_curl, & !< RMS of curl of F
|
||||||
err_div !< RMS of div of P
|
err_div !< RMS of div of P
|
||||||
|
|
||||||
integer, private :: &
|
integer, private :: &
|
||||||
totalIter = 0 !< total iteration in current increment
|
totalIter = 0 !< total iteration in current increment
|
||||||
|
|
||||||
public :: &
|
public :: &
|
||||||
grid_mech_spectral_polarisation_init, &
|
grid_mech_spectral_polarisation_init, &
|
||||||
grid_mech_spectral_polarisation_solution, &
|
grid_mech_spectral_polarisation_solution, &
|
||||||
|
@ -90,26 +90,26 @@ 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_mech_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
|
||||||
real(pReal), dimension(3,3) :: &
|
real(pReal), dimension(3,3) :: &
|
||||||
temp33_Real = 0.0_pReal
|
temp33_Real = 0.0_pReal
|
||||||
|
|
||||||
PetscErrorCode :: ierr
|
PetscErrorCode :: ierr
|
||||||
PetscScalar, pointer, dimension(:,:,:,:) :: &
|
PetscScalar, pointer, dimension(:,:,:,:) :: &
|
||||||
FandF_tau, & ! overall pointer to solution data
|
FandF_tau, & ! overall pointer to solution data
|
||||||
F, & ! specific (sub)pointer
|
F, & ! specific (sub)pointer
|
||||||
F_tau ! specific (sub)pointer
|
F_tau ! specific (sub)pointer
|
||||||
PetscInt, dimension(0:worldsize-1) :: localK
|
PetscInt, dimension(0:worldsize-1) :: localK
|
||||||
integer(HID_T) :: fileHandle, groupHandle
|
integer(HID_T) :: fileHandle, groupHandle
|
||||||
integer :: fileUnit
|
integer :: fileUnit
|
||||||
character(len=pStringLen) :: fileName
|
character(len=pStringLen) :: fileName
|
||||||
|
|
||||||
write(6,'(/,a)') ' <<<+- grid_mech_spectral_polarisation init -+>>>'; flush(6)
|
write(6,'(/,a)') ' <<<+- grid_mech_spectral_polarisation init -+>>>'; flush(6)
|
||||||
|
|
||||||
write(6,'(/,a)') ' Shanthraj et al., International Journal of Plasticity 66:31–45, 2015'
|
write(6,'(/,a)') ' Shanthraj et al., International Journal of Plasticity 66:31–45, 2015'
|
||||||
write(6,'(a)') ' https://doi.org/10.1016/j.ijplas.2014.02.006'
|
write(6,'(a)') ' https://doi.org/10.1016/j.ijplas.2014.02.006'
|
||||||
|
|
||||||
num%update_gamma = config_numerics%getInt('update_gamma',defaultVal=0) > 0
|
num%update_gamma = config_numerics%getInt('update_gamma',defaultVal=0) > 0
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
@ -125,11 +125,11 @@ subroutine grid_mech_spectral_polarisation_init
|
||||||
allocate(Fdot (3,3,grid(1),grid(2),grid3),source = 0.0_pReal)
|
allocate(Fdot (3,3,grid(1),grid(2),grid3),source = 0.0_pReal)
|
||||||
allocate(F_tau_lastInc(3,3,grid(1),grid(2),grid3),source = 0.0_pReal)
|
allocate(F_tau_lastInc(3,3,grid(1),grid(2),grid3),source = 0.0_pReal)
|
||||||
allocate(F_tauDot (3,3,grid(1),grid(2),grid3),source = 0.0_pReal)
|
allocate(F_tauDot (3,3,grid(1),grid(2),grid3),source = 0.0_pReal)
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! 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,'mech_',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)
|
||||||
|
@ -147,24 +147,24 @@ subroutine grid_mech_spectral_polarisation_init
|
||||||
call DMsetUp(da,ierr); CHKERRQ(ierr)
|
call DMsetUp(da,ierr); CHKERRQ(ierr)
|
||||||
call DMcreateGlobalVector(da,solution_vec,ierr); CHKERRQ(ierr) ! global solution vector (grid x 18, i.e. every def grad tensor)
|
call DMcreateGlobalVector(da,solution_vec,ierr); CHKERRQ(ierr) ! global solution vector (grid x 18, i.e. every def grad tensor)
|
||||||
call DMDASNESsetFunctionLocal(da,INSERT_VALUES,formResidual,PETSC_NULL_SNES,ierr) ! residual vector of same shape as solution vector
|
call DMDASNESsetFunctionLocal(da,INSERT_VALUES,formResidual,PETSC_NULL_SNES,ierr) ! residual vector of same shape as solution vector
|
||||||
CHKERRQ(ierr)
|
CHKERRQ(ierr)
|
||||||
call SNESsetConvergenceTest(snes,converged,PETSC_NULL_SNES,PETSC_NULL_FUNCTION,ierr) ! specify custom convergence check function "converged"
|
call SNESsetConvergenceTest(snes,converged,PETSC_NULL_SNES,PETSC_NULL_FUNCTION,ierr) ! specify custom convergence check function "converged"
|
||||||
CHKERRQ(ierr)
|
CHKERRQ(ierr)
|
||||||
call SNESsetFromOptions(snes,ierr); CHKERRQ(ierr) ! pull it all together with additional CLI arguments
|
call SNESsetFromOptions(snes,ierr); CHKERRQ(ierr) ! pull it all together with additional CLI arguments
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! init fields
|
! init fields
|
||||||
call DMDAVecGetArrayF90(da,solution_vec,FandF_tau,ierr); CHKERRQ(ierr) ! places pointer on PETSc data
|
call DMDAVecGetArrayF90(da,solution_vec,FandF_tau,ierr); CHKERRQ(ierr) ! places pointer on PETSc data
|
||||||
F => FandF_tau(0: 8,:,:,:)
|
F => FandF_tau(0: 8,:,:,:)
|
||||||
F_tau => FandF_tau(9:17,:,:,:)
|
F_tau => FandF_tau(9:17,:,:,:)
|
||||||
|
|
||||||
restartRead: if (interface_restartInc > 0) then
|
restartRead: if (interface_restartInc > 0) then
|
||||||
write(6,'(/,a,i0,a)') ' reading restart data of increment ', interface_restartInc, ' from file'
|
write(6,'(/,a,i0,a)') ' reading restart data of increment ', interface_restartInc, ' from file'
|
||||||
|
|
||||||
write(fileName,'(a,a,i0,a)') trim(getSolverJobName()),'_',worldrank,'.hdf5'
|
write(fileName,'(a,a,i0,a)') trim(getSolverJobName()),'_',worldrank,'.hdf5'
|
||||||
fileHandle = HDF5_openFile(fileName)
|
fileHandle = HDF5_openFile(fileName)
|
||||||
groupHandle = HDF5_openGroup(fileHandle,'solver')
|
groupHandle = HDF5_openGroup(fileHandle,'solver')
|
||||||
|
|
||||||
call HDF5_read(groupHandle,F_aim, 'F_aim')
|
call HDF5_read(groupHandle,F_aim, 'F_aim')
|
||||||
call HDF5_read(groupHandle,F_aim_lastInc,'F_aim_lastInc')
|
call HDF5_read(groupHandle,F_aim_lastInc,'F_aim_lastInc')
|
||||||
call HDF5_read(groupHandle,F_aimDot, 'F_aimDot')
|
call HDF5_read(groupHandle,F_aimDot, 'F_aimDot')
|
||||||
|
@ -172,21 +172,21 @@ subroutine grid_mech_spectral_polarisation_init
|
||||||
call HDF5_read(groupHandle,F_lastInc, 'F_lastInc')
|
call HDF5_read(groupHandle,F_lastInc, 'F_lastInc')
|
||||||
call HDF5_read(groupHandle,F_tau, 'F_tau')
|
call HDF5_read(groupHandle,F_tau, 'F_tau')
|
||||||
call HDF5_read(groupHandle,F_tau_lastInc,'F_tau_lastInc')
|
call HDF5_read(groupHandle,F_tau_lastInc,'F_tau_lastInc')
|
||||||
|
|
||||||
elseif (interface_restartInc == 0) then restartRead
|
elseif (interface_restartInc == 0) then restartRead
|
||||||
F_lastInc = spread(spread(spread(math_I3,3,grid(1)),4,grid(2)),5,grid3) ! initialize to identity
|
F_lastInc = spread(spread(spread(math_I3,3,grid(1)),4,grid(2)),5,grid3) ! initialize to identity
|
||||||
F = reshape(F_lastInc,[9,grid(1),grid(2),grid3])
|
F = reshape(F_lastInc,[9,grid(1),grid(2),grid3])
|
||||||
F_tau = 2.0_pReal*F
|
F_tau = 2.0_pReal*F
|
||||||
F_tau_lastInc = 2.0_pReal*F_lastInc
|
F_tau_lastInc = 2.0_pReal*F_lastInc
|
||||||
endif restartRead
|
endif restartRead
|
||||||
|
|
||||||
materialpoint_F0 = reshape(F_lastInc, [3,3,1,product(grid(1:2))*grid3]) ! set starting condition for materialpoint_stressAndItsTangent
|
materialpoint_F0 = reshape(F_lastInc, [3,3,1,product(grid(1:2))*grid3]) ! set starting condition for materialpoint_stressAndItsTangent
|
||||||
call Utilities_updateCoords(reshape(F,shape(F_lastInc)))
|
call Utilities_updateCoords(reshape(F,shape(F_lastInc)))
|
||||||
call Utilities_constitutiveResponse(P,temp33_Real,C_volAvg,C_minMaxAvg, & ! stress field, stress avg, global average of stiffness and (min+max)/2
|
call Utilities_constitutiveResponse(P,temp33_Real,C_volAvg,C_minMaxAvg, & ! stress field, stress avg, global average of stiffness and (min+max)/2
|
||||||
reshape(F,shape(F_lastInc)), & ! target F
|
reshape(F,shape(F_lastInc)), & ! target F
|
||||||
0.0_pReal) ! time increment
|
0.0_pReal) ! time increment
|
||||||
call DMDAVecRestoreArrayF90(da,solution_vec,FandF_tau,ierr); CHKERRQ(ierr) ! deassociate pointer
|
call DMDAVecRestoreArrayF90(da,solution_vec,FandF_tau,ierr); CHKERRQ(ierr) ! deassociate pointer
|
||||||
|
|
||||||
restartRead2: if (interface_restartInc > 0) then
|
restartRead2: if (interface_restartInc > 0) then
|
||||||
write(6,'(/,a,i0,a)') ' reading more restart data of increment ', interface_restartInc, ' from file'
|
write(6,'(/,a,i0,a)') ' reading more restart data of increment ', interface_restartInc, ' from file'
|
||||||
call HDF5_read(groupHandle,C_volAvg, 'C_volAvg')
|
call HDF5_read(groupHandle,C_volAvg, 'C_volAvg')
|
||||||
|
@ -200,12 +200,12 @@ subroutine grid_mech_spectral_polarisation_init
|
||||||
call MPI_File_read(fileUnit,C_minMaxAvg,81,MPI_DOUBLE,MPI_STATUS_IGNORE,ierr)
|
call MPI_File_read(fileUnit,C_minMaxAvg,81,MPI_DOUBLE,MPI_STATUS_IGNORE,ierr)
|
||||||
call MPI_File_close(fileUnit,ierr)
|
call MPI_File_close(fileUnit,ierr)
|
||||||
endif restartRead2
|
endif restartRead2
|
||||||
|
|
||||||
call utilities_updateGamma(C_minMaxAvg)
|
call utilities_updateGamma(C_minMaxAvg)
|
||||||
call utilities_saveReferenceStiffness
|
call utilities_saveReferenceStiffness
|
||||||
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_mech_spectral_polarisation_init
|
||||||
|
|
||||||
|
|
||||||
|
@ -229,9 +229,9 @@ function grid_mech_spectral_polarisation_solution(incInfoIn,timeinc,timeinc_old,
|
||||||
solution
|
solution
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! PETSc Data
|
! PETSc Data
|
||||||
PetscErrorCode :: ierr
|
PetscErrorCode :: ierr
|
||||||
SNESConvergedReason :: reason
|
SNESConvergedReason :: reason
|
||||||
|
|
||||||
incInfo = incInfoIn
|
incInfo = incInfoIn
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
@ -241,10 +241,10 @@ function grid_mech_spectral_polarisation_solution(incInfoIn,timeinc,timeinc_old,
|
||||||
call utilities_updateGamma(C_minMaxAvg)
|
call utilities_updateGamma(C_minMaxAvg)
|
||||||
C_scale = C_minMaxAvg
|
C_scale = C_minMaxAvg
|
||||||
S_scale = math_invSym3333(C_minMaxAvg)
|
S_scale = math_invSym3333(C_minMaxAvg)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! set module wide available data
|
! set module wide available data
|
||||||
params%stress_mask = stress_BC%maskFloat
|
params%stress_mask = stress_BC%maskFloat
|
||||||
params%stress_BC = stress_BC%values
|
params%stress_BC = stress_BC%values
|
||||||
params%rotation_BC = rotation_BC
|
params%rotation_BC = rotation_BC
|
||||||
|
@ -252,13 +252,13 @@ function grid_mech_spectral_polarisation_solution(incInfoIn,timeinc,timeinc_old,
|
||||||
params%timeincOld = timeinc_old
|
params%timeincOld = timeinc_old
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! solve BVP
|
! solve BVP
|
||||||
call SNESsolve(snes,PETSC_NULL_VEC,solution_vec,ierr); CHKERRQ(ierr)
|
call SNESsolve(snes,PETSC_NULL_VEC,solution_vec,ierr); CHKERRQ(ierr)
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! check convergence
|
! check convergence
|
||||||
call SNESGetConvergedReason(snes,reason,ierr); CHKERRQ(ierr)
|
call SNESGetConvergedReason(snes,reason,ierr); CHKERRQ(ierr)
|
||||||
|
|
||||||
solution%converged = reason > 0
|
solution%converged = reason > 0
|
||||||
solution%iterationsNeeded = totalIter
|
solution%iterationsNeeded = totalIter
|
||||||
solution%termIll = terminallyIll
|
solution%termIll = terminallyIll
|
||||||
|
@ -299,7 +299,7 @@ subroutine grid_mech_spectral_polarisation_forward(cutBack,guess,timeinc,timeinc
|
||||||
if (cutBack) then
|
if (cutBack) then
|
||||||
C_volAvg = C_volAvgLastInc
|
C_volAvg = C_volAvgLastInc
|
||||||
C_minMaxAvg = C_minMaxAvgLastInc
|
C_minMaxAvg = C_minMaxAvgLastInc
|
||||||
else
|
else
|
||||||
C_volAvgLastInc = C_volAvg
|
C_volAvgLastInc = C_volAvg
|
||||||
C_minMaxAvgLastInc = C_minMaxAvg
|
C_minMaxAvgLastInc = C_minMaxAvg
|
||||||
|
|
||||||
|
@ -321,13 +321,13 @@ subroutine grid_mech_spectral_polarisation_forward(cutBack,guess,timeinc,timeinc
|
||||||
|
|
||||||
Fdot = utilities_calculateRate(guess, &
|
Fdot = utilities_calculateRate(guess, &
|
||||||
F_lastInc,reshape(F,[3,3,grid(1),grid(2),grid3]),timeinc_old, &
|
F_lastInc,reshape(F,[3,3,grid(1),grid(2),grid3]),timeinc_old, &
|
||||||
rotation_BC%rotTensor2(F_aimDot,active=.true.))
|
rotation_BC%rotate(F_aimDot,active=.true.))
|
||||||
F_tauDot = utilities_calculateRate(guess, &
|
F_tauDot = utilities_calculateRate(guess, &
|
||||||
F_tau_lastInc,reshape(F_tau,[3,3,grid(1),grid(2),grid3]), timeinc_old, &
|
F_tau_lastInc,reshape(F_tau,[3,3,grid(1),grid(2),grid3]), timeinc_old, &
|
||||||
rotation_BC%rotTensor2(F_aimDot,active=.true.))
|
rotation_BC%rotate(F_aimDot,active=.true.))
|
||||||
F_lastInc = reshape(F, [3,3,grid(1),grid(2),grid3])
|
F_lastInc = reshape(F, [3,3,grid(1),grid(2),grid3])
|
||||||
F_tau_lastInc = reshape(F_tau,[3,3,grid(1),grid(2),grid3])
|
F_tau_lastInc = reshape(F_tau,[3,3,grid(1),grid(2),grid3])
|
||||||
|
|
||||||
materialpoint_F0 = reshape(F,[3,3,1,product(grid(1:2))*grid3])
|
materialpoint_F0 = reshape(F,[3,3,1,product(grid(1:2))*grid3])
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
@ -335,7 +335,7 @@ subroutine grid_mech_spectral_polarisation_forward(cutBack,guess,timeinc,timeinc
|
||||||
! update average and local deformation gradients
|
! update average and local deformation gradients
|
||||||
F_aim = F_aim_lastInc + F_aimDot * timeinc
|
F_aim = F_aim_lastInc + F_aimDot * timeinc
|
||||||
F = reshape(utilities_forwardField(timeinc,F_lastInc,Fdot, & ! estimate of F at end of time+timeinc that matches rotated F_aim on average
|
F = reshape(utilities_forwardField(timeinc,F_lastInc,Fdot, & ! estimate of F at end of time+timeinc that matches rotated F_aim on average
|
||||||
rotation_BC%rotTensor2(F_aim,active=.true.)),&
|
rotation_BC%rotate(F_aim,active=.true.)),&
|
||||||
[9,grid(1),grid(2),grid3])
|
[9,grid(1),grid(2),grid3])
|
||||||
if (guess) then
|
if (guess) then
|
||||||
F_tau = reshape(Utilities_forwardField(timeinc,F_tau_lastInc,F_taudot), &
|
F_tau = reshape(Utilities_forwardField(timeinc,F_tau_lastInc,F_taudot), &
|
||||||
|
@ -351,7 +351,7 @@ subroutine grid_mech_spectral_polarisation_forward(cutBack,guess,timeinc,timeinc
|
||||||
F_tau(1:9,i,j,k) = reshape(F_lambda33,[9])+F(1:9,i,j,k)
|
F_tau(1:9,i,j,k) = reshape(F_lambda33,[9])+F(1:9,i,j,k)
|
||||||
enddo; enddo; enddo
|
enddo; enddo; enddo
|
||||||
endif
|
endif
|
||||||
|
|
||||||
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_forward
|
end subroutine grid_mech_spectral_polarisation_forward
|
||||||
|
@ -364,7 +364,7 @@ subroutine grid_mech_spectral_polarisation_updateCoords
|
||||||
|
|
||||||
PetscErrorCode :: ierr
|
PetscErrorCode :: ierr
|
||||||
PetscScalar, dimension(:,:,:,:), pointer :: FandF_tau
|
PetscScalar, dimension(:,:,:,:), pointer :: FandF_tau
|
||||||
|
|
||||||
call DMDAVecGetArrayF90(da,solution_vec,FandF_tau,ierr); CHKERRQ(ierr)
|
call DMDAVecGetArrayF90(da,solution_vec,FandF_tau,ierr); CHKERRQ(ierr)
|
||||||
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)
|
||||||
|
@ -391,7 +391,7 @@ subroutine grid_mech_spectral_polarisation_restartWrite
|
||||||
write(fileName,'(a,a,i0,a)') trim(getSolverJobName()),'_',worldrank,'.hdf5'
|
write(fileName,'(a,a,i0,a)') trim(getSolverJobName()),'_',worldrank,'.hdf5'
|
||||||
fileHandle = HDF5_openFile(fileName,'w')
|
fileHandle = HDF5_openFile(fileName,'w')
|
||||||
groupHandle = HDF5_addGroup(fileHandle,'solver')
|
groupHandle = HDF5_addGroup(fileHandle,'solver')
|
||||||
|
|
||||||
call HDF5_write(groupHandle,F_aim, 'F_aim')
|
call HDF5_write(groupHandle,F_aim, 'F_aim')
|
||||||
call HDF5_write(groupHandle,F_aim_lastInc,'F_aim_lastInc')
|
call HDF5_write(groupHandle,F_aim_lastInc,'F_aim_lastInc')
|
||||||
call HDF5_write(groupHandle,F_aimDot, 'F_aimDot')
|
call HDF5_write(groupHandle,F_aimDot, 'F_aimDot')
|
||||||
|
@ -405,9 +405,9 @@ subroutine grid_mech_spectral_polarisation_restartWrite
|
||||||
|
|
||||||
call HDF5_closeGroup(groupHandle)
|
call HDF5_closeGroup(groupHandle)
|
||||||
call HDF5_closeFile(fileHandle)
|
call HDF5_closeFile(fileHandle)
|
||||||
|
|
||||||
if(num%update_gamma) call utilities_saveReferenceStiffness
|
if(num%update_gamma) call utilities_saveReferenceStiffness
|
||||||
|
|
||||||
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_mech_spectral_polarisation_restartWrite
|
||||||
|
@ -417,13 +417,13 @@ end subroutine grid_mech_spectral_polarisation_restartWrite
|
||||||
!> @brief convergence check
|
!> @brief convergence check
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
subroutine converged(snes_local,PETScIter,devNull1,devNull2,devNull3,reason,dummy,ierr)
|
subroutine converged(snes_local,PETScIter,devNull1,devNull2,devNull3,reason,dummy,ierr)
|
||||||
|
|
||||||
SNES :: snes_local
|
SNES :: snes_local
|
||||||
PetscInt, intent(in) :: PETScIter
|
PetscInt, intent(in) :: PETScIter
|
||||||
PetscReal, intent(in) :: &
|
PetscReal, intent(in) :: &
|
||||||
devNull1, &
|
devNull1, &
|
||||||
devNull2, &
|
devNull2, &
|
||||||
devNull3
|
devNull3
|
||||||
SNESConvergedReason :: reason
|
SNESConvergedReason :: reason
|
||||||
PetscObject :: dummy
|
PetscObject :: dummy
|
||||||
PetscErrorCode :: ierr
|
PetscErrorCode :: ierr
|
||||||
|
@ -431,11 +431,11 @@ subroutine converged(snes_local,PETScIter,devNull1,devNull2,devNull3,reason,dumm
|
||||||
curlTol, &
|
curlTol, &
|
||||||
divTol, &
|
divTol, &
|
||||||
BCTol
|
BCTol
|
||||||
|
|
||||||
curlTol = max(maxval(abs(F_aim-math_I3))*err_curl_tolRel ,err_curl_tolAbs)
|
curlTol = max(maxval(abs(F_aim-math_I3))*err_curl_tolRel ,err_curl_tolAbs)
|
||||||
divTol = max(maxval(abs(P_av)) *err_div_tolRel ,err_div_tolAbs)
|
divTol = max(maxval(abs(P_av)) *err_div_tolRel ,err_div_tolAbs)
|
||||||
BCTol = max(maxval(abs(P_av)) *err_stress_tolRel,err_stress_tolAbs)
|
BCTol = max(maxval(abs(P_av)) *err_stress_tolRel,err_stress_tolAbs)
|
||||||
|
|
||||||
if ((totalIter >= itmin .and. &
|
if ((totalIter >= itmin .and. &
|
||||||
all([ err_div /divTol, &
|
all([ err_div /divTol, &
|
||||||
err_curl/curlTol, &
|
err_curl/curlTol, &
|
||||||
|
@ -456,9 +456,9 @@ subroutine converged(snes_local,PETScIter,devNull1,devNull2,devNull3,reason,dumm
|
||||||
write(6, '(a,f12.2,a,es8.2,a,es9.2,a)') ' error curl = ', &
|
write(6, '(a,f12.2,a,es8.2,a,es9.2,a)') ' error curl = ', &
|
||||||
err_curl/curlTol,' (',err_curl,' -, tol = ',curlTol,')'
|
err_curl/curlTol,' (',err_curl,' -, tol = ',curlTol,')'
|
||||||
write(6, '(a,f12.2,a,es8.2,a,es9.2,a)') ' error BC = ', &
|
write(6, '(a,f12.2,a,es8.2,a,es9.2,a)') ' error BC = ', &
|
||||||
err_BC/BCTol, ' (',err_BC, ' Pa, tol = ',BCTol,')'
|
err_BC/BCTol, ' (',err_BC, ' Pa, tol = ',BCTol,')'
|
||||||
write(6,'(/,a)') ' ==========================================================================='
|
write(6,'(/,a)') ' ==========================================================================='
|
||||||
flush(6)
|
flush(6)
|
||||||
|
|
||||||
end subroutine converged
|
end subroutine converged
|
||||||
|
|
||||||
|
@ -498,7 +498,7 @@ subroutine formResidual(in, FandF_tau, &
|
||||||
|
|
||||||
F_av = sum(sum(sum(F,dim=5),dim=4),dim=3) * wgt
|
F_av = sum(sum(sum(F,dim=5),dim=4),dim=3) * wgt
|
||||||
call MPI_Allreduce(MPI_IN_PLACE,F_av,9,MPI_DOUBLE,MPI_SUM,PETSC_COMM_WORLD,ierr)
|
call MPI_Allreduce(MPI_IN_PLACE,F_av,9,MPI_DOUBLE,MPI_SUM,PETSC_COMM_WORLD,ierr)
|
||||||
|
|
||||||
call SNESGetNumberFunctionEvals(snes,nfuncs,ierr); CHKERRQ(ierr)
|
call SNESGetNumberFunctionEvals(snes,nfuncs,ierr); CHKERRQ(ierr)
|
||||||
call SNESGetIterationNumber(snes,PETScIter,ierr); CHKERRQ(ierr)
|
call SNESGetIterationNumber(snes,PETScIter,ierr); CHKERRQ(ierr)
|
||||||
|
|
||||||
|
@ -510,14 +510,14 @@ subroutine formResidual(in, FandF_tau, &
|
||||||
write(6,'(1x,a,3(a,i0))') trim(incInfo), ' @ Iteration ', itmin, '≤',totalIter, '≤', itmax
|
write(6,'(1x,a,3(a,i0))') trim(incInfo), ' @ Iteration ', itmin, '≤',totalIter, '≤', itmax
|
||||||
if (iand(debug_level(debug_spectral),debug_spectralRotation) /= 0) &
|
if (iand(debug_level(debug_spectral),debug_spectralRotation) /= 0) &
|
||||||
write(6,'(/,a,/,3(3(f12.7,1x)/))',advance='no') &
|
write(6,'(/,a,/,3(3(f12.7,1x)/))',advance='no') &
|
||||||
' deformation gradient aim (lab) =', transpose(params%rotation_BC%rotTensor2(F_aim,active=.true.))
|
' deformation gradient aim (lab) =', transpose(params%rotation_BC%rotate(F_aim,active=.true.))
|
||||||
write(6,'(/,a,/,3(3(f12.7,1x)/))',advance='no') &
|
write(6,'(/,a,/,3(3(f12.7,1x)/))',advance='no') &
|
||||||
' deformation gradient aim =', transpose(F_aim)
|
' deformation gradient aim =', transpose(F_aim)
|
||||||
flush(6)
|
flush(6)
|
||||||
endif newIteration
|
endif newIteration
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!
|
!
|
||||||
tensorField_real = 0.0_pReal
|
tensorField_real = 0.0_pReal
|
||||||
do k = 1, grid3; do j = 1, grid(2); do i = 1, grid(1)
|
do k = 1, grid3; do j = 1, grid(2); do i = 1, grid(1)
|
||||||
tensorField_real(1:3,1:3,i,j,k) = &
|
tensorField_real(1:3,1:3,i,j,k) = &
|
||||||
|
@ -525,15 +525,15 @@ subroutine formResidual(in, FandF_tau, &
|
||||||
polarAlpha*matmul(F(1:3,1:3,i,j,k), &
|
polarAlpha*matmul(F(1:3,1:3,i,j,k), &
|
||||||
math_mul3333xx33(C_scale,F_tau(1:3,1:3,i,j,k) - F(1:3,1:3,i,j,k) - math_I3))
|
math_mul3333xx33(C_scale,F_tau(1:3,1:3,i,j,k) - F(1:3,1:3,i,j,k) - math_I3))
|
||||||
enddo; enddo; enddo
|
enddo; enddo; enddo
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! doing convolution in Fourier space
|
! doing convolution in Fourier space
|
||||||
call utilities_FFTtensorForward
|
call utilities_FFTtensorForward
|
||||||
call utilities_fourierGammaConvolution(params%rotation_BC%rotTensor2(polarBeta*F_aim,active=.true.))
|
call utilities_fourierGammaConvolution(params%rotation_BC%rotate(polarBeta*F_aim,active=.true.))
|
||||||
call utilities_FFTtensorBackward
|
call utilities_FFTtensorBackward
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! constructing residual
|
! constructing residual
|
||||||
residual_F_tau = polarBeta*F - tensorField_real(1:3,1:3,1:grid(1),1:grid(2),1:grid3)
|
residual_F_tau = polarBeta*F - tensorField_real(1:3,1:3,1:grid(1),1:grid(2),1:grid3)
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
@ -541,13 +541,13 @@ subroutine formResidual(in, FandF_tau, &
|
||||||
call utilities_constitutiveResponse(residual_F, & ! "residuum" gets field of first PK stress (to save memory)
|
call utilities_constitutiveResponse(residual_F, & ! "residuum" gets field of first PK stress (to save memory)
|
||||||
P_av,C_volAvg,C_minMaxAvg, &
|
P_av,C_volAvg,C_minMaxAvg, &
|
||||||
F - residual_F_tau/polarBeta,params%timeinc,params%rotation_BC)
|
F - residual_F_tau/polarBeta,params%timeinc,params%rotation_BC)
|
||||||
call MPI_Allreduce(MPI_IN_PLACE,terminallyIll,1,MPI_LOGICAL,MPI_LOR,PETSC_COMM_WORLD,ierr)
|
call MPI_Allreduce(MPI_IN_PLACE,terminallyIll,1,MPI_LOGICAL,MPI_LOR,PETSC_COMM_WORLD,ierr)
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! stress BC handling
|
! stress BC handling
|
||||||
F_aim = F_aim - math_mul3333xx33(S, ((P_av - params%stress_BC))) ! S = 0.0 for no bc
|
F_aim = F_aim - math_mul3333xx33(S, ((P_av - params%stress_BC))) ! S = 0.0 for no bc
|
||||||
err_BC = maxval(abs((1.0_pReal-params%stress_mask) * math_mul3333xx33(C_scale,F_aim &
|
err_BC = maxval(abs((1.0_pReal-params%stress_mask) * math_mul3333xx33(C_scale,F_aim &
|
||||||
-params%rotation_BC%rotTensor2(F_av)) + &
|
-params%rotation_BC%rotate(F_av)) + &
|
||||||
params%stress_mask * (P_av-params%stress_BC))) ! mask = 0.0 for no bc
|
params%stress_mask * (P_av-params%stress_BC))) ! mask = 0.0 for no bc
|
||||||
! calculate divergence
|
! calculate divergence
|
||||||
tensorField_real = 0.0_pReal
|
tensorField_real = 0.0_pReal
|
||||||
|
@ -566,7 +566,7 @@ subroutine formResidual(in, FandF_tau, &
|
||||||
math_mul3333xx33(C_scale,F_tau(1:3,1:3,i,j,k) - F(1:3,1:3,i,j,k) - math_I3))) &
|
math_mul3333xx33(C_scale,F_tau(1:3,1:3,i,j,k) - F(1:3,1:3,i,j,k) - math_I3))) &
|
||||||
+ residual_F_tau(1:3,1:3,i,j,k)
|
+ residual_F_tau(1:3,1:3,i,j,k)
|
||||||
enddo; enddo; enddo
|
enddo; enddo; enddo
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! calculating curl
|
! calculating curl
|
||||||
tensorField_real = 0.0_pReal
|
tensorField_real = 0.0_pReal
|
||||||
|
|
|
@ -18,12 +18,12 @@ module spectral_utilities
|
||||||
use config
|
use config
|
||||||
use discretization
|
use discretization
|
||||||
use homogenization
|
use homogenization
|
||||||
|
|
||||||
implicit none
|
implicit none
|
||||||
private
|
private
|
||||||
|
|
||||||
include 'fftw3-mpi.f03'
|
include 'fftw3-mpi.f03'
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! field labels information
|
! field labels information
|
||||||
enum, bind(c)
|
enum, bind(c)
|
||||||
|
@ -109,8 +109,8 @@ module spectral_utilities
|
||||||
real(pReal) :: timeinc
|
real(pReal) :: timeinc
|
||||||
real(pReal) :: timeincOld
|
real(pReal) :: timeincOld
|
||||||
end type tSolutionParams
|
end type tSolutionParams
|
||||||
|
|
||||||
type, private :: tNumerics
|
type, private :: tNumerics
|
||||||
real(pReal) :: &
|
real(pReal) :: &
|
||||||
FFTW_timelimit !< timelimit for FFTW plan creation, see www.fftw.org
|
FFTW_timelimit !< timelimit for FFTW plan creation, see www.fftw.org
|
||||||
integer :: &
|
integer :: &
|
||||||
|
@ -122,7 +122,7 @@ module spectral_utilities
|
||||||
FFTW_plan_mode, & !< FFTW plan mode, see www.fftw.org
|
FFTW_plan_mode, & !< FFTW plan mode, see www.fftw.org
|
||||||
PETSc_options
|
PETSc_options
|
||||||
end type tNumerics
|
end type tNumerics
|
||||||
|
|
||||||
type(tNumerics) :: num ! numerics parameters. Better name?
|
type(tNumerics) :: num ! numerics parameters. Better name?
|
||||||
|
|
||||||
enum, bind(c)
|
enum, bind(c)
|
||||||
|
@ -189,18 +189,18 @@ subroutine utilities_init
|
||||||
scalarSize = 1_C_INTPTR_T, &
|
scalarSize = 1_C_INTPTR_T, &
|
||||||
vecSize = 3_C_INTPTR_T, &
|
vecSize = 3_C_INTPTR_T, &
|
||||||
tensorSize = 9_C_INTPTR_T
|
tensorSize = 9_C_INTPTR_T
|
||||||
|
|
||||||
write(6,'(/,a)') ' <<<+- spectral_utilities init -+>>>'
|
write(6,'(/,a)') ' <<<+- spectral_utilities init -+>>>'
|
||||||
|
|
||||||
write(6,'(/,a)') ' Diehl, Diploma Thesis TU München, 2010'
|
write(6,'(/,a)') ' Diehl, Diploma Thesis TU München, 2010'
|
||||||
write(6,'(a)') ' https://doi.org/10.13140/2.1.3234.3840'
|
write(6,'(a)') ' https://doi.org/10.13140/2.1.3234.3840'
|
||||||
|
|
||||||
write(6,'(/,a)') ' Eisenlohr et al., International Journal of Plasticity 46:37–53, 2013'
|
write(6,'(/,a)') ' Eisenlohr et al., International Journal of Plasticity 46:37–53, 2013'
|
||||||
write(6,'(a)') ' https://doi.org/10.1016/j.ijplas.2012.09.012'
|
write(6,'(a)') ' https://doi.org/10.1016/j.ijplas.2012.09.012'
|
||||||
|
|
||||||
write(6,'(/,a)') ' Shanthraj et al., International Journal of Plasticity 66:31–45, 2015'
|
write(6,'(/,a)') ' Shanthraj et al., International Journal of Plasticity 66:31–45, 2015'
|
||||||
write(6,'(a)') ' https://doi.org/10.1016/j.ijplas.2014.02.006'
|
write(6,'(a)') ' https://doi.org/10.1016/j.ijplas.2014.02.006'
|
||||||
|
|
||||||
write(6,'(/,a)') ' Shanthraj et al., Handbook of Mechanics of Materials, 2019'
|
write(6,'(/,a)') ' Shanthraj et al., Handbook of Mechanics of Materials, 2019'
|
||||||
write(6,'(a)') ' https://doi.org/10.1007/978-981-10-6855-3_80'
|
write(6,'(a)') ' https://doi.org/10.1007/978-981-10-6855-3_80'
|
||||||
|
|
||||||
|
@ -209,34 +209,34 @@ subroutine utilities_init
|
||||||
debugGeneral = iand(debug_level(debug_SPECTRAL),debug_LEVELBASIC) /= 0
|
debugGeneral = iand(debug_level(debug_SPECTRAL),debug_LEVELBASIC) /= 0
|
||||||
debugRotation = iand(debug_level(debug_SPECTRAL),debug_SPECTRALROTATION) /= 0
|
debugRotation = iand(debug_level(debug_SPECTRAL),debug_SPECTRALROTATION) /= 0
|
||||||
debugPETSc = iand(debug_level(debug_SPECTRAL),debug_SPECTRALPETSC) /= 0
|
debugPETSc = iand(debug_level(debug_SPECTRAL),debug_SPECTRALPETSC) /= 0
|
||||||
|
|
||||||
if(debugPETSc) write(6,'(3(/,a),/)') &
|
if(debugPETSc) write(6,'(3(/,a),/)') &
|
||||||
' Initializing PETSc with debug options: ', &
|
' Initializing PETSc with debug options: ', &
|
||||||
trim(PETScDebug), &
|
trim(PETScDebug), &
|
||||||
' add more using the PETSc_Options keyword in numerics.config '; flush(6)
|
' add more using the PETSc_Options keyword in numerics.config '; flush(6)
|
||||||
|
|
||||||
call PETScOptionsClear(PETSC_NULL_OPTIONS,ierr)
|
call PETScOptionsClear(PETSC_NULL_OPTIONS,ierr)
|
||||||
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,trim(petsc_options),ierr)
|
call PETScOptionsInsertString(PETSC_NULL_OPTIONS,trim(petsc_options),ierr)
|
||||||
CHKERRQ(ierr)
|
CHKERRQ(ierr)
|
||||||
|
|
||||||
grid1Red = grid(1)/2 + 1
|
grid1Red = grid(1)/2 + 1
|
||||||
wgt = 1.0/real(product(grid),pReal)
|
wgt = 1.0/real(product(grid),pReal)
|
||||||
|
|
||||||
write(6,'(/,a,3(i12 ))') ' grid a b c: ', grid
|
write(6,'(/,a,3(i12 ))') ' grid a b c: ', grid
|
||||||
write(6,'(a,3(es12.5))') ' size x y z: ', geomSize
|
write(6,'(a,3(es12.5))') ' size x y z: ', geomSize
|
||||||
|
|
||||||
num%memory_efficient = config_numerics%getInt ('memory_efficient', defaultVal=1) > 0
|
num%memory_efficient = config_numerics%getInt ('memory_efficient', defaultVal=1) > 0
|
||||||
num%FFTW_timelimit = config_numerics%getFloat ('fftw_timelimit', defaultVal=-1.0_pReal)
|
num%FFTW_timelimit = config_numerics%getFloat ('fftw_timelimit', defaultVal=-1.0_pReal)
|
||||||
num%divergence_correction = config_numerics%getInt ('divergence_correction', defaultVal=2)
|
num%divergence_correction = config_numerics%getInt ('divergence_correction', defaultVal=2)
|
||||||
num%spectral_derivative = config_numerics%getString('spectral_derivative', defaultVal='continuous')
|
num%spectral_derivative = config_numerics%getString('spectral_derivative', defaultVal='continuous')
|
||||||
num%FFTW_plan_mode = config_numerics%getString('fftw_plan_mode', defaultVal='FFTW_MEASURE')
|
num%FFTW_plan_mode = config_numerics%getString('fftw_plan_mode', defaultVal='FFTW_MEASURE')
|
||||||
|
|
||||||
if (num%divergence_correction < 0 .or. num%divergence_correction > 2) &
|
if (num%divergence_correction < 0 .or. num%divergence_correction > 2) &
|
||||||
call IO_error(301,ext_msg='divergence_correction')
|
call IO_error(301,ext_msg='divergence_correction')
|
||||||
|
|
||||||
select case (num%spectral_derivative)
|
select case (num%spectral_derivative)
|
||||||
case ('continuous')
|
case ('continuous')
|
||||||
spectral_derivative_ID = DERIVATIVE_CONTINUOUS_ID
|
spectral_derivative_ID = DERIVATIVE_CONTINUOUS_ID
|
||||||
|
@ -265,8 +265,8 @@ subroutine utilities_init
|
||||||
else
|
else
|
||||||
scaledGeomSize = geomSize
|
scaledGeomSize = geomSize
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
||||||
select case(IO_lc(num%FFTW_plan_mode)) ! setting parameters for the plan creation of FFTW. Basically a translation from fftw3.f
|
select case(IO_lc(num%FFTW_plan_mode)) ! setting parameters for the plan creation of FFTW. Basically a translation from fftw3.f
|
||||||
case('fftw_estimate') ! ordered from slow execution (but fast plan creation) to fast execution
|
case('fftw_estimate') ! ordered from slow execution (but fast plan creation) to fast execution
|
||||||
FFTW_planner_flag = FFTW_ESTIMATE
|
FFTW_planner_flag = FFTW_ESTIMATE
|
||||||
|
@ -285,7 +285,7 @@ subroutine utilities_init
|
||||||
! general initialization of FFTW (see manual on fftw.org for more details)
|
! general initialization of FFTW (see manual on fftw.org for more details)
|
||||||
if (pReal /= C_DOUBLE .or. kind(1) /= C_INT) call IO_error(0,ext_msg='Fortran to C') ! check for correct precision in C
|
if (pReal /= C_DOUBLE .or. kind(1) /= C_INT) call IO_error(0,ext_msg='Fortran to C') ! check for correct precision in C
|
||||||
call fftw_set_timelimit(num%FFTW_timelimit) ! set timelimit for plan creation
|
call fftw_set_timelimit(num%FFTW_timelimit) ! set timelimit for plan creation
|
||||||
|
|
||||||
if (debugGeneral) write(6,'(/,a)') ' FFTW initialized'; flush(6)
|
if (debugGeneral) write(6,'(/,a)') ' FFTW initialized'; flush(6)
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
@ -295,19 +295,19 @@ subroutine utilities_init
|
||||||
PETSC_COMM_WORLD, local_K, local_K_offset)
|
PETSC_COMM_WORLD, local_K, local_K_offset)
|
||||||
allocate (xi1st (3,grid1Red,grid(2),grid3),source = cmplx(0.0_pReal,0.0_pReal,pReal)) ! frequencies for first derivatives, only half the size for first dimension
|
allocate (xi1st (3,grid1Red,grid(2),grid3),source = cmplx(0.0_pReal,0.0_pReal,pReal)) ! frequencies for first derivatives, only half the size for first dimension
|
||||||
allocate (xi2nd (3,grid1Red,grid(2),grid3),source = cmplx(0.0_pReal,0.0_pReal,pReal)) ! frequencies for second derivatives, only half the size for first dimension
|
allocate (xi2nd (3,grid1Red,grid(2),grid3),source = cmplx(0.0_pReal,0.0_pReal,pReal)) ! frequencies for second derivatives, only half the size for first dimension
|
||||||
|
|
||||||
tensorField = fftw_alloc_complex(tensorSize*alloc_local)
|
tensorField = fftw_alloc_complex(tensorSize*alloc_local)
|
||||||
call c_f_pointer(tensorField, tensorField_real, [3_C_INTPTR_T,3_C_INTPTR_T, &
|
call c_f_pointer(tensorField, tensorField_real, [3_C_INTPTR_T,3_C_INTPTR_T, &
|
||||||
2_C_INTPTR_T*(gridFFTW(1)/2_C_INTPTR_T + 1_C_INTPTR_T),gridFFTW(2),local_K]) ! place a pointer for a real tensor representation
|
2_C_INTPTR_T*(gridFFTW(1)/2_C_INTPTR_T + 1_C_INTPTR_T),gridFFTW(2),local_K]) ! place a pointer for a real tensor representation
|
||||||
call c_f_pointer(tensorField, tensorField_fourier, [3_C_INTPTR_T,3_C_INTPTR_T, &
|
call c_f_pointer(tensorField, tensorField_fourier, [3_C_INTPTR_T,3_C_INTPTR_T, &
|
||||||
gridFFTW(1)/2_C_INTPTR_T + 1_C_INTPTR_T , gridFFTW(2),local_K]) ! place a pointer for a fourier tensor representation
|
gridFFTW(1)/2_C_INTPTR_T + 1_C_INTPTR_T , gridFFTW(2),local_K]) ! place a pointer for a fourier tensor representation
|
||||||
|
|
||||||
vectorField = fftw_alloc_complex(vecSize*alloc_local)
|
vectorField = fftw_alloc_complex(vecSize*alloc_local)
|
||||||
call c_f_pointer(vectorField, vectorField_real, [3_C_INTPTR_T,&
|
call c_f_pointer(vectorField, vectorField_real, [3_C_INTPTR_T,&
|
||||||
2_C_INTPTR_T*(gridFFTW(1)/2_C_INTPTR_T + 1_C_INTPTR_T),gridFFTW(2),local_K]) ! place a pointer for a real vector representation
|
2_C_INTPTR_T*(gridFFTW(1)/2_C_INTPTR_T + 1_C_INTPTR_T),gridFFTW(2),local_K]) ! place a pointer for a real vector representation
|
||||||
call c_f_pointer(vectorField, vectorField_fourier,[3_C_INTPTR_T,&
|
call c_f_pointer(vectorField, vectorField_fourier,[3_C_INTPTR_T,&
|
||||||
gridFFTW(1)/2_C_INTPTR_T + 1_C_INTPTR_T, gridFFTW(2),local_K]) ! place a pointer for a fourier vector representation
|
gridFFTW(1)/2_C_INTPTR_T + 1_C_INTPTR_T, gridFFTW(2),local_K]) ! place a pointer for a fourier vector representation
|
||||||
|
|
||||||
scalarField = fftw_alloc_complex(scalarSize*alloc_local) ! allocate data for real representation (no in place transform)
|
scalarField = fftw_alloc_complex(scalarSize*alloc_local) ! allocate data for real representation (no in place transform)
|
||||||
call c_f_pointer(scalarField, scalarField_real, &
|
call c_f_pointer(scalarField, scalarField_real, &
|
||||||
[2_C_INTPTR_T*(gridFFTW(1)/2_C_INTPTR_T + 1),gridFFTW(2),local_K]) ! place a pointer for a real scalar representation
|
[2_C_INTPTR_T*(gridFFTW(1)/2_C_INTPTR_T + 1),gridFFTW(2),local_K]) ! place a pointer for a real scalar representation
|
||||||
|
@ -371,7 +371,7 @@ subroutine utilities_init
|
||||||
xi1st(1:3,i,j,k-grid3Offset) = xi2nd(1:3,i,j,k-grid3Offset)
|
xi1st(1:3,i,j,k-grid3Offset) = xi2nd(1:3,i,j,k-grid3Offset)
|
||||||
endwhere
|
endwhere
|
||||||
enddo; enddo; enddo
|
enddo; enddo; enddo
|
||||||
|
|
||||||
if(num%memory_efficient) then ! allocate just single fourth order tensor
|
if(num%memory_efficient) then ! allocate just single fourth order tensor
|
||||||
allocate (gamma_hat(3,3,3,3,1,1,1), source = cmplx(0.0_pReal,0.0_pReal,pReal))
|
allocate (gamma_hat(3,3,3,3,1,1,1), source = cmplx(0.0_pReal,0.0_pReal,pReal))
|
||||||
else ! precalculation of gamma_hat field
|
else ! precalculation of gamma_hat field
|
||||||
|
@ -388,7 +388,7 @@ end subroutine utilities_init
|
||||||
!> In case of an on-the-fly calculation, only the reference stiffness is updated.
|
!> In case of an on-the-fly calculation, only the reference stiffness is updated.
|
||||||
!---------------------------------------------------------------------------------------------------
|
!---------------------------------------------------------------------------------------------------
|
||||||
subroutine utilities_updateGamma(C)
|
subroutine utilities_updateGamma(C)
|
||||||
|
|
||||||
real(pReal), intent(in), dimension(3,3,3,3) :: C !< input stiffness to store as reference stiffness
|
real(pReal), intent(in), dimension(3,3,3,3) :: C !< input stiffness to store as reference stiffness
|
||||||
complex(pReal), dimension(3,3) :: temp33_complex, xiDyad_cmplx
|
complex(pReal), dimension(3,3) :: temp33_complex, xiDyad_cmplx
|
||||||
real(pReal), dimension(6,6) :: A, A_inv
|
real(pReal), dimension(6,6) :: A, A_inv
|
||||||
|
@ -396,9 +396,9 @@ subroutine utilities_updateGamma(C)
|
||||||
i, j, k, &
|
i, j, k, &
|
||||||
l, m, n, o
|
l, m, n, o
|
||||||
logical :: err
|
logical :: err
|
||||||
|
|
||||||
C_ref = C
|
C_ref = C
|
||||||
|
|
||||||
if(.not. num%memory_efficient) then
|
if(.not. num%memory_efficient) then
|
||||||
gamma_hat = cmplx(0.0_pReal,0.0_pReal,pReal) ! for the singular point and any non invertible A
|
gamma_hat = cmplx(0.0_pReal,0.0_pReal,pReal) ! for the singular point and any non invertible A
|
||||||
do k = grid3Offset+1, grid3Offset+grid3; do j = 1, grid(2); do i = 1, grid1Red
|
do k = grid3Offset+1, grid3Offset+grid3; do j = 1, grid(2); do i = 1, grid1Red
|
||||||
|
@ -419,7 +419,7 @@ subroutine utilities_updateGamma(C)
|
||||||
endif
|
endif
|
||||||
enddo; enddo; enddo
|
enddo; enddo; enddo
|
||||||
endif
|
endif
|
||||||
|
|
||||||
end subroutine utilities_updateGamma
|
end subroutine utilities_updateGamma
|
||||||
|
|
||||||
|
|
||||||
|
@ -501,17 +501,17 @@ end subroutine utilities_FFTvectorBackward
|
||||||
!> @brief doing convolution gamma_hat * field_real, ensuring that average value = fieldAim
|
!> @brief doing convolution gamma_hat * field_real, ensuring that average value = fieldAim
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
subroutine utilities_fourierGammaConvolution(fieldAim)
|
subroutine utilities_fourierGammaConvolution(fieldAim)
|
||||||
|
|
||||||
real(pReal), intent(in), dimension(3,3) :: fieldAim !< desired average value of the field after convolution
|
real(pReal), intent(in), dimension(3,3) :: fieldAim !< desired average value of the field after convolution
|
||||||
complex(pReal), dimension(3,3) :: temp33_complex, xiDyad_cmplx
|
complex(pReal), dimension(3,3) :: temp33_complex, xiDyad_cmplx
|
||||||
real(pReal), dimension(6,6) :: A, A_inv
|
real(pReal), dimension(6,6) :: A, A_inv
|
||||||
|
|
||||||
integer :: &
|
integer :: &
|
||||||
i, j, k, &
|
i, j, k, &
|
||||||
l, m, n, o
|
l, m, n, o
|
||||||
logical :: err
|
logical :: err
|
||||||
|
|
||||||
|
|
||||||
write(6,'(/,a)') ' ... doing gamma convolution ...............................................'
|
write(6,'(/,a)') ' ... doing gamma convolution ...............................................'
|
||||||
flush(6)
|
flush(6)
|
||||||
|
|
||||||
|
@ -531,7 +531,7 @@ subroutine utilities_fourierGammaConvolution(fieldAim)
|
||||||
temp33_complex = cmplx(A_inv(1:3,1:3),A_inv(1:3,4:6),pReal)
|
temp33_complex = cmplx(A_inv(1:3,1:3),A_inv(1:3,4:6),pReal)
|
||||||
forall(l=1:3, m=1:3, n=1:3, o=1:3) &
|
forall(l=1:3, m=1:3, n=1:3, o=1:3) &
|
||||||
gamma_hat(l,m,n,o,1,1,1) = temp33_complex(l,n)*conjg(-xi1st(o,i,j,k))*xi1st(m,i,j,k)
|
gamma_hat(l,m,n,o,1,1,1) = temp33_complex(l,n)*conjg(-xi1st(o,i,j,k))*xi1st(m,i,j,k)
|
||||||
else
|
else
|
||||||
gamma_hat(1:3,1:3,1:3,1:3,1,1,1) = cmplx(0.0_pReal,0.0_pReal,pReal)
|
gamma_hat(1:3,1:3,1:3,1:3,1,1,1) = cmplx(0.0_pReal,0.0_pReal,pReal)
|
||||||
endif
|
endif
|
||||||
forall(l = 1:3, m = 1:3) &
|
forall(l = 1:3, m = 1:3) &
|
||||||
|
@ -546,7 +546,7 @@ subroutine utilities_fourierGammaConvolution(fieldAim)
|
||||||
tensorField_fourier(1:3,1:3,i,j,k) = temp33_Complex
|
tensorField_fourier(1:3,1:3,i,j,k) = temp33_Complex
|
||||||
enddo; enddo; enddo
|
enddo; enddo; enddo
|
||||||
endif memoryEfficient
|
endif memoryEfficient
|
||||||
|
|
||||||
if (grid3Offset == 0) tensorField_fourier(1:3,1:3,1,1,1) = cmplx(fieldAim/wgt,0.0_pReal,pReal)
|
if (grid3Offset == 0) tensorField_fourier(1:3,1:3,1,1,1) = cmplx(fieldAim/wgt,0.0_pReal,pReal)
|
||||||
|
|
||||||
end subroutine utilities_fourierGammaConvolution
|
end subroutine utilities_fourierGammaConvolution
|
||||||
|
@ -561,7 +561,7 @@ subroutine utilities_fourierGreenConvolution(D_ref, mobility_ref, deltaT)
|
||||||
real(pReal), intent(in) :: mobility_ref, deltaT
|
real(pReal), intent(in) :: mobility_ref, deltaT
|
||||||
complex(pReal) :: GreenOp_hat
|
complex(pReal) :: GreenOp_hat
|
||||||
integer :: i, j, k
|
integer :: i, j, k
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! do the actual spectral method calculation
|
! do the actual spectral method calculation
|
||||||
do k = 1, grid3; do j = 1, grid(2) ;do i = 1, grid1Red
|
do k = 1, grid3; do j = 1, grid(2) ;do i = 1, grid1Red
|
||||||
|
@ -625,16 +625,16 @@ real(pReal) function utilities_curlRMS()
|
||||||
integer :: i, j, k, l, ierr
|
integer :: i, j, k, l, ierr
|
||||||
complex(pReal), dimension(3,3) :: curl_fourier
|
complex(pReal), dimension(3,3) :: curl_fourier
|
||||||
complex(pReal), dimension(3) :: rescaledGeom
|
complex(pReal), dimension(3) :: rescaledGeom
|
||||||
|
|
||||||
write(6,'(/,a)') ' ... calculating curl ......................................................'
|
write(6,'(/,a)') ' ... calculating curl ......................................................'
|
||||||
flush(6)
|
flush(6)
|
||||||
|
|
||||||
rescaledGeom = cmplx(geomSize/scaledGeomSize,0.0_pReal)
|
rescaledGeom = cmplx(geomSize/scaledGeomSize,0.0_pReal)
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! calculating max curl criterion in Fourier space
|
! calculating max curl criterion in Fourier space
|
||||||
utilities_curlRMS = 0.0_pReal
|
utilities_curlRMS = 0.0_pReal
|
||||||
|
|
||||||
do k = 1, grid3; do j = 1, grid(2);
|
do k = 1, grid3; do j = 1, grid(2);
|
||||||
do i = 2, grid1Red - 1
|
do i = 2, grid1Red - 1
|
||||||
do l = 1, 3
|
do l = 1, 3
|
||||||
|
@ -669,7 +669,7 @@ real(pReal) function utilities_curlRMS()
|
||||||
utilities_curlRMS = utilities_curlRMS &
|
utilities_curlRMS = utilities_curlRMS &
|
||||||
+ sum(real(curl_fourier)**2.0_pReal + aimag(curl_fourier)**2.0_pReal) ! this layer (Nyquist) does not have a conjugate complex counterpart (if grid(1) /= 1)
|
+ sum(real(curl_fourier)**2.0_pReal + aimag(curl_fourier)**2.0_pReal) ! this layer (Nyquist) does not have a conjugate complex counterpart (if grid(1) /= 1)
|
||||||
enddo; enddo
|
enddo; enddo
|
||||||
|
|
||||||
call MPI_Allreduce(MPI_IN_PLACE,utilities_curlRMS,1,MPI_DOUBLE,MPI_SUM,PETSC_COMM_WORLD,ierr)
|
call MPI_Allreduce(MPI_IN_PLACE,utilities_curlRMS,1,MPI_DOUBLE,MPI_SUM,PETSC_COMM_WORLD,ierr)
|
||||||
if(ierr /=0) call IO_error(894, ext_msg='utilities_curlRMS')
|
if(ierr /=0) call IO_error(894, ext_msg='utilities_curlRMS')
|
||||||
utilities_curlRMS = sqrt(utilities_curlRMS) * wgt
|
utilities_curlRMS = sqrt(utilities_curlRMS) * wgt
|
||||||
|
@ -688,9 +688,10 @@ function utilities_maskedCompliance(rot_BC,mask_stress,C)
|
||||||
type(rotation), intent(in) :: rot_BC !< rotation of load frame
|
type(rotation), intent(in) :: rot_BC !< rotation of load frame
|
||||||
logical, intent(in), dimension(3,3) :: mask_stress !< mask of stress BC
|
logical, intent(in), dimension(3,3) :: mask_stress !< mask of stress BC
|
||||||
|
|
||||||
integer :: j, k, m, n
|
integer :: i, j
|
||||||
logical, dimension(9) :: mask_stressVector
|
logical, dimension(9) :: mask_stressVector
|
||||||
real(pReal), dimension(9,9) :: temp99_Real
|
logical, dimension(9,9) :: mask
|
||||||
|
real(pReal), dimension(9,9) :: temp99_real
|
||||||
integer :: size_reduced = 0
|
integer :: size_reduced = 0
|
||||||
real(pReal), dimension(:,:), allocatable :: &
|
real(pReal), dimension(:,:), allocatable :: &
|
||||||
s_reduced, & !< reduced compliance matrix (depending on number of stress BC)
|
s_reduced, & !< reduced compliance matrix (depending on number of stress BC)
|
||||||
|
@ -698,57 +699,33 @@ function utilities_maskedCompliance(rot_BC,mask_stress,C)
|
||||||
sTimesC !< temp variable to check inversion
|
sTimesC !< temp variable to check inversion
|
||||||
logical :: errmatinv
|
logical :: errmatinv
|
||||||
character(len=pStringLen):: formatString
|
character(len=pStringLen):: formatString
|
||||||
|
|
||||||
mask_stressVector = reshape(transpose(mask_stress), [9])
|
mask_stressVector = reshape(transpose(mask_stress), [9])
|
||||||
size_reduced = count(mask_stressVector)
|
size_reduced = count(mask_stressVector)
|
||||||
if(size_reduced > 0 )then
|
if(size_reduced > 0) then
|
||||||
allocate (c_reduced(size_reduced,size_reduced), source =0.0_pReal)
|
temp99_real = math_3333to99(rot_BC%rotate(C))
|
||||||
allocate (s_reduced(size_reduced,size_reduced), source =0.0_pReal)
|
|
||||||
allocate (sTimesC(size_reduced,size_reduced), source =0.0_pReal)
|
|
||||||
temp99_Real = math_3333to99(rot_BC%rotTensor4(C))
|
|
||||||
|
|
||||||
if(debugGeneral) then
|
if(debugGeneral) then
|
||||||
write(6,'(/,a)') ' ... updating masked compliance ............................................'
|
write(6,'(/,a)') ' ... updating masked compliance ............................................'
|
||||||
write(6,'(/,a,/,9(9(2x,f12.7,1x)/))',advance='no') ' Stiffness C (load) / GPa =',&
|
write(6,'(/,a,/,9(9(2x,f12.7,1x)/))',advance='no') ' Stiffness C (load) / GPa =',&
|
||||||
transpose(temp99_Real)*1.0e-9_pReal
|
transpose(temp99_Real)*1.0e-9_pReal
|
||||||
flush(6)
|
flush(6)
|
||||||
endif
|
endif
|
||||||
k = 0 ! calculate reduced stiffness
|
|
||||||
do n = 1,9
|
do i = 1,9; do j = 1,9
|
||||||
if(mask_stressVector(n)) then
|
mask(i,j) = mask_stressVector(i) .and. mask_stressVector(j)
|
||||||
k = k + 1
|
enddo; enddo
|
||||||
j = 0
|
c_reduced = reshape(pack(temp99_Real,mask),[size_reduced,size_reduced])
|
||||||
do m = 1,9
|
|
||||||
if(mask_stressVector(m)) then
|
allocate(s_reduced,mold = c_reduced)
|
||||||
j = j + 1
|
|
||||||
c_reduced(k,j) = temp99_Real(n,m)
|
|
||||||
endif; enddo; endif; enddo
|
|
||||||
|
|
||||||
call math_invert(s_reduced, errmatinv, c_reduced) ! invert reduced stiffness
|
call math_invert(s_reduced, errmatinv, c_reduced) ! invert reduced stiffness
|
||||||
if (any(IEEE_is_NaN(s_reduced))) errmatinv = .true.
|
if (any(IEEE_is_NaN(s_reduced))) errmatinv = .true.
|
||||||
if (errmatinv) call IO_error(error_ID=400,ext_msg='utilities_maskedCompliance')
|
if (errmatinv) call IO_error(error_ID=400,ext_msg='utilities_maskedCompliance')
|
||||||
temp99_Real = 0.0_pReal ! fill up compliance with zeros
|
|
||||||
k = 0
|
|
||||||
do n = 1,9
|
|
||||||
if(mask_stressVector(n)) then
|
|
||||||
k = k + 1
|
|
||||||
j = 0
|
|
||||||
do m = 1,9
|
|
||||||
if(mask_stressVector(m)) then
|
|
||||||
j = j + 1
|
|
||||||
temp99_Real(n,m) = s_reduced(k,j)
|
|
||||||
endif; enddo; endif; enddo
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! check if inversion was successful
|
! check if inversion was successful
|
||||||
sTimesC = matmul(c_reduced,s_reduced)
|
sTimesC = matmul(c_reduced,s_reduced)
|
||||||
do m=1, size_reduced
|
errmatinv = errmatinv .or. any(dNeq(sTimesC,math_identity2nd(size_reduced),1.0e-12_pReal))
|
||||||
do n=1, size_reduced
|
|
||||||
errmatinv = errmatinv &
|
|
||||||
.or. (m==n .and. abs(sTimesC(m,n)-1.0_pReal) > 1.0e-12_pReal) & ! diagonal elements of S*C should be 1
|
|
||||||
.or. (m/=n .and. abs(sTimesC(m,n)) > 1.0e-12_pReal) ! off-diagonal elements of S*C should be 0
|
|
||||||
enddo
|
|
||||||
enddo
|
|
||||||
if (debugGeneral .or. errmatinv) then
|
if (debugGeneral .or. errmatinv) then
|
||||||
write(formatString, '(i2)') size_reduced
|
write(formatString, '(i2)') size_reduced
|
||||||
formatString = '(/,a,/,'//trim(formatString)//'('//trim(formatString)//'(2x,es9.2,1x)/))'
|
formatString = '(/,a,/,'//trim(formatString)//'('//trim(formatString)//'(2x,es9.2,1x)/))'
|
||||||
|
@ -757,15 +734,18 @@ function utilities_maskedCompliance(rot_BC,mask_stress,C)
|
||||||
write(6,trim(formatString),advance='no') ' S (load) ', transpose(s_reduced)
|
write(6,trim(formatString),advance='no') ' S (load) ', transpose(s_reduced)
|
||||||
if(errmatinv) call IO_error(error_ID=400,ext_msg='utilities_maskedCompliance')
|
if(errmatinv) call IO_error(error_ID=400,ext_msg='utilities_maskedCompliance')
|
||||||
endif
|
endif
|
||||||
|
temp99_real = reshape(unpack(reshape(s_reduced,[size_reduced**2]),reshape(mask,[81]),0.0_pReal),[9,9])
|
||||||
else
|
else
|
||||||
temp99_real = 0.0_pReal
|
temp99_real = 0.0_pReal
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
utilities_maskedCompliance = math_99to3333(temp99_Real)
|
||||||
|
|
||||||
if(debugGeneral) then
|
if(debugGeneral) then
|
||||||
write(6,'(/,a,/,9(9(2x,f10.5,1x)/),/)',advance='no') &
|
write(6,'(/,a,/,9(9(2x,f10.5,1x)/),/)',advance='no') &
|
||||||
' Masked Compliance (load) * GPa =', transpose(temp99_Real)*1.0e9_pReal
|
' Masked Compliance (load) * GPa =', transpose(temp99_Real)*1.0e9_pReal
|
||||||
flush(6)
|
flush(6)
|
||||||
endif
|
endif
|
||||||
utilities_maskedCompliance = math_99to3333(temp99_Real)
|
|
||||||
|
|
||||||
end function utilities_maskedCompliance
|
end function utilities_maskedCompliance
|
||||||
|
|
||||||
|
@ -774,9 +754,9 @@ end function utilities_maskedCompliance
|
||||||
!> @brief calculate scalar gradient in fourier field
|
!> @brief calculate scalar gradient in fourier field
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
subroutine utilities_fourierScalarGradient()
|
subroutine utilities_fourierScalarGradient()
|
||||||
|
|
||||||
integer :: i, j, k
|
integer :: i, j, k
|
||||||
|
|
||||||
do k = 1, grid3; do j = 1, grid(2); do i = 1,grid1Red
|
do k = 1, grid3; do j = 1, grid(2); do i = 1,grid1Red
|
||||||
vectorField_fourier(1:3,i,j,k) = scalarField_fourier(i,j,k)*xi1st(1:3,i,j,k) ! ToDo: no -conjg?
|
vectorField_fourier(1:3,i,j,k) = scalarField_fourier(i,j,k)*xi1st(1:3,i,j,k) ! ToDo: no -conjg?
|
||||||
enddo; enddo; enddo
|
enddo; enddo; enddo
|
||||||
|
@ -788,9 +768,9 @@ end subroutine utilities_fourierScalarGradient
|
||||||
!> @brief calculate vector divergence in fourier field
|
!> @brief calculate vector divergence in fourier field
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
subroutine utilities_fourierVectorDivergence()
|
subroutine utilities_fourierVectorDivergence()
|
||||||
|
|
||||||
integer :: i, j, k
|
integer :: i, j, k
|
||||||
|
|
||||||
do k = 1, grid3; do j = 1, grid(2); do i = 1,grid1Red
|
do k = 1, grid3; do j = 1, grid(2); do i = 1,grid1Red
|
||||||
scalarField_fourier(i,j,k) = sum(vectorField_fourier(1:3,i,j,k)*conjg(-xi1st(1:3,i,j,k)))
|
scalarField_fourier(i,j,k) = sum(vectorField_fourier(1:3,i,j,k)*conjg(-xi1st(1:3,i,j,k)))
|
||||||
enddo; enddo; enddo
|
enddo; enddo; enddo
|
||||||
|
@ -802,9 +782,9 @@ end subroutine utilities_fourierVectorDivergence
|
||||||
!> @brief calculate vector gradient in fourier field
|
!> @brief calculate vector gradient in fourier field
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
subroutine utilities_fourierVectorGradient()
|
subroutine utilities_fourierVectorGradient()
|
||||||
|
|
||||||
integer :: i, j, k, m, n
|
integer :: i, j, k, m, n
|
||||||
|
|
||||||
do k = 1, grid3; do j = 1, grid(2); do i = 1,grid1Red
|
do k = 1, grid3; do j = 1, grid(2); do i = 1,grid1Red
|
||||||
do m = 1, 3; do n = 1, 3
|
do m = 1, 3; do n = 1, 3
|
||||||
tensorField_fourier(m,n,i,j,k) = vectorField_fourier(m,i,j,k)*xi1st(n,i,j,k)
|
tensorField_fourier(m,n,i,j,k) = vectorField_fourier(m,i,j,k)*xi1st(n,i,j,k)
|
||||||
|
@ -820,7 +800,7 @@ end subroutine utilities_fourierVectorGradient
|
||||||
subroutine utilities_fourierTensorDivergence()
|
subroutine utilities_fourierTensorDivergence()
|
||||||
|
|
||||||
integer :: i, j, k
|
integer :: i, j, k
|
||||||
|
|
||||||
do k = 1, grid3; do j = 1, grid(2); do i = 1,grid1Red
|
do k = 1, grid3; do j = 1, grid(2); do i = 1,grid1Red
|
||||||
vectorField_fourier(:,i,j,k) = matmul(tensorField_fourier(:,:,i,j,k),conjg(-xi1st(:,i,j,k)))
|
vectorField_fourier(:,i,j,k) = matmul(tensorField_fourier(:,:,i,j,k),conjg(-xi1st(:,i,j,k)))
|
||||||
enddo; enddo; enddo
|
enddo; enddo; enddo
|
||||||
|
@ -833,28 +813,28 @@ end subroutine utilities_fourierTensorDivergence
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
subroutine utilities_constitutiveResponse(P,P_av,C_volAvg,C_minmaxAvg,&
|
subroutine utilities_constitutiveResponse(P,P_av,C_volAvg,C_minmaxAvg,&
|
||||||
F,timeinc,rotation_BC)
|
F,timeinc,rotation_BC)
|
||||||
|
|
||||||
real(pReal), intent(out), dimension(3,3,3,3) :: C_volAvg, C_minmaxAvg !< average stiffness
|
real(pReal), intent(out), dimension(3,3,3,3) :: C_volAvg, C_minmaxAvg !< average stiffness
|
||||||
real(pReal), intent(out), dimension(3,3) :: P_av !< average PK stress
|
real(pReal), intent(out), dimension(3,3) :: P_av !< average PK stress
|
||||||
real(pReal), intent(out), dimension(3,3,grid(1),grid(2),grid3) :: P !< PK stress
|
real(pReal), intent(out), dimension(3,3,grid(1),grid(2),grid3) :: P !< PK stress
|
||||||
real(pReal), intent(in), dimension(3,3,grid(1),grid(2),grid3) :: F !< deformation gradient target
|
real(pReal), intent(in), dimension(3,3,grid(1),grid(2),grid3) :: F !< deformation gradient target
|
||||||
real(pReal), intent(in) :: timeinc !< loading time
|
real(pReal), intent(in) :: timeinc !< loading time
|
||||||
type(rotation), intent(in), optional :: rotation_BC !< rotation of load frame
|
type(rotation), intent(in), optional :: rotation_BC !< rotation of load frame
|
||||||
|
|
||||||
|
|
||||||
integer :: &
|
integer :: &
|
||||||
i,ierr
|
i,ierr
|
||||||
real(pReal), dimension(3,3,3,3) :: dPdF_max, dPdF_min
|
real(pReal), dimension(3,3,3,3) :: dPdF_max, dPdF_min
|
||||||
real(pReal) :: dPdF_norm_max, dPdF_norm_min
|
real(pReal) :: dPdF_norm_max, dPdF_norm_min
|
||||||
real(pReal), dimension(2) :: valueAndRank !< pair of min/max norm of dPdF to synchronize min/max of dPdF
|
real(pReal), dimension(2) :: valueAndRank !< pair of min/max norm of dPdF to synchronize min/max of dPdF
|
||||||
|
|
||||||
write(6,'(/,a)') ' ... evaluating constitutive response ......................................'
|
write(6,'(/,a)') ' ... evaluating constitutive response ......................................'
|
||||||
flush(6)
|
flush(6)
|
||||||
|
|
||||||
materialpoint_F = reshape(F,[3,3,1,product(grid(1:2))*grid3]) ! set materialpoint target F to estimated field
|
materialpoint_F = reshape(F,[3,3,1,product(grid(1:2))*grid3]) ! set materialpoint target F to estimated field
|
||||||
|
|
||||||
call materialpoint_stressAndItsTangent(.true.,timeinc) ! calculate P field
|
call materialpoint_stressAndItsTangent(.true.,timeinc) ! calculate P field
|
||||||
|
|
||||||
P = reshape(materialpoint_P, [3,3,grid(1),grid(2),grid3])
|
P = reshape(materialpoint_P, [3,3,grid(1),grid(2),grid3])
|
||||||
P_av = sum(sum(sum(P,dim=5),dim=4),dim=3) * wgt ! average of P
|
P_av = sum(sum(sum(P,dim=5),dim=4),dim=3) * wgt ! average of P
|
||||||
call MPI_Allreduce(MPI_IN_PLACE,P_av,9,MPI_DOUBLE,MPI_SUM,PETSC_COMM_WORLD,ierr)
|
call MPI_Allreduce(MPI_IN_PLACE,P_av,9,MPI_DOUBLE,MPI_SUM,PETSC_COMM_WORLD,ierr)
|
||||||
|
@ -862,11 +842,11 @@ subroutine utilities_constitutiveResponse(P,P_av,C_volAvg,C_minmaxAvg,&
|
||||||
write(6,'(/,a,/,3(3(2x,f12.4,1x)/))',advance='no') ' Piola--Kirchhoff stress (lab) / MPa =',&
|
write(6,'(/,a,/,3(3(2x,f12.4,1x)/))',advance='no') ' Piola--Kirchhoff stress (lab) / MPa =',&
|
||||||
transpose(P_av)*1.e-6_pReal
|
transpose(P_av)*1.e-6_pReal
|
||||||
if(present(rotation_BC)) &
|
if(present(rotation_BC)) &
|
||||||
P_av = rotation_BC%rotTensor2(P_av)
|
P_av = rotation_BC%rotate(P_av)
|
||||||
write(6,'(/,a,/,3(3(2x,f12.4,1x)/))',advance='no') ' Piola--Kirchhoff stress / MPa =',&
|
write(6,'(/,a,/,3(3(2x,f12.4,1x)/))',advance='no') ' Piola--Kirchhoff stress / MPa =',&
|
||||||
transpose(P_av)*1.e-6_pReal
|
transpose(P_av)*1.e-6_pReal
|
||||||
flush(6)
|
flush(6)
|
||||||
|
|
||||||
dPdF_max = 0.0_pReal
|
dPdF_max = 0.0_pReal
|
||||||
dPdF_norm_max = 0.0_pReal
|
dPdF_norm_max = 0.0_pReal
|
||||||
dPdF_min = huge(1.0_pReal)
|
dPdF_min = huge(1.0_pReal)
|
||||||
|
@ -881,21 +861,21 @@ subroutine utilities_constitutiveResponse(P,P_av,C_volAvg,C_minmaxAvg,&
|
||||||
dPdF_norm_min = sum(materialpoint_dPdF(1:3,1:3,1:3,1:3,1,i)**2.0_pReal)
|
dPdF_norm_min = sum(materialpoint_dPdF(1:3,1:3,1:3,1:3,1,i)**2.0_pReal)
|
||||||
endif
|
endif
|
||||||
end do
|
end do
|
||||||
|
|
||||||
valueAndRank = [dPdF_norm_max,real(worldrank,pReal)]
|
valueAndRank = [dPdF_norm_max,real(worldrank,pReal)]
|
||||||
call MPI_Allreduce(MPI_IN_PLACE,valueAndRank,1, MPI_2DOUBLE_PRECISION, MPI_MAXLOC, PETSC_COMM_WORLD, ierr)
|
call MPI_Allreduce(MPI_IN_PLACE,valueAndRank,1, MPI_2DOUBLE_PRECISION, MPI_MAXLOC, PETSC_COMM_WORLD, ierr)
|
||||||
if (ierr /= 0) call IO_error(894, ext_msg='MPI_Allreduce max')
|
if (ierr /= 0) call IO_error(894, ext_msg='MPI_Allreduce max')
|
||||||
call MPI_Bcast(dPdF_max,81,MPI_DOUBLE,int(valueAndRank(2)),PETSC_COMM_WORLD, ierr)
|
call MPI_Bcast(dPdF_max,81,MPI_DOUBLE,int(valueAndRank(2)),PETSC_COMM_WORLD, ierr)
|
||||||
if (ierr /= 0) call IO_error(894, ext_msg='MPI_Bcast max')
|
if (ierr /= 0) call IO_error(894, ext_msg='MPI_Bcast max')
|
||||||
|
|
||||||
valueAndRank = [dPdF_norm_min,real(worldrank,pReal)]
|
valueAndRank = [dPdF_norm_min,real(worldrank,pReal)]
|
||||||
call MPI_Allreduce(MPI_IN_PLACE,valueAndRank,1, MPI_2DOUBLE_PRECISION, MPI_MINLOC, PETSC_COMM_WORLD, ierr)
|
call MPI_Allreduce(MPI_IN_PLACE,valueAndRank,1, MPI_2DOUBLE_PRECISION, MPI_MINLOC, PETSC_COMM_WORLD, ierr)
|
||||||
if (ierr /= 0) call IO_error(894, ext_msg='MPI_Allreduce min')
|
if (ierr /= 0) call IO_error(894, ext_msg='MPI_Allreduce min')
|
||||||
call MPI_Bcast(dPdF_min,81,MPI_DOUBLE,int(valueAndRank(2)),PETSC_COMM_WORLD, ierr)
|
call MPI_Bcast(dPdF_min,81,MPI_DOUBLE,int(valueAndRank(2)),PETSC_COMM_WORLD, ierr)
|
||||||
if (ierr /= 0) call IO_error(894, ext_msg='MPI_Bcast min')
|
if (ierr /= 0) call IO_error(894, ext_msg='MPI_Bcast min')
|
||||||
|
|
||||||
C_minmaxAvg = 0.5_pReal*(dPdF_max + dPdF_min)
|
C_minmaxAvg = 0.5_pReal*(dPdF_max + dPdF_min)
|
||||||
|
|
||||||
C_volAvg = sum(sum(materialpoint_dPdF,dim=6),dim=5)
|
C_volAvg = sum(sum(materialpoint_dPdF,dim=6),dim=5)
|
||||||
call MPI_Allreduce(MPI_IN_PLACE,C_volAvg,81,MPI_DOUBLE,MPI_SUM,PETSC_COMM_WORLD,ierr)
|
call MPI_Allreduce(MPI_IN_PLACE,C_volAvg,81,MPI_DOUBLE,MPI_SUM,PETSC_COMM_WORLD,ierr)
|
||||||
C_volAvg = C_volAvg * wgt
|
C_volAvg = C_volAvg * wgt
|
||||||
|
@ -908,7 +888,7 @@ end subroutine utilities_constitutiveResponse
|
||||||
!> @brief calculates forward rate, either guessing or just add delta/timeinc
|
!> @brief calculates forward rate, either guessing or just add delta/timeinc
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
pure function utilities_calculateRate(heterogeneous,field0,field,dt,avRate)
|
pure function utilities_calculateRate(heterogeneous,field0,field,dt,avRate)
|
||||||
|
|
||||||
real(pReal), intent(in), dimension(3,3) :: &
|
real(pReal), intent(in), dimension(3,3) :: &
|
||||||
avRate !< homogeneous addon
|
avRate !< homogeneous addon
|
||||||
real(pReal), intent(in) :: &
|
real(pReal), intent(in) :: &
|
||||||
|
@ -920,7 +900,7 @@ pure function utilities_calculateRate(heterogeneous,field0,field,dt,avRate)
|
||||||
field !< data of current step
|
field !< data of current step
|
||||||
real(pReal), dimension(3,3,grid(1),grid(2),grid3) :: &
|
real(pReal), dimension(3,3,grid(1),grid(2),grid3) :: &
|
||||||
utilities_calculateRate
|
utilities_calculateRate
|
||||||
|
|
||||||
if (heterogeneous) then
|
if (heterogeneous) then
|
||||||
utilities_calculateRate = (field-field0) / dt
|
utilities_calculateRate = (field-field0) / dt
|
||||||
else
|
else
|
||||||
|
@ -971,14 +951,14 @@ pure function utilities_getFreqDerivative(k_s)
|
||||||
complex(pReal), dimension(3) :: utilities_getFreqDerivative
|
complex(pReal), dimension(3) :: utilities_getFreqDerivative
|
||||||
|
|
||||||
select case (spectral_derivative_ID)
|
select case (spectral_derivative_ID)
|
||||||
case (DERIVATIVE_CONTINUOUS_ID)
|
case (DERIVATIVE_CONTINUOUS_ID)
|
||||||
utilities_getFreqDerivative = cmplx(0.0_pReal, 2.0_pReal*PI*real(k_s,pReal)/geomSize,pReal)
|
utilities_getFreqDerivative = cmplx(0.0_pReal, 2.0_pReal*PI*real(k_s,pReal)/geomSize,pReal)
|
||||||
|
|
||||||
case (DERIVATIVE_CENTRAL_DIFF_ID)
|
case (DERIVATIVE_CENTRAL_DIFF_ID)
|
||||||
utilities_getFreqDerivative = cmplx(0.0_pReal, sin(2.0_pReal*PI*real(k_s,pReal)/real(grid,pReal)), pReal)/ &
|
utilities_getFreqDerivative = cmplx(0.0_pReal, sin(2.0_pReal*PI*real(k_s,pReal)/real(grid,pReal)), pReal)/ &
|
||||||
cmplx(2.0_pReal*geomSize/real(grid,pReal), 0.0_pReal, pReal)
|
cmplx(2.0_pReal*geomSize/real(grid,pReal), 0.0_pReal, pReal)
|
||||||
|
|
||||||
case (DERIVATIVE_FWBW_DIFF_ID)
|
case (DERIVATIVE_FWBW_DIFF_ID)
|
||||||
utilities_getFreqDerivative(1) = &
|
utilities_getFreqDerivative(1) = &
|
||||||
cmplx(cos(2.0_pReal*PI*real(k_s(1),pReal)/real(grid(1),pReal)) - 1.0_pReal, &
|
cmplx(cos(2.0_pReal*PI*real(k_s(1),pReal)/real(grid(1),pReal)) - 1.0_pReal, &
|
||||||
sin(2.0_pReal*PI*real(k_s(1),pReal)/real(grid(1),pReal)), pReal)* &
|
sin(2.0_pReal*PI*real(k_s(1),pReal)/real(grid(1),pReal)), pReal)* &
|
||||||
|
@ -986,7 +966,7 @@ pure function utilities_getFreqDerivative(k_s)
|
||||||
sin(2.0_pReal*PI*real(k_s(2),pReal)/real(grid(2),pReal)), pReal)* &
|
sin(2.0_pReal*PI*real(k_s(2),pReal)/real(grid(2),pReal)), pReal)* &
|
||||||
cmplx(cos(2.0_pReal*PI*real(k_s(3),pReal)/real(grid(3),pReal)) + 1.0_pReal, &
|
cmplx(cos(2.0_pReal*PI*real(k_s(3),pReal)/real(grid(3),pReal)) + 1.0_pReal, &
|
||||||
sin(2.0_pReal*PI*real(k_s(3),pReal)/real(grid(3),pReal)), pReal)/ &
|
sin(2.0_pReal*PI*real(k_s(3),pReal)/real(grid(3),pReal)), pReal)/ &
|
||||||
cmplx(4.0_pReal*geomSize(1)/real(grid(1),pReal), 0.0_pReal, pReal)
|
cmplx(4.0_pReal*geomSize(1)/real(grid(1),pReal), 0.0_pReal, pReal)
|
||||||
utilities_getFreqDerivative(2) = &
|
utilities_getFreqDerivative(2) = &
|
||||||
cmplx(cos(2.0_pReal*PI*real(k_s(1),pReal)/real(grid(1),pReal)) + 1.0_pReal, &
|
cmplx(cos(2.0_pReal*PI*real(k_s(1),pReal)/real(grid(1),pReal)) + 1.0_pReal, &
|
||||||
sin(2.0_pReal*PI*real(k_s(1),pReal)/real(grid(1),pReal)), pReal)* &
|
sin(2.0_pReal*PI*real(k_s(1),pReal)/real(grid(1),pReal)), pReal)* &
|
||||||
|
@ -994,7 +974,7 @@ pure function utilities_getFreqDerivative(k_s)
|
||||||
sin(2.0_pReal*PI*real(k_s(2),pReal)/real(grid(2),pReal)), pReal)* &
|
sin(2.0_pReal*PI*real(k_s(2),pReal)/real(grid(2),pReal)), pReal)* &
|
||||||
cmplx(cos(2.0_pReal*PI*real(k_s(3),pReal)/real(grid(3),pReal)) + 1.0_pReal, &
|
cmplx(cos(2.0_pReal*PI*real(k_s(3),pReal)/real(grid(3),pReal)) + 1.0_pReal, &
|
||||||
sin(2.0_pReal*PI*real(k_s(3),pReal)/real(grid(3),pReal)), pReal)/ &
|
sin(2.0_pReal*PI*real(k_s(3),pReal)/real(grid(3),pReal)), pReal)/ &
|
||||||
cmplx(4.0_pReal*geomSize(2)/real(grid(2),pReal), 0.0_pReal, pReal)
|
cmplx(4.0_pReal*geomSize(2)/real(grid(2),pReal), 0.0_pReal, pReal)
|
||||||
utilities_getFreqDerivative(3) = &
|
utilities_getFreqDerivative(3) = &
|
||||||
cmplx(cos(2.0_pReal*PI*real(k_s(1),pReal)/real(grid(1),pReal)) + 1.0_pReal, &
|
cmplx(cos(2.0_pReal*PI*real(k_s(1),pReal)/real(grid(1),pReal)) + 1.0_pReal, &
|
||||||
sin(2.0_pReal*PI*real(k_s(1),pReal)/real(grid(1),pReal)), pReal)* &
|
sin(2.0_pReal*PI*real(k_s(1),pReal)/real(grid(1),pReal)), pReal)* &
|
||||||
|
@ -1002,7 +982,7 @@ pure function utilities_getFreqDerivative(k_s)
|
||||||
sin(2.0_pReal*PI*real(k_s(2),pReal)/real(grid(2),pReal)), pReal)* &
|
sin(2.0_pReal*PI*real(k_s(2),pReal)/real(grid(2),pReal)), pReal)* &
|
||||||
cmplx(cos(2.0_pReal*PI*real(k_s(3),pReal)/real(grid(3),pReal)) - 1.0_pReal, &
|
cmplx(cos(2.0_pReal*PI*real(k_s(3),pReal)/real(grid(3),pReal)) - 1.0_pReal, &
|
||||||
sin(2.0_pReal*PI*real(k_s(3),pReal)/real(grid(3),pReal)), pReal)/ &
|
sin(2.0_pReal*PI*real(k_s(3),pReal)/real(grid(3),pReal)), pReal)/ &
|
||||||
cmplx(4.0_pReal*geomSize(3)/real(grid(3),pReal), 0.0_pReal, pReal)
|
cmplx(4.0_pReal*geomSize(3)/real(grid(3),pReal), 0.0_pReal, pReal)
|
||||||
end select
|
end select
|
||||||
|
|
||||||
end function utilities_getFreqDerivative
|
end function utilities_getFreqDerivative
|
||||||
|
@ -1014,7 +994,7 @@ end function utilities_getFreqDerivative
|
||||||
! convolution
|
! convolution
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
subroutine utilities_updateCoords(F)
|
subroutine utilities_updateCoords(F)
|
||||||
|
|
||||||
real(pReal), dimension(3,3,grid(1),grid(2),grid3), intent(in) :: F
|
real(pReal), dimension(3,3,grid(1),grid(2),grid3), intent(in) :: F
|
||||||
real(pReal), dimension(3, grid(1),grid(2),grid3) :: IPcoords
|
real(pReal), dimension(3, grid(1),grid(2),grid3) :: IPcoords
|
||||||
real(pReal), dimension(3, grid(1),grid(2),grid3+2) :: IPfluct_padded ! Fluctuations of cell center displacement (padded along z for MPI)
|
real(pReal), dimension(3, grid(1),grid(2),grid3+2) :: IPfluct_padded ! Fluctuations of cell center displacement (padded along z for MPI)
|
||||||
|
@ -1040,7 +1020,7 @@ subroutine utilities_updateCoords(F)
|
||||||
1, 0, 1, &
|
1, 0, 1, &
|
||||||
1, 1, 1, &
|
1, 1, 1, &
|
||||||
0, 1, 1 ], [3,8])
|
0, 1, 1 ], [3,8])
|
||||||
|
|
||||||
step = geomSize/real(grid, pReal)
|
step = geomSize/real(grid, pReal)
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! integration in Fourier space to get fluctuations of cell center discplacements
|
! integration in Fourier space to get fluctuations of cell center discplacements
|
||||||
|
@ -1057,27 +1037,27 @@ subroutine utilities_updateCoords(F)
|
||||||
enddo; enddo; enddo
|
enddo; enddo; enddo
|
||||||
|
|
||||||
call fftw_mpi_execute_dft_c2r(planVectorBack,vectorField_fourier,vectorField_real)
|
call fftw_mpi_execute_dft_c2r(planVectorBack,vectorField_fourier,vectorField_real)
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! average F
|
! average F
|
||||||
if (grid3Offset == 0) Favg = real(tensorField_fourier(1:3,1:3,1,1,1),pReal)*wgt
|
if (grid3Offset == 0) Favg = real(tensorField_fourier(1:3,1:3,1,1,1),pReal)*wgt
|
||||||
call MPI_Bcast(Favg,9,MPI_DOUBLE,0,PETSC_COMM_WORLD,ierr)
|
call MPI_Bcast(Favg,9,MPI_DOUBLE,0,PETSC_COMM_WORLD,ierr)
|
||||||
if(ierr /=0) call IO_error(894, ext_msg='update_IPcoords/MPI_Bcast')
|
if(ierr /=0) call IO_error(894, ext_msg='update_IPcoords/MPI_Bcast')
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! pad cell center fluctuations along z-direction (needed when running MPI simulation)
|
! pad cell center fluctuations along z-direction (needed when running MPI simulation)
|
||||||
IPfluct_padded(1:3,1:grid(1),1:grid(2),2:grid3+1) = vectorField_real(1:3,1:grid(1),1:grid(2),1:grid3)
|
IPfluct_padded(1:3,1:grid(1),1:grid(2),2:grid3+1) = vectorField_real(1:3,1:grid(1),1:grid(2),1:grid3)
|
||||||
c = product(shape(IPfluct_padded(:,:,:,1))) !< amount of data to transfer
|
c = product(shape(IPfluct_padded(:,:,:,1))) !< amount of data to transfer
|
||||||
rank_t = modulo(worldrank+1,worldsize)
|
rank_t = modulo(worldrank+1,worldsize)
|
||||||
rank_b = modulo(worldrank-1,worldsize)
|
rank_b = modulo(worldrank-1,worldsize)
|
||||||
|
|
||||||
! send bottom layer to process below
|
! send bottom layer to process below
|
||||||
call MPI_Isend(IPfluct_padded(:,:,:,2), c,MPI_DOUBLE,rank_b,0,PETSC_COMM_WORLD,r,ierr)
|
call MPI_Isend(IPfluct_padded(:,:,:,2), c,MPI_DOUBLE,rank_b,0,PETSC_COMM_WORLD,r,ierr)
|
||||||
if(ierr /=0) call IO_error(894, ext_msg='update_IPcoords/MPI_Isend')
|
if(ierr /=0) call IO_error(894, ext_msg='update_IPcoords/MPI_Isend')
|
||||||
call MPI_Irecv(IPfluct_padded(:,:,:,grid3+2),c,MPI_DOUBLE,rank_t,0,PETSC_COMM_WORLD,r,ierr)
|
call MPI_Irecv(IPfluct_padded(:,:,:,grid3+2),c,MPI_DOUBLE,rank_t,0,PETSC_COMM_WORLD,r,ierr)
|
||||||
if(ierr /=0) call IO_error(894, ext_msg='update_IPcoords/MPI_Irecv')
|
if(ierr /=0) call IO_error(894, ext_msg='update_IPcoords/MPI_Irecv')
|
||||||
call MPI_Wait(r,s,ierr)
|
call MPI_Wait(r,s,ierr)
|
||||||
|
|
||||||
! send top layer to process above
|
! send top layer to process above
|
||||||
if(ierr /=0) call IO_error(894, ext_msg='update_IPcoords/MPI_Wait')
|
if(ierr /=0) call IO_error(894, ext_msg='update_IPcoords/MPI_Wait')
|
||||||
call MPI_Isend(IPfluct_padded(:,:,:,grid3+1),c,MPI_DOUBLE,rank_t,0,PETSC_COMM_WORLD,r,ierr)
|
call MPI_Isend(IPfluct_padded(:,:,:,grid3+1),c,MPI_DOUBLE,rank_t,0,PETSC_COMM_WORLD,r,ierr)
|
||||||
|
@ -1085,9 +1065,9 @@ subroutine utilities_updateCoords(F)
|
||||||
call MPI_Irecv(IPfluct_padded(:,:,:,1), c,MPI_DOUBLE,rank_b,0,PETSC_COMM_WORLD,r,ierr)
|
call MPI_Irecv(IPfluct_padded(:,:,:,1), c,MPI_DOUBLE,rank_b,0,PETSC_COMM_WORLD,r,ierr)
|
||||||
if(ierr /=0) call IO_error(894, ext_msg='update_IPcoords/MPI_Irecv')
|
if(ierr /=0) call IO_error(894, ext_msg='update_IPcoords/MPI_Irecv')
|
||||||
call MPI_Wait(r,s,ierr)
|
call MPI_Wait(r,s,ierr)
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! calculate nodal displacements
|
! calculate nodal displacements
|
||||||
nodeCoords = 0.0_pReal
|
nodeCoords = 0.0_pReal
|
||||||
do k = 0,grid3; do j = 0,grid(2); do i = 0,grid(1)
|
do k = 0,grid3; do j = 0,grid(2); do i = 0,grid(1)
|
||||||
nodeCoords(1:3,i+1,j+1,k+1) = matmul(Favg,step*(real([i,j,k+grid3Offset],pReal)))
|
nodeCoords(1:3,i+1,j+1,k+1) = matmul(Favg,step*(real([i,j,k+grid3Offset],pReal)))
|
||||||
|
@ -1097,17 +1077,17 @@ subroutine utilities_updateCoords(F)
|
||||||
+ IPfluct_padded(1:3,modulo(me(1)-1,grid(1))+1,modulo(me(2)-1,grid(2))+1,me(3)+1)*0.125_pReal
|
+ IPfluct_padded(1:3,modulo(me(1)-1,grid(1))+1,modulo(me(2)-1,grid(2))+1,me(3)+1)*0.125_pReal
|
||||||
enddo averageFluct
|
enddo averageFluct
|
||||||
enddo; enddo; enddo
|
enddo; enddo; enddo
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! calculate cell center displacements
|
! calculate cell center displacements
|
||||||
do k = 1,grid3; do j = 1,grid(2); do i = 1,grid(1)
|
do k = 1,grid3; do j = 1,grid(2); do i = 1,grid(1)
|
||||||
IPcoords(1:3,i,j,k) = vectorField_real(1:3,i,j,k) &
|
IPcoords(1:3,i,j,k) = vectorField_real(1:3,i,j,k) &
|
||||||
+ matmul(Favg,step*real([i,j,k+grid3Offset]-0.5_pReal,pReal))
|
+ matmul(Favg,step*real([i,j,k+grid3Offset]-0.5_pReal,pReal))
|
||||||
enddo; enddo; enddo
|
enddo; enddo; enddo
|
||||||
|
|
||||||
call discretization_setNodeCoords(reshape(NodeCoords,[3,(grid(1)+1)*(grid(2)+1)*(grid3+1)]))
|
call discretization_setNodeCoords(reshape(NodeCoords,[3,(grid(1)+1)*(grid(2)+1)*(grid3+1)]))
|
||||||
call discretization_setIPcoords (reshape(IPcoords, [3,grid(1)*grid(2)*grid3]))
|
call discretization_setIPcoords (reshape(IPcoords, [3,grid(1)*grid(2)*grid3]))
|
||||||
|
|
||||||
end subroutine utilities_updateCoords
|
end subroutine utilities_updateCoords
|
||||||
|
|
||||||
|
|
||||||
|
@ -1115,7 +1095,7 @@ end subroutine utilities_updateCoords
|
||||||
!> @brief Write out the current reference stiffness for restart.
|
!> @brief Write out the current reference stiffness for restart.
|
||||||
!---------------------------------------------------------------------------------------------------
|
!---------------------------------------------------------------------------------------------------
|
||||||
subroutine utilities_saveReferenceStiffness
|
subroutine utilities_saveReferenceStiffness
|
||||||
|
|
||||||
integer :: &
|
integer :: &
|
||||||
fileUnit
|
fileUnit
|
||||||
|
|
||||||
|
@ -1125,7 +1105,7 @@ subroutine utilities_saveReferenceStiffness
|
||||||
write(fileUnit) C_ref
|
write(fileUnit) C_ref
|
||||||
close(fileUnit)
|
close(fileUnit)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
end subroutine utilities_saveReferenceStiffness
|
end subroutine utilities_saveReferenceStiffness
|
||||||
|
|
||||||
end module spectral_utilities
|
end module spectral_utilities
|
||||||
|
|
|
@ -146,9 +146,7 @@ subroutine homogenization_init
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! allocate and initialize global variables
|
! allocate and initialize global variables
|
||||||
allocate(materialpoint_dPdF(3,3,3,3,discretization_nIP,discretization_nElem), source=0.0_pReal)
|
allocate(materialpoint_dPdF(3,3,3,3,discretization_nIP,discretization_nElem), source=0.0_pReal)
|
||||||
allocate(materialpoint_F0(3,3,discretization_nIP,discretization_nElem), source=0.0_pReal)
|
|
||||||
materialpoint_F0 = spread(spread(math_I3,3,discretization_nIP),4,discretization_nElem) ! initialize to identity
|
materialpoint_F0 = spread(spread(math_I3,3,discretization_nIP),4,discretization_nElem) ! initialize to identity
|
||||||
allocate(materialpoint_F(3,3,discretization_nIP,discretization_nElem), source=0.0_pReal)
|
|
||||||
materialpoint_F = materialpoint_F0 ! initialize to identity
|
materialpoint_F = materialpoint_F0 ! initialize to identity
|
||||||
allocate(materialpoint_subF0(3,3,discretization_nIP,discretization_nElem), source=0.0_pReal)
|
allocate(materialpoint_subF0(3,3,discretization_nIP,discretization_nElem), source=0.0_pReal)
|
||||||
allocate(materialpoint_subF(3,3,discretization_nIP,discretization_nElem), source=0.0_pReal)
|
allocate(materialpoint_subF(3,3,discretization_nIP,discretization_nElem), source=0.0_pReal)
|
||||||
|
@ -333,12 +331,10 @@ subroutine materialpoint_stressAndItsTangent(updateJaco,dt)
|
||||||
!$OMP FLUSH(terminallyIll)
|
!$OMP FLUSH(terminallyIll)
|
||||||
if (.not. terminallyIll) then ! so first signals terminally ill...
|
if (.not. terminallyIll) then ! so first signals terminally ill...
|
||||||
!$OMP CRITICAL (write2out)
|
!$OMP CRITICAL (write2out)
|
||||||
write(6,*) 'Integration point ', i,' at element ', e, ' terminally ill'
|
write(6,*) 'Integration point ', i,' at element ', e, ' terminally ill'
|
||||||
!$OMP END CRITICAL (write2out)
|
!$OMP END CRITICAL (write2out)
|
||||||
endif
|
endif
|
||||||
!$OMP CRITICAL (setTerminallyIll)
|
terminallyIll = .true. ! ...and kills all others
|
||||||
terminallyIll = .true. ! ...and kills all others
|
|
||||||
!$OMP END CRITICAL (setTerminallyIll)
|
|
||||||
else ! cutback makes sense
|
else ! cutback makes sense
|
||||||
materialpoint_subStep(i,e) = subStepSizeHomog * materialpoint_subStep(i,e) ! crystallite had severe trouble, so do a significant cutback
|
materialpoint_subStep(i,e) = subStepSizeHomog * materialpoint_subStep(i,e) ! crystallite had severe trouble, so do a significant cutback
|
||||||
|
|
||||||
|
|
|
@ -9,17 +9,6 @@
|
||||||
submodule(homogenization) homogenization_mech_RGC
|
submodule(homogenization) homogenization_mech_RGC
|
||||||
use rotations
|
use rotations
|
||||||
|
|
||||||
enum, bind(c)
|
|
||||||
enumerator :: &
|
|
||||||
undefined_ID, &
|
|
||||||
constitutivework_ID, &
|
|
||||||
penaltyenergy_ID, &
|
|
||||||
volumediscrepancy_ID, &
|
|
||||||
averagerelaxrate_ID,&
|
|
||||||
maximumrelaxrate_ID,&
|
|
||||||
magnitudemismatch_ID
|
|
||||||
end enum
|
|
||||||
|
|
||||||
type :: tParameters
|
type :: tParameters
|
||||||
integer, dimension(:), allocatable :: &
|
integer, dimension(:), allocatable :: &
|
||||||
Nconstituents
|
Nconstituents
|
||||||
|
@ -31,8 +20,8 @@ submodule(homogenization) homogenization_mech_RGC
|
||||||
angles
|
angles
|
||||||
integer :: &
|
integer :: &
|
||||||
of_debug = 0
|
of_debug = 0
|
||||||
integer(kind(undefined_ID)), dimension(:), allocatable :: &
|
character(len=pStringLen), allocatable, dimension(:) :: &
|
||||||
outputID
|
output
|
||||||
end type tParameters
|
end type tParameters
|
||||||
|
|
||||||
type :: tRGCstate
|
type :: tRGCstate
|
||||||
|
@ -71,23 +60,18 @@ module subroutine mech_RGC_init
|
||||||
|
|
||||||
integer :: &
|
integer :: &
|
||||||
Ninstance, &
|
Ninstance, &
|
||||||
h, i, &
|
h, &
|
||||||
NofMyHomog, &
|
NofMyHomog, &
|
||||||
sizeState, nIntFaceTot
|
sizeState, nIntFaceTot
|
||||||
|
|
||||||
integer(kind(undefined_ID)) :: &
|
|
||||||
outputID
|
|
||||||
|
|
||||||
character(len=pStringLen), dimension(:), allocatable :: &
|
|
||||||
outputs
|
|
||||||
|
|
||||||
write(6,'(/,a)') ' <<<+- homogenization_'//HOMOGENIZATION_RGC_label//' init -+>>>'
|
write(6,'(/,a)') ' <<<+- homogenization_'//HOMOGENIZATION_RGC_label//' init -+>>>'; flush(6)
|
||||||
|
|
||||||
write(6,'(/,a)') ' Tjahjanto et al., International Journal of Material Forming 2(1):939–942, 2009'
|
write(6,'(/,a)') ' Tjahjanto et al., International Journal of Material Forming 2(1):939–942, 2009'
|
||||||
write(6,'(a)') ' https://doi.org/10.1007/s12289-009-0619-1'
|
write(6,'(a)') ' https://doi.org/10.1007/s12289-009-0619-1'
|
||||||
|
|
||||||
write(6,'(/,a)') ' Tjahjanto et al., Modelling and Simulation in Materials Science and Engineering 18:015006, 2010'
|
write(6,'(/,a)') ' Tjahjanto et al., Modelling and Simulation in Materials Science and Engineering 18:015006, 2010'
|
||||||
write(6,'(a)') ' https://doi.org/10.1088/0965-0393/18/1/015006'
|
write(6,'(a)') ' https://doi.org/10.1088/0965-0393/18/1/015006'
|
||||||
|
|
||||||
Ninstance = count(homogenization_type == HOMOGENIZATION_RGC_ID)
|
Ninstance = count(homogenization_type == HOMOGENIZATION_RGC_ID)
|
||||||
if (iand(debug_level(debug_HOMOGENIZATION),debug_levelBasic) /= 0) &
|
if (iand(debug_level(debug_HOMOGENIZATION),debug_levelBasic) /= 0) &
|
||||||
|
@ -123,34 +107,8 @@ module subroutine mech_RGC_init
|
||||||
prm%dAlpha = config%getFloats('grainsize', requiredSize=3)
|
prm%dAlpha = config%getFloats('grainsize', requiredSize=3)
|
||||||
prm%angles = config%getFloats('clusterorientation',requiredSize=3)
|
prm%angles = config%getFloats('clusterorientation',requiredSize=3)
|
||||||
|
|
||||||
outputs = config%getStrings('(output)',defaultVal=emptyStringArray)
|
prm%output = config%getStrings('(output)',defaultVal=emptyStringArray)
|
||||||
allocate(prm%outputID(0))
|
|
||||||
|
|
||||||
do i=1, size(outputs)
|
|
||||||
outputID = undefined_ID
|
|
||||||
select case(outputs(i))
|
|
||||||
|
|
||||||
case('constitutivework')
|
|
||||||
outputID = constitutivework_ID
|
|
||||||
case('penaltyenergy')
|
|
||||||
outputID = penaltyenergy_ID
|
|
||||||
case('volumediscrepancy')
|
|
||||||
outputID = volumediscrepancy_ID
|
|
||||||
case('averagerelaxrate')
|
|
||||||
outputID = averagerelaxrate_ID
|
|
||||||
case('maximumrelaxrate')
|
|
||||||
outputID = maximumrelaxrate_ID
|
|
||||||
case('magnitudemismatch')
|
|
||||||
outputID = magnitudemismatch_ID
|
|
||||||
|
|
||||||
end select
|
|
||||||
|
|
||||||
if (outputID /= undefined_ID) then
|
|
||||||
prm%outputID = [prm%outputID , outputID]
|
|
||||||
endif
|
|
||||||
|
|
||||||
enddo
|
|
||||||
|
|
||||||
NofMyHomog = count(material_homogenizationAt == h)
|
NofMyHomog = count(material_homogenizationAt == h)
|
||||||
nIntFaceTot = 3*( (prm%Nconstituents(1)-1)*prm%Nconstituents(2)*prm%Nconstituents(3) &
|
nIntFaceTot = 3*( (prm%Nconstituents(1)-1)*prm%Nconstituents(2)*prm%Nconstituents(3) &
|
||||||
+ prm%Nconstituents(1)*(prm%Nconstituents(2)-1)*prm%Nconstituents(3) &
|
+ prm%Nconstituents(1)*(prm%Nconstituents(2)-1)*prm%Nconstituents(3) &
|
||||||
|
@ -711,7 +669,7 @@ module procedure mech_RGC_updateState
|
||||||
nDef = 0.0_pReal
|
nDef = 0.0_pReal
|
||||||
do i = 1,3; do j = 1,3
|
do i = 1,3; do j = 1,3
|
||||||
do k = 1,3; do l = 1,3
|
do k = 1,3; do l = 1,3
|
||||||
nDef(i,j) = nDef(i,j) - nVect(k)*gDef(i,l)*math_civita(j,k,l) ! compute the interface mismatch tensor from the jump of deformation gradient
|
nDef(i,j) = nDef(i,j) - nVect(k)*gDef(i,l)*math_LeviCivita(j,k,l) ! compute the interface mismatch tensor from the jump of deformation gradient
|
||||||
enddo; enddo
|
enddo; enddo
|
||||||
nDefNorm = nDefNorm + nDef(i,j)**2.0_pReal ! compute the norm of the mismatch tensor
|
nDefNorm = nDefNorm + nDef(i,j)**2.0_pReal ! compute the norm of the mismatch tensor
|
||||||
enddo; enddo
|
enddo; enddo
|
||||||
|
@ -731,7 +689,7 @@ module procedure mech_RGC_updateState
|
||||||
rPen(i,j,iGrain) = rPen(i,j,iGrain) + 0.5_pReal*(muGrain*bgGrain + muGNghb*bgGNghb)*prm%xiAlpha &
|
rPen(i,j,iGrain) = rPen(i,j,iGrain) + 0.5_pReal*(muGrain*bgGrain + muGNghb*bgGNghb)*prm%xiAlpha &
|
||||||
*surfCorr(abs(intFace(1)))/prm%dAlpha(abs(intFace(1))) &
|
*surfCorr(abs(intFace(1)))/prm%dAlpha(abs(intFace(1))) &
|
||||||
*cosh(prm%ciAlpha*nDefNorm) &
|
*cosh(prm%ciAlpha*nDefNorm) &
|
||||||
*0.5_pReal*nVect(l)*nDef(i,k)/nDefNorm*math_civita(k,l,j) &
|
*0.5_pReal*nVect(l)*nDef(i,k)/nDefNorm*math_LeviCivita(k,l,j) &
|
||||||
*tanh(nDefNorm/xSmoo_RGC)
|
*tanh(nDefNorm/xSmoo_RGC)
|
||||||
enddo; enddo;enddo; enddo
|
enddo; enddo;enddo; enddo
|
||||||
enddo interfaceLoop
|
enddo interfaceLoop
|
||||||
|
@ -934,26 +892,24 @@ module subroutine mech_RGC_results(instance,group)
|
||||||
integer :: o
|
integer :: o
|
||||||
|
|
||||||
associate(stt => state(instance), dst => dependentState(instance), prm => param(instance))
|
associate(stt => state(instance), dst => dependentState(instance), prm => param(instance))
|
||||||
|
outputsLoop: do o = 1,size(prm%output)
|
||||||
outputsLoop: do o = 1,size(prm%outputID)
|
select case(trim(prm%output(o)))
|
||||||
select case(prm%outputID(o))
|
case('constitutivework')
|
||||||
|
|
||||||
case (constitutivework_ID)
|
|
||||||
call results_writeDataset(group,stt%work,'W',&
|
call results_writeDataset(group,stt%work,'W',&
|
||||||
'work density','J/m³')
|
'work density','J/m³')
|
||||||
case (magnitudemismatch_ID)
|
case('magnitudemismatch')
|
||||||
call results_writeDataset(group,dst%mismatch,'N',&
|
call results_writeDataset(group,dst%mismatch,'N',&
|
||||||
'average mismatch tensor','1')
|
'average mismatch tensor','1')
|
||||||
case (penaltyenergy_ID)
|
case('penaltyenergy')
|
||||||
call results_writeDataset(group,stt%penaltyEnergy,'R',&
|
call results_writeDataset(group,stt%penaltyEnergy,'R',&
|
||||||
'mismatch penalty density','J/m³')
|
'mismatch penalty density','J/m³')
|
||||||
case (volumediscrepancy_ID)
|
case('volumediscrepancy')
|
||||||
call results_writeDataset(group,dst%volumeDiscrepancy,'Delta_V',&
|
call results_writeDataset(group,dst%volumeDiscrepancy,'Delta_V',&
|
||||||
'volume discrepancy','m³')
|
'volume discrepancy','m³')
|
||||||
case (maximumrelaxrate_ID)
|
case('maximumrelaxrate')
|
||||||
call results_writeDataset(group,dst%relaxationrate_max,'max_alpha_dot',&
|
call results_writeDataset(group,dst%relaxationrate_max,'max_alpha_dot',&
|
||||||
'maximum relaxation rate','m/s')
|
'maximum relaxation rate','m/s')
|
||||||
case (averagerelaxrate_ID)
|
case('averagerelaxrate')
|
||||||
call results_writeDataset(group,dst%relaxationrate_avg,'avg_alpha_dot',&
|
call results_writeDataset(group,dst%relaxationrate_avg,'avg_alpha_dot',&
|
||||||
'average relaxation rate','m/s')
|
'average relaxation rate','m/s')
|
||||||
end select
|
end select
|
||||||
|
|
724
src/lattice.f90
724
src/lattice.f90
File diff suppressed because it is too large
Load Diff
|
@ -257,7 +257,7 @@ subroutine material_init
|
||||||
allocate(damage (material_Nhomogenization))
|
allocate(damage (material_Nhomogenization))
|
||||||
|
|
||||||
allocate(temperatureRate (material_Nhomogenization))
|
allocate(temperatureRate (material_Nhomogenization))
|
||||||
|
|
||||||
do m = 1,size(config_microstructure)
|
do m = 1,size(config_microstructure)
|
||||||
if(minval(microstructure_phase(1:microstructure_Nconstituents(m),m)) < 1 .or. &
|
if(minval(microstructure_phase(1:microstructure_Nconstituents(m),m)) < 1 .or. &
|
||||||
maxval(microstructure_phase(1:microstructure_Nconstituents(m),m)) > size(config_phase)) &
|
maxval(microstructure_phase(1:microstructure_Nconstituents(m),m)) > size(config_phase)) &
|
||||||
|
@ -268,6 +268,7 @@ subroutine material_init
|
||||||
if(microstructure_Nconstituents(m) < 1) &
|
if(microstructure_Nconstituents(m) < 1) &
|
||||||
call IO_error(151,m)
|
call IO_error(151,m)
|
||||||
enddo
|
enddo
|
||||||
|
if(homogenization_maxNgrains > size(microstructure_phase,1)) call IO_error(148)
|
||||||
|
|
||||||
debugOut: if (iand(myDebug,debug_levelExtensive) /= 0) then
|
debugOut: if (iand(myDebug,debug_levelExtensive) /= 0) then
|
||||||
write(6,'(/,a,/)') ' MATERIAL configuration'
|
write(6,'(/,a,/)') ' MATERIAL configuration'
|
||||||
|
@ -290,6 +291,7 @@ subroutine material_init
|
||||||
|
|
||||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||||
! new mappings
|
! new mappings
|
||||||
|
|
||||||
allocate(material_phaseAt(homogenization_maxNgrains,discretization_nElem), source=0)
|
allocate(material_phaseAt(homogenization_maxNgrains,discretization_nElem), source=0)
|
||||||
allocate(material_texture(homogenization_maxNgrains,discretization_nIP,discretization_nElem),source=0) !this is only needed by plasticity nonlocal
|
allocate(material_texture(homogenization_maxNgrains,discretization_nIP,discretization_nElem),source=0) !this is only needed by plasticity nonlocal
|
||||||
allocate(material_orientation0(homogenization_maxNgrains,discretization_nIP,discretization_nElem))
|
allocate(material_orientation0(homogenization_maxNgrains,discretization_nIP,discretization_nElem))
|
||||||
|
@ -298,15 +300,24 @@ subroutine material_init
|
||||||
do i = 1, discretization_nIP
|
do i = 1, discretization_nIP
|
||||||
myMicro = discretization_microstructureAt(e)
|
myMicro = discretization_microstructureAt(e)
|
||||||
do c = 1, homogenization_Ngrains(discretization_homogenizationAt(e))
|
do c = 1, homogenization_Ngrains(discretization_homogenizationAt(e))
|
||||||
material_phaseAt(c,e) = microstructure_phase(c,myMicro)
|
if(microstructure_phase(c,myMicro) > 0) then
|
||||||
material_texture(c,i,e) = microstructure_texture(c,myMicro)
|
material_phaseAt(c,e) = microstructure_phase(c,myMicro)
|
||||||
material_orientation0(c,i,e) = texture_orientation(material_texture(c,i,e))
|
else
|
||||||
|
call IO_error(150,ext_msg='phase')
|
||||||
|
endif
|
||||||
|
if(microstructure_texture(c,myMicro) > 0) then
|
||||||
|
material_texture(c,i,e) = microstructure_texture(c,myMicro)
|
||||||
|
material_orientation0(c,i,e) = texture_orientation(material_texture(c,i,e))
|
||||||
|
else
|
||||||
|
call IO_error(150,ext_msg='texture')
|
||||||
|
endif
|
||||||
enddo
|
enddo
|
||||||
enddo
|
enddo
|
||||||
enddo
|
enddo
|
||||||
|
|
||||||
deallocate(microstructure_phase)
|
deallocate(microstructure_phase)
|
||||||
deallocate(microstructure_texture)
|
deallocate(microstructure_texture)
|
||||||
|
deallocate(texture_orientation)
|
||||||
|
|
||||||
|
|
||||||
allocate(material_homogenizationAt,source=discretization_homogenizationAt)
|
allocate(material_homogenizationAt,source=discretization_homogenizationAt)
|
||||||
|
@ -464,7 +475,7 @@ subroutine material_parseMicrostructure
|
||||||
real(pReal), dimension(:,:), allocatable :: &
|
real(pReal), dimension(:,:), allocatable :: &
|
||||||
microstructure_fraction !< vol fraction of each constituent in microstructure
|
microstructure_fraction !< vol fraction of each constituent in microstructure
|
||||||
integer :: &
|
integer :: &
|
||||||
microstructure_maxNconstituents !< max number of constituents in any phase
|
maxNconstituents !< max number of constituents in any phase
|
||||||
|
|
||||||
allocate(microstructure_Nconstituents(size(config_microstructure)), source=0)
|
allocate(microstructure_Nconstituents(size(config_microstructure)), source=0)
|
||||||
|
|
||||||
|
@ -475,10 +486,10 @@ subroutine material_parseMicrostructure
|
||||||
microstructure_Nconstituents(m) = config_microstructure(m)%countKeys('(constituent)')
|
microstructure_Nconstituents(m) = config_microstructure(m)%countKeys('(constituent)')
|
||||||
enddo
|
enddo
|
||||||
|
|
||||||
microstructure_maxNconstituents = maxval(microstructure_Nconstituents)
|
maxNconstituents = maxval(microstructure_Nconstituents)
|
||||||
allocate(microstructure_phase (microstructure_maxNconstituents,size(config_microstructure)),source=0)
|
allocate(microstructure_phase (maxNconstituents,size(config_microstructure)),source=0)
|
||||||
allocate(microstructure_texture (microstructure_maxNconstituents,size(config_microstructure)),source=0)
|
allocate(microstructure_texture (maxNconstituents,size(config_microstructure)),source=0)
|
||||||
allocate(microstructure_fraction(microstructure_maxNconstituents,size(config_microstructure)),source=0.0_pReal)
|
allocate(microstructure_fraction(maxNconstituents,size(config_microstructure)),source=0.0_pReal)
|
||||||
|
|
||||||
allocate(strings(1)) ! Intel 16.0 Bug
|
allocate(strings(1)) ! Intel 16.0 Bug
|
||||||
do m=1, size(config_microstructure)
|
do m=1, size(config_microstructure)
|
||||||
|
|
186
src/math.f90
186
src/math.f90
|
@ -72,7 +72,12 @@ module math
|
||||||
3,2, &
|
3,2, &
|
||||||
3,3 &
|
3,3 &
|
||||||
],[2,9]) !< arrangement in Plain notation
|
],[2,9]) !< arrangement in Plain notation
|
||||||
|
|
||||||
|
|
||||||
|
interface math_mul33xx33
|
||||||
|
module procedure math_tensordot
|
||||||
|
end interface math_mul33xx33
|
||||||
|
|
||||||
!---------------------------------------------------------------------------------------------------
|
!---------------------------------------------------------------------------------------------------
|
||||||
private :: &
|
private :: &
|
||||||
unitTest
|
unitTest
|
||||||
|
@ -88,7 +93,7 @@ subroutine math_init
|
||||||
real(pReal), dimension(4) :: randTest
|
real(pReal), dimension(4) :: randTest
|
||||||
integer :: randSize
|
integer :: randSize
|
||||||
integer, dimension(:), allocatable :: randInit
|
integer, dimension(:), allocatable :: randInit
|
||||||
|
|
||||||
write(6,'(/,a)') ' <<<+- math init -+>>>'; flush(6)
|
write(6,'(/,a)') ' <<<+- math init -+>>>'; flush(6)
|
||||||
|
|
||||||
call random_seed(size=randSize)
|
call random_seed(size=randSize)
|
||||||
|
@ -140,7 +145,7 @@ recursive subroutine math_sort(a, istart, iend, sortDim)
|
||||||
else
|
else
|
||||||
e = ubound(a,2)
|
e = ubound(a,2)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if(present(sortDim)) then
|
if(present(sortDim)) then
|
||||||
d = sortDim
|
d = sortDim
|
||||||
else
|
else
|
||||||
|
@ -160,12 +165,12 @@ recursive subroutine math_sort(a, istart, iend, sortDim)
|
||||||
!> @brief Partitioning required for quicksort
|
!> @brief Partitioning required for quicksort
|
||||||
!-------------------------------------------------------------------------------------------------
|
!-------------------------------------------------------------------------------------------------
|
||||||
integer function qsort_partition(a, istart, iend, sort)
|
integer function qsort_partition(a, istart, iend, sort)
|
||||||
|
|
||||||
integer, dimension(:,:), intent(inout) :: a
|
integer, dimension(:,:), intent(inout) :: a
|
||||||
integer, intent(in) :: istart,iend,sort
|
integer, intent(in) :: istart,iend,sort
|
||||||
integer, dimension(size(a,1)) :: tmp
|
integer, dimension(size(a,1)) :: tmp
|
||||||
integer :: i,j
|
integer :: i,j
|
||||||
|
|
||||||
do
|
do
|
||||||
! find the first element on the right side less than or equal to the pivot point
|
! find the first element on the right side less than or equal to the pivot point
|
||||||
do j = iend, istart, -1
|
do j = iend, istart, -1
|
||||||
|
@ -187,7 +192,7 @@ recursive subroutine math_sort(a, istart, iend, sortDim)
|
||||||
a(:,j) = tmp
|
a(:,j) = tmp
|
||||||
endif cross
|
endif cross
|
||||||
enddo
|
enddo
|
||||||
|
|
||||||
end function qsort_partition
|
end function qsort_partition
|
||||||
|
|
||||||
end subroutine math_sort
|
end subroutine math_sort
|
||||||
|
@ -196,7 +201,7 @@ end subroutine math_sort
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @brief vector expansion
|
!> @brief vector expansion
|
||||||
!> @details takes a set of numbers (a,b,c,...) and corresponding multiples (x,y,z,...)
|
!> @details takes a set of numbers (a,b,c,...) and corresponding multiples (x,y,z,...)
|
||||||
!> to return a vector of x times a, y times b, z times c, ...
|
!> to return a vector of x times a, y times b, z times c, ...
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
pure function math_expand(what,how)
|
pure function math_expand(what,how)
|
||||||
|
|
||||||
|
@ -204,9 +209,9 @@ pure function math_expand(what,how)
|
||||||
integer, dimension(:), intent(in) :: how
|
integer, dimension(:), intent(in) :: how
|
||||||
real(pReal), dimension(sum(how)) :: math_expand
|
real(pReal), dimension(sum(how)) :: math_expand
|
||||||
integer :: i
|
integer :: i
|
||||||
|
|
||||||
if (sum(how) == 0) return
|
if (sum(how) == 0) return
|
||||||
|
|
||||||
do i = 1, size(how)
|
do i = 1, size(how)
|
||||||
math_expand(sum(how(1:i-1))+1:sum(how(1:i))) = what(mod(i-1,size(what))+1)
|
math_expand(sum(how(1:i-1))+1:sum(how(1:i))) = what(mod(i-1,size(what))+1)
|
||||||
enddo
|
enddo
|
||||||
|
@ -266,31 +271,30 @@ end function math_identity4th
|
||||||
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @brief permutation tensor e_ijk used for computing cross product of two tensors
|
!> @brief permutation tensor e_ijk
|
||||||
! e_ijk = 1 if even permutation of ijk
|
! e_ijk = 1 if even permutation of ijk
|
||||||
! e_ijk = -1 if odd permutation of ijk
|
! e_ijk = -1 if odd permutation of ijk
|
||||||
! e_ijk = 0 otherwise
|
! e_ijk = 0 otherwise
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
real(pReal) pure function math_civita(i,j,k)
|
real(pReal) pure function math_LeviCivita(i,j,k)
|
||||||
|
|
||||||
integer, intent(in) :: i,j,k
|
integer, intent(in) :: i,j,k
|
||||||
|
|
||||||
math_civita = 0.0_pReal
|
if (all([i,j,k] == [1,2,3]) .or. all([i,j,k] == [2,3,1]) .or. all([i,j,k] == [3,1,2])) then
|
||||||
if (((i == 1).and.(j == 2).and.(k == 3)) .or. &
|
math_LeviCivita = +1.0_pReal
|
||||||
((i == 2).and.(j == 3).and.(k == 1)) .or. &
|
elseif (all([i,j,k] == [3,2,1]) .or. all([i,j,k] == [2,1,3]) .or. all([i,j,k] == [1,3,2])) then
|
||||||
((i == 3).and.(j == 1).and.(k == 2))) math_civita = 1.0_pReal
|
math_LeviCivita = -1.0_pReal
|
||||||
if (((i == 1).and.(j == 3).and.(k == 2)) .or. &
|
else
|
||||||
((i == 2).and.(j == 1).and.(k == 3)) .or. &
|
math_LeviCivita = 0.0_pReal
|
||||||
((i == 3).and.(j == 2).and.(k == 1))) math_civita = -1.0_pReal
|
endif
|
||||||
|
|
||||||
end function math_civita
|
end function math_LeviCivita
|
||||||
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @brief kronecker delta function d_ij
|
!> @brief kronecker delta function d_ij
|
||||||
! d_ij = 1 if i = j
|
! d_ij = 1 if i = j
|
||||||
! d_ij = 0 otherwise
|
! d_ij = 0 otherwise
|
||||||
! inspired by http://fortraninacworld.blogspot.de/2012/12/ternary-operator.html
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
real(pReal) pure function math_delta(i,j)
|
real(pReal) pure function math_delta(i,j)
|
||||||
|
|
||||||
|
@ -317,7 +321,7 @@ end function math_cross
|
||||||
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @brief outer product A \otimes B of arbitrary sized vectors A and B
|
!> @brief outer product of arbitrary sized vectors (A ⊗ B / i,j)
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
pure function math_outer(A,B)
|
pure function math_outer(A,B)
|
||||||
|
|
||||||
|
@ -333,7 +337,7 @@ end function math_outer
|
||||||
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @brief outer product A \otimes B of arbitrary sized vectors A and B
|
!> @brief inner product of arbitrary sized vectors (A · B / i,i)
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
real(pReal) pure function math_inner(A,B)
|
real(pReal) pure function math_inner(A,B)
|
||||||
|
|
||||||
|
@ -346,31 +350,26 @@ end function math_inner
|
||||||
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @brief matrix multiplication 33xx33 = 1 (double contraction --> ij * ij)
|
!> @brief double contraction of 3x3 matrices (A : B / ij,ij)
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
real(pReal) pure function math_mul33xx33(A,B)
|
real(pReal) pure function math_tensordot(A,B)
|
||||||
|
|
||||||
real(pReal), dimension(3,3), intent(in) :: A,B
|
real(pReal), dimension(3,3), intent(in) :: A,B
|
||||||
integer :: i,j
|
|
||||||
real(pReal), dimension(3,3) :: C
|
|
||||||
|
|
||||||
do i=1,3; do j=1,3
|
math_tensordot = sum(A*B)
|
||||||
C(i,j) = A(i,j) * B(i,j)
|
|
||||||
enddo; enddo
|
|
||||||
math_mul33xx33 = sum(C)
|
|
||||||
|
|
||||||
end function math_mul33xx33
|
end function math_tensordot
|
||||||
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @brief matrix multiplication 3333x33 = 33 (double contraction --> ijkl *kl = ij)
|
!> @brief matrix double contraction 3333x33 = 33 (ijkl,kl)
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
pure function math_mul3333xx33(A,B)
|
pure function math_mul3333xx33(A,B)
|
||||||
|
|
||||||
real(pReal), dimension(3,3,3,3), intent(in) :: A
|
real(pReal), dimension(3,3,3,3), intent(in) :: A
|
||||||
real(pReal), dimension(3,3), intent(in) :: B
|
real(pReal), dimension(3,3), intent(in) :: B
|
||||||
real(pReal), dimension(3,3) :: math_mul3333xx33
|
real(pReal), dimension(3,3) :: math_mul3333xx33
|
||||||
integer :: i,j
|
integer :: i,j
|
||||||
|
|
||||||
do i=1,3; do j=1,3
|
do i=1,3; do j=1,3
|
||||||
math_mul3333xx33(i,j) = sum(A(i,j,1:3,1:3)*B(1:3,1:3))
|
math_mul3333xx33(i,j) = sum(A(i,j,1:3,1:3)*B(1:3,1:3))
|
||||||
|
@ -380,7 +379,7 @@ end function math_mul3333xx33
|
||||||
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @brief matrix multiplication 3333x3333 = 3333 (ijkl *klmn = ijmn)
|
!> @brief matrix multiplication 3333x3333 = 3333 (ijkl,klmn)
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
pure function math_mul3333xx3333(A,B)
|
pure function math_mul3333xx3333(A,B)
|
||||||
|
|
||||||
|
@ -402,8 +401,9 @@ end function math_mul3333xx3333
|
||||||
pure function math_exp33(A,n)
|
pure function math_exp33(A,n)
|
||||||
|
|
||||||
real(pReal), dimension(3,3), intent(in) :: A
|
real(pReal), dimension(3,3), intent(in) :: A
|
||||||
integer, intent(in), optional :: n
|
integer, intent(in), optional :: n
|
||||||
real(pReal), dimension(3,3) :: B, math_exp33
|
real(pReal), dimension(3,3) :: B, math_exp33
|
||||||
|
|
||||||
real(pReal) :: invFac
|
real(pReal) :: invFac
|
||||||
integer :: n_,i
|
integer :: n_,i
|
||||||
|
|
||||||
|
@ -428,15 +428,16 @@ end function math_exp33
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @brief Cramer inversion of 33 matrix (function)
|
!> @brief Cramer inversion of 33 matrix (function)
|
||||||
!> @details Direct Cramer inversion of matrix A. Returns all zeroes if not possible, i.e.
|
!> @details Direct Cramer inversion of matrix A. Returns all zeroes if not possible, i.e.
|
||||||
! if determinant is close to zero
|
! if determinant is close to zero
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
pure function math_inv33(A)
|
pure function math_inv33(A)
|
||||||
|
|
||||||
real(pReal),dimension(3,3),intent(in) :: A
|
real(pReal), dimension(3,3), intent(in) :: A
|
||||||
real(pReal) :: DetA
|
real(pReal), dimension(3,3) :: math_inv33
|
||||||
real(pReal),dimension(3,3) :: math_inv33
|
|
||||||
logical :: error
|
real(pReal) :: DetA
|
||||||
|
logical :: error
|
||||||
|
|
||||||
call math_invert33(math_inv33,DetA,error,A)
|
call math_invert33(math_inv33,DetA,error,A)
|
||||||
if(error) math_inv33 = 0.0_pReal
|
if(error) math_inv33 = 0.0_pReal
|
||||||
|
@ -451,10 +452,10 @@ end function math_inv33
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
pure subroutine math_invert33(InvA, DetA, error, A)
|
pure subroutine math_invert33(InvA, DetA, error, A)
|
||||||
|
|
||||||
logical, intent(out) :: error
|
real(pReal), dimension(3,3), intent(out) :: InvA
|
||||||
real(pReal),dimension(3,3),intent(in) :: A
|
real(pReal), intent(out) :: DetA
|
||||||
real(pReal),dimension(3,3),intent(out) :: InvA
|
logical, intent(out) :: error
|
||||||
real(pReal), intent(out) :: DetA
|
real(pReal), dimension(3,3), intent(in) :: A
|
||||||
|
|
||||||
InvA(1,1) = A(2,2) * A(3,3) - A(2,3) * A(3,2)
|
InvA(1,1) = A(2,2) * A(3,3) - A(2,3) * A(3,2)
|
||||||
InvA(2,1) = -A(2,1) * A(3,3) + A(2,3) * A(3,1)
|
InvA(2,1) = -A(2,1) * A(3,3) + A(2,3) * A(3,1)
|
||||||
|
@ -529,12 +530,12 @@ subroutine math_invert(InvA, error, A)
|
||||||
dgetrf, &
|
dgetrf, &
|
||||||
dgetri
|
dgetri
|
||||||
|
|
||||||
invA = A
|
invA = A
|
||||||
call dgetrf(size(A,1),size(A,1),invA,size(A,1),ipiv,ierr)
|
call dgetrf(size(A,1),size(A,1),invA,size(A,1),ipiv,ierr)
|
||||||
error = (ierr /= 0)
|
error = (ierr /= 0)
|
||||||
call dgetri(size(A,1),InvA,size(A,1),ipiv,work,size(work,1),ierr)
|
call dgetri(size(A,1),InvA,size(A,1),ipiv,work,size(work,1),ierr)
|
||||||
error = error .or. (ierr /= 0)
|
error = error .or. (ierr /= 0)
|
||||||
|
|
||||||
end subroutine math_invert
|
end subroutine math_invert
|
||||||
|
|
||||||
|
|
||||||
|
@ -621,7 +622,7 @@ end function math_trace33
|
||||||
real(pReal) pure function math_det33(m)
|
real(pReal) pure function math_det33(m)
|
||||||
|
|
||||||
real(pReal), dimension(3,3), intent(in) :: m
|
real(pReal), dimension(3,3), intent(in) :: m
|
||||||
|
|
||||||
math_det33 = m(1,1)* (m(2,2)*m(3,3)-m(2,3)*m(3,2)) &
|
math_det33 = m(1,1)* (m(2,2)*m(3,3)-m(2,3)*m(3,2)) &
|
||||||
- m(1,2)* (m(2,1)*m(3,3)-m(2,3)*m(3,1)) &
|
- m(1,2)* (m(2,1)*m(3,3)-m(2,3)*m(3,1)) &
|
||||||
+ m(1,3)* (m(2,1)*m(3,2)-m(2,2)*m(3,1))
|
+ m(1,3)* (m(2,1)*m(3,2)-m(2,2)*m(3,1))
|
||||||
|
@ -635,7 +636,7 @@ end function math_det33
|
||||||
real(pReal) pure function math_detSym33(m)
|
real(pReal) pure function math_detSym33(m)
|
||||||
|
|
||||||
real(pReal), dimension(3,3), intent(in) :: m
|
real(pReal), dimension(3,3), intent(in) :: m
|
||||||
|
|
||||||
math_detSym33 = -(m(1,1)*m(2,3)**2 + m(2,2)*m(1,3)**2 + m(3,3)*m(1,2)**2) &
|
math_detSym33 = -(m(1,1)*m(2,3)**2 + m(2,2)*m(1,3)**2 + m(3,3)*m(1,2)**2) &
|
||||||
+ m(1,1)*m(2,2)*m(3,3) + 2.0_pReal * m(1,2)*m(1,3)*m(2,3)
|
+ m(1,1)*m(2,2)*m(3,3) + 2.0_pReal * m(1,2)*m(1,3)*m(2,3)
|
||||||
|
|
||||||
|
@ -649,9 +650,9 @@ pure function math_33to9(m33)
|
||||||
|
|
||||||
real(pReal), dimension(9) :: math_33to9
|
real(pReal), dimension(9) :: math_33to9
|
||||||
real(pReal), dimension(3,3), intent(in) :: m33
|
real(pReal), dimension(3,3), intent(in) :: m33
|
||||||
|
|
||||||
integer :: i
|
integer :: i
|
||||||
|
|
||||||
do i = 1, 9
|
do i = 1, 9
|
||||||
math_33to9(i) = m33(MAPPLAIN(1,i),MAPPLAIN(2,i))
|
math_33to9(i) = m33(MAPPLAIN(1,i),MAPPLAIN(2,i))
|
||||||
enddo
|
enddo
|
||||||
|
@ -666,7 +667,7 @@ pure function math_9to33(v9)
|
||||||
|
|
||||||
real(pReal), dimension(3,3) :: math_9to33
|
real(pReal), dimension(3,3) :: math_9to33
|
||||||
real(pReal), dimension(9), intent(in) :: v9
|
real(pReal), dimension(9), intent(in) :: v9
|
||||||
|
|
||||||
integer :: i
|
integer :: i
|
||||||
|
|
||||||
do i = 1, 9
|
do i = 1, 9
|
||||||
|
@ -687,10 +688,10 @@ pure function math_sym33to6(m33,weighted)
|
||||||
real(pReal), dimension(6) :: math_sym33to6
|
real(pReal), dimension(6) :: math_sym33to6
|
||||||
real(pReal), dimension(3,3), intent(in) :: m33 !< symmetric matrix (no internal check)
|
real(pReal), dimension(3,3), intent(in) :: m33 !< symmetric matrix (no internal check)
|
||||||
logical, optional, intent(in) :: weighted !< weight according to Mandel (.true. by default)
|
logical, optional, intent(in) :: weighted !< weight according to Mandel (.true. by default)
|
||||||
|
|
||||||
real(pReal), dimension(6) :: w
|
real(pReal), dimension(6) :: w
|
||||||
integer :: i
|
integer :: i
|
||||||
|
|
||||||
if(present(weighted)) then
|
if(present(weighted)) then
|
||||||
w = merge(NRMMANDEL,1.0_pReal,weighted)
|
w = merge(NRMMANDEL,1.0_pReal,weighted)
|
||||||
else
|
else
|
||||||
|
@ -699,7 +700,7 @@ pure function math_sym33to6(m33,weighted)
|
||||||
|
|
||||||
do i = 1, 6
|
do i = 1, 6
|
||||||
math_sym33to6(i) = w(i)*m33(MAPNYE(1,i),MAPNYE(2,i))
|
math_sym33to6(i) = w(i)*m33(MAPNYE(1,i),MAPNYE(2,i))
|
||||||
enddo
|
enddo
|
||||||
|
|
||||||
end function math_sym33to6
|
end function math_sym33to6
|
||||||
|
|
||||||
|
@ -718,7 +719,7 @@ pure function math_6toSym33(v6,weighted)
|
||||||
|
|
||||||
real(pReal), dimension(6) :: w
|
real(pReal), dimension(6) :: w
|
||||||
integer :: i
|
integer :: i
|
||||||
|
|
||||||
if(present(weighted)) then
|
if(present(weighted)) then
|
||||||
w = merge(INVNRMMANDEL,1.0_pReal,weighted)
|
w = merge(INVNRMMANDEL,1.0_pReal,weighted)
|
||||||
else
|
else
|
||||||
|
@ -781,7 +782,7 @@ pure function math_sym3333to66(m3333,weighted)
|
||||||
|
|
||||||
real(pReal), dimension(6) :: w
|
real(pReal), dimension(6) :: w
|
||||||
integer :: i,j
|
integer :: i,j
|
||||||
|
|
||||||
if(present(weighted)) then
|
if(present(weighted)) then
|
||||||
w = merge(NRMMANDEL,1.0_pReal,weighted)
|
w = merge(NRMMANDEL,1.0_pReal,weighted)
|
||||||
else
|
else
|
||||||
|
@ -806,10 +807,10 @@ pure function math_66toSym3333(m66,weighted)
|
||||||
real(pReal), dimension(3,3,3,3) :: math_66toSym3333
|
real(pReal), dimension(3,3,3,3) :: math_66toSym3333
|
||||||
real(pReal), dimension(6,6), intent(in) :: m66
|
real(pReal), dimension(6,6), intent(in) :: m66
|
||||||
logical, optional, intent(in) :: weighted !< weight according to Mandel (.true. by default)
|
logical, optional, intent(in) :: weighted !< weight according to Mandel (.true. by default)
|
||||||
|
|
||||||
real(pReal), dimension(6) :: w
|
real(pReal), dimension(6) :: w
|
||||||
integer :: i,j
|
integer :: i,j
|
||||||
|
|
||||||
if(present(weighted)) then
|
if(present(weighted)) then
|
||||||
w = merge(INVNRMMANDEL,1.0_pReal,weighted)
|
w = merge(INVNRMMANDEL,1.0_pReal,weighted)
|
||||||
else
|
else
|
||||||
|
@ -909,48 +910,48 @@ end subroutine math_eigenValuesVectorsSym
|
||||||
! ToDo: has wrong oder of arguments
|
! ToDo: has wrong oder of arguments
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
subroutine math_eigenValuesVectorsSym33(m,values,vectors)
|
subroutine math_eigenValuesVectorsSym33(m,values,vectors)
|
||||||
|
|
||||||
real(pReal), dimension(3,3),intent(in) :: m
|
real(pReal), dimension(3,3),intent(in) :: m
|
||||||
real(pReal), dimension(3), intent(out) :: values
|
real(pReal), dimension(3), intent(out) :: values
|
||||||
real(pReal), dimension(3,3),intent(out) :: vectors
|
real(pReal), dimension(3,3),intent(out) :: vectors
|
||||||
real(pReal) :: T, U, norm, threshold
|
real(pReal) :: T, U, norm, threshold
|
||||||
logical :: error
|
logical :: error
|
||||||
|
|
||||||
values = math_eigenvaluesSym33(m)
|
values = math_eigenvaluesSym33(m)
|
||||||
|
|
||||||
vectors(1:3,2) = [ m(1, 2) * m(2, 3) - m(1, 3) * m(2, 2), &
|
vectors(1:3,2) = [ m(1, 2) * m(2, 3) - m(1, 3) * m(2, 2), &
|
||||||
m(1, 3) * m(1, 2) - m(2, 3) * m(1, 1), &
|
m(1, 3) * m(1, 2) - m(2, 3) * m(1, 1), &
|
||||||
m(1, 2)**2]
|
m(1, 2)**2]
|
||||||
|
|
||||||
T = maxval(abs(values))
|
T = maxval(abs(values))
|
||||||
U = max(T, T**2)
|
U = max(T, T**2)
|
||||||
threshold = sqrt(5.68e-14_pReal * U**2)
|
threshold = sqrt(5.68e-14_pReal * U**2)
|
||||||
|
|
||||||
! Calculate first eigenvector by the formula v[0] = (m - lambda[0]).e1 x (m - lambda[0]).e2
|
! Calculate first eigenvector by the formula v[0] = (m - lambda[0]).e1 x (m - lambda[0]).e2
|
||||||
vectors(1:3,1) = [ vectors(1,2) + m(1, 3) * values(1), &
|
vectors(1:3,1) = [ vectors(1,2) + m(1, 3) * values(1), &
|
||||||
vectors(2,2) + m(2, 3) * values(1), &
|
vectors(2,2) + m(2, 3) * values(1), &
|
||||||
(m(1,1) - values(1)) * (m(2,2) - values(1)) - vectors(3,2)]
|
(m(1,1) - values(1)) * (m(2,2) - values(1)) - vectors(3,2)]
|
||||||
norm = norm2(vectors(1:3, 1))
|
norm = norm2(vectors(1:3, 1))
|
||||||
|
|
||||||
fallback1: if(norm < threshold) then
|
fallback1: if(norm < threshold) then
|
||||||
call math_eigenValuesVectorsSym(m,values,vectors,error)
|
call math_eigenValuesVectorsSym(m,values,vectors,error)
|
||||||
return
|
return
|
||||||
endif fallback1
|
endif fallback1
|
||||||
|
|
||||||
vectors(1:3,1) = vectors(1:3, 1) / norm
|
vectors(1:3,1) = vectors(1:3, 1) / norm
|
||||||
|
|
||||||
! Calculate second eigenvector by the formula v[1] = (m - lambda[1]).e1 x (m - lambda[1]).e2
|
! Calculate second eigenvector by the formula v[1] = (m - lambda[1]).e1 x (m - lambda[1]).e2
|
||||||
vectors(1:3,2) = [ vectors(1,2) + m(1, 3) * values(2), &
|
vectors(1:3,2) = [ vectors(1,2) + m(1, 3) * values(2), &
|
||||||
vectors(2,2) + m(2, 3) * values(2), &
|
vectors(2,2) + m(2, 3) * values(2), &
|
||||||
(m(1,1) - values(2)) * (m(2,2) - values(2)) - vectors(3,2)]
|
(m(1,1) - values(2)) * (m(2,2) - values(2)) - vectors(3,2)]
|
||||||
norm = norm2(vectors(1:3, 2))
|
norm = norm2(vectors(1:3, 2))
|
||||||
|
|
||||||
fallback2: if(norm < threshold) then
|
fallback2: if(norm < threshold) then
|
||||||
call math_eigenValuesVectorsSym(m,values,vectors,error)
|
call math_eigenValuesVectorsSym(m,values,vectors,error)
|
||||||
return
|
return
|
||||||
endif fallback2
|
endif fallback2
|
||||||
vectors(1:3,2) = vectors(1:3, 2) / norm
|
vectors(1:3,2) = vectors(1:3, 2) / norm
|
||||||
|
|
||||||
! Calculate third eigenvector according to v[2] = v[0] x v[1]
|
! Calculate third eigenvector according to v[2] = v[0] x v[1]
|
||||||
vectors(1:3,3) = math_cross(vectors(1:3,1),vectors(1:3,2))
|
vectors(1:3,3) = math_cross(vectors(1:3,1),vectors(1:3,2))
|
||||||
|
|
||||||
|
@ -968,11 +969,11 @@ function math_eigenvectorBasisSym(m)
|
||||||
real(pReal), dimension(size(m,1),size(m,1)) :: math_eigenvectorBasisSym
|
real(pReal), dimension(size(m,1),size(m,1)) :: math_eigenvectorBasisSym
|
||||||
logical :: error
|
logical :: error
|
||||||
integer :: i
|
integer :: i
|
||||||
|
|
||||||
math_eigenvectorBasisSym = 0.0_pReal
|
math_eigenvectorBasisSym = 0.0_pReal
|
||||||
call math_eigenValuesVectorsSym(m,values,vectors,error)
|
call math_eigenValuesVectorsSym(m,values,vectors,error)
|
||||||
if(error) return
|
if(error) return
|
||||||
|
|
||||||
do i=1, size(m,1)
|
do i=1, size(m,1)
|
||||||
math_eigenvectorBasisSym = math_eigenvectorBasisSym &
|
math_eigenvectorBasisSym = math_eigenvectorBasisSym &
|
||||||
+ sqrt(values(i)) * math_outer(vectors(:,i),vectors(:,i))
|
+ sqrt(values(i)) * math_outer(vectors(:,i),vectors(:,i))
|
||||||
|
@ -992,13 +993,13 @@ pure function math_eigenvectorBasisSym33(m)
|
||||||
real(pReal) :: P, Q, rho, phi
|
real(pReal) :: P, Q, rho, phi
|
||||||
real(pReal), parameter :: TOL=1.e-14_pReal
|
real(pReal), parameter :: TOL=1.e-14_pReal
|
||||||
real(pReal), dimension(3,3,3) :: N, EB
|
real(pReal), dimension(3,3,3) :: N, EB
|
||||||
|
|
||||||
invariants = math_invariantsSym33(m)
|
invariants = math_invariantsSym33(m)
|
||||||
EB = 0.0_pReal
|
EB = 0.0_pReal
|
||||||
|
|
||||||
P = invariants(2)-invariants(1)**2.0_pReal/3.0_pReal
|
P = invariants(2)-invariants(1)**2.0_pReal/3.0_pReal
|
||||||
Q = -2.0_pReal/27.0_pReal*invariants(1)**3.0_pReal+product(invariants(1:2))/3.0_pReal-invariants(3)
|
Q = -2.0_pReal/27.0_pReal*invariants(1)**3.0_pReal+product(invariants(1:2))/3.0_pReal-invariants(3)
|
||||||
|
|
||||||
threeSimilarEigenvalues: if(all(abs([P,Q]) < TOL)) then
|
threeSimilarEigenvalues: if(all(abs([P,Q]) < TOL)) then
|
||||||
values = invariants(1)/3.0_pReal
|
values = invariants(1)/3.0_pReal
|
||||||
! this is not really correct, but at least the basis is correct
|
! this is not really correct, but at least the basis is correct
|
||||||
|
@ -1016,7 +1017,7 @@ pure function math_eigenvectorBasisSym33(m)
|
||||||
N(1:3,1:3,1) = m-values(1)*math_I3
|
N(1:3,1:3,1) = m-values(1)*math_I3
|
||||||
N(1:3,1:3,2) = m-values(2)*math_I3
|
N(1:3,1:3,2) = m-values(2)*math_I3
|
||||||
N(1:3,1:3,3) = m-values(3)*math_I3
|
N(1:3,1:3,3) = m-values(3)*math_I3
|
||||||
twoSimilarEigenvalues: if(abs(values(1)-values(2)) < TOL) then
|
twoSimilarEigenvalues: if(abs(values(1)-values(2)) < TOL) then
|
||||||
EB(1:3,1:3,3)=matmul(N(1:3,1:3,1),N(1:3,1:3,2))/ &
|
EB(1:3,1:3,3)=matmul(N(1:3,1:3,1),N(1:3,1:3,2))/ &
|
||||||
((values(3)-values(1))*(values(3)-values(2)))
|
((values(3)-values(1))*(values(3)-values(2)))
|
||||||
EB(1:3,1:3,1)=math_I3-EB(1:3,1:3,3)
|
EB(1:3,1:3,1)=math_I3-EB(1:3,1:3,3)
|
||||||
|
@ -1024,7 +1025,7 @@ pure function math_eigenvectorBasisSym33(m)
|
||||||
EB(1:3,1:3,1)=matmul(N(1:3,1:3,2),N(1:3,1:3,3))/ &
|
EB(1:3,1:3,1)=matmul(N(1:3,1:3,2),N(1:3,1:3,3))/ &
|
||||||
((values(1)-values(2))*(values(1)-values(3)))
|
((values(1)-values(2))*(values(1)-values(3)))
|
||||||
EB(1:3,1:3,2)=math_I3-EB(1:3,1:3,1)
|
EB(1:3,1:3,2)=math_I3-EB(1:3,1:3,1)
|
||||||
elseif(abs(values(3)-values(1)) < TOL) then twoSimilarEigenvalues
|
elseif(abs(values(3)-values(1)) < TOL) then twoSimilarEigenvalues
|
||||||
EB(1:3,1:3,2)=matmul(N(1:3,1:3,1),N(1:3,1:3,3))/ &
|
EB(1:3,1:3,2)=matmul(N(1:3,1:3,1),N(1:3,1:3,3))/ &
|
||||||
((values(2)-values(1))*(values(2)-values(3)))
|
((values(2)-values(1))*(values(2)-values(3)))
|
||||||
EB(1:3,1:3,1)=math_I3-EB(1:3,1:3,2)
|
EB(1:3,1:3,1)=math_I3-EB(1:3,1:3,2)
|
||||||
|
@ -1080,7 +1081,7 @@ pure function math_eigenvectorBasisSym33_log(m)
|
||||||
N(1:3,1:3,1) = m-values(1)*math_I3
|
N(1:3,1:3,1) = m-values(1)*math_I3
|
||||||
N(1:3,1:3,2) = m-values(2)*math_I3
|
N(1:3,1:3,2) = m-values(2)*math_I3
|
||||||
N(1:3,1:3,3) = m-values(3)*math_I3
|
N(1:3,1:3,3) = m-values(3)*math_I3
|
||||||
twoSimilarEigenvalues: if(abs(values(1)-values(2)) < TOL) then
|
twoSimilarEigenvalues: if(abs(values(1)-values(2)) < TOL) then
|
||||||
EB(1:3,1:3,3)=matmul(N(1:3,1:3,1),N(1:3,1:3,2))/ &
|
EB(1:3,1:3,3)=matmul(N(1:3,1:3,1),N(1:3,1:3,2))/ &
|
||||||
((values(3)-values(1))*(values(3)-values(2)))
|
((values(3)-values(1))*(values(3)-values(2)))
|
||||||
EB(1:3,1:3,1)=math_I3-EB(1:3,1:3,3)
|
EB(1:3,1:3,1)=math_I3-EB(1:3,1:3,3)
|
||||||
|
@ -1088,7 +1089,7 @@ pure function math_eigenvectorBasisSym33_log(m)
|
||||||
EB(1:3,1:3,1)=matmul(N(1:3,1:3,2),N(1:3,1:3,3))/ &
|
EB(1:3,1:3,1)=matmul(N(1:3,1:3,2),N(1:3,1:3,3))/ &
|
||||||
((values(1)-values(2))*(values(1)-values(3)))
|
((values(1)-values(2))*(values(1)-values(3)))
|
||||||
EB(1:3,1:3,2)=math_I3-EB(1:3,1:3,1)
|
EB(1:3,1:3,2)=math_I3-EB(1:3,1:3,1)
|
||||||
elseif(abs(values(3)-values(1)) < TOL) then twoSimilarEigenvalues
|
elseif(abs(values(3)-values(1)) < TOL) then twoSimilarEigenvalues
|
||||||
EB(1:3,1:3,2)=matmul(N(1:3,1:3,1),N(1:3,1:3,3))/ &
|
EB(1:3,1:3,2)=matmul(N(1:3,1:3,1),N(1:3,1:3,3))/ &
|
||||||
((values(2)-values(1))*(values(2)-values(3)))
|
((values(2)-values(1))*(values(2)-values(3)))
|
||||||
EB(1:3,1:3,1)=math_I3-EB(1:3,1:3,2)
|
EB(1:3,1:3,1)=math_I3-EB(1:3,1:3,2)
|
||||||
|
@ -1136,7 +1137,7 @@ end function math_rotationalPart33
|
||||||
! will return NaN on error
|
! will return NaN on error
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
function math_eigenvaluesSym(m)
|
function math_eigenvaluesSym(m)
|
||||||
|
|
||||||
real(pReal), dimension(:,:), intent(in) :: m
|
real(pReal), dimension(:,:), intent(in) :: m
|
||||||
real(pReal), dimension(size(m,1)) :: math_eigenvaluesSym
|
real(pReal), dimension(size(m,1)) :: math_eigenvaluesSym
|
||||||
real(pReal), dimension(size(m,1),size(m,1)) :: m_
|
real(pReal), dimension(size(m,1),size(m,1)) :: m_
|
||||||
|
@ -1221,7 +1222,7 @@ integer pure function math_binomial(n,k)
|
||||||
|
|
||||||
integer, intent(in) :: n, k
|
integer, intent(in) :: n, k
|
||||||
integer :: i, k_, n_
|
integer :: i, k_, n_
|
||||||
|
|
||||||
k_ = min(k,n-k)
|
k_ = min(k,n-k)
|
||||||
n_ = n
|
n_ = n
|
||||||
math_binomial = merge(1,0,k_>-1) ! handling special cases k < 0 or k > n
|
math_binomial = merge(1,0,k_>-1) ! handling special cases k < 0 or k > n
|
||||||
|
@ -1244,7 +1245,7 @@ integer pure function math_multinomial(alpha)
|
||||||
math_multinomial = 1
|
math_multinomial = 1
|
||||||
do i = 1, size(alpha)
|
do i = 1, size(alpha)
|
||||||
math_multinomial = math_multinomial*math_binomial(sum(alpha(1:i)),alpha(i))
|
math_multinomial = math_multinomial*math_binomial(sum(alpha(1:i)),alpha(i))
|
||||||
enddo
|
enddo
|
||||||
|
|
||||||
end function math_multinomial
|
end function math_multinomial
|
||||||
|
|
||||||
|
@ -1307,6 +1308,7 @@ subroutine unitTest
|
||||||
sort_out_ = reshape([-1,-1, +1,+5, +5,+6, +3,-2],[2,4])
|
sort_out_ = reshape([-1,-1, +1,+5, +5,+6, +3,-2],[2,4])
|
||||||
|
|
||||||
integer, dimension(5) :: range_out_ = [1,2,3,4,5]
|
integer, dimension(5) :: range_out_ = [1,2,3,4,5]
|
||||||
|
integer, dimension(3) :: ijk
|
||||||
|
|
||||||
real(pReal) :: det
|
real(pReal) :: det
|
||||||
real(pReal), dimension(3) :: v3_1,v3_2,v3_3,v3_4
|
real(pReal), dimension(3) :: v3_1,v3_2,v3_3,v3_4
|
||||||
|
@ -1349,7 +1351,7 @@ subroutine unitTest
|
||||||
call random_number(v9)
|
call random_number(v9)
|
||||||
if(any(dNeq(math_33to9(math_9to33(v9)),v9))) &
|
if(any(dNeq(math_33to9(math_9to33(v9)),v9))) &
|
||||||
call IO_error(0,ext_msg='math_33to9/math_9to33')
|
call IO_error(0,ext_msg='math_33to9/math_9to33')
|
||||||
|
|
||||||
call random_number(t99)
|
call random_number(t99)
|
||||||
if(any(dNeq(math_3333to99(math_99to3333(t99)),t99))) &
|
if(any(dNeq(math_3333to99(math_99to3333(t99)),t99))) &
|
||||||
call IO_error(0,ext_msg='math_3333to99/math_99to3333')
|
call IO_error(0,ext_msg='math_3333to99/math_99to3333')
|
||||||
|
@ -1378,7 +1380,7 @@ subroutine unitTest
|
||||||
call random_number(t33)
|
call random_number(t33)
|
||||||
if(dNeq(math_det33(math_symmetric33(t33)),math_detSym33(math_symmetric33(t33)),tol=1.0e-12_pReal)) &
|
if(dNeq(math_det33(math_symmetric33(t33)),math_detSym33(math_symmetric33(t33)),tol=1.0e-12_pReal)) &
|
||||||
call IO_error(0,ext_msg='math_det33/math_detSym33')
|
call IO_error(0,ext_msg='math_det33/math_detSym33')
|
||||||
|
|
||||||
if(any(dNeq0(math_identity2nd(3),math_inv33(math_I3)))) &
|
if(any(dNeq0(math_identity2nd(3),math_inv33(math_I3)))) &
|
||||||
call IO_error(0,ext_msg='math_inv33(math_I3)')
|
call IO_error(0,ext_msg='math_inv33(math_I3)')
|
||||||
|
|
||||||
|
@ -1410,18 +1412,28 @@ subroutine unitTest
|
||||||
if(any(dNeq0(txx_2,txx) .or. e)) &
|
if(any(dNeq0(txx_2,txx) .or. e)) &
|
||||||
call IO_error(0,ext_msg='math_invert(txx)/math_identity2nd')
|
call IO_error(0,ext_msg='math_invert(txx)/math_identity2nd')
|
||||||
|
|
||||||
call math_invert(t99_2,e,t99) ! not sure how likely it is that we get a singular matrix
|
call math_invert(t99_2,e,t99) ! not sure how likely it is that we get a singular matrix
|
||||||
if(any(dNeq0(matmul(t99_2,t99)-math_identity2nd(9),tol=1.0e-9_pReal)) .or. e) &
|
if(any(dNeq0(matmul(t99_2,t99)-math_identity2nd(9),tol=1.0e-9_pReal)) .or. e) &
|
||||||
call IO_error(0,ext_msg='math_invert(t99)')
|
call IO_error(0,ext_msg='math_invert(t99)')
|
||||||
|
|
||||||
if(any(dNeq(math_clip([4.0_pReal,9.0_pReal],5.0_pReal,6.5_pReal),[5.0_pReal,6.5_pReal]))) &
|
if(any(dNeq(math_clip([4.0_pReal,9.0_pReal],5.0_pReal,6.5_pReal),[5.0_pReal,6.5_pReal]))) &
|
||||||
call IO_error(0,ext_msg='math_clip')
|
call IO_error(0,ext_msg='math_clip')
|
||||||
|
|
||||||
if(math_factorial(10) /= 3628800) &
|
if(math_factorial(10) /= 3628800) &
|
||||||
call IO_error(0,ext_msg='math_factorial')
|
call IO_error(0,ext_msg='math_factorial')
|
||||||
|
|
||||||
if(math_binomial(49,6) /= 13983816) &
|
if(math_binomial(49,6) /= 13983816) &
|
||||||
call IO_error(0,ext_msg='math_binomial')
|
call IO_error(0,ext_msg='math_binomial')
|
||||||
|
|
||||||
|
ijk = cshift([1,2,3],int(r*1.0e2_pReal))
|
||||||
|
if(dNeq(math_LeviCivita(ijk(1),ijk(2),ijk(3)),+1.0_pReal)) &
|
||||||
|
call IO_error(0,ext_msg='math_LeviCivita(even)')
|
||||||
|
ijk = cshift([3,2,1],int(r*2.0e2_pReal))
|
||||||
|
if(dNeq(math_LeviCivita(ijk(1),ijk(2),ijk(3)),-1.0_pReal)) &
|
||||||
|
call IO_error(0,ext_msg='math_LeviCivita(odd)')
|
||||||
|
ijk = cshift([2,2,1],int(r*2.0e2_pReal))
|
||||||
|
if(dNeq0(math_LeviCivita(ijk(1),ijk(2),ijk(3))))&
|
||||||
|
call IO_error(0,ext_msg='math_LeviCivita')
|
||||||
|
|
||||||
end subroutine unitTest
|
end subroutine unitTest
|
||||||
|
|
||||||
|
|
|
@ -485,15 +485,15 @@ end subroutine results_writeScalarDataset_rotation
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @brief adds the unique mapping from spatial position and constituent ID to results
|
!> @brief adds the unique mapping from spatial position and constituent ID to results
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
subroutine results_mapping_constituent(phaseAt,memberAt,label)
|
subroutine results_mapping_constituent(phaseAt,memberAtLocal,label)
|
||||||
|
|
||||||
integer, dimension(:,:), intent(in) :: phaseAt !< phase section at (constituent,element)
|
integer, dimension(:,:), intent(in) :: phaseAt !< phase section at (constituent,element)
|
||||||
integer, dimension(:,:,:), intent(in) :: memberAt !< phase member at (constituent,IP,element)
|
integer, dimension(:,:,:), intent(in) :: memberAtLocal !< phase member at (constituent,IP,element)
|
||||||
character(len=*), dimension(:), intent(in) :: label !< label of each phase section
|
character(len=pStringLen), dimension(:), intent(in) :: label !< label of each phase section
|
||||||
|
|
||||||
integer, dimension(size(memberAt,1),size(memberAt,2),size(memberAt,3)) :: &
|
integer, dimension(size(memberAtLocal,1),size(memberAtLocal,2),size(memberAtLocal,3)) :: &
|
||||||
phaseAt_perIP, &
|
phaseAtMaterialpoint, &
|
||||||
memberAt_total
|
memberAtGlobal
|
||||||
integer, dimension(size(label),0:worldsize-1) :: memberOffset !< offset in member counting per process
|
integer, dimension(size(label),0:worldsize-1) :: memberOffset !< offset in member counting per process
|
||||||
integer, dimension(0:worldsize-1) :: writeSize !< amount of data written per process
|
integer, dimension(0:worldsize-1) :: writeSize !< amount of data written per process
|
||||||
integer(HSIZE_T), dimension(2) :: &
|
integer(HSIZE_T), dimension(2) :: &
|
||||||
|
@ -543,10 +543,10 @@ subroutine results_mapping_constituent(phaseAt,memberAt,label)
|
||||||
call h5pcreate_f(H5P_DATASET_XFER_F, plist_id, ierr)
|
call h5pcreate_f(H5P_DATASET_XFER_F, plist_id, ierr)
|
||||||
memberOffset = 0
|
memberOffset = 0
|
||||||
do i=1, size(label)
|
do i=1, size(label)
|
||||||
memberOffset(i,worldrank) = count(phaseAt == i)*size(memberAt,2) ! number of points/instance of this process
|
memberOffset(i,worldrank) = count(phaseAt == i)*size(memberAtLocal,2) ! number of points/instance of this process
|
||||||
enddo
|
enddo
|
||||||
writeSize = 0
|
writeSize = 0
|
||||||
writeSize(worldrank) = size(memberAt(1,:,:)) ! total number of points by this process
|
writeSize(worldrank) = size(memberAtLocal(1,:,:)) ! total number of points by this process
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! MPI settings and communication
|
! MPI settings and communication
|
||||||
|
@ -578,14 +578,14 @@ subroutine results_mapping_constituent(phaseAt,memberAt,label)
|
||||||
|
|
||||||
!---------------------------------------------------------------------------------------------------
|
!---------------------------------------------------------------------------------------------------
|
||||||
! expand phaseAt to consider IPs (is not stored per IP)
|
! expand phaseAt to consider IPs (is not stored per IP)
|
||||||
do i = 1, size(phaseAt_perIP,2)
|
do i = 1, size(phaseAtMaterialpoint,2)
|
||||||
phaseAt_perIP(:,i,:) = phaseAt
|
phaseAtMaterialpoint(:,i,:) = phaseAt
|
||||||
enddo
|
enddo
|
||||||
|
|
||||||
!---------------------------------------------------------------------------------------------------
|
!---------------------------------------------------------------------------------------------------
|
||||||
! renumber member from my process to all processes
|
! renumber member from my process to all processes
|
||||||
do i = 1, size(label)
|
do i = 1, size(label)
|
||||||
where(phaseAt_perIP == i) memberAt_total = memberAt + sum(memberOffset(i,0:worldrank-1)) -1 ! convert to 0-based
|
where(phaseAtMaterialpoint == i) memberAtGlobal = memberAtLocal + sum(memberOffset(i,0:worldrank-1)) -1 ! convert to 0-based
|
||||||
enddo
|
enddo
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
@ -596,10 +596,10 @@ subroutine results_mapping_constituent(phaseAt,memberAt,label)
|
||||||
call h5dcreate_f(loc_id, 'constituent', dtype_id, filespace_id, dset_id, ierr)
|
call h5dcreate_f(loc_id, 'constituent', dtype_id, filespace_id, dset_id, ierr)
|
||||||
if (ierr < 0) call IO_error(1,ext_msg='results_mapping_constituent: h5dcreate_f')
|
if (ierr < 0) call IO_error(1,ext_msg='results_mapping_constituent: h5dcreate_f')
|
||||||
|
|
||||||
call h5dwrite_f(dset_id, name_id, reshape(label(pack(phaseAt_perIP,.true.)),myShape), &
|
call h5dwrite_f(dset_id, name_id, reshape(label(pack(phaseAtMaterialpoint,.true.)),myShape), &
|
||||||
myShape, ierr, file_space_id = filespace_id, mem_space_id = memspace_id, xfer_prp = plist_id)
|
myShape, ierr, file_space_id = filespace_id, mem_space_id = memspace_id, xfer_prp = plist_id)
|
||||||
if (ierr < 0) call IO_error(1,ext_msg='results_mapping_constituent: h5dwrite_f/name_id')
|
if (ierr < 0) call IO_error(1,ext_msg='results_mapping_constituent: h5dwrite_f/name_id')
|
||||||
call h5dwrite_f(dset_id, position_id, reshape(pack(memberAt_total,.true.),myShape), &
|
call h5dwrite_f(dset_id, position_id, reshape(pack(memberAtGlobal,.true.),myShape), &
|
||||||
myShape, ierr, file_space_id = filespace_id, mem_space_id = memspace_id, xfer_prp = plist_id)
|
myShape, ierr, file_space_id = filespace_id, mem_space_id = memspace_id, xfer_prp = plist_id)
|
||||||
if (ierr < 0) call IO_error(1,ext_msg='results_mapping_constituent: h5dwrite_f/position_id')
|
if (ierr < 0) call IO_error(1,ext_msg='results_mapping_constituent: h5dwrite_f/position_id')
|
||||||
|
|
||||||
|
@ -620,15 +620,15 @@ end subroutine results_mapping_constituent
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @brief adds the unique mapping from spatial position and constituent ID to results
|
!> @brief adds the unique mapping from spatial position and constituent ID to results
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
subroutine results_mapping_materialpoint(homogenizationAt,memberAt,label)
|
subroutine results_mapping_materialpoint(homogenizationAt,memberAtLocal,label)
|
||||||
|
|
||||||
integer, dimension(:), intent(in) :: homogenizationAt !< homogenization section at (element)
|
integer, dimension(:), intent(in) :: homogenizationAt !< homogenization section at (element)
|
||||||
integer, dimension(:,:), intent(in) :: memberAt !< homogenization member at (IP,element)
|
integer, dimension(:,:), intent(in) :: memberAtLocal !< homogenization member at (IP,element)
|
||||||
character(len=*), dimension(:), intent(in) :: label !< label of each homogenization section
|
character(len=pStringLen), dimension(:), intent(in) :: label !< label of each homogenization section
|
||||||
|
|
||||||
integer, dimension(size(memberAt,1),size(memberAt,2)) :: &
|
integer, dimension(size(memberAtLocal,1),size(memberAtLocal,2)) :: &
|
||||||
homogenizationAt_perIP, &
|
homogenizationAtMaterialpoint, &
|
||||||
memberAt_total
|
memberAtGlobal
|
||||||
integer, dimension(size(label),0:worldsize-1) :: memberOffset !< offset in member counting per process
|
integer, dimension(size(label),0:worldsize-1) :: memberOffset !< offset in member counting per process
|
||||||
integer, dimension(0:worldsize-1) :: writeSize !< amount of data written per process
|
integer, dimension(0:worldsize-1) :: writeSize !< amount of data written per process
|
||||||
integer(HSIZE_T), dimension(1) :: &
|
integer(HSIZE_T), dimension(1) :: &
|
||||||
|
@ -678,10 +678,10 @@ subroutine results_mapping_materialpoint(homogenizationAt,memberAt,label)
|
||||||
call h5pcreate_f(H5P_DATASET_XFER_F, plist_id, ierr)
|
call h5pcreate_f(H5P_DATASET_XFER_F, plist_id, ierr)
|
||||||
memberOffset = 0
|
memberOffset = 0
|
||||||
do i=1, size(label)
|
do i=1, size(label)
|
||||||
memberOffset(i,worldrank) = count(homogenizationAt == i)*size(memberAt,1) ! number of points/instance of this process
|
memberOffset(i,worldrank) = count(homogenizationAt == i)*size(memberAtLocal,1) ! number of points/instance of this process
|
||||||
enddo
|
enddo
|
||||||
writeSize = 0
|
writeSize = 0
|
||||||
writeSize(worldrank) = size(memberAt) ! total number of points by this process
|
writeSize(worldrank) = size(memberAtLocal) ! total number of points by this process
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! MPI settings and communication
|
! MPI settings and communication
|
||||||
|
@ -713,14 +713,14 @@ subroutine results_mapping_materialpoint(homogenizationAt,memberAt,label)
|
||||||
|
|
||||||
!---------------------------------------------------------------------------------------------------
|
!---------------------------------------------------------------------------------------------------
|
||||||
! expand phaseAt to consider IPs (is not stored per IP)
|
! expand phaseAt to consider IPs (is not stored per IP)
|
||||||
do i = 1, size(homogenizationAt_perIP,1)
|
do i = 1, size(homogenizationAtMaterialpoint,1)
|
||||||
homogenizationAt_perIP(i,:) = homogenizationAt
|
homogenizationAtMaterialpoint(i,:) = homogenizationAt
|
||||||
enddo
|
enddo
|
||||||
|
|
||||||
!---------------------------------------------------------------------------------------------------
|
!---------------------------------------------------------------------------------------------------
|
||||||
! renumber member from my process to all processes
|
! renumber member from my process to all processes
|
||||||
do i = 1, size(label)
|
do i = 1, size(label)
|
||||||
where(homogenizationAt_perIP == i) memberAt_total = memberAt + sum(memberOffset(i,0:worldrank-1)) - 1 ! convert to 0-based
|
where(homogenizationAtMaterialpoint == i) memberAtGlobal = memberAtLocal + sum(memberOffset(i,0:worldrank-1)) - 1 ! convert to 0-based
|
||||||
enddo
|
enddo
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
@ -731,10 +731,10 @@ subroutine results_mapping_materialpoint(homogenizationAt,memberAt,label)
|
||||||
call h5dcreate_f(loc_id, 'materialpoint', dtype_id, filespace_id, dset_id, ierr)
|
call h5dcreate_f(loc_id, 'materialpoint', dtype_id, filespace_id, dset_id, ierr)
|
||||||
if (ierr < 0) call IO_error(1,ext_msg='results_mapping_materialpoint: h5dcreate_f')
|
if (ierr < 0) call IO_error(1,ext_msg='results_mapping_materialpoint: h5dcreate_f')
|
||||||
|
|
||||||
call h5dwrite_f(dset_id, name_id, reshape(label(pack(homogenizationAt_perIP,.true.)),myShape), &
|
call h5dwrite_f(dset_id, name_id, reshape(label(pack(homogenizationAtMaterialpoint,.true.)),myShape), &
|
||||||
myShape, ierr, file_space_id = filespace_id, mem_space_id = memspace_id, xfer_prp = plist_id)
|
myShape, ierr, file_space_id = filespace_id, mem_space_id = memspace_id, xfer_prp = plist_id)
|
||||||
if (ierr < 0) call IO_error(1,ext_msg='results_mapping_materialpoint: h5dwrite_f/name_id')
|
if (ierr < 0) call IO_error(1,ext_msg='results_mapping_materialpoint: h5dwrite_f/name_id')
|
||||||
call h5dwrite_f(dset_id, position_id, reshape(pack(memberAt_total,.true.),myShape), &
|
call h5dwrite_f(dset_id, position_id, reshape(pack(memberAtGlobal,.true.),myShape), &
|
||||||
myShape, ierr, file_space_id = filespace_id, mem_space_id = memspace_id, xfer_prp = plist_id)
|
myShape, ierr, file_space_id = filespace_id, mem_space_id = memspace_id, xfer_prp = plist_id)
|
||||||
if (ierr < 0) call IO_error(1,ext_msg='results_mapping_materialpoint: h5dwrite_f/position_id')
|
if (ierr < 0) call IO_error(1,ext_msg='results_mapping_materialpoint: h5dwrite_f/position_id')
|
||||||
|
|
||||||
|
|
|
@ -16,14 +16,9 @@ module thermal_adiabatic
|
||||||
implicit none
|
implicit none
|
||||||
private
|
private
|
||||||
|
|
||||||
enum, bind(c)
|
|
||||||
enumerator :: undefined_ID, &
|
|
||||||
temperature_ID
|
|
||||||
end enum
|
|
||||||
|
|
||||||
type :: tParameters
|
type :: tParameters
|
||||||
integer(kind(undefined_ID)), dimension(:), allocatable :: &
|
character(len=pStringLen), allocatable, dimension(:) :: &
|
||||||
outputID
|
output
|
||||||
end type tParameters
|
end type tParameters
|
||||||
|
|
||||||
type(tparameters), dimension(:), allocatable :: &
|
type(tparameters), dimension(:), allocatable :: &
|
||||||
|
@ -46,10 +41,9 @@ contains
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
subroutine thermal_adiabatic_init
|
subroutine thermal_adiabatic_init
|
||||||
|
|
||||||
integer :: maxNinstance,o,h,NofMyHomog
|
integer :: maxNinstance,h,NofMyHomog
|
||||||
character(len=pStringLen), dimension(:), allocatable :: outputs
|
|
||||||
|
|
||||||
write(6,'(/,a)') ' <<<+- thermal_'//THERMAL_ADIABATIC_label//' init -+>>>'; flush(6)
|
write(6,'(/,a)') ' <<<+- thermal_'//THERMAL_ADIABATIC_label//' init -+>>>'; flush(6)
|
||||||
|
|
||||||
maxNinstance = count(thermal_type == THERMAL_adiabatic_ID)
|
maxNinstance = count(thermal_type == THERMAL_adiabatic_ID)
|
||||||
if (maxNinstance == 0) return
|
if (maxNinstance == 0) return
|
||||||
|
@ -60,15 +54,7 @@ subroutine thermal_adiabatic_init
|
||||||
if (thermal_type(h) /= THERMAL_adiabatic_ID) cycle
|
if (thermal_type(h) /= THERMAL_adiabatic_ID) cycle
|
||||||
associate(prm => param(thermal_typeInstance(h)),config => config_homogenization(h))
|
associate(prm => param(thermal_typeInstance(h)),config => config_homogenization(h))
|
||||||
|
|
||||||
outputs = config%getStrings('(output)',defaultVal=emptyStringArray)
|
prm%output = config%getStrings('(output)',defaultVal=emptyStringArray)
|
||||||
allocate(prm%outputID(0))
|
|
||||||
|
|
||||||
do o=1, size(outputs)
|
|
||||||
select case(outputs(o))
|
|
||||||
case('temperature')
|
|
||||||
prm%outputID = [prm%outputID, temperature_ID]
|
|
||||||
end select
|
|
||||||
enddo
|
|
||||||
|
|
||||||
NofMyHomog=count(material_homogenizationAt==h)
|
NofMyHomog=count(material_homogenizationAt==h)
|
||||||
thermalState(h)%sizeState = 1
|
thermalState(h)%sizeState = 1
|
||||||
|
@ -76,7 +62,6 @@ subroutine thermal_adiabatic_init
|
||||||
allocate(thermalState(h)%subState0(1,NofMyHomog), source=thermal_initialT(h))
|
allocate(thermalState(h)%subState0(1,NofMyHomog), source=thermal_initialT(h))
|
||||||
allocate(thermalState(h)%state (1,NofMyHomog), source=thermal_initialT(h))
|
allocate(thermalState(h)%state (1,NofMyHomog), source=thermal_initialT(h))
|
||||||
|
|
||||||
nullify(thermalMapping(h)%p)
|
|
||||||
thermalMapping(h)%p => material_homogenizationMemberAt
|
thermalMapping(h)%p => material_homogenizationMemberAt
|
||||||
deallocate(temperature(h)%p)
|
deallocate(temperature(h)%p)
|
||||||
temperature(h)%p => thermalState(h)%state(1,:)
|
temperature(h)%p => thermalState(h)%state(1,:)
|
||||||
|
@ -246,14 +231,13 @@ subroutine thermal_adiabatic_results(homog,group)
|
||||||
|
|
||||||
integer, intent(in) :: homog
|
integer, intent(in) :: homog
|
||||||
character(len=*), intent(in) :: group
|
character(len=*), intent(in) :: group
|
||||||
|
|
||||||
integer :: o
|
integer :: o
|
||||||
|
|
||||||
associate(prm => param(damage_typeInstance(homog)))
|
associate(prm => param(damage_typeInstance(homog)))
|
||||||
|
outputsLoop: do o = 1,size(prm%output)
|
||||||
outputsLoop: do o = 1,size(prm%outputID)
|
select case(trim(prm%output(o)))
|
||||||
select case(prm%outputID(o))
|
case('temperature') ! ToDo: should be 'T'
|
||||||
|
|
||||||
case (temperature_ID)
|
|
||||||
call results_writeDataset(group,temperature(homog)%p,'T',&
|
call results_writeDataset(group,temperature(homog)%p,'T',&
|
||||||
'temperature','K')
|
'temperature','K')
|
||||||
end select
|
end select
|
||||||
|
|
|
@ -15,15 +15,9 @@ module thermal_conduction
|
||||||
implicit none
|
implicit none
|
||||||
private
|
private
|
||||||
|
|
||||||
enum, bind(c)
|
|
||||||
enumerator :: &
|
|
||||||
undefined_ID, &
|
|
||||||
temperature_ID
|
|
||||||
end enum
|
|
||||||
|
|
||||||
type :: tParameters
|
type :: tParameters
|
||||||
integer(kind(undefined_ID)), dimension(:), allocatable :: &
|
character(len=pStringLen), allocatable, dimension(:) :: &
|
||||||
outputID
|
output
|
||||||
end type tParameters
|
end type tParameters
|
||||||
|
|
||||||
type(tparameters), dimension(:), allocatable :: &
|
type(tparameters), dimension(:), allocatable :: &
|
||||||
|
@ -48,10 +42,9 @@ contains
|
||||||
subroutine thermal_conduction_init
|
subroutine thermal_conduction_init
|
||||||
|
|
||||||
|
|
||||||
integer :: maxNinstance,o,NofMyHomog,h
|
integer :: maxNinstance,NofMyHomog,h
|
||||||
character(len=pStringLen), dimension(:), allocatable :: outputs
|
|
||||||
|
|
||||||
write(6,'(/,a)') ' <<<+- thermal_'//THERMAL_CONDUCTION_label//' init -+>>>'; flush(6)
|
write(6,'(/,a)') ' <<<+- thermal_'//THERMAL_CONDUCTION_label//' init -+>>>'; flush(6)
|
||||||
|
|
||||||
maxNinstance = count(thermal_type == THERMAL_conduction_ID)
|
maxNinstance = count(thermal_type == THERMAL_conduction_ID)
|
||||||
if (maxNinstance == 0) return
|
if (maxNinstance == 0) return
|
||||||
|
@ -62,15 +55,7 @@ subroutine thermal_conduction_init
|
||||||
if (thermal_type(h) /= THERMAL_conduction_ID) cycle
|
if (thermal_type(h) /= THERMAL_conduction_ID) cycle
|
||||||
associate(prm => param(thermal_typeInstance(h)),config => config_homogenization(h))
|
associate(prm => param(thermal_typeInstance(h)),config => config_homogenization(h))
|
||||||
|
|
||||||
outputs = config%getStrings('(output)',defaultVal=emptyStringArray)
|
prm%output = config%getStrings('(output)',defaultVal=emptyStringArray)
|
||||||
allocate(prm%outputID(0))
|
|
||||||
|
|
||||||
do o=1, size(outputs)
|
|
||||||
select case(outputs(o))
|
|
||||||
case('temperature')
|
|
||||||
prm%outputID = [prm%outputID, temperature_ID]
|
|
||||||
end select
|
|
||||||
enddo
|
|
||||||
|
|
||||||
NofMyHomog=count(material_homogenizationAt==h)
|
NofMyHomog=count(material_homogenizationAt==h)
|
||||||
thermalState(h)%sizeState = 0
|
thermalState(h)%sizeState = 0
|
||||||
|
@ -78,7 +63,6 @@ subroutine thermal_conduction_init
|
||||||
allocate(thermalState(h)%subState0(0,NofMyHomog))
|
allocate(thermalState(h)%subState0(0,NofMyHomog))
|
||||||
allocate(thermalState(h)%state (0,NofMyHomog))
|
allocate(thermalState(h)%state (0,NofMyHomog))
|
||||||
|
|
||||||
nullify(thermalMapping(h)%p)
|
|
||||||
thermalMapping(h)%p => material_homogenizationMemberAt
|
thermalMapping(h)%p => material_homogenizationMemberAt
|
||||||
deallocate(temperature (h)%p)
|
deallocate(temperature (h)%p)
|
||||||
allocate (temperature (h)%p(NofMyHomog), source=thermal_initialT(h))
|
allocate (temperature (h)%p(NofMyHomog), source=thermal_initialT(h))
|
||||||
|
@ -259,14 +243,13 @@ subroutine thermal_conduction_results(homog,group)
|
||||||
|
|
||||||
integer, intent(in) :: homog
|
integer, intent(in) :: homog
|
||||||
character(len=*), intent(in) :: group
|
character(len=*), intent(in) :: group
|
||||||
|
|
||||||
integer :: o
|
integer :: o
|
||||||
|
|
||||||
associate(prm => param(damage_typeInstance(homog)))
|
associate(prm => param(damage_typeInstance(homog)))
|
||||||
|
outputsLoop: do o = 1,size(prm%output)
|
||||||
outputsLoop: do o = 1,size(prm%outputID)
|
select case(trim(prm%output(o)))
|
||||||
select case(prm%outputID(o))
|
case('temperature') ! ToDo: should be 'T'
|
||||||
|
|
||||||
case (temperature_ID)
|
|
||||||
call results_writeDataset(group,temperature(homog)%p,'T',&
|
call results_writeDataset(group,temperature(homog)%p,'T',&
|
||||||
'temperature','K')
|
'temperature','K')
|
||||||
end select
|
end select
|
||||||
|
|
Loading…
Reference in New Issue