From c880052250f2f2d0fe50def3a90f60185d3db5a0 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Wed, 2 Dec 2020 14:37:44 +0100 Subject: [PATCH 001/148] avoid evil eval --- python/damask/_vtk.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/python/damask/_vtk.py b/python/damask/_vtk.py index 2f4d63791..a1a48f38e 100644 --- a/python/damask/_vtk.py +++ b/python/damask/_vtk.py @@ -76,7 +76,8 @@ class VTK: nodes : numpy.ndarray of shape (:,3) Spatial position of the nodes. connectivity : numpy.ndarray of np.dtype = int - Cell connectivity (0-based), first dimension determines #Cells, second dimension determines #Nodes/Cell. + Cell connectivity (0-based), first dimension determines #Cells, + second dimension determines #Nodes/Cell. cell_type : str Name of the vtk.vtkCell subclass. Tested for TRIANGLE, QUAD, TETRA, and HEXAHEDRON. @@ -91,7 +92,9 @@ class VTK: vtk_data = vtk.vtkUnstructuredGrid() vtk_data.SetPoints(vtk_nodes) - vtk_data.SetCells(eval(f'vtk.VTK_{cell_type.split("_",1)[-1].upper()}'),cells) + cell_types = {'TRIANGLE':vtk.VTK_TRIANGLE, 'QUAD':vtk.VTK_QUAD, + 'TETRA' :vtk.VTK_TETRA, 'HEXAHEDRON':vtk.VTK_HEXAHEDRON} + vtk_data.SetCells(cell_types[cell_type.split("_",1)[-1].upper()],cells) return VTK(vtk_data) From d3a5979d25b312058f5015cfc209d6dece1f3a83 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Wed, 2 Dec 2020 14:45:47 +0100 Subject: [PATCH 002/148] meaningful result --- python/damask/_result.py | 9 +++++---- python/tests/test_Result.py | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/python/damask/_result.py b/python/damask/_result.py index 0e74f86df..bdc1b6d14 100644 --- a/python/damask/_result.py +++ b/python/damask/_result.py @@ -780,7 +780,7 @@ class Result: @staticmethod - def _add_IPF_color(q,l): + def _add_IPF_color(l,q): m = util.scale_to_coprime(np.array(l)) try: lattice = {'fcc':'cF','bcc':'cI','hex':'hP'}[q['meta']['Lattice']] @@ -798,16 +798,17 @@ class Result: 'Creator': 'add_IPF_color' } } - def add_IPF_color(self,q,l): + def add_IPF_color(self,l,q='O'): """ Add RGB color tuple of inverse pole figure (IPF) color. Parameters ---------- - q : str - Label of the dataset containing the crystallographic orientation as quaternions. l : numpy.array of shape (3) Lab frame direction for inverse pole figure. + q : str + Label of the dataset containing the crystallographic orientation as quaternions. + Defaults to 'O'. """ self._add_generic_pointwise(self._add_IPF_color,{'q':q},{'l':l}) diff --git a/python/tests/test_Result.py b/python/tests/test_Result.py index 1e014216e..015265456 100644 --- a/python/tests/test_Result.py +++ b/python/tests/test_Result.py @@ -169,7 +169,7 @@ class TestResult: @pytest.mark.parametrize('d',[[1,0,0],[0,1,0],[0,0,1]]) def test_add_IPF_color(self,default,d): - default.add_IPF_color('O',np.array(d)) + default.add_IPF_color(d,'O') loc = {'O': default.get_dataset_location('O'), 'color': default.get_dataset_location('IPFcolor_[{} {} {}]'.format(*d))} qu = default.read_dataset(loc['O']).view(np.double).squeeze() From 487733498662d112c3a5a5383a2f8187a51789a9 Mon Sep 17 00:00:00 2001 From: Philip Eisenlohr Date: Wed, 2 Dec 2020 19:25:54 -0500 Subject: [PATCH 003/148] added getitem and where functionality to Table --- python/damask/_table.py | 13 +++++++++++++ python/tests/test_Table.py | 17 ++++++++++++++--- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/python/damask/_table.py b/python/damask/_table.py index c05fa71a7..43a8a3ebf 100644 --- a/python/damask/_table.py +++ b/python/damask/_table.py @@ -33,6 +33,10 @@ class Table: """Brief overview.""" return '\n'.join(['# '+c for c in self.comments])+'\n'+self.data.__repr__() + def __getitem__(self,item): + """Return slice according to item.""" + return self.__class__(data=self.data[item],shapes=self.shapes,comments=self.comments) + def __len__(self): """Number of rows.""" return len(self.data) @@ -45,6 +49,15 @@ class Table: """Copy Table.""" return self.__copy__() + def where(self,expression): + """ + Return boolean array corresponding to interpolated expression being True. + + Table columns are addressed as #column# and will have appropriate shapes. + + """ + return eval(re.sub('#(.+?)#',r'self.get("\1")',expression)) + def _label_discrete(self): """Label data individually, e.g. v v v ==> 1_v 2_v 3_v.""" diff --git a/python/tests/test_Table.py b/python/tests/test_Table.py index 8c4465dc1..b1d7684fd 100644 --- a/python/tests/test_Table.py +++ b/python/tests/test_Table.py @@ -8,7 +8,7 @@ from damask import Table def default(): """Simple Table.""" x = np.ones((5,13),dtype=float) - return Table(x,{'F':(3,3),'v':(3,),'s':(1,)},['test data','contains only ones']) + return Table(x,{'F':(3,3),'v':(3,),'s':(1,)},['test data','contains five rows of only ones']) @pytest.fixture def reference_dir(reference_dir_base): @@ -20,8 +20,9 @@ class TestTable: def test_repr(self,default): print(default) - def test_len(self): - len(Table(np.random.rand(7,3),{'X':3})) == 7 + @pytest.mark.parametrize('N',[10,40]) + def test_len(self,N): + len(Table(np.random.rand(N,3),{'X':3})) == N def test_get_scalar(self,default): d = default.get('s') @@ -39,6 +40,16 @@ class TestTable: d = default.get('5_F') assert np.allclose(d,1.0) and d.shape[1:] == (1,) + @pytest.mark.parametrize('N',[10,40]) + def test_getitem(self,N): + assert len(Table(np.random.rand(N,1),{'X':1})[:N//2]) == N//2 + + @pytest.mark.parametrize('N',[10,40]) + @pytest.mark.parametrize('limit',[0.1,0.6]) + def test_where(self,N,limit): + r = Table(np.random.rand(N,1),{'X':1}) + assert np.all(r[r.where(f'#X# > {limit}')].get('X') > limit) + @pytest.mark.parametrize('mode',['str','path']) def test_write_read(self,default,tmp_path,mode): default.save(tmp_path/'default.txt') From ac0a20696c858030ba0b1fdb610f1e66d5c8457e Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Thu, 3 Dec 2020 21:58:24 +0100 Subject: [PATCH 004/148] rename: grid -> cells --- PRIVATE | 2 +- processing/pre/geom_grainGrowth.py | 2 +- processing/pre/mentat_spectralBox.py | 2 +- processing/pre/seeds_fromDistribution.py | 2 +- processing/pre/seeds_fromPokes.py | 14 +- python/damask/_colormap.py | 8 +- python/damask/_geom.py | 177 +++++++++++------------ python/damask/_result.py | 26 ++-- python/damask/_table.py | 4 +- python/damask/_vtk.py | 4 +- python/damask/grid_filters.py | 110 +++++++------- python/damask/seeds.py | 18 +-- python/tests/test_Geom.py | 72 ++++----- python/tests/test_Result.py | 8 +- python/tests/test_VTK.py | 20 +-- python/tests/test_grid_filters.py | 122 ++++++++-------- python/tests/test_seeds.py | 30 ++-- src/discretization.f90 | 2 +- src/grid/discretization_grid.f90 | 8 +- src/marc/discretization_marc.f90 | 2 +- src/results.f90 | 2 +- 21 files changed, 319 insertions(+), 316 deletions(-) diff --git a/PRIVATE b/PRIVATE index 68cde5229..fc27bbd6e 160000 --- a/PRIVATE +++ b/PRIVATE @@ -1 +1 @@ -Subproject commit 68cde52291ebb683ca6f610879f2ae28372597a7 +Subproject commit fc27bbd6e028aa73545327aebdb206840063e135 diff --git a/processing/pre/geom_grainGrowth.py b/processing/pre/geom_grainGrowth.py index 5c751d662..b49d7c126 100755 --- a/processing/pre/geom_grainGrowth.py +++ b/processing/pre/geom_grainGrowth.py @@ -64,7 +64,7 @@ for name in filenames: geom = damask.Geom.load(StringIO(''.join(sys.stdin.read())) if name is None else name) - grid_original = geom.grid + grid_original = geom.cells damask.util.croak(geom) material = np.tile(geom.material,np.where(grid_original == 1, 2,1)) # make one copy along dimensions with grid == 1 grid = np.array(material.shape) diff --git a/processing/pre/mentat_spectralBox.py b/processing/pre/mentat_spectralBox.py index d182a6d54..5c7cc377f 100755 --- a/processing/pre/mentat_spectralBox.py +++ b/processing/pre/mentat_spectralBox.py @@ -201,7 +201,7 @@ for name in filenames: cmds = [\ init(), - mesh(geom.grid,geom.size), + mesh(geom.cells,geom.size), materials(), geometry(), initial_conditions(material), diff --git a/processing/pre/seeds_fromDistribution.py b/processing/pre/seeds_fromDistribution.py index 1f20db995..250e0c6ab 100755 --- a/processing/pre/seeds_fromDistribution.py +++ b/processing/pre/seeds_fromDistribution.py @@ -212,7 +212,7 @@ points = np.array(options.grid).prod().astype('float') # ----------- calculate target distribution and bin edges targetGeom = damask.Geom.load_ASCII(os.path.splitext(os.path.basename(options.target))[0]+'.geom') nMaterials = len(np.unique(targetGeom.material)) -targetVolFrac = np.bincount(targetGeom.material.flatten())/targetGeom.grid.prod().astype(np.float) +targetVolFrac = np.bincount(targetGeom.material.flatten())/targetGeom.cells.prod().astype(np.float) target = [] for i in range(1,nMaterials+1): targetHist,targetBins = np.histogram(targetVolFrac,bins=i) #bin boundaries diff --git a/processing/pre/seeds_fromPokes.py b/processing/pre/seeds_fromPokes.py index 67acf0f6b..535ac0291 100755 --- a/processing/pre/seeds_fromPokes.py +++ b/processing/pre/seeds_fromPokes.py @@ -54,13 +54,13 @@ for name in filenames: damask.util.report(scriptName,name) geom = damask.Geom.load_ASCII(StringIO(''.join(sys.stdin.read())) if name is None else name) - offset =(np.amin(options.box, axis=1)*geom.grid/geom.size).astype(int) + offset =(np.amin(options.box, axis=1)*geom.cells/geom.size).astype(int) box = np.amax(options.box, axis=1) \ - np.amin(options.box, axis=1) Nx = int(options.N/np.sqrt(options.N*geom.size[1]*box[1]/geom.size[0]/box[0])) Ny = int(options.N/np.sqrt(options.N*geom.size[0]*box[0]/geom.size[1]/box[1])) - Nz = int(box[2]*geom.grid[2]) + Nz = int(box[2]*geom.cells[2]) damask.util.croak('poking {} x {} x {} in box {} {} {}...'.format(Nx,Ny,Nz,*box)) @@ -70,12 +70,12 @@ for name in filenames: n = 0 for i in range(Nx): for j in range(Ny): - g[0] = round((i+0.5)*box[0]*geom.grid[0]/Nx-0.5)+offset[0] - g[1] = round((j+0.5)*box[1]*geom.grid[1]/Ny-0.5)+offset[1] + g[0] = round((i+0.5)*box[0]*geom.cells[0]/Nx-0.5)+offset[0] + g[1] = round((j+0.5)*box[1]*geom.cells[1]/Ny-0.5)+offset[1] for k in range(Nz): g[2] = k + offset[2] - g %= geom.grid - seeds[n,0:3] = (g+0.5)/geom.grid # normalize coordinates to box + g %= geom.cells + seeds[n,0:3] = (g+0.5)/geom.cells # normalize coordinates to box seeds[n, 3] = geom.material[g[0],g[1],g[2]] if options.x: g[0] += 1 if options.y: g[1] += 1 @@ -85,7 +85,7 @@ for name in filenames: comments = geom.comments \ + [scriptID + ' ' + ' '.join(sys.argv[1:]), 'poking\ta {}\tb {}\tc {}'.format(Nx,Ny,Nz), - 'grid\ta {}\tb {}\tc {}'.format(*geom.grid), + 'grid\ta {}\tb {}\tc {}'.format(*geom.cells), 'size\tx {}\ty {}\tz {}'.format(*geom.size), 'origin\tx {}\ty {}\tz {}'.format(*geom.origin), ] diff --git a/python/damask/_colormap.py b/python/damask/_colormap.py index aaa3fdc4a..7deaf4ca4 100644 --- a/python/damask/_colormap.py +++ b/python/damask/_colormap.py @@ -225,7 +225,7 @@ class Colormap(mpl.colors.ListedColormap): def save_paraview(self,fname=None): """ - Write colormap to JSON file for Paraview. + Save as JSON file for use in Paraview. Parameters ---------- @@ -260,7 +260,7 @@ class Colormap(mpl.colors.ListedColormap): def save_ASCII(self,fname=None): """ - Write colormap to ASCII table. + Save as ASCII file. Parameters ---------- @@ -286,7 +286,7 @@ class Colormap(mpl.colors.ListedColormap): def save_GOM(self,fname=None): """ - Write colormap to GOM Aramis compatible format. + Save as ASCII file for use in GOM Aramis. Parameters ---------- @@ -314,7 +314,7 @@ class Colormap(mpl.colors.ListedColormap): def save_gmsh(self,fname=None): """ - Write colormap to Gmsh compatible format. + Save as ASCII file for use in gmsh. Parameters ---------- diff --git a/python/damask/_geom.py b/python/damask/_geom.py index fece522c3..495ed05ac 100644 --- a/python/damask/_geom.py +++ b/python/damask/_geom.py @@ -44,7 +44,7 @@ class Geom: def __repr__(self): """Basic information on geometry definition.""" return util.srepr([ - f'grid a b c: {util.srepr(self.grid, " x ")}', + f'cells a b c: {util.srepr(self.cells, " x ")}', f'size x y z: {util.srepr(self.size, " x ")}', f'origin x y z: {util.srepr(self.origin," ")}', f'# materials: {self.N_materials}', @@ -73,9 +73,9 @@ class Geom: """ message = [] - if np.any(other.grid != self.grid): - message.append(util.deemph(f'grid a b c: {util.srepr(other.grid," x ")}')) - message.append(util.emph( f'grid a b c: {util.srepr( self.grid," x ")}')) + if np.any(other.cells != self.cells): + message.append(util.deemph(f'cells a b c: {util.srepr(other.cells," x ")}')) + message.append(util.emph( f'cells a b c: {util.srepr( self.cells," x ")}')) if not np.allclose(other.size,self.size): message.append(util.deemph(f'size x y z: {util.srepr(other.size," x ")}')) @@ -150,8 +150,8 @@ class Geom: @property - def grid(self): - """Grid dimension of geometry.""" + def cells(self): + """Number of cells in x,y,z direction.""" return np.asarray(self.material.shape) @@ -164,7 +164,7 @@ class Geom: @staticmethod def load(fname): """ - Read a VTK rectilinear grid. + Load from VTK rectilinear grid file. Parameters ---------- @@ -175,10 +175,10 @@ class Geom: """ v = VTK.load(fname if str(fname).endswith('.vtr') else str(fname)+'.vtr') comments = v.get_comments() - grid = np.array(v.vtk_data.GetDimensions())-1 - bbox = np.array(v.vtk_data.GetBounds()).reshape(3,2).T + cells = np.array(v.vtk_data.GetDimensions())-1 + bbox = np.array(v.vtk_data.GetBounds()).reshape(3,2).T - return Geom(material = v.get('material').reshape(grid,order='F'), + return Geom(material = v.get('material').reshape(cells,order='F'), size = bbox[1] - bbox[0], origin = bbox[0], comments=comments) @@ -187,7 +187,7 @@ class Geom: @staticmethod def load_ASCII(fname): """ - Read a geom file. + Load from geom file. Storing geometry files in ASCII format is deprecated. This function will be removed in a future version of DAMASK. @@ -219,7 +219,7 @@ class Geom: items = line.split('#')[0].lower().strip().split() key = items[0] if items else '' if key == 'grid': - grid = np.array([ int(dict(zip(items[1::2],items[2::2]))[i]) for i in ['a','b','c']]) + cells = np.array([ int(dict(zip(items[1::2],items[2::2]))[i]) for i in ['a','b','c']]) elif key == 'size': size = np.array([float(dict(zip(items[1::2],items[2::2]))[i]) for i in ['x','y','z']]) elif key == 'origin': @@ -227,7 +227,7 @@ class Geom: else: comments.append(line.strip()) - material = np.empty(grid.prod()) # initialize as flat array + material = np.empty(cells.prod()) # initialize as flat array i = 0 for line in content[header_length:]: items = line.split('#')[0].split() @@ -242,19 +242,19 @@ class Geom: material[i:i+len(items)] = items i += len(items) - if i != grid.prod(): - raise TypeError(f'Invalid file: expected {grid.prod()} entries, found {i}') + if i != cells.prod(): + raise TypeError(f'Invalid file: expected {cells.prod()} entries, found {i}') if not np.any(np.mod(material,1) != 0.0): # no float present material = material.astype('int') - (1 if material.min() > 0 else 0) - return Geom(material.reshape(grid,order='F'),size,origin,comments) + return Geom(material.reshape(cells,order='F'),size,origin,comments) @staticmethod def load_DREAM3D(fname,base_group,point_data=None,material='FeatureIds'): """ - Load a DREAM.3D file. + Load from DREAM.3D file. Parameters ---------- @@ -274,21 +274,21 @@ class Geom: root_dir ='DataContainers' f = h5py.File(fname, 'r') g = path.join(root_dir,base_group,'_SIMPL_GEOMETRY') - grid = f[path.join(g,'DIMENSIONS')][()] - size = f[path.join(g,'SPACING')][()] * grid + cells = f[path.join(g,'DIMENSIONS')][()] + size = f[path.join(g,'SPACING')][()] * cells origin = f[path.join(g,'ORIGIN')][()] - ma = np.arange(grid.prod(),dtype=int) \ + ma = np.arange(cells.prod(),dtype=int) \ if point_data is None else \ - np.reshape(f[path.join(root_dir,base_group,point_data,material)],grid.prod()) + np.reshape(f[path.join(root_dir,base_group,point_data,material)],cells.prod()) - return Geom(ma.reshape(grid,order='F'),size,origin,util.execution_stamp('Geom','load_DREAM3D')) + return Geom(ma.reshape(cells,order='F'),size,origin,util.execution_stamp('Geom','load_DREAM3D')) @staticmethod def from_table(table,coordinates,labels): """ - Derive geometry from an ASCII table. + Generate grid from ASCII table. Parameters ---------- @@ -302,15 +302,15 @@ class Geom: Each unique combintation of values results in one material ID. """ - grid,size,origin = grid_filters.cell_coord0_gridSizeOrigin(table.get(coordinates)) + cells,size,origin = grid_filters.cell_coord0_gridSizeOrigin(table.get(coordinates)) labels_ = [labels] if isinstance(labels,str) else labels unique,unique_inverse = np.unique(np.hstack([table.get(l) for l in labels_]),return_inverse=True,axis=0) - ma = np.arange(grid.prod()) if len(unique) == grid.prod() else \ + ma = np.arange(cells.prod()) if len(unique) == cells.prod() else \ np.arange(unique.size)[np.argsort(pd.unique(unique_inverse))][unique_inverse] - return Geom(ma.reshape(grid,order='F'),size,origin,util.execution_stamp('Geom','from_table')) + return Geom(ma.reshape(cells,order='F'),size,origin,util.execution_stamp('Geom','from_table')) @staticmethod @@ -318,14 +318,14 @@ class Geom: return np.argmin(np.sum((np.broadcast_to(point,(len(seeds),3))-seeds)**2,axis=1) - weights) @staticmethod - def from_Laguerre_tessellation(grid,size,seeds,weights,material=None,periodic=True): + def from_Laguerre_tessellation(cells,size,seeds,weights,material=None,periodic=True): """ - Generate geometry from Laguerre tessellation. + Generate grid from Laguerre tessellation. Parameters ---------- - grid : int numpy.ndarray of shape (3) - Number of grid points in x,y,z direction. + cells : int numpy.ndarray of shape (3) + Number of cells in x,y,z direction. size : list or numpy.ndarray of shape (3) Physical size of the geometry in meter. seeds : numpy.ndarray of shape (:,3) @@ -344,11 +344,11 @@ class Geom: seeds_p = np.vstack((seeds -np.array([size[0],0.,0.]),seeds, seeds +np.array([size[0],0.,0.]))) seeds_p = np.vstack((seeds_p-np.array([0.,size[1],0.]),seeds_p,seeds_p+np.array([0.,size[1],0.]))) seeds_p = np.vstack((seeds_p-np.array([0.,0.,size[2]]),seeds_p,seeds_p+np.array([0.,0.,size[2]]))) - coords = grid_filters.cell_coord0(grid*3,size*3,-size).reshape(-1,3) + coords = grid_filters.cell_coord0(cells*3,size*3,-size).reshape(-1,3) else: weights_p = weights seeds_p = seeds - coords = grid_filters.cell_coord0(grid,size).reshape(-1,3) + coords = grid_filters.cell_coord0(cells,size).reshape(-1,3) pool = mp.Pool(processes = int(environment.options['DAMASK_NUM_THREADS'])) result = pool.map_async(partial(Geom._find_closest_seed,seeds_p,weights_p), [coord for coord in coords]) @@ -357,10 +357,10 @@ class Geom: material_ = np.array(result.get()) if periodic: - material_ = material_.reshape(grid*3) - material_ = material_[grid[0]:grid[0]*2,grid[1]:grid[1]*2,grid[2]:grid[2]*2]%seeds.shape[0] + material_ = material_.reshape(cells*3) + material_ = material_[cells[0]:cells[0]*2,cells[1]:cells[1]*2,cells[2]:cells[2]*2]%seeds.shape[0] else: - material_ = material_.reshape(grid) + material_ = material_.reshape(cells) return Geom(material = material_ if material is None else material[material_], size = size, @@ -369,14 +369,14 @@ class Geom: @staticmethod - def from_Voronoi_tessellation(grid,size,seeds,material=None,periodic=True): + def from_Voronoi_tessellation(cells,size,seeds,material=None,periodic=True): """ - Generate geometry from Voronoi tessellation. + Generate grid from Voronoi tessellation. Parameters ---------- - grid : int numpy.ndarray of shape (3) - Number of grid points in x,y,z direction. + cells : int numpy.ndarray of shape (3) + Number of cells in x,y,z direction. size : list or numpy.ndarray of shape (3) Physical size of the geometry in meter. seeds : numpy.ndarray of shape (:,3) @@ -388,11 +388,11 @@ class Geom: Perform a periodic tessellation. Defaults to True. """ - coords = grid_filters.cell_coord0(grid,size).reshape(-1,3) + coords = grid_filters.cell_coord0(cells,size).reshape(-1,3) KDTree = spatial.cKDTree(seeds,boxsize=size) if periodic else spatial.cKDTree(seeds) devNull,material_ = KDTree.query(coords) - return Geom(material = (material_ if material is None else material[material_]).reshape(grid), + return Geom(material = (material_ if material is None else material[material_]).reshape(cells), size = size, comments = util.execution_stamp('Geom','from_Voronoi_tessellation'), ) @@ -441,14 +441,14 @@ class Geom: @staticmethod - def from_minimal_surface(grid,size,surface,threshold=0.0,periods=1,materials=(0,1)): + def from_minimal_surface(cells,size,surface,threshold=0.0,periods=1,materials=(0,1)): """ - Generate geometry from definition of triply periodic minimal surface. + Generate grid from definition of triply periodic minimal surface. Parameters ---------- - grid : int numpy.ndarray of shape (3) - Number of grid points in x,y,z direction. + cells : int numpy.ndarray of shape (3) + Number of cells in x,y,z direction. size : list or numpy.ndarray of shape (3) Physical size of the geometry in meter. surface : str @@ -493,9 +493,9 @@ class Geom: https://doi.org/10.1016/j.simpa.2020.100026 """ - x,y,z = np.meshgrid(periods*2.0*np.pi*(np.arange(grid[0])+0.5)/grid[0], - periods*2.0*np.pi*(np.arange(grid[1])+0.5)/grid[1], - periods*2.0*np.pi*(np.arange(grid[2])+0.5)/grid[2], + x,y,z = np.meshgrid(periods*2.0*np.pi*(np.arange(cells[0])+0.5)/cells[0], + periods*2.0*np.pi*(np.arange(cells[1])+0.5)/cells[1], + periods*2.0*np.pi*(np.arange(cells[2])+0.5)/cells[2], indexing='ij',sparse=True) return Geom(material = np.where(threshold < Geom._minimal_surface[surface](x,y,z),materials[1],materials[0]), size = size, @@ -505,7 +505,7 @@ class Geom: def save(self,fname,compress=True): """ - Store as VTK rectilinear grid. + Save as VTK rectilinear grid file. Parameters ---------- @@ -515,7 +515,7 @@ class Geom: Compress with zlib algorithm. Defaults to True. """ - v = VTK.from_rectilinear_grid(self.grid,self.size,self.origin) + v = VTK.from_rectilinear_grid(self.cells,self.size,self.origin) v.add(self.material.flatten(order='F'),'material') v.add_comments(self.comments) @@ -524,7 +524,7 @@ class Geom: def save_ASCII(self,fname): """ - Write a geom file. + Save as geom file. Storing geometry files in ASCII format is deprecated. This function will be removed in a future version of DAMASK. @@ -539,7 +539,7 @@ class Geom: """ warnings.warn('Support for ASCII-based geom format will be removed in DAMASK 3.1.0', DeprecationWarning) header = [f'{len(self.comments)+4} header'] + self.comments \ - + ['grid a {} b {} c {}'.format(*self.grid), + + ['grid a {} b {} c {}'.format(*self.cells), 'size x {} y {} z {}'.format(*self.size), 'origin x {} y {} z {}'.format(*self.origin), 'homogenization 1', @@ -548,13 +548,13 @@ class Geom: format_string = '%g' if self.material.dtype in np.sctypes['float'] else \ '%{}i'.format(1+int(np.floor(np.log10(np.nanmax(self.material))))) np.savetxt(fname, - self.material.reshape([self.grid[0],np.prod(self.grid[1:])],order='F').T, + self.material.reshape([self.cells[0],np.prod(self.cells[1:])],order='F').T, header='\n'.join(header), fmt=format_string, comments='') def show(self): """Show on screen.""" - VTK.from_rectilinear_grid(self.grid,self.size,self.origin).show() + VTK.from_rectilinear_grid(self.cells,self.size,self.origin).show() def add_primitive(self,dimension,center,exponent, @@ -566,11 +566,10 @@ class Geom: ---------- dimension : int or float numpy.ndarray of shape (3) Dimension (diameter/side length) of the primitive. If given as - integers, grid point locations (cell centers) are addressed. + integers, cell centers are addressed. If given as floats, coordinates are addressed. center : int or float numpy.ndarray of shape (3) - Center of the primitive. If given as integers, grid point - coordinates (cell centers) are addressed. + Center of the primitive. If given as integers, cell centers are addressed. If given as floats, coordinates in space are addressed. exponent : numpy.ndarray of shape (3) or float Exponents for the three axes. @@ -588,22 +587,22 @@ class Geom: """ # radius and center - r = np.array(dimension)/2.0*self.size/self.grid if np.array(dimension).dtype in np.sctypes['int'] else \ + r = np.array(dimension)/2.0*self.size/self.cells if np.array(dimension).dtype in np.sctypes['int'] else \ np.array(dimension)/2.0 - c = (np.array(center) + .5)*self.size/self.grid if np.array(center).dtype in np.sctypes['int'] else \ + c = (np.array(center) + .5)*self.size/self.cells if np.array(center).dtype in np.sctypes['int'] else \ (np.array(center) - self.origin) - coords = grid_filters.cell_coord0(self.grid,self.size, - -(0.5*(self.size + (self.size/self.grid + coords = grid_filters.cell_coord0(self.cells,self.size, + -(0.5*(self.size + (self.size/self.cells if np.array(center).dtype in np.sctypes['int'] else 0)) if periodic else c)) - coords_rot = R.broadcast_to(tuple(self.grid))@coords + coords_rot = R.broadcast_to(tuple(self.cells))@coords with np.errstate(all='ignore'): mask = np.sum(np.power(coords_rot/r,2.0**np.array(exponent)),axis=-1) > 1.0 if periodic: # translate back to center - mask = np.roll(mask,((c/self.size-0.5)*self.grid).round().astype(int),(0,1,2)) + mask = np.roll(mask,((c/self.size-0.5)*self.cells).round().astype(int),(0,1,2)) return Geom(material = np.where(np.logical_not(mask) if inverse else mask, self.material, @@ -642,7 +641,7 @@ class Geom: mat = np.concatenate([mat,mat[:,:,limits[0]:limits[1]:-1]],2) return Geom(material = mat, - size = self.size/self.grid*np.asarray(mat.shape), + size = self.size/self.cells*np.asarray(mat.shape), origin = self.origin, comments = self.comments+[util.execution_stamp('Geom','mirror')], ) @@ -672,21 +671,21 @@ class Geom: ) - def scale(self,grid,periodic=True): + def scale(self,cells,periodic=True): """ - Scale geometry to new grid. + Scale geometry to new cells. Parameters ---------- - grid : numpy.ndarray of shape (3) - Number of grid points in x,y,z direction. + cells : numpy.ndarray of shape (3) + Number of cells in x,y,z direction. periodic : Boolean, optional Assume geometry to be periodic. Defaults to True. """ return Geom(material = ndimage.interpolation.zoom( self.material, - grid/self.grid, + cells/self.cells, output=self.material.dtype, order=0, mode=('wrap' if periodic else 'nearest'), @@ -737,7 +736,7 @@ class Geom: """Renumber sorted material indices as 0,...,N-1.""" _,renumbered = np.unique(self.material,return_inverse=True) - return Geom(material = renumbered.reshape(self.grid), + return Geom(material = renumbered.reshape(self.cells), size = self.size, origin = self.origin, comments = self.comments+[util.execution_stamp('Geom','renumber')], @@ -773,25 +772,25 @@ class Geom: else: material_in = material_out - origin = self.origin-(np.asarray(material_in.shape)-self.grid)*.5 * self.size/self.grid + origin = self.origin-(np.asarray(material_in.shape)-self.cells)*.5 * self.size/self.cells return Geom(material = material_in, - size = self.size/self.grid*np.asarray(material_in.shape), + size = self.size/self.cells*np.asarray(material_in.shape), origin = origin, comments = self.comments+[util.execution_stamp('Geom','rotate')], ) - def canvas(self,grid=None,offset=None,fill=None): + def canvas(self,cells=None,offset=None,fill=None): """ Crop or enlarge/pad geometry. Parameters ---------- - grid : numpy.ndarray of shape (3) - Number of grid points in x,y,z direction. + cells : numpy.ndarray of shape (3) + Number of cells x,y,z direction. offset : numpy.ndarray of shape (3) - Offset (measured in grid points) from old to new geometry [0,0,0]. + Offset (measured in cells) from old to new geometry [0,0,0]. fill : int or float, optional Material index to fill the background. Defaults to material.max() + 1. @@ -800,18 +799,18 @@ class Geom: if fill is None: fill = np.nanmax(self.material) + 1 dtype = float if int(fill) != fill or self.material.dtype in np.sctypes['float'] else int - canvas = np.full(self.grid if grid is None else grid,fill,dtype) + canvas = np.full(self.cells if cells is None else cells,fill,dtype) - LL = np.clip( offset, 0,np.minimum(self.grid, grid+offset)) - UR = np.clip( offset+grid, 0,np.minimum(self.grid, grid+offset)) - ll = np.clip(-offset, 0,np.minimum( grid,self.grid-offset)) - ur = np.clip(-offset+self.grid,0,np.minimum( grid,self.grid-offset)) + LL = np.clip( offset, 0,np.minimum(self.cells, cells+offset)) + UR = np.clip( offset+cells, 0,np.minimum(self.cells, cells+offset)) + ll = np.clip(-offset, 0,np.minimum( cells,self.cells-offset)) + ur = np.clip(-offset+self.cells,0,np.minimum( cells,self.cells-offset)) canvas[ll[0]:ur[0],ll[1]:ur[1],ll[2]:ur[2]] = self.material[LL[0]:UR[0],LL[1]:UR[1],LL[2]:UR[2]] return Geom(material = canvas, - size = self.size/self.grid*np.asarray(canvas.shape), - origin = self.origin+offset*self.size/self.grid, + size = self.size/self.cells*np.asarray(canvas.shape), + origin = self.origin+offset*self.size/self.cells, comments = self.comments+[util.execution_stamp('Geom','canvas')], ) @@ -834,7 +833,7 @@ class Geom: mp = np.vectorize(mp) mapper = dict(zip(from_material,to_material)) - return Geom(material = mp(self.material,mapper).reshape(self.grid), + return Geom(material = mp(self.material,mapper).reshape(self.cells), size = self.size, origin = self.origin, comments = self.comments+[util.execution_stamp('Geom','substitute')], @@ -848,7 +847,7 @@ class Geom: sort_idx = np.argsort(from_ma) ma = np.unique(a)[sort_idx][np.searchsorted(from_ma,a,sorter = sort_idx)] - return Geom(material = ma.reshape(self.grid,order='F'), + return Geom(material = ma.reshape(self.cells,order='F'), size = self.size, origin = self.origin, comments = self.comments+[util.execution_stamp('Geom','sort')], @@ -916,9 +915,9 @@ class Geom: if not set(directions).issubset(valid): raise ValueError(f'Invalid direction {set(directions).difference(valid)} specified.') - o = [[0, self.grid[0]+1, np.prod(self.grid[:2]+1)+self.grid[0]+1, np.prod(self.grid[:2]+1)], - [0, np.prod(self.grid[:2]+1), np.prod(self.grid[:2]+1)+1, 1], - [0, 1, self.grid[0]+1+1, self.grid[0]+1]] # offset for connectivity + o = [[0, self.cells[0]+1, np.prod(self.cells[:2]+1)+self.cells[0]+1, np.prod(self.cells[:2]+1)], + [0, np.prod(self.cells[:2]+1), np.prod(self.cells[:2]+1)+1, 1], + [0, 1, self.cells[0]+1+1, self.cells[0]+1]] # offset for connectivity connectivity = [] for i,d in enumerate(['x','y','z']): @@ -933,5 +932,5 @@ class Geom: base_nodes = np.argwhere(mask.flatten(order='F')).reshape(-1,1) connectivity.append(np.block([base_nodes + o[i][k] for k in range(4)])) - coords = grid_filters.node_coord0(self.grid,self.size,self.origin).reshape(-1,3,order='F') + coords = grid_filters.node_coord0(self.cells,self.size,self.origin).reshape(-1,3,order='F') return VTK.from_unstructured_grid(coords,np.vstack(connectivity),'QUAD') diff --git a/python/damask/_result.py b/python/damask/_result.py index 0e74f86df..38b18d5ec 100644 --- a/python/damask/_result.py +++ b/python/damask/_result.py @@ -46,13 +46,17 @@ class Result: self.version_major = f.attrs['DADF5_version_major'] self.version_minor = f.attrs['DADF5_version_minor'] - if self.version_major != 0 or not 7 <= self.version_minor <= 9: + if self.version_major != 0 or not 7 <= self.version_minor <= 10: raise TypeError(f'Unsupported DADF5 version {self.version_major}.{self.version_minor}') - self.structured = 'grid' in f['geometry'].attrs.keys() + self.structured = 'grid' in f['geometry'].attrs.keys() or \ + 'cells' in f['geometry'].attrs.keys() if self.structured: - self.grid = f['geometry'].attrs['grid'] + try: + self.cells = f['geometry'].attrs['cells'] + except KeyError: + self.cells = f['geometry'].attrs['grid'] self.size = f['geometry'].attrs['size'] self.origin = f['geometry'].attrs['origin'] @@ -561,7 +565,7 @@ class Result: def cell_coordinates(self): """Return initial coordinates of the cell centers.""" if self.structured: - return grid_filters.cell_coord0(self.grid,self.size,self.origin).reshape(-1,3,order='F') + return grid_filters.cell_coord0(self.cells,self.size,self.origin).reshape(-1,3,order='F') else: with h5py.File(self.fname,'r') as f: return f['geometry/x_c'][()] @@ -570,7 +574,7 @@ class Result: def node_coordinates(self): """Return initial coordinates of the cell centers.""" if self.structured: - return grid_filters.node_coord0(self.grid,self.size,self.origin).reshape(-1,3,order='F') + return grid_filters.node_coord0(self.cells,self.size,self.origin).reshape(-1,3,order='F') else: with h5py.File(self.fname,'r') as f: return f['geometry/x_n'][()] @@ -1218,7 +1222,7 @@ class Result: topology=ET.SubElement(grid, 'Topology') topology.attrib={'TopologyType': '3DCoRectMesh', - 'Dimensions': '{} {} {}'.format(*self.grid+1)} + 'Dimensions': '{} {} {}'.format(*self.cells+1)} geometry=ET.SubElement(grid, 'Geometry') geometry.attrib={'GeometryType':'Origin_DxDyDz'} @@ -1233,7 +1237,7 @@ class Result: delta.attrib={'Format': 'XML', 'NumberType': 'Float', 'Dimensions': '3'} - delta.text="{} {} {}".format(*(self.size/self.grid)) + delta.text="{} {} {}".format(*(self.size/self.cells)) with h5py.File(self.fname,'r') as f: @@ -1244,7 +1248,7 @@ class Result: data_items.append(ET.SubElement(attributes[-1], 'DataItem')) data_items[-1].attrib={'Format': 'HDF', 'Precision': '8', - 'Dimensions': '{} {} {} 3'.format(*(self.grid+1))} + 'Dimensions': '{} {} {} 3'.format(*(self.cells+1))} data_items[-1].text=f'{os.path.split(self.fname)[1]}:/{inc}/geometry/u_n' for o,p in zip(['phases','homogenizations'],['out_type_ph','out_type_ho']): @@ -1267,8 +1271,8 @@ class Result: data_items[-1].attrib={'Format': 'HDF', 'NumberType': number_type_map(dtype), 'Precision': f'{dtype.itemsize}', - 'Dimensions': '{} {} {} {}'.format(*self.grid,1 if shape == () else - np.prod(shape))} + 'Dimensions': '{} {} {} {}'.format(*self.cells,1 if shape == () else + np.prod(shape))} data_items[-1].text=f'{os.path.split(self.fname)[1]}:{name}' with open(self.fname.with_suffix('.xdmf').name,'w') as f: @@ -1291,7 +1295,7 @@ class Result: if mode.lower()=='cell': if self.structured: - v = VTK.from_rectilinear_grid(self.grid,self.size,self.origin) + v = VTK.from_rectilinear_grid(self.cells,self.size,self.origin) else: with h5py.File(self.fname,'r') as f: v = VTK.from_unstructured_grid(f['/geometry/x_n'][()], diff --git a/python/damask/_table.py b/python/damask/_table.py index c05fa71a7..45c6fc787 100644 --- a/python/damask/_table.py +++ b/python/damask/_table.py @@ -73,7 +73,7 @@ class Table: @staticmethod def load(fname): """ - Load ASCII table file. + Load from ASCII table file. In legacy style, the first line indicates the number of subsequent header lines as "N header", with the last header line being @@ -131,7 +131,7 @@ class Table: @staticmethod def load_ang(fname): """ - Load ang file. + Load from ang file. A valid TSL ang file needs to contains the following columns: * Euler angles (Bunge notation) in radians, 3 floats, label 'eu'. diff --git a/python/damask/_vtk.py b/python/damask/_vtk.py index 2f4d63791..6ae6b534f 100644 --- a/python/damask/_vtk.py +++ b/python/damask/_vtk.py @@ -128,7 +128,7 @@ class VTK: @staticmethod def load(fname,dataset_type=None): """ - Create VTK from file. + Load from VTK file. Parameters ---------- @@ -181,7 +181,7 @@ class VTK: writer.Write() def save(self,fname,parallel=True,compress=True): """ - Write to file. + Save as VTK file. Parameters ---------- diff --git a/python/damask/grid_filters.py b/python/damask/grid_filters.py index 6c3f24cff..7496a0d52 100644 --- a/python/damask/grid_filters.py +++ b/python/damask/grid_filters.py @@ -8,14 +8,14 @@ This convention is consistent with the geom file format. When converting to/from a plain list (e.g. storage in ASCII table), the following operations are required for tensorial data: -D3 = D1.reshape(grid+(-1,),order='F').reshape(grid+(3,3)) -D1 = D3.reshape(grid+(-1,)).reshape(-1,9,order='F') +D3 = D1.reshape(cells+(-1,),order='F').reshape(cells+(3,3)) +D1 = D3.reshape(cells+(-1,)).reshape(-1,9,order='F') """ from scipy import spatial as _spatial import numpy as _np -def _ks(size,grid,first_order=False): +def _ks(size,cells,first_order=False): """ Get wave numbers operator. @@ -23,19 +23,19 @@ def _ks(size,grid,first_order=False): ---------- size : numpy.ndarray of shape (3) physical size of the periodic field. - grid : numpy.ndarray of shape (3) - number of grid points. + cells : numpy.ndarray of shape (3) + number of cells. first_order : bool, optional correction for first order derivatives, defaults to False. """ - k_sk = _np.where(_np.arange(grid[0])>grid[0]//2,_np.arange(grid[0])-grid[0],_np.arange(grid[0]))/size[0] - if grid[0]%2 == 0 and first_order: k_sk[grid[0]//2] = 0 # Nyquist freq=0 for even grid (Johnson, MIT, 2011) + k_sk = _np.where(_np.arange(cells[0])>cells[0]//2,_np.arange(cells[0])-cells[0],_np.arange(cells[0]))/size[0] + if cells[0]%2 == 0 and first_order: k_sk[cells[0]//2] = 0 # Nyquist freq=0 for even cells (Johnson, MIT, 2011) - k_sj = _np.where(_np.arange(grid[1])>grid[1]//2,_np.arange(grid[1])-grid[1],_np.arange(grid[1]))/size[1] - if grid[1]%2 == 0 and first_order: k_sj[grid[1]//2] = 0 # Nyquist freq=0 for even grid (Johnson, MIT, 2011) + k_sj = _np.where(_np.arange(cells[1])>cells[1]//2,_np.arange(cells[1])-cells[1],_np.arange(cells[1]))/size[1] + if cells[1]%2 == 0 and first_order: k_sj[cells[1]//2] = 0 # Nyquist freq=0 for even cells (Johnson, MIT, 2011) - k_si = _np.arange(grid[2]//2+1)/size[2] + k_si = _np.arange(cells[2]//2+1)/size[2] return _np.stack(_np.meshgrid(k_sk,k_sj,k_si,indexing = 'ij'), axis=-1) @@ -110,26 +110,26 @@ def gradient(size,field): return _np.fft.irfftn(grad_,axes=(0,1,2),s=field.shape[:3]) -def cell_coord0(grid,size,origin=_np.zeros(3)): +def cell_coord0(cells,size,origin=_np.zeros(3)): """ Cell center positions (undeformed). Parameters ---------- - grid : numpy.ndarray of shape (3) - number of grid points. + cells : numpy.ndarray of shape (3) + number of cells. size : numpy.ndarray of shape (3) physical size of the periodic field. origin : numpy.ndarray, optional physical origin of the periodic field. Defaults to [0.0,0.0,0.0]. """ - start = origin + size/grid*.5 - end = origin + size - size/grid*.5 + start = origin + size/cells*.5 + end = origin + size - size/cells*.5 - return _np.stack(_np.meshgrid(_np.linspace(start[0],end[0],grid[0]), - _np.linspace(start[1],end[1],grid[1]), - _np.linspace(start[2],end[2],grid[2]),indexing = 'ij'), + return _np.stack(_np.meshgrid(_np.linspace(start[0],end[0],cells[0]), + _np.linspace(start[1],end[1],cells[1]), + _np.linspace(start[2],end[2],cells[2]),indexing = 'ij'), axis = -1) @@ -210,7 +210,7 @@ def cell_coord(size,F,origin=_np.zeros(3)): def cell_coord0_gridSizeOrigin(coord0,ordered=True): """ - Return grid 'DNA', i.e. grid, size, and origin from 1D array of cell positions. + Return grid 'DNA', i.e. cells, size, and origin from 1D array of cell positions. Parameters ---------- @@ -223,31 +223,31 @@ def cell_coord0_gridSizeOrigin(coord0,ordered=True): coords = [_np.unique(coord0[:,i]) for i in range(3)] mincorner = _np.array(list(map(min,coords))) maxcorner = _np.array(list(map(max,coords))) - grid = _np.array(list(map(len,coords)),'i') - size = grid/_np.maximum(grid-1,1) * (maxcorner-mincorner) - delta = size/grid + cells = _np.array(list(map(len,coords)),'i') + size = cells/_np.maximum(cells-1,1) * (maxcorner-mincorner) + delta = size/cells origin = mincorner - delta*.5 # 1D/2D: size/origin combination undefined, set origin to 0.0 - size [_np.where(grid==1)] = origin[_np.where(grid==1)]*2. - origin[_np.where(grid==1)] = 0.0 + size [_np.where(cells==1)] = origin[_np.where(cells==1)]*2. + origin[_np.where(cells==1)] = 0.0 - if grid.prod() != len(coord0): - raise ValueError('Data count {len(coord0)} does not match grid {grid}.') + if cells.prod() != len(coord0): + raise ValueError('Data count {len(coord0)} does not match cells {cells}.') start = origin + delta*.5 end = origin - delta*.5 + size atol = _np.max(size)*5e-2 - if not (_np.allclose(coords[0],_np.linspace(start[0],end[0],grid[0]),atol=atol) and \ - _np.allclose(coords[1],_np.linspace(start[1],end[1],grid[1]),atol=atol) and \ - _np.allclose(coords[2],_np.linspace(start[2],end[2],grid[2]),atol=atol)): - raise ValueError('Regular grid spacing violated.') + if not (_np.allclose(coords[0],_np.linspace(start[0],end[0],cells[0]),atol=atol) and \ + _np.allclose(coords[1],_np.linspace(start[1],end[1],cells[1]),atol=atol) and \ + _np.allclose(coords[2],_np.linspace(start[2],end[2],cells[2]),atol=atol)): + raise ValueError('Regular cells spacing violated.') - if ordered and not _np.allclose(coord0.reshape(tuple(grid)+(3,),order='F'),cell_coord0(grid,size,origin),atol=atol): + if ordered and not _np.allclose(coord0.reshape(tuple(cells)+(3,),order='F'),cell_coord0(cells,size,origin),atol=atol): raise ValueError('Input data is not ordered (x fast, z slow).') - return (grid,size,origin) + return (cells,size,origin) def coord0_check(coord0): @@ -263,23 +263,23 @@ def coord0_check(coord0): cell_coord0_gridSizeOrigin(coord0,ordered=True) -def node_coord0(grid,size,origin=_np.zeros(3)): +def node_coord0(cells,size,origin=_np.zeros(3)): """ Nodal positions (undeformed). Parameters ---------- - grid : numpy.ndarray of shape (3) - number of grid points. + cells : numpy.ndarray of shape (3) + number of cells. size : numpy.ndarray of shape (3) physical size of the periodic field. origin : numpy.ndarray of shape (3), optional physical origin of the periodic field. Defaults to [0.0,0.0,0.0]. """ - return _np.stack(_np.meshgrid(_np.linspace(origin[0],size[0]+origin[0],grid[0]+1), - _np.linspace(origin[1],size[1]+origin[1],grid[1]+1), - _np.linspace(origin[2],size[2]+origin[2],grid[2]+1),indexing = 'ij'), + return _np.stack(_np.meshgrid(_np.linspace(origin[0],size[0]+origin[0],cells[0]+1), + _np.linspace(origin[1],size[1]+origin[1],cells[1]+1), + _np.linspace(origin[2],size[2]+origin[2],cells[2]+1),indexing = 'ij'), axis = -1) @@ -366,7 +366,7 @@ def node_2_cell(node_data): def node_coord0_gridSizeOrigin(coord0,ordered=True): """ - Return grid 'DNA', i.e. grid, size, and origin from 1D array of nodal positions. + Return grid 'DNA', i.e. cells, size, and origin from 1D array of nodal positions. Parameters ---------- @@ -379,37 +379,37 @@ def node_coord0_gridSizeOrigin(coord0,ordered=True): coords = [_np.unique(coord0[:,i]) for i in range(3)] mincorner = _np.array(list(map(min,coords))) maxcorner = _np.array(list(map(max,coords))) - grid = _np.array(list(map(len,coords)),'i') - 1 + cells = _np.array(list(map(len,coords)),'i') - 1 size = maxcorner-mincorner origin = mincorner - if (grid+1).prod() != len(coord0): - raise ValueError('Data count {len(coord0)} does not match grid {grid}.') + if (cells+1).prod() != len(coord0): + raise ValueError('Data count {len(coord0)} does not match cells {cells}.') atol = _np.max(size)*5e-2 - if not (_np.allclose(coords[0],_np.linspace(mincorner[0],maxcorner[0],grid[0]+1),atol=atol) and \ - _np.allclose(coords[1],_np.linspace(mincorner[1],maxcorner[1],grid[1]+1),atol=atol) and \ - _np.allclose(coords[2],_np.linspace(mincorner[2],maxcorner[2],grid[2]+1),atol=atol)): - raise ValueError('Regular grid spacing violated.') + if not (_np.allclose(coords[0],_np.linspace(mincorner[0],maxcorner[0],cells[0]+1),atol=atol) and \ + _np.allclose(coords[1],_np.linspace(mincorner[1],maxcorner[1],cells[1]+1),atol=atol) and \ + _np.allclose(coords[2],_np.linspace(mincorner[2],maxcorner[2],cells[2]+1),atol=atol)): + raise ValueError('Regular cells spacing violated.') - if ordered and not _np.allclose(coord0.reshape(tuple(grid+1)+(3,),order='F'),node_coord0(grid,size,origin),atol=atol): + if ordered and not _np.allclose(coord0.reshape(tuple(cells+1)+(3,),order='F'),node_coord0(cells,size,origin),atol=atol): raise ValueError('Input data is not ordered (x fast, z slow).') - return (grid,size,origin) + return (cells,size,origin) -def regrid(size,F,new_grid): +def regrid(size,F,cells_new): """ - Return mapping from coordinates in deformed configuration to a regular grid. + Return mapping from coordinates in deformed configuration to a regular cells. Parameters ---------- size : numpy.ndarray of shape (3) - physical size + Physical size. F : numpy.ndarray of shape (:,:,:,3,3) - deformation gradient field - new_grid : numpy.ndarray of shape (3) - new grid for undeformed coordinates + Deformation gradient field. + cells_new : numpy.ndarray of shape (3) + New cells for undeformed coordinates. """ c = cell_coord0(F.shape[:3],size) \ @@ -422,4 +422,4 @@ def regrid(size,F,new_grid): c[_np.where(c[:,:,:,d]>outer[d])] -= outer[d] tree = _spatial.cKDTree(c.reshape(-1,3),boxsize=outer) - return tree.query(cell_coord0(new_grid,outer))[1].flatten() + return tree.query(cell_coord0(cells_new,outer))[1].flatten() diff --git a/python/damask/seeds.py b/python/damask/seeds.py index 1c4150c2d..90c1f58cc 100644 --- a/python/damask/seeds.py +++ b/python/damask/seeds.py @@ -7,7 +7,7 @@ from . import util from . import grid_filters -def from_random(size,N_seeds,grid=None,rng_seed=None): +def from_random(size,N_seeds,cells=None,rng_seed=None): """ Random seeding in space. @@ -17,7 +17,7 @@ def from_random(size,N_seeds,grid=None,rng_seed=None): Physical size of the seeding domain. N_seeds : int Number of seeds. - grid : numpy.ndarray of shape (3), optional. + cells : numpy.ndarray of shape (3), optional. If given, ensures that all seeds initiate one grain if using a standard Voronoi tessellation. rng_seed : {None, int, array_like[ints], SeedSequence, BitGenerator, Generator}, optional @@ -26,12 +26,12 @@ def from_random(size,N_seeds,grid=None,rng_seed=None): """ rng = _np.random.default_rng(rng_seed) - if grid is None: + if cells is None: coords = rng.random((N_seeds,3)) * size else: - grid_coords = grid_filters.cell_coord0(grid,size).reshape(-1,3,order='F') - coords = grid_coords[rng.choice(_np.prod(grid),N_seeds, replace=False)] \ - + _np.broadcast_to(size/grid,(N_seeds,3))*(rng.random((N_seeds,3))*.5-.25) # wobble without leaving grid + grid_coords = grid_filters.cell_coord0(cells,size).reshape(-1,3,order='F') + coords = grid_coords[rng.choice(_np.prod(cells),N_seeds, replace=False)] \ + + _np.broadcast_to(size/cells,(N_seeds,3))*(rng.random((N_seeds,3))*.5-.25) # wobble without leaving cells return coords @@ -51,7 +51,7 @@ def from_Poisson_disc(size,N_seeds,N_candidates,distance,periodic=True,rng_seed= distance : float Minimum acceptable distance to other seeds. periodic : boolean, optional - Calculate minimum distance for periodically repeated grid. + Calculate minimum distance for periodically repeated cells. rng_seed : {None, int, array_like[ints], SeedSequence, BitGenerator, Generator}, optional A seed to initialize the BitGenerator. Defaults to None. If None, then fresh, unpredictable entropy will be pulled from the OS. @@ -96,9 +96,9 @@ def from_geom(geom,selection=None,invert=False,average=False,periodic=True): """ material = geom.material.reshape((-1,1),order='F') - mask = _np.full(geom.grid.prod(),True,dtype=bool) if selection is None else \ + mask = _np.full(geom.cells.prod(),True,dtype=bool) if selection is None else \ _np.isin(material,selection,invert=invert).flatten() - coords = grid_filters.cell_coord0(geom.grid,geom.size).reshape(-1,3,order='F') + coords = grid_filters.cell_coord0(geom.cells,geom.size).reshape(-1,3,order='F') if not average: return (coords[mask],material[mask]) diff --git a/python/tests/test_Geom.py b/python/tests/test_Geom.py index 85da049fa..891cd3937 100644 --- a/python/tests/test_Geom.py +++ b/python/tests/test_Geom.py @@ -12,7 +12,7 @@ from damask import grid_filters def geom_equal(a,b): return np.all(a.material == b.material) and \ - np.all(a.grid == b.grid) and \ + np.all(a.cells == b.cells) and \ np.allclose(a.size, b.size) and \ str(a.diff(b)) == str(b.diff(a)) @@ -167,7 +167,7 @@ class TestGeom: ) - @pytest.mark.parametrize('grid',[ + @pytest.mark.parametrize('cells',[ (10,11,10), [10,13,10], np.array((10,10,10)), @@ -176,9 +176,9 @@ class TestGeom: np.array((10,20,2)) ] ) - def test_scale(self,default,update,ref_path,grid): - modified = default.scale(grid) - tag = f'grid_{util.srepr(grid,"-")}' + def test_scale(self,default,update,ref_path,cells): + modified = default.scale(cells) + tag = f'grid_{util.srepr(cells,"-")}' reference = ref_path/f'scale_{tag}.vtr' if update: modified.save(reference) assert geom_equal(Geom.load(reference), @@ -216,8 +216,8 @@ class TestGeom: assert geom_equal(default, modified.substitute(t,f)) def test_sort(self): - grid = np.random.randint(5,20,3) - m = Geom(np.random.randint(1,20,grid)*3,np.ones(3)).sort().material.flatten(order='F') + cells = np.random.randint(5,20,3) + m = Geom(np.random.randint(1,20,cells)*3,np.ones(3)).sort().material.flatten(order='F') for i,v in enumerate(m): assert i==0 or v > m[:i].max() or v in m[:i] @@ -242,10 +242,10 @@ class TestGeom: def test_canvas(self,default): - grid = default.grid + cells = default.cells grid_add = np.random.randint(0,30,(3)) - modified = default.canvas(grid + grid_add) - assert np.all(modified.material[:grid[0],:grid[1],:grid[2]] == default.material) + modified = default.canvas(cells + grid_add) + assert np.all(modified.material[:cells[0],:cells[1],:cells[2]] == default.material) @pytest.mark.parametrize('center1,center2',[(np.random.random(3)*.5,np.random.random()*8), @@ -314,38 +314,38 @@ class TestGeom: @pytest.mark.parametrize('periodic',[True,False]) def test_tessellation_approaches(self,periodic): - grid = np.random.randint(10,20,3) + cells = np.random.randint(10,20,3) size = np.random.random(3) + 1.0 N_seeds= np.random.randint(10,30) seeds = np.random.rand(N_seeds,3) * np.broadcast_to(size,(N_seeds,3)) - Voronoi = Geom.from_Voronoi_tessellation( grid,size,seeds, np.arange(N_seeds)+5,periodic) - Laguerre = Geom.from_Laguerre_tessellation(grid,size,seeds,np.ones(N_seeds),np.arange(N_seeds)+5,periodic) + Voronoi = Geom.from_Voronoi_tessellation( cells,size,seeds, np.arange(N_seeds)+5,periodic) + Laguerre = Geom.from_Laguerre_tessellation(cells,size,seeds,np.ones(N_seeds),np.arange(N_seeds)+5,periodic) assert geom_equal(Laguerre,Voronoi) def test_Laguerre_weights(self): - grid = np.random.randint(10,20,3) + cells = np.random.randint(10,20,3) size = np.random.random(3) + 1.0 N_seeds= np.random.randint(10,30) seeds = np.random.rand(N_seeds,3) * np.broadcast_to(size,(N_seeds,3)) weights= np.full((N_seeds),-np.inf) ms = np.random.randint(N_seeds) weights[ms] = np.random.random() - Laguerre = Geom.from_Laguerre_tessellation(grid,size,seeds,weights,periodic=np.random.random()>0.5) + Laguerre = Geom.from_Laguerre_tessellation(cells,size,seeds,weights,periodic=np.random.random()>0.5) assert np.all(Laguerre.material == ms) @pytest.mark.parametrize('approach',['Laguerre','Voronoi']) def test_tessellate_bicrystal(self,approach): - grid = np.random.randint(5,10,3)*2 - size = grid.astype(np.float) + cells = np.random.randint(5,10,3)*2 + size = cells.astype(np.float) seeds = np.vstack((size*np.array([0.5,0.25,0.5]),size*np.array([0.5,0.75,0.5]))) - material = np.zeros(grid) - material[:,grid[1]//2:,:] = 1 + material = np.zeros(cells) + material[:,cells[1]//2:,:] = 1 if approach == 'Laguerre': - geom = Geom.from_Laguerre_tessellation(grid,size,seeds,np.ones(2),periodic=np.random.random()>0.5) + geom = Geom.from_Laguerre_tessellation(cells,size,seeds,np.ones(2),periodic=np.random.random()>0.5) elif approach == 'Voronoi': - geom = Geom.from_Voronoi_tessellation(grid,size,seeds, periodic=np.random.random()>0.5) + geom = Geom.from_Voronoi_tessellation(cells,size,seeds, periodic=np.random.random()>0.5) assert np.all(geom.material == material) @@ -363,14 +363,14 @@ class TestGeom: 'Fisher-Koch S', ]) def test_minimal_surface_basic_properties(self,surface): - grid = np.random.randint(60,100,3) - size = np.ones(3)+np.random.rand(3) + cells = np.random.randint(60,100,3) + size = np.ones(3)+np.random.rand(3) threshold = 2*np.random.rand()-1. periods = np.random.randint(2)+1 materials = np.random.randint(0,40,2) - geom = Geom.from_minimal_surface(grid,size,surface,threshold,periods,materials) + geom = Geom.from_minimal_surface(cells,size,surface,threshold,periods,materials) assert set(geom.material.flatten()) | set(materials) == set(materials) \ - and (geom.size == size).all() and (geom.grid == grid).all() + and (geom.size == size).all() and (geom.cells == cells).all() @pytest.mark.parametrize('surface,threshold',[('Schwarz P',0), ('Double Primitive',-1./6.), @@ -386,28 +386,28 @@ class TestGeom: ('Fisher-Koch S',0), ]) def test_minimal_surface_volume(self,surface,threshold): - grid = np.ones(3,dtype=int)*64 - geom = Geom.from_minimal_surface(grid,np.ones(3),surface,threshold) - assert np.isclose(np.count_nonzero(geom.material==1)/np.prod(geom.grid),.5,rtol=1e-3) + cells = np.ones(3,dtype=int)*64 + geom = Geom.from_minimal_surface(cells,np.ones(3),surface,threshold) + assert np.isclose(np.count_nonzero(geom.material==1)/np.prod(geom.cells),.5,rtol=1e-3) def test_from_table(self): - grid = np.random.randint(60,100,3) + cells = np.random.randint(60,100,3) size = np.ones(3)+np.random.rand(3) - coords = grid_filters.cell_coord0(grid,size).reshape(-1,3,order='F') - z=np.ones(grid.prod()) - z[grid[:2].prod()*int(grid[2]/2):]=0 + coords = grid_filters.cell_coord0(cells,size).reshape(-1,3,order='F') + z=np.ones(cells.prod()) + z[cells[:2].prod()*int(cells[2]/2):]=0 t = Table(np.column_stack((coords,z)),{'coords':3,'z':1}) g = Geom.from_table(t,'coords',['1_coords','z']) - assert g.N_materials == g.grid[0]*2 and (g.material[:,:,-1]-g.material[:,:,0] == grid[0]).all() + assert g.N_materials == g.cells[0]*2 and (g.material[:,:,-1]-g.material[:,:,0] == cells[0]).all() def test_from_table_recover(self,tmp_path): - grid = np.random.randint(60,100,3) + cells = np.random.randint(60,100,3) size = np.ones(3)+np.random.rand(3) s = seeds.from_random(size,np.random.randint(60,100)) - geom = Geom.from_Voronoi_tessellation(grid,size,s) - coords = grid_filters.cell_coord0(grid,size) + geom = Geom.from_Voronoi_tessellation(cells,size,s) + coords = grid_filters.cell_coord0(cells,size) t = Table(np.column_stack((coords.reshape(-1,3,order='F'),geom.material.flatten(order='F'))),{'c':3,'m':1}) assert geom_equal(geom.sort().renumber(),Geom.from_table(t,'c',['m'])) diff --git a/python/tests/test_Result.py b/python/tests/test_Result.py index 1e014216e..8ebeff80a 100644 --- a/python/tests/test_Result.py +++ b/python/tests/test_Result.py @@ -356,11 +356,11 @@ class TestResult: @pytest.mark.parametrize('mode',['cell','node']) def test_coordinates(self,default,mode): if mode == 'cell': - a = grid_filters.cell_coord0(default.grid,default.size,default.origin) - b = default.cell_coordinates.reshape(tuple(default.grid)+(3,),order='F') + a = grid_filters.cell_coord0(default.cells,default.size,default.origin) + b = default.cell_coordinates.reshape(tuple(default.cells)+(3,),order='F') elif mode == 'node': - a = grid_filters.node_coord0(default.grid,default.size,default.origin) - b = default.node_coordinates.reshape(tuple(default.grid+1)+(3,),order='F') + a = grid_filters.node_coord0(default.cells,default.size,default.origin) + b = default.node_coordinates.reshape(tuple(default.cells+1)+(3,),order='F') assert np.allclose(a,b) @pytest.mark.parametrize('output',['F',[],['F','P']]) diff --git a/python/tests/test_VTK.py b/python/tests/test_VTK.py index 1b90fff88..39dec373c 100644 --- a/python/tests/test_VTK.py +++ b/python/tests/test_VTK.py @@ -16,9 +16,9 @@ def ref_path(ref_path_base): @pytest.fixture def default(): """Simple VTK.""" - grid = np.array([5,6,7],int) - size = np.array([.6,1.,.5]) - return VTK.from_rectilinear_grid(grid,size) + cells = np.array([5,6,7],int) + size = np.array([.6,1.,.5]) + return VTK.from_rectilinear_grid(cells,size) class TestVTK: @@ -27,10 +27,10 @@ class TestVTK: print('patched damask.util.execution_stamp') def test_rectilinearGrid(self,tmp_path): - grid = np.random.randint(5,10,3)*2 + cells = np.random.randint(5,10,3)*2 size = np.random.random(3) + 1.0 origin = np.random.random(3) - v = VTK.from_rectilinear_grid(grid,size,origin) + v = VTK.from_rectilinear_grid(cells,size,origin) string = v.__repr__() v.save(tmp_path/'rectilinearGrid',False) vtr = VTK.load(tmp_path/'rectilinearGrid.vtr') @@ -152,11 +152,11 @@ class TestVTK: np.allclose(polyData.get('coordinates'),points) def test_compare_reference_rectilinearGrid(self,update,ref_path,tmp_path): - grid = np.array([5,6,7],int) - size = np.array([.6,1.,.5]) - rectilinearGrid = VTK.from_rectilinear_grid(grid,size) - c = grid_filters.cell_coord0(grid,size).reshape(-1,3,order='F') - n = grid_filters.node_coord0(grid,size).reshape(-1,3,order='F') + cells = np.array([5,6,7],int) + size = np.array([.6,1.,.5]) + rectilinearGrid = VTK.from_rectilinear_grid(cells,size) + c = grid_filters.cell_coord0(cells,size).reshape(-1,3,order='F') + n = grid_filters.node_coord0(cells,size).reshape(-1,3,order='F') rectilinearGrid.add(c,'cell') rectilinearGrid.add(n,'node') if update: diff --git a/python/tests/test_grid_filters.py b/python/tests/test_grid_filters.py index 3acb554a7..fa2bf2bb7 100644 --- a/python/tests/test_grid_filters.py +++ b/python/tests/test_grid_filters.py @@ -7,58 +7,58 @@ class TestGridFilters: def test_cell_coord0(self): size = np.random.random(3) - grid = np.random.randint(8,32,(3)) - coord = grid_filters.cell_coord0(grid,size) - assert np.allclose(coord[0,0,0],size/grid*.5) and coord.shape == tuple(grid) + (3,) + cells = np.random.randint(8,32,(3)) + coord = grid_filters.cell_coord0(cells,size) + assert np.allclose(coord[0,0,0],size/cells*.5) and coord.shape == tuple(cells) + (3,) def test_node_coord0(self): size = np.random.random(3) - grid = np.random.randint(8,32,(3)) - coord = grid_filters.node_coord0(grid,size) - assert np.allclose(coord[-1,-1,-1],size) and coord.shape == tuple(grid+1) + (3,) + cells = np.random.randint(8,32,(3)) + coord = grid_filters.node_coord0(cells,size) + assert np.allclose(coord[-1,-1,-1],size) and coord.shape == tuple(cells+1) + (3,) def test_coord0(self): size = np.random.random(3) - grid = np.random.randint(8,32,(3)) - c = grid_filters.cell_coord0(grid+1,size+size/grid) - n = grid_filters.node_coord0(grid,size) + size/grid*.5 + cells = np.random.randint(8,32,(3)) + c = grid_filters.cell_coord0(cells+1,size+size/cells) + n = grid_filters.node_coord0(cells,size) + size/cells*.5 assert np.allclose(c,n) @pytest.mark.parametrize('mode',['cell','node']) def test_grid_DNA(self,mode): """Ensure that xx_coord0_gridSizeOrigin is the inverse of xx_coord0.""" - grid = np.random.randint(8,32,(3)) + cells = np.random.randint(8,32,(3)) size = np.random.random(3) origin = np.random.random(3) - coord0 = eval(f'grid_filters.{mode}_coord0(grid,size,origin)') # noqa - _grid,_size,_origin = eval(f'grid_filters.{mode}_coord0_gridSizeOrigin(coord0.reshape(-1,3,order="F"))') - assert np.allclose(grid,_grid) and np.allclose(size,_size) and np.allclose(origin,_origin) + coord0 = eval(f'grid_filters.{mode}_coord0(cells,size,origin)') # noqa + _cells,_size,_origin = eval(f'grid_filters.{mode}_coord0_gridSizeOrigin(coord0.reshape(-1,3,order="F"))') + assert np.allclose(cells,_cells) and np.allclose(size,_size) and np.allclose(origin,_origin) def test_displacement_fluct_equivalence(self): """Ensure that fluctuations are periodic.""" size = np.random.random(3) - grid = np.random.randint(8,32,(3)) - F = np.random.random(tuple(grid)+(3,3)) + cells = np.random.randint(8,32,(3)) + F = np.random.random(tuple(cells)+(3,3)) assert np.allclose(grid_filters.node_displacement_fluct(size,F), grid_filters.cell_2_node(grid_filters.cell_displacement_fluct(size,F))) def test_interpolation_to_node(self): size = np.random.random(3) - grid = np.random.randint(8,32,(3)) - F = np.random.random(tuple(grid)+(3,3)) + cells = np.random.randint(8,32,(3)) + F = np.random.random(tuple(cells)+(3,3)) assert np.allclose(grid_filters.node_coord(size,F) [1:-1,1:-1,1:-1], grid_filters.cell_2_node(grid_filters.cell_coord(size,F))[1:-1,1:-1,1:-1]) def test_interpolation_to_cell(self): - grid = np.random.randint(1,30,(3)) + cells = np.random.randint(1,30,(3)) - node_coord_x = np.linspace(0,np.pi*2,num=grid[0]+1) + node_coord_x = np.linspace(0,np.pi*2,num=cells[0]+1) node_field_x = np.cos(node_coord_x) - node_field = np.broadcast_to(node_field_x.reshape(-1,1,1),grid+1) + node_field = np.broadcast_to(node_field_x.reshape(-1,1,1),cells+1) cell_coord_x = node_coord_x[:-1]+node_coord_x[1]*.5 cell_field_x = np.interp(cell_coord_x,node_coord_x,node_field_x,period=np.pi*2.) - cell_field = np.broadcast_to(cell_field_x.reshape(-1,1,1),grid) + cell_field = np.broadcast_to(cell_field_x.reshape(-1,1,1),cells) assert np.allclose(cell_field,grid_filters.node_2_cell(node_field)) @@ -66,21 +66,21 @@ class TestGridFilters: def test_coord0_origin(self,mode): origin= np.random.random(3) size = np.random.random(3) # noqa - grid = np.random.randint(8,32,(3)) - shifted = eval(f'grid_filters.{mode}_coord0(grid,size,origin)') - unshifted = eval(f'grid_filters.{mode}_coord0(grid,size)') + cells = np.random.randint(8,32,(3)) + shifted = eval(f'grid_filters.{mode}_coord0(cells,size,origin)') + unshifted = eval(f'grid_filters.{mode}_coord0(cells,size)') if mode == 'cell': - assert np.allclose(shifted,unshifted+np.broadcast_to(origin,tuple(grid) +(3,))) + assert np.allclose(shifted,unshifted+np.broadcast_to(origin,tuple(cells) +(3,))) elif mode == 'node': - assert np.allclose(shifted,unshifted+np.broadcast_to(origin,tuple(grid+1)+(3,))) + assert np.allclose(shifted,unshifted+np.broadcast_to(origin,tuple(cells+1)+(3,))) @pytest.mark.parametrize('function',[grid_filters.cell_displacement_avg, grid_filters.node_displacement_avg]) def test_displacement_avg_vanishes(self,function): """Ensure that random fluctuations in F do not result in average displacement.""" size = np.random.random(3) - grid = np.random.randint(8,32,(3)) - F = np.random.random(tuple(grid)+(3,3)) + cells = np.random.randint(8,32,(3)) + F = np.random.random(tuple(cells)+(3,3)) F += np.eye(3) - np.average(F,axis=(0,1,2)) assert np.allclose(function(size,F),0.0) @@ -89,8 +89,8 @@ class TestGridFilters: def test_displacement_fluct_vanishes(self,function): """Ensure that constant F does not result in fluctuating displacement.""" size = np.random.random(3) - grid = np.random.randint(8,32,(3)) - F = np.broadcast_to(np.random.random((3,3)), tuple(grid)+(3,3)) + cells = np.random.randint(8,32,(3)) + F = np.broadcast_to(np.random.random((3,3)), tuple(cells)+(3,3)) assert np.allclose(function(size,F),0.0) @pytest.mark.parametrize('function',[grid_filters.coord0_check, @@ -106,11 +106,11 @@ class TestGridFilters: def test_uneven_spaced_coordinates(self,function): start = np.random.random(3) end = np.random.random(3)*10. + start - grid = np.random.randint(8,32,(3)) - uneven = np.stack(np.meshgrid(np.logspace(start[0],end[0],grid[0]), - np.logspace(start[1],end[1],grid[1]), - np.logspace(start[2],end[2],grid[2]),indexing = 'ij'), - axis = -1).reshape((grid.prod(),3),order='F') + cells = np.random.randint(8,32,(3)) + uneven = np.stack(np.meshgrid(np.logspace(start[0],end[0],cells[0]), + np.logspace(start[1],end[1],cells[1]), + np.logspace(start[2],end[2],cells[2]),indexing = 'ij'), + axis = -1).reshape((cells.prod(),3),order='F') with pytest.raises(ValueError): function(uneven) @@ -121,8 +121,8 @@ class TestGridFilters: def test_unordered_coordinates(self,function,mode): origin = np.random.random(3) size = np.random.random(3)*10.+origin - grid = np.random.randint(8,32,(3)) - unordered = grid_filters.node_coord0(grid,size,origin).reshape(-1,3) + cells = np.random.randint(8,32,(3)) + unordered = grid_filters.node_coord0(cells,size,origin).reshape(-1,3) if mode: with pytest.raises(ValueError): function(unordered,mode) @@ -131,9 +131,9 @@ class TestGridFilters: def test_regrid(self): size = np.random.random(3) - grid = np.random.randint(8,32,(3)) - F = np.broadcast_to(np.eye(3), tuple(grid)+(3,3)) - assert all(grid_filters.regrid(size,F,grid) == np.arange(grid.prod())) + cells = np.random.randint(8,32,(3)) + F = np.broadcast_to(np.eye(3), tuple(cells)+(3,3)) + assert all(grid_filters.regrid(size,F,cells) == np.arange(cells.prod())) @pytest.mark.parametrize('differential_operator',[grid_filters.curl, @@ -141,14 +141,14 @@ class TestGridFilters: grid_filters.gradient]) def test_differential_operator_constant(self,differential_operator): size = np.random.random(3)+1.0 - grid = np.random.randint(8,32,(3)) + cells = np.random.randint(8,32,(3)) shapes = { grid_filters.curl: [(3,),(3,3)], grid_filters.divergence:[(3,),(3,3)], grid_filters.gradient: [(1,),(3,)] } for shape in shapes[differential_operator]: - field = np.ones(tuple(grid)+shape)*np.random.random()*1.0e5 + field = np.ones(tuple(cells)+shape)*np.random.random()*1.0e5 assert np.allclose(differential_operator(size,field),0.0) @@ -190,15 +190,15 @@ class TestGridFilters: @pytest.mark.parametrize('field_def,grad_def',grad_test_data) def test_grad(self,field_def,grad_def): size = np.random.random(3)+1.0 - grid = np.random.randint(8,32,(3)) + cells = np.random.randint(8,32,(3)) - nodes = grid_filters.cell_coord0(grid,size) + nodes = grid_filters.cell_coord0(cells,size) my_locals = locals() # needed for list comprehension - field = np.stack([np.broadcast_to(eval(f,globals(),my_locals),grid) for f in field_def],axis=-1) - field = field.reshape(tuple(grid) + ((3,) if len(field_def)==3 else (1,))) - grad = np.stack([np.broadcast_to(eval(c,globals(),my_locals),grid) for c in grad_def], axis=-1) - grad = grad.reshape(tuple(grid) + ((3,3) if len(grad_def)==9 else (3,))) + field = np.stack([np.broadcast_to(eval(f,globals(),my_locals),cells) for f in field_def],axis=-1) + field = field.reshape(tuple(cells) + ((3,) if len(field_def)==3 else (1,))) + grad = np.stack([np.broadcast_to(eval(c,globals(),my_locals),cells) for c in grad_def], axis=-1) + grad = grad.reshape(tuple(cells) + ((3,3) if len(grad_def)==9 else (3,))) assert np.allclose(grad,grid_filters.gradient(size,field)) @@ -250,15 +250,15 @@ class TestGridFilters: @pytest.mark.parametrize('field_def,curl_def',curl_test_data) def test_curl(self,field_def,curl_def): size = np.random.random(3)+1.0 - grid = np.random.randint(8,32,(3)) + cells = np.random.randint(8,32,(3)) - nodes = grid_filters.cell_coord0(grid,size) + nodes = grid_filters.cell_coord0(cells,size) my_locals = locals() # needed for list comprehension - field = np.stack([np.broadcast_to(eval(f,globals(),my_locals),grid) for f in field_def],axis=-1) - field = field.reshape(tuple(grid) + ((3,3) if len(field_def)==9 else (3,))) - curl = np.stack([np.broadcast_to(eval(c,globals(),my_locals),grid) for c in curl_def], axis=-1) - curl = curl.reshape(tuple(grid) + ((3,3) if len(curl_def)==9 else (3,))) + field = np.stack([np.broadcast_to(eval(f,globals(),my_locals),cells) for f in field_def],axis=-1) + field = field.reshape(tuple(cells) + ((3,3) if len(field_def)==9 else (3,))) + curl = np.stack([np.broadcast_to(eval(c,globals(),my_locals),cells) for c in curl_def], axis=-1) + curl = curl.reshape(tuple(cells) + ((3,3) if len(curl_def)==9 else (3,))) assert np.allclose(curl,grid_filters.curl(size,field)) @@ -303,17 +303,17 @@ class TestGridFilters: def test_div(self,field_def,div_def): size = np.random.random(3)+1.0 - grid = np.random.randint(8,32,(3)) + cells = np.random.randint(8,32,(3)) - nodes = grid_filters.cell_coord0(grid,size) + nodes = grid_filters.cell_coord0(cells,size) my_locals = locals() # needed for list comprehension - field = np.stack([np.broadcast_to(eval(f,globals(),my_locals),grid) for f in field_def],axis=-1) - field = field.reshape(tuple(grid) + ((3,3) if len(field_def)==9 else (3,))) - div = np.stack([np.broadcast_to(eval(c,globals(),my_locals),grid) for c in div_def], axis=-1) + field = np.stack([np.broadcast_to(eval(f,globals(),my_locals),cells) for f in field_def],axis=-1) + field = field.reshape(tuple(cells) + ((3,3) if len(field_def)==9 else (3,))) + div = np.stack([np.broadcast_to(eval(c,globals(),my_locals),cells) for c in div_def], axis=-1) if len(div_def)==3: - div = div.reshape(tuple(grid) + ((3,))) + div = div.reshape(tuple(cells) + ((3,))) else: - div=div.reshape(tuple(grid)) + div=div.reshape(tuple(cells)) assert np.allclose(div,grid_filters.divergence(size,field)) diff --git a/python/tests/test_seeds.py b/python/tests/test_seeds.py index c9ad6f0e3..f7c46e889 100644 --- a/python/tests/test_seeds.py +++ b/python/tests/test_seeds.py @@ -8,11 +8,11 @@ from damask import Geom class TestSeeds: - @pytest.mark.parametrize('grid',[None,np.ones(3,dtype='i')*10]) - def test_from_random(self,grid): + @pytest.mark.parametrize('cells',[None,np.ones(3,dtype='i')*10]) + def test_from_random(self,cells): N_seeds = np.random.randint(30,300) size = np.ones(3) + np.random.random(3) - coords = seeds.from_random(size,N_seeds,grid) + coords = seeds.from_random(size,N_seeds,cells) assert (0<=coords).all() and (coords=distance def test_from_geom_reconstruct(self): - grid = np.random.randint(10,20,3) + cells = np.random.randint(10,20,3) N_seeds = np.random.randint(30,300) size = np.ones(3) + np.random.random(3) - coords = seeds.from_random(size,N_seeds,grid) - geom_1 = Geom.from_Voronoi_tessellation(grid,size,coords) + coords = seeds.from_random(size,N_seeds,cells) + geom_1 = Geom.from_Voronoi_tessellation(cells,size,coords) coords,material = seeds.from_geom(geom_1) - geom_2 = Geom.from_Voronoi_tessellation(grid,size,coords,material) + geom_2 = Geom.from_Voronoi_tessellation(cells,size,coords,material) assert (geom_2.material==geom_1.material).all() @pytest.mark.parametrize('periodic',[True,False]) @pytest.mark.parametrize('average',[True,False]) def test_from_geom_grid(self,periodic,average): - grid = np.random.randint(10,20,3) - size = np.ones(3) + np.random.random(3) - coords = grid_filters.cell_coord0(grid,size).reshape(-1,3) + cells = np.random.randint(10,20,3) + size = np.ones(3) + np.random.random(3) + coords = grid_filters.cell_coord0(cells,size).reshape(-1,3) np.random.shuffle(coords) - geom_1 = Geom.from_Voronoi_tessellation(grid,size,coords) + geom_1 = Geom.from_Voronoi_tessellation(cells,size,coords) coords,material = seeds.from_geom(geom_1,average=average,periodic=periodic) - geom_2 = Geom.from_Voronoi_tessellation(grid,size,coords,material) + geom_2 = Geom.from_Voronoi_tessellation(cells,size,coords,material) assert (geom_2.material==geom_1.material).all() @pytest.mark.parametrize('periodic',[True,False]) @pytest.mark.parametrize('average',[True,False]) @pytest.mark.parametrize('invert',[True,False]) def test_from_geom_selection(self,periodic,average,invert): - grid = np.random.randint(10,20,3) + cells = np.random.randint(10,20,3) N_seeds = np.random.randint(30,300) size = np.ones(3) + np.random.random(3) - coords = seeds.from_random(size,N_seeds,grid) - geom = Geom.from_Voronoi_tessellation(grid,size,coords) + coords = seeds.from_random(size,N_seeds,cells) + geom = Geom.from_Voronoi_tessellation(cells,size,coords) selection=np.random.randint(N_seeds)+1 coords,material = seeds.from_geom(geom,average=average,periodic=periodic,invert=invert,selection=[selection]) assert selection not in material if invert else (selection==material).all() diff --git a/src/discretization.f90 b/src/discretization.f90 index 0b8925e4a..2b19cb20b 100644 --- a/src/discretization.f90 +++ b/src/discretization.f90 @@ -86,7 +86,7 @@ subroutine discretization_results u = discretization_IPcoords & - discretization_IPcoords0 - call results_writeDataset('current/geometry',u,'u_p','displacements of the materialpoints','m') + call results_writeDataset('current/geometry',u,'u_p','displacements of the materialpoints (cell centers)','m') end subroutine discretization_results diff --git a/src/grid/discretization_grid.f90 b/src/grid/discretization_grid.f90 index e869c0781..e4b64c9c0 100644 --- a/src/grid/discretization_grid.f90 +++ b/src/grid/discretization_grid.f90 @@ -79,7 +79,7 @@ subroutine discretization_grid_init(restart) call MPI_Bcast(origin,3,MPI_DOUBLE,0,PETSC_COMM_WORLD, ierr) if (ierr /= 0) error stop 'MPI error' - print'(/,a,3(i12 ))', ' grid a b c: ', grid + print'(/,a,3(i12 ))', ' cells a b c: ', grid print'(a,3(es12.5))', ' size x y z: ', geomSize print'(a,3(es12.5))', ' origin x y z: ', origin @@ -125,9 +125,9 @@ subroutine discretization_grid_init(restart) if(.not. restart) then call results_openJobFile call results_closeGroup(results_addGroup('geometry')) - call results_addAttribute('grid', grid, 'geometry') - call results_addAttribute('size', geomSize,'geometry') - call results_addAttribute('origin',origin, 'geometry') + call results_addAttribute('cells', grid, '/geometry') + call results_addAttribute('size', geomSize,'/geometry') + call results_addAttribute('origin',origin, '/geometry') call results_closeJobFile endif diff --git a/src/marc/discretization_marc.f90 b/src/marc/discretization_marc.f90 index 9696572e5..ca0b54b73 100644 --- a/src/marc/discretization_marc.f90 +++ b/src/marc/discretization_marc.f90 @@ -162,7 +162,7 @@ subroutine writeGeometry(elem, & coordinates_temp = coordinates_points call results_writeDataset('geometry',coordinates_temp,'x_p', & - 'initial coordinates of the materialpoints','m') + 'initial coordinates of the materialpoints (cell centers)','m') call results_closeJobFile diff --git a/src/results.f90 b/src/results.f90 index bf276f561..524a65eaf 100644 --- a/src/results.f90 +++ b/src/results.f90 @@ -74,7 +74,7 @@ subroutine results_init(restart) if(.not. restart) then resultsFile = HDF5_openFile(trim(getSolverJobName())//'.hdf5','w',.true.) call results_addAttribute('DADF5_version_major',0) - call results_addAttribute('DADF5_version_minor',9) + call results_addAttribute('DADF5_version_minor',10) call results_addAttribute('DAMASK_version',DAMASKVERSION) call get_command(commandLine) call results_addAttribute('Call',trim(commandLine)) From 0fdefa5e78e52734ebce9ae2e4a2851ffe8c084e Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Thu, 3 Dec 2020 23:00:49 +0100 Subject: [PATCH 005/148] renames: after the rename of "grid" to "cell", the name cell should not be used for the coordinates of the cell centers. In agreement with the names x_p/u_p for point positions/displacements, now the "point" is used to refer to the materialpoints (i.e. cell centers) Additionally, "_node"/"_point" are now suffixes to "coordinates"/"displacements". Finally, "coords" is renamed to "coordinates" --- processing/post/DADF5_postResults.py | 8 +- processing/post/addCompatibilityMismatch.py | 6 +- processing/post/addCurl.py | 2 +- processing/post/addDisplacement.py | 12 +- processing/post/addDivergence.py | 2 +- processing/post/addEuclideanDistance.py | 2 +- processing/post/addGradient.py | 2 +- python/damask/_geom.py | 12 +- python/damask/_result.py | 10 +- python/damask/_rotation.py | 2 +- python/damask/grid_filters.py | 160 ++++++++++---------- python/damask/seeds.py | 4 +- python/tests/test_Geom.py | 4 +- python/tests/test_Result.py | 8 +- python/tests/test_Rotation.py | 4 +- python/tests/test_VTK.py | 4 +- python/tests/test_grid_filters.py | 76 +++++----- python/tests/test_seeds.py | 2 +- 18 files changed, 161 insertions(+), 159 deletions(-) diff --git a/processing/post/DADF5_postResults.py b/processing/post/DADF5_postResults.py index be4f78569..a1b162e3d 100755 --- a/processing/post/DADF5_postResults.py +++ b/processing/post/DADF5_postResults.py @@ -33,12 +33,12 @@ for filename in options.filenames: results = damask.Result(filename) if not results.structured: continue - coords = damask.grid_filters.cell_coord0(results.grid,results.size,results.origin).reshape(-1,3,order='F') + coords = damask.grid_filters.coordinates0_point(results.cells,results.size,results.origin).reshape(-1,3,order='F') N_digits = int(np.floor(np.log10(int(results.increments[-1][3:]))))+1 N_digits = 5 # hack to keep test intact for inc in damask.util.show_progress(results.iterate('increments'),len(results.increments)): - table = damask.Table(np.ones(np.product(results.grid),dtype=int)*int(inc[3:]),{'inc':(1,)})\ + table = damask.Table(np.ones(np.product(results.cells),dtype=int)*int(inc[3:]),{'inc':(1,)})\ .add('pos',coords.reshape(-1,3)) results.pick('homogenizations',False) @@ -46,14 +46,14 @@ for filename in options.filenames: for label in options.con: x = results.get_dataset_location(label) if len(x) != 0: - table = table.add(label,results.read_dataset(x,0,plain=True).reshape(results.grid.prod(),-1)) + table = table.add(label,results.read_dataset(x,0,plain=True).reshape(results.cells.prod(),-1)) results.pick('phases',False) results.pick('homogenizations',True) for label in options.mat: x = results.get_dataset_location(label) if len(x) != 0: - table = table.add(label,results.read_dataset(x,0,plain=True).reshape(results.grid.prod(),-1)) + table = table.add(label,results.read_dataset(x,0,plain=True).reshape(results.cells.prod(),-1)) dirname = os.path.abspath(os.path.join(os.path.dirname(filename),options.dir)) if not os.path.isdir(dirname): diff --git a/processing/post/addCompatibilityMismatch.py b/processing/post/addCompatibilityMismatch.py index 1b4425e06..e3219d839 100755 --- a/processing/post/addCompatibilityMismatch.py +++ b/processing/post/addCompatibilityMismatch.py @@ -71,13 +71,13 @@ for name in filenames: damask.util.report(scriptName,name) table = damask.Table.load(StringIO(''.join(sys.stdin.read())) if name is None else name) - grid,size,origin = damask.grid_filters.cell_coord0_gridSizeOrigin(table.get(options.pos)) + grid,size,origin = damask.grid_filters.cellSizeOrigin_coordinates0_point(table.get(options.pos)) F = table.get(options.defgrad).reshape(tuple(grid)+(-1,),order='F').reshape(tuple(grid)+(3,3)) - nodes = damask.grid_filters.node_coord(size,F) + nodes = damask.grid_filters.coordinates_node(size,F) if options.shape: - centers = damask.grid_filters.cell_coord(size,F) + centers = damask.grid_filters.coordinates_point(size,F) shapeMismatch = shapeMismatch(size,F,nodes,centers) table = table.add('shapeMismatch(({}))'.format(options.defgrad), shapeMismatch.reshape(-1,1,order='F'), diff --git a/processing/post/addCurl.py b/processing/post/addCurl.py index d91c2be92..a6de51445 100755 --- a/processing/post/addCurl.py +++ b/processing/post/addCurl.py @@ -44,7 +44,7 @@ for name in filenames: damask.util.report(scriptName,name) table = damask.Table.load(StringIO(''.join(sys.stdin.read())) if name is None else name) - grid,size,origin = damask.grid_filters.cell_coord0_gridSizeOrigin(table.get(options.pos)) + grid,size,origin = damask.grid_filters.cellSizeOrigin_coordinates0_point(table.get(options.pos)) for label in options.labels: field = table.get(label) diff --git a/processing/post/addDisplacement.py b/processing/post/addDisplacement.py index c3ba4a8af..3d24d6f0c 100755 --- a/processing/post/addDisplacement.py +++ b/processing/post/addDisplacement.py @@ -48,24 +48,24 @@ for name in filenames: damask.util.report(scriptName,name) table = damask.Table.load(StringIO(''.join(sys.stdin.read())) if name is None else name) - grid,size,origin = damask.grid_filters.cell_coord0_gridSizeOrigin(table.get(options.pos)) + grid,size,origin = damask.grid_filters.cellSizeOrigin_coordinates0_point(table.get(options.pos)) F = table.get(options.f).reshape(tuple(grid)+(-1,),order='F').reshape(tuple(grid)+(3,3)) if options.nodal: - damask.Table(damask.grid_filters.node_coord0(grid,size).reshape(-1,3,order='F'), + damask.Table(damask.grid_filters.coordinates0_node(grid,size).reshape(-1,3,order='F'), {'pos':(3,)})\ .add('avg({}).{}'.format(options.f,options.pos), - damask.grid_filters.node_displacement_avg(size,F).reshape(-1,3,order='F'), + damask.grid_filters.displacement_avg_node(size,F).reshape(-1,3,order='F'), scriptID+' '+' '.join(sys.argv[1:]))\ .add('fluct({}).{}'.format(options.f,options.pos), - damask.grid_filters.node_displacement_fluct(size,F).reshape(-1,3,order='F'), + damask.grid_filters.displacement_fluct_node(size,F).reshape(-1,3,order='F'), scriptID+' '+' '.join(sys.argv[1:]))\ .save((sys.stdout if name is None else os.path.splitext(name)[0]+'_nodal.txt')) else: table.add('avg({}).{}'.format(options.f,options.pos), - damask.grid_filters.cell_displacement_avg(size,F).reshape(-1,3,order='F'), + damask.grid_filters.displacement_avg_point(size,F).reshape(-1,3,order='F'), scriptID+' '+' '.join(sys.argv[1:]))\ .add('fluct({}).{}'.format(options.f,options.pos), - damask.grid_filters.cell_displacement_fluct(size,F).reshape(-1,3,order='F'), + damask.grid_filters.displacement_fluct_point(size,F).reshape(-1,3,order='F'), scriptID+' '+' '.join(sys.argv[1:]))\ .save((sys.stdout if name is None else name)) diff --git a/processing/post/addDivergence.py b/processing/post/addDivergence.py index 6e5629285..e6bf1caa0 100755 --- a/processing/post/addDivergence.py +++ b/processing/post/addDivergence.py @@ -44,7 +44,7 @@ for name in filenames: damask.util.report(scriptName,name) table = damask.Table.load(StringIO(''.join(sys.stdin.read())) if name is None else name) - grid,size,origin = damask.grid_filters.cell_coord0_gridSizeOrigin(table.get(options.pos)) + grid,size,origin = damask.grid_filters.cellSizeOrigin_coordinates0_point(table.get(options.pos)) for label in options.labels: field = table.get(label) diff --git a/processing/post/addEuclideanDistance.py b/processing/post/addEuclideanDistance.py index 0c18bdccc..f35f5285a 100755 --- a/processing/post/addEuclideanDistance.py +++ b/processing/post/addEuclideanDistance.py @@ -143,7 +143,7 @@ for name in filenames: damask.util.report(scriptName,name) table = damask.Table.load(StringIO(''.join(sys.stdin.read())) if name is None else name) - grid,size,origin = damask.grid_filters.cell_coord0_gridSizeOrigin(table.get(options.pos)) + grid,size,origin = damask.grid_filters.cellSizeOrigin_coordinates0_point(table.get(options.pos)) neighborhood = neighborhoods[options.neighborhood] diffToNeighbor = np.empty(list(grid+2)+[len(neighborhood)],'i') diff --git a/processing/post/addGradient.py b/processing/post/addGradient.py index 147773734..66b122082 100755 --- a/processing/post/addGradient.py +++ b/processing/post/addGradient.py @@ -44,7 +44,7 @@ for name in filenames: damask.util.report(scriptName,name) table = damask.Table.load(StringIO(''.join(sys.stdin.read())) if name is None else name) - grid,size,origin = damask.grid_filters.cell_coord0_gridSizeOrigin(table.get(options.pos)) + grid,size,origin = damask.grid_filters.cellSizeOrigin_coordinates0_point(table.get(options.pos)) for label in options.labels: field = table.get(label) diff --git a/python/damask/_geom.py b/python/damask/_geom.py index 495ed05ac..8ccde0843 100644 --- a/python/damask/_geom.py +++ b/python/damask/_geom.py @@ -302,7 +302,7 @@ class Geom: Each unique combintation of values results in one material ID. """ - cells,size,origin = grid_filters.cell_coord0_gridSizeOrigin(table.get(coordinates)) + cells,size,origin = grid_filters.cellSizeOrigin_coordinates0_point(table.get(coordinates)) labels_ = [labels] if isinstance(labels,str) else labels unique,unique_inverse = np.unique(np.hstack([table.get(l) for l in labels_]),return_inverse=True,axis=0) @@ -344,11 +344,11 @@ class Geom: seeds_p = np.vstack((seeds -np.array([size[0],0.,0.]),seeds, seeds +np.array([size[0],0.,0.]))) seeds_p = np.vstack((seeds_p-np.array([0.,size[1],0.]),seeds_p,seeds_p+np.array([0.,size[1],0.]))) seeds_p = np.vstack((seeds_p-np.array([0.,0.,size[2]]),seeds_p,seeds_p+np.array([0.,0.,size[2]]))) - coords = grid_filters.cell_coord0(cells*3,size*3,-size).reshape(-1,3) + coords = grid_filters.coordinates0_point(cells*3,size*3,-size).reshape(-1,3) else: weights_p = weights seeds_p = seeds - coords = grid_filters.cell_coord0(cells,size).reshape(-1,3) + coords = grid_filters.coordinates0_point(cells,size).reshape(-1,3) pool = mp.Pool(processes = int(environment.options['DAMASK_NUM_THREADS'])) result = pool.map_async(partial(Geom._find_closest_seed,seeds_p,weights_p), [coord for coord in coords]) @@ -388,7 +388,7 @@ class Geom: Perform a periodic tessellation. Defaults to True. """ - coords = grid_filters.cell_coord0(cells,size).reshape(-1,3) + coords = grid_filters.coordinates0_point(cells,size).reshape(-1,3) KDTree = spatial.cKDTree(seeds,boxsize=size) if periodic else spatial.cKDTree(seeds) devNull,material_ = KDTree.query(coords) @@ -592,7 +592,7 @@ class Geom: c = (np.array(center) + .5)*self.size/self.cells if np.array(center).dtype in np.sctypes['int'] else \ (np.array(center) - self.origin) - coords = grid_filters.cell_coord0(self.cells,self.size, + coords = grid_filters.coordinates0_point(self.cells,self.size, -(0.5*(self.size + (self.size/self.cells if np.array(center).dtype in np.sctypes['int'] else 0)) if periodic else c)) @@ -932,5 +932,5 @@ class Geom: base_nodes = np.argwhere(mask.flatten(order='F')).reshape(-1,1) connectivity.append(np.block([base_nodes + o[i][k] for k in range(4)])) - coords = grid_filters.node_coord0(self.cells,self.size,self.origin).reshape(-1,3,order='F') + coords = grid_filters.coordinates0_node(self.cells,self.size,self.origin).reshape(-1,3,order='F') return VTK.from_unstructured_grid(coords,np.vstack(connectivity),'QUAD') diff --git a/python/damask/_result.py b/python/damask/_result.py index 38b18d5ec..afeea568f 100644 --- a/python/damask/_result.py +++ b/python/damask/_result.py @@ -562,19 +562,19 @@ class Result: return dataset @property - def cell_coordinates(self): + def coordinates0_point(self): """Return initial coordinates of the cell centers.""" if self.structured: - return grid_filters.cell_coord0(self.cells,self.size,self.origin).reshape(-1,3,order='F') + return grid_filters.coordinates0_point(self.cells,self.size,self.origin).reshape(-1,3,order='F') else: with h5py.File(self.fname,'r') as f: return f['geometry/x_c'][()] @property - def node_coordinates(self): + def coordinates0_node(self): """Return initial coordinates of the cell centers.""" if self.structured: - return grid_filters.node_coord0(self.cells,self.size,self.origin).reshape(-1,3,order='F') + return grid_filters.coordinates0_node(self.cells,self.size,self.origin).reshape(-1,3,order='F') else: with h5py.File(self.fname,'r') as f: return f['geometry/x_n'][()] @@ -1303,7 +1303,7 @@ class Result: f['/geometry/T_c'].attrs['VTK_TYPE'] if h5py3 else \ f['/geometry/T_c'].attrs['VTK_TYPE'].decode()) elif mode.lower()=='point': - v = VTK.from_poly_data(self.cell_coordinates) + v = VTK.from_poly_data(self.coordinates0_point) N_digits = int(np.floor(np.log10(max(1,int(self.increments[-1][3:])))))+1 diff --git a/python/damask/_rotation.py b/python/damask/_rotation.py index 5fb8109c3..e7bf50bd1 100644 --- a/python/damask/_rotation.py +++ b/python/damask/_rotation.py @@ -763,7 +763,7 @@ class Rotation: def _dg(eu,deg): """Return infinitesimal Euler space volume of bin(s).""" phi_sorted = eu[np.lexsort((eu[:,0],eu[:,1],eu[:,2]))] - steps,size,_ = grid_filters.cell_coord0_gridSizeOrigin(phi_sorted) + steps,size,_ = grid_filters.cellSizeOrigin_coordinates0_point(phi_sorted) delta = np.radians(size/steps) if deg else size/steps return delta[0]*2.0*np.sin(delta[1]/2.0)*delta[2] / 8.0 / np.pi**2 * np.sin(np.radians(eu[:,1]) if deg else eu[:,1]) diff --git a/python/damask/grid_filters.py b/python/damask/grid_filters.py index 7496a0d52..8e930d69d 100644 --- a/python/damask/grid_filters.py +++ b/python/damask/grid_filters.py @@ -22,11 +22,11 @@ def _ks(size,cells,first_order=False): Parameters ---------- size : numpy.ndarray of shape (3) - physical size of the periodic field. + Physical size of the periodic field. cells : numpy.ndarray of shape (3) - number of cells. + Number of cells. first_order : bool, optional - correction for first order derivatives, defaults to False. + Correction for first order derivatives, defaults to False. """ k_sk = _np.where(_np.arange(cells[0])>cells[0]//2,_np.arange(cells[0])-cells[0],_np.arange(cells[0]))/size[0] @@ -47,9 +47,9 @@ def curl(size,field): Parameters ---------- size : numpy.ndarray of shape (3) - physical size of the periodic field. + Physical size of the periodic field. field : numpy.ndarray of shape (:,:,:,3) or (:,:,:,3,3) - periodic field of which the curl is calculated. + Periodic field of which the curl is calculated. """ n = _np.prod(field.shape[3:]) @@ -73,9 +73,9 @@ def divergence(size,field): Parameters ---------- size : numpy.ndarray of shape (3) - physical size of the periodic field. + Physical size of the periodic field. field : numpy.ndarray of shape (:,:,:,3) or (:,:,:,3,3) - periodic field of which the divergence is calculated. + Periodic field of which the divergence is calculated. """ n = _np.prod(field.shape[3:]) @@ -95,9 +95,9 @@ def gradient(size,field): Parameters ---------- size : numpy.ndarray of shape (3) - physical size of the periodic field. + Physical size of the periodic field. field : numpy.ndarray of shape (:,:,:,1) or (:,:,:,3) - periodic field of which the gradient is calculated. + Periodic field of which the gradient is calculated. """ n = _np.prod(field.shape[3:]) @@ -110,18 +110,18 @@ def gradient(size,field): return _np.fft.irfftn(grad_,axes=(0,1,2),s=field.shape[:3]) -def cell_coord0(cells,size,origin=_np.zeros(3)): +def coordinates0_point(cells,size,origin=_np.zeros(3)): """ Cell center positions (undeformed). Parameters ---------- cells : numpy.ndarray of shape (3) - number of cells. + Number of cells. size : numpy.ndarray of shape (3) - physical size of the periodic field. + Physical size of the periodic field. origin : numpy.ndarray, optional - physical origin of the periodic field. Defaults to [0.0,0.0,0.0]. + Physical origin of the periodic field. Defaults to [0.0,0.0,0.0]. """ start = origin + size/cells*.5 @@ -133,16 +133,16 @@ def cell_coord0(cells,size,origin=_np.zeros(3)): axis = -1) -def cell_displacement_fluct(size,F): +def displacement_fluct_point(size,F): """ Cell center displacement field from fluctuation part of the deformation gradient field. Parameters ---------- size : numpy.ndarray of shape (3) - physical size of the periodic field. + Physical size of the periodic field. F : numpy.ndarray - deformation gradient field. + Deformation gradient field. """ integrator = 0.5j*size/_np.pi @@ -160,67 +160,67 @@ def cell_displacement_fluct(size,F): return _np.fft.irfftn(displacement,axes=(0,1,2),s=F.shape[:3]) -def cell_displacement_avg(size,F): +def displacement_avg_point(size,F): """ Cell center displacement field from average part of the deformation gradient field. Parameters ---------- size : numpy.ndarray of shape (3) - physical size of the periodic field. + Physical size of the periodic field. F : numpy.ndarray - deformation gradient field. + Deformation gradient field. """ F_avg = _np.average(F,axis=(0,1,2)) - return _np.einsum('ml,ijkl->ijkm',F_avg - _np.eye(3),cell_coord0(F.shape[:3],size)) + return _np.einsum('ml,ijkl->ijkm',F_avg - _np.eye(3),coordinates0_point(F.shape[:3],size)) -def cell_displacement(size,F): +def displacement_point(size,F): """ Cell center displacement field from deformation gradient field. Parameters ---------- size : numpy.ndarray of shape (3) - physical size of the periodic field. + Physical size of the periodic field. F : numpy.ndarray - deformation gradient field. + Deformation gradient field. """ - return cell_displacement_avg(size,F) + cell_displacement_fluct(size,F) + return displacement_avg_point(size,F) + displacement_fluct_point(size,F) -def cell_coord(size,F,origin=_np.zeros(3)): +def coordinates_point(size,F,origin=_np.zeros(3)): """ Cell center positions. Parameters ---------- size : numpy.ndarray of shape (3) - physical size of the periodic field. + Physical size of the periodic field. F : numpy.ndarray - deformation gradient field. + Deformation gradient field. origin : numpy.ndarray of shape (3), optional - physical origin of the periodic field. Defaults to [0.0,0.0,0.0]. + Physical origin of the periodic field. Defaults to [0.0,0.0,0.0]. """ - return cell_coord0(F.shape[:3],size,origin) + cell_displacement(size,F) + return coordinates0_point(F.shape[:3],size,origin) + displacement_point(size,F) -def cell_coord0_gridSizeOrigin(coord0,ordered=True): +def cellSizeOrigin_coordinates0_point(coordinates0,ordered=True): """ - Return grid 'DNA', i.e. cells, size, and origin from 1D array of cell positions. + Return grid 'DNA', i.e. cells, size, and origin from 1D array of point positions. Parameters ---------- - coord0 : numpy.ndarray of shape (:,3) - undeformed cell coordinates. + coordinates0 : numpy.ndarray of shape (:,3) + Undeformed cell coordinates. ordered : bool, optional - expect coord0 data to be ordered (x fast, z slow). + Expect coordinates0 data to be ordered (x fast, z slow). """ - coords = [_np.unique(coord0[:,i]) for i in range(3)] + coords = [_np.unique(coordinates0[:,i]) for i in range(3)] mincorner = _np.array(list(map(min,coords))) maxcorner = _np.array(list(map(max,coords))) cells = _np.array(list(map(len,coords)),'i') @@ -232,8 +232,8 @@ def cell_coord0_gridSizeOrigin(coord0,ordered=True): size [_np.where(cells==1)] = origin[_np.where(cells==1)]*2. origin[_np.where(cells==1)] = 0.0 - if cells.prod() != len(coord0): - raise ValueError('Data count {len(coord0)} does not match cells {cells}.') + if cells.prod() != len(coordinates0): + raise ValueError('Data count {len(coordinates0)} does not match cells {cells}.') start = origin + delta*.5 end = origin - delta*.5 + size @@ -244,37 +244,38 @@ def cell_coord0_gridSizeOrigin(coord0,ordered=True): _np.allclose(coords[2],_np.linspace(start[2],end[2],cells[2]),atol=atol)): raise ValueError('Regular cells spacing violated.') - if ordered and not _np.allclose(coord0.reshape(tuple(cells)+(3,),order='F'),cell_coord0(cells,size,origin),atol=atol): + if ordered and not _np.allclose(coordinates0.reshape(tuple(cells)+(3,),order='F'), + coordinates0_point(cells,size,origin),atol=atol): raise ValueError('Input data is not ordered (x fast, z slow).') return (cells,size,origin) -def coord0_check(coord0): +def coordinates0_check(coordinates0): """ Check whether coordinates lie on a regular grid. Parameters ---------- - coord0 : numpy.ndarray - array of undeformed cell coordinates. + coordinates0 : numpy.ndarray + Array of undeformed cell coordinates. """ - cell_coord0_gridSizeOrigin(coord0,ordered=True) + cellSizeOrigin_coordinates0_point(coordinates0,ordered=True) -def node_coord0(cells,size,origin=_np.zeros(3)): +def coordinates0_node(cells,size,origin=_np.zeros(3)): """ Nodal positions (undeformed). Parameters ---------- cells : numpy.ndarray of shape (3) - number of cells. + Number of cells. size : numpy.ndarray of shape (3) - physical size of the periodic field. + Physical size of the periodic field. origin : numpy.ndarray of shape (3), optional - physical origin of the periodic field. Defaults to [0.0,0.0,0.0]. + Physical origin of the periodic field. Defaults to [0.0,0.0,0.0]. """ return _np.stack(_np.meshgrid(_np.linspace(origin[0],size[0]+origin[0],cells[0]+1), @@ -283,71 +284,71 @@ def node_coord0(cells,size,origin=_np.zeros(3)): axis = -1) -def node_displacement_fluct(size,F): +def displacement_fluct_node(size,F): """ Nodal displacement field from fluctuation part of the deformation gradient field. Parameters ---------- size : numpy.ndarray of shape (3) - physical size of the periodic field. + Physical size of the periodic field. F : numpy.ndarray - deformation gradient field. + Deformation gradient field. """ - return cell_2_node(cell_displacement_fluct(size,F)) + return point_2_node(displacement_fluct_point(size,F)) -def node_displacement_avg(size,F): +def displacement_avg_node(size,F): """ Nodal displacement field from average part of the deformation gradient field. Parameters ---------- size : numpy.ndarray of shape (3) - physical size of the periodic field. + Physical size of the periodic field. F : numpy.ndarray - deformation gradient field. + Deformation gradient field. """ F_avg = _np.average(F,axis=(0,1,2)) - return _np.einsum('ml,ijkl->ijkm',F_avg - _np.eye(3),node_coord0(F.shape[:3],size)) + return _np.einsum('ml,ijkl->ijkm',F_avg - _np.eye(3),coordinates0_node(F.shape[:3],size)) -def node_displacement(size,F): +def displacement_node(size,F): """ Nodal displacement field from deformation gradient field. Parameters ---------- size : numpy.ndarray of shape (3) - physical size of the periodic field. + Physical size of the periodic field. F : numpy.ndarray - deformation gradient field. + Deformation gradient field. """ - return node_displacement_avg(size,F) + node_displacement_fluct(size,F) + return displacement_avg_node(size,F) + displacement_fluct_node(size,F) -def node_coord(size,F,origin=_np.zeros(3)): +def coordinates_node(size,F,origin=_np.zeros(3)): """ Nodal positions. Parameters ---------- size : numpy.ndarray of shape (3) - physical size of the periodic field. + Physical size of the periodic field. F : numpy.ndarray - deformation gradient field. + Deformation gradient field. origin : numpy.ndarray of shape (3), optional - physical origin of the periodic field. Defaults to [0.0,0.0,0.0]. + Physical origin of the periodic field. Defaults to [0.0,0.0,0.0]. """ - return node_coord0(F.shape[:3],size,origin) + node_displacement(size,F) + return coordinates0_node(F.shape[:3],size,origin) + displacement_node(size,F) -def cell_2_node(cell_data): - """Interpolate periodic cell data to nodal data.""" +def point_2_node(cell_data): + """Interpolate periodic point data to nodal data.""" n = ( cell_data + _np.roll(cell_data,1,(0,1,2)) + _np.roll(cell_data,1,(0,)) + _np.roll(cell_data,1,(1,)) + _np.roll(cell_data,1,(2,)) + _np.roll(cell_data,1,(0,1)) + _np.roll(cell_data,1,(1,2)) + _np.roll(cell_data,1,(2,0)))*0.125 @@ -355,8 +356,8 @@ def cell_2_node(cell_data): return _np.pad(n,((0,1),(0,1),(0,1))+((0,0),)*len(cell_data.shape[3:]),mode='wrap') -def node_2_cell(node_data): - """Interpolate periodic nodal data to cell data.""" +def node_2_point(node_data): + """Interpolate periodic nodal data to point data.""" c = ( node_data + _np.roll(node_data,1,(0,1,2)) + _np.roll(node_data,1,(0,)) + _np.roll(node_data,1,(1,)) + _np.roll(node_data,1,(2,)) + _np.roll(node_data,1,(0,1)) + _np.roll(node_data,1,(1,2)) + _np.roll(node_data,1,(2,0)))*0.125 @@ -364,27 +365,27 @@ def node_2_cell(node_data): return c[1:,1:,1:] -def node_coord0_gridSizeOrigin(coord0,ordered=True): +def cellSizeOrigin_coordinates0_node(coordinates0,ordered=True): """ Return grid 'DNA', i.e. cells, size, and origin from 1D array of nodal positions. Parameters ---------- - coord0 : numpy.ndarray of shape (:,3) - undeformed nodal coordinates. + coordinates0 : numpy.ndarray of shape (:,3) + Undeformed nodal coordinates. ordered : bool, optional - expect coord0 data to be ordered (x fast, z slow). + Expect coordinates0 data to be ordered (x fast, z slow). """ - coords = [_np.unique(coord0[:,i]) for i in range(3)] + coords = [_np.unique(coordinates0[:,i]) for i in range(3)] mincorner = _np.array(list(map(min,coords))) maxcorner = _np.array(list(map(max,coords))) cells = _np.array(list(map(len,coords)),'i') - 1 size = maxcorner-mincorner origin = mincorner - if (cells+1).prod() != len(coord0): - raise ValueError('Data count {len(coord0)} does not match cells {cells}.') + if (cells+1).prod() != len(coordinates0): + raise ValueError('Data count {len(coordinates0)} does not match cells {cells}.') atol = _np.max(size)*5e-2 if not (_np.allclose(coords[0],_np.linspace(mincorner[0],maxcorner[0],cells[0]+1),atol=atol) and \ @@ -392,7 +393,8 @@ def node_coord0_gridSizeOrigin(coord0,ordered=True): _np.allclose(coords[2],_np.linspace(mincorner[2],maxcorner[2],cells[2]+1),atol=atol)): raise ValueError('Regular cells spacing violated.') - if ordered and not _np.allclose(coord0.reshape(tuple(cells+1)+(3,),order='F'),node_coord0(cells,size,origin),atol=atol): + if ordered and not _np.allclose(coordinates0.reshape(tuple(cells+1)+(3,),order='F'), + coordinates0_node(cells,size,origin),atol=atol): raise ValueError('Input data is not ordered (x fast, z slow).') return (cells,size,origin) @@ -412,9 +414,9 @@ def regrid(size,F,cells_new): New cells for undeformed coordinates. """ - c = cell_coord0(F.shape[:3],size) \ - + cell_displacement_avg(size,F) \ - + cell_displacement_fluct(size,F) + c = coordinates0_point(F.shape[:3],size) \ + + displacement_avg_point(size,F) \ + + displacement_fluct_point(size,F) outer = _np.dot(_np.average(F,axis=(0,1,2)),size) for d in range(3): @@ -422,4 +424,4 @@ def regrid(size,F,cells_new): c[_np.where(c[:,:,:,d]>outer[d])] -= outer[d] tree = _spatial.cKDTree(c.reshape(-1,3),boxsize=outer) - return tree.query(cell_coord0(cells_new,outer))[1].flatten() + return tree.query(coordinates0_point(cells_new,outer))[1].flatten() diff --git a/python/damask/seeds.py b/python/damask/seeds.py index 90c1f58cc..d65cffd7f 100644 --- a/python/damask/seeds.py +++ b/python/damask/seeds.py @@ -29,7 +29,7 @@ def from_random(size,N_seeds,cells=None,rng_seed=None): if cells is None: coords = rng.random((N_seeds,3)) * size else: - grid_coords = grid_filters.cell_coord0(cells,size).reshape(-1,3,order='F') + grid_coords = grid_filters.coordinates0_point(cells,size).reshape(-1,3,order='F') coords = grid_coords[rng.choice(_np.prod(cells),N_seeds, replace=False)] \ + _np.broadcast_to(size/cells,(N_seeds,3))*(rng.random((N_seeds,3))*.5-.25) # wobble without leaving cells @@ -98,7 +98,7 @@ def from_geom(geom,selection=None,invert=False,average=False,periodic=True): material = geom.material.reshape((-1,1),order='F') mask = _np.full(geom.cells.prod(),True,dtype=bool) if selection is None else \ _np.isin(material,selection,invert=invert).flatten() - coords = grid_filters.cell_coord0(geom.cells,geom.size).reshape(-1,3,order='F') + coords = grid_filters.coordinates0_point(geom.cells,geom.size).reshape(-1,3,order='F') if not average: return (coords[mask],material[mask]) diff --git a/python/tests/test_Geom.py b/python/tests/test_Geom.py index 891cd3937..670e1caf8 100644 --- a/python/tests/test_Geom.py +++ b/python/tests/test_Geom.py @@ -394,7 +394,7 @@ class TestGeom: def test_from_table(self): cells = np.random.randint(60,100,3) size = np.ones(3)+np.random.rand(3) - coords = grid_filters.cell_coord0(cells,size).reshape(-1,3,order='F') + coords = grid_filters.coordinates0_point(cells,size).reshape(-1,3,order='F') z=np.ones(cells.prod()) z[cells[:2].prod()*int(cells[2]/2):]=0 t = Table(np.column_stack((coords,z)),{'coords':3,'z':1}) @@ -407,7 +407,7 @@ class TestGeom: size = np.ones(3)+np.random.rand(3) s = seeds.from_random(size,np.random.randint(60,100)) geom = Geom.from_Voronoi_tessellation(cells,size,s) - coords = grid_filters.cell_coord0(cells,size) + coords = grid_filters.coordinates0_point(cells,size) t = Table(np.column_stack((coords.reshape(-1,3,order='F'),geom.material.flatten(order='F'))),{'c':3,'m':1}) assert geom_equal(geom.sort().renumber(),Geom.from_table(t,'c',['m'])) diff --git a/python/tests/test_Result.py b/python/tests/test_Result.py index 8ebeff80a..417066fdf 100644 --- a/python/tests/test_Result.py +++ b/python/tests/test_Result.py @@ -356,11 +356,11 @@ class TestResult: @pytest.mark.parametrize('mode',['cell','node']) def test_coordinates(self,default,mode): if mode == 'cell': - a = grid_filters.cell_coord0(default.cells,default.size,default.origin) - b = default.cell_coordinates.reshape(tuple(default.cells)+(3,),order='F') + a = grid_filters.coordinates0_point(default.cells,default.size,default.origin) + b = default.coordinates0_point.reshape(tuple(default.cells)+(3,),order='F') elif mode == 'node': - a = grid_filters.node_coord0(default.cells,default.size,default.origin) - b = default.node_coordinates.reshape(tuple(default.cells+1)+(3,),order='F') + a = grid_filters.coordinates0_node(default.cells,default.size,default.origin) + b = default.coordinates0_node.reshape(tuple(default.cells+1)+(3,),order='F') assert np.allclose(a,b) @pytest.mark.parametrize('output',['F',[],['F','P']]) diff --git a/python/tests/test_Rotation.py b/python/tests/test_Rotation.py index a827b7a70..c60029046 100644 --- a/python/tests/test_Rotation.py +++ b/python/tests/test_Rotation.py @@ -1022,7 +1022,7 @@ class TestRotation: rng = tuple(zip(np.zeros(3),limits)) weights = Table.load(ref_path/'ODF_experimental_cell.txt').get('intensity').flatten() - Eulers = grid_filters.cell_coord0(steps,limits) + Eulers = grid_filters.coordinates0_point(steps,limits) Eulers = np.radians(Eulers) if not degrees else Eulers Eulers_r = Rotation.from_ODF(weights,Eulers.reshape(-1,3,order='F'),N,degrees,fractions).as_Euler_angles(True) @@ -1040,7 +1040,7 @@ class TestRotation: weights = Table.load(ref_path/'ODF_experimental.txt').get('intensity') weights = weights.reshape(steps+1,order='F')[:-1,:-1,:-1].reshape(-1,order='F') - Eulers = grid_filters.node_coord0(steps,limits)[:-1,:-1,:-1] + Eulers = grid_filters.coordinates0_node(steps,limits)[:-1,:-1,:-1] Eulers = np.radians(Eulers) if not degrees else Eulers Eulers_r = Rotation.from_ODF(weights,Eulers.reshape(-1,3,order='F'),N,degrees).as_Euler_angles(True) diff --git a/python/tests/test_VTK.py b/python/tests/test_VTK.py index 39dec373c..a3cba354f 100644 --- a/python/tests/test_VTK.py +++ b/python/tests/test_VTK.py @@ -155,8 +155,8 @@ class TestVTK: cells = np.array([5,6,7],int) size = np.array([.6,1.,.5]) rectilinearGrid = VTK.from_rectilinear_grid(cells,size) - c = grid_filters.cell_coord0(cells,size).reshape(-1,3,order='F') - n = grid_filters.node_coord0(cells,size).reshape(-1,3,order='F') + c = grid_filters.coordinates0_point(cells,size).reshape(-1,3,order='F') + n = grid_filters.coordinates0_node(cells,size).reshape(-1,3,order='F') rectilinearGrid.add(c,'cell') rectilinearGrid.add(n,'node') if update: diff --git a/python/tests/test_grid_filters.py b/python/tests/test_grid_filters.py index fa2bf2bb7..c48ab39d0 100644 --- a/python/tests/test_grid_filters.py +++ b/python/tests/test_grid_filters.py @@ -5,33 +5,33 @@ from damask import grid_filters class TestGridFilters: - def test_cell_coord0(self): + def test_coordinates0_point(self): size = np.random.random(3) cells = np.random.randint(8,32,(3)) - coord = grid_filters.cell_coord0(cells,size) + coord = grid_filters.coordinates0_point(cells,size) assert np.allclose(coord[0,0,0],size/cells*.5) and coord.shape == tuple(cells) + (3,) - def test_node_coord0(self): + def test_coordinates0_node(self): size = np.random.random(3) cells = np.random.randint(8,32,(3)) - coord = grid_filters.node_coord0(cells,size) + coord = grid_filters.coordinates0_node(cells,size) assert np.allclose(coord[-1,-1,-1],size) and coord.shape == tuple(cells+1) + (3,) def test_coord0(self): size = np.random.random(3) cells = np.random.randint(8,32,(3)) - c = grid_filters.cell_coord0(cells+1,size+size/cells) - n = grid_filters.node_coord0(cells,size) + size/cells*.5 + c = grid_filters.coordinates0_point(cells+1,size+size/cells) + n = grid_filters.coordinates0_node(cells,size) + size/cells*.5 assert np.allclose(c,n) - @pytest.mark.parametrize('mode',['cell','node']) + @pytest.mark.parametrize('mode',['point','node']) def test_grid_DNA(self,mode): - """Ensure that xx_coord0_gridSizeOrigin is the inverse of xx_coord0.""" + """Ensure that cellSizeOrigin_coordinates0_xx is the inverse of coordinates0_xx.""" cells = np.random.randint(8,32,(3)) size = np.random.random(3) origin = np.random.random(3) - coord0 = eval(f'grid_filters.{mode}_coord0(cells,size,origin)') # noqa - _cells,_size,_origin = eval(f'grid_filters.{mode}_coord0_gridSizeOrigin(coord0.reshape(-1,3,order="F"))') + coord0 = eval(f'grid_filters.coordinates0_{mode}(cells,size,origin)') # noqa + _cells,_size,_origin = eval(f'grid_filters.cellSizeOrigin_coordinates0_{mode}(coord0.reshape(-1,3,order="F"))') assert np.allclose(cells,_cells) and np.allclose(size,_size) and np.allclose(origin,_origin) def test_displacement_fluct_equivalence(self): @@ -39,43 +39,43 @@ class TestGridFilters: size = np.random.random(3) cells = np.random.randint(8,32,(3)) F = np.random.random(tuple(cells)+(3,3)) - assert np.allclose(grid_filters.node_displacement_fluct(size,F), - grid_filters.cell_2_node(grid_filters.cell_displacement_fluct(size,F))) + assert np.allclose(grid_filters.displacement_fluct_node(size,F), + grid_filters.point_2_node(grid_filters.displacement_fluct_point(size,F))) def test_interpolation_to_node(self): size = np.random.random(3) cells = np.random.randint(8,32,(3)) F = np.random.random(tuple(cells)+(3,3)) - assert np.allclose(grid_filters.node_coord(size,F) [1:-1,1:-1,1:-1], - grid_filters.cell_2_node(grid_filters.cell_coord(size,F))[1:-1,1:-1,1:-1]) + assert np.allclose(grid_filters.coordinates_node(size,F) [1:-1,1:-1,1:-1], + grid_filters.point_2_node(grid_filters.coordinates_point(size,F))[1:-1,1:-1,1:-1]) def test_interpolation_to_cell(self): cells = np.random.randint(1,30,(3)) - node_coord_x = np.linspace(0,np.pi*2,num=cells[0]+1) - node_field_x = np.cos(node_coord_x) + coordinates_node_x = np.linspace(0,np.pi*2,num=cells[0]+1) + node_field_x = np.cos(coordinates_node_x) node_field = np.broadcast_to(node_field_x.reshape(-1,1,1),cells+1) - cell_coord_x = node_coord_x[:-1]+node_coord_x[1]*.5 - cell_field_x = np.interp(cell_coord_x,node_coord_x,node_field_x,period=np.pi*2.) + coordinates0_point_x = coordinates_node_x[:-1]+coordinates_node_x[1]*.5 + cell_field_x = np.interp(coordinates0_point_x,coordinates_node_x,node_field_x,period=np.pi*2.) cell_field = np.broadcast_to(cell_field_x.reshape(-1,1,1),cells) - assert np.allclose(cell_field,grid_filters.node_2_cell(node_field)) + assert np.allclose(cell_field,grid_filters.node_2_point(node_field)) - @pytest.mark.parametrize('mode',['cell','node']) - def test_coord0_origin(self,mode): + @pytest.mark.parametrize('mode',['point','node']) + def test_coordinates0_origin(self,mode): origin= np.random.random(3) size = np.random.random(3) # noqa cells = np.random.randint(8,32,(3)) - shifted = eval(f'grid_filters.{mode}_coord0(cells,size,origin)') - unshifted = eval(f'grid_filters.{mode}_coord0(cells,size)') + shifted = eval(f'grid_filters.coordinates0_{mode}(cells,size,origin)') + unshifted = eval(f'grid_filters.coordinates0_{mode}(cells,size)') if mode == 'cell': assert np.allclose(shifted,unshifted+np.broadcast_to(origin,tuple(cells) +(3,))) elif mode == 'node': assert np.allclose(shifted,unshifted+np.broadcast_to(origin,tuple(cells+1)+(3,))) - @pytest.mark.parametrize('function',[grid_filters.cell_displacement_avg, - grid_filters.node_displacement_avg]) + @pytest.mark.parametrize('function',[grid_filters.displacement_avg_point, + grid_filters.displacement_avg_node]) def test_displacement_avg_vanishes(self,function): """Ensure that random fluctuations in F do not result in average displacement.""" size = np.random.random(3) @@ -84,8 +84,8 @@ class TestGridFilters: F += np.eye(3) - np.average(F,axis=(0,1,2)) assert np.allclose(function(size,F),0.0) - @pytest.mark.parametrize('function',[grid_filters.cell_displacement_fluct, - grid_filters.node_displacement_fluct]) + @pytest.mark.parametrize('function',[grid_filters.displacement_fluct_point, + grid_filters.displacement_fluct_node]) def test_displacement_fluct_vanishes(self,function): """Ensure that constant F does not result in fluctuating displacement.""" size = np.random.random(3) @@ -93,16 +93,16 @@ class TestGridFilters: F = np.broadcast_to(np.random.random((3,3)), tuple(cells)+(3,3)) assert np.allclose(function(size,F),0.0) - @pytest.mark.parametrize('function',[grid_filters.coord0_check, - grid_filters.node_coord0_gridSizeOrigin, - grid_filters.cell_coord0_gridSizeOrigin]) + @pytest.mark.parametrize('function',[grid_filters.coordinates0_check, + grid_filters.cellSizeOrigin_coordinates0_node, + grid_filters.cellSizeOrigin_coordinates0_point]) def test_invalid_coordinates(self,function): invalid_coordinates = np.random.random((np.random.randint(12,52),3)) with pytest.raises(ValueError): function(invalid_coordinates) - @pytest.mark.parametrize('function',[grid_filters.node_coord0_gridSizeOrigin, - grid_filters.cell_coord0_gridSizeOrigin]) + @pytest.mark.parametrize('function',[grid_filters.cellSizeOrigin_coordinates0_node, + grid_filters.cellSizeOrigin_coordinates0_point]) def test_uneven_spaced_coordinates(self,function): start = np.random.random(3) end = np.random.random(3)*10. + start @@ -116,13 +116,13 @@ class TestGridFilters: @pytest.mark.parametrize('mode',[True,False]) - @pytest.mark.parametrize('function',[grid_filters.node_coord0_gridSizeOrigin, - grid_filters.cell_coord0_gridSizeOrigin]) + @pytest.mark.parametrize('function',[grid_filters.cellSizeOrigin_coordinates0_node, + grid_filters.cellSizeOrigin_coordinates0_point]) def test_unordered_coordinates(self,function,mode): origin = np.random.random(3) size = np.random.random(3)*10.+origin cells = np.random.randint(8,32,(3)) - unordered = grid_filters.node_coord0(cells,size,origin).reshape(-1,3) + unordered = grid_filters.coordinates0_node(cells,size,origin).reshape(-1,3) if mode: with pytest.raises(ValueError): function(unordered,mode) @@ -192,7 +192,7 @@ class TestGridFilters: size = np.random.random(3)+1.0 cells = np.random.randint(8,32,(3)) - nodes = grid_filters.cell_coord0(cells,size) + nodes = grid_filters.coordinates0_point(cells,size) my_locals = locals() # needed for list comprehension field = np.stack([np.broadcast_to(eval(f,globals(),my_locals),cells) for f in field_def],axis=-1) @@ -252,7 +252,7 @@ class TestGridFilters: size = np.random.random(3)+1.0 cells = np.random.randint(8,32,(3)) - nodes = grid_filters.cell_coord0(cells,size) + nodes = grid_filters.coordinates0_point(cells,size) my_locals = locals() # needed for list comprehension field = np.stack([np.broadcast_to(eval(f,globals(),my_locals),cells) for f in field_def],axis=-1) @@ -305,7 +305,7 @@ class TestGridFilters: size = np.random.random(3)+1.0 cells = np.random.randint(8,32,(3)) - nodes = grid_filters.cell_coord0(cells,size) + nodes = grid_filters.coordinates0_point(cells,size) my_locals = locals() # needed for list comprehension field = np.stack([np.broadcast_to(eval(f,globals(),my_locals),cells) for f in field_def],axis=-1) diff --git a/python/tests/test_seeds.py b/python/tests/test_seeds.py index f7c46e889..65624b51f 100644 --- a/python/tests/test_seeds.py +++ b/python/tests/test_seeds.py @@ -41,7 +41,7 @@ class TestSeeds: def test_from_geom_grid(self,periodic,average): cells = np.random.randint(10,20,3) size = np.ones(3) + np.random.random(3) - coords = grid_filters.cell_coord0(cells,size).reshape(-1,3) + coords = grid_filters.coordinates0_point(cells,size).reshape(-1,3) np.random.shuffle(coords) geom_1 = Geom.from_Voronoi_tessellation(cells,size,coords) coords,material = seeds.from_geom(geom_1,average=average,periodic=periodic) From 171d642dbdd15a777f00a546c5333a96011ef380 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Fri, 4 Dec 2020 07:12:18 +0100 Subject: [PATCH 006/148] rename: Geom -> Grid --- PRIVATE | 2 +- processing/pre/geom_fromDREAM3D.py | 2 +- processing/pre/geom_fromOsteonGeometry.py | 2 +- processing/pre/geom_grainGrowth.py | 4 +- processing/pre/mentat_spectralBox.py | 2 +- processing/pre/seeds_fromDistribution.py | 6 +- processing/pre/seeds_fromPokes.py | 2 +- python/damask/__init__.py | 2 +- python/damask/{_geom.py => _grid.py} | 142 +++++++++--------- python/damask/grid_filters.py | 2 +- python/damask/seeds.py | 18 +-- .../{Geom => Grid}/clean_1_1+2+3_False.vtr | 0 .../{Geom => Grid}/clean_1_1+2+3_True.vtr | 0 .../{Geom => Grid}/clean_1_1_False.vtr | 0 .../{Geom => Grid}/clean_1_1_True.vtr | 0 .../{Geom => Grid}/clean_1_None_False.vtr | 0 .../{Geom => Grid}/clean_1_None_True.vtr | 0 .../{Geom => Grid}/clean_2_1+2+3_False.vtr | 0 .../{Geom => Grid}/clean_2_1+2+3_True.vtr | 0 .../{Geom => Grid}/clean_2_1_False.vtr | 0 .../{Geom => Grid}/clean_2_1_True.vtr | 0 .../{Geom => Grid}/clean_2_2_False.vtr | 0 .../{Geom => Grid}/clean_2_2_True.vtr | 0 .../{Geom => Grid}/clean_2_None_False.vtr | 0 .../{Geom => Grid}/clean_2_None_True.vtr | 0 .../{Geom => Grid}/clean_3_1+2+3_False.vtr | 0 .../{Geom => Grid}/clean_3_1+2+3_True.vtr | 0 .../{Geom => Grid}/clean_3_1_False.vtr | 0 .../{Geom => Grid}/clean_3_1_True.vtr | 0 .../{Geom => Grid}/clean_3_2_False.vtr | 0 .../{Geom => Grid}/clean_3_2_True.vtr | 0 .../{Geom => Grid}/clean_3_None_False.vtr | 0 .../{Geom => Grid}/clean_3_None_True.vtr | 0 .../{Geom => Grid}/clean_4_1+2+3_False.vtr | 0 .../{Geom => Grid}/clean_4_1+2+3_True.vtr | 0 .../{Geom => Grid}/clean_4_1_False.vtr | 0 .../{Geom => Grid}/clean_4_1_True.vtr | 0 .../{Geom => Grid}/clean_4_2_False.vtr | 0 .../{Geom => Grid}/clean_4_2_True.vtr | 0 .../{Geom => Grid}/clean_4_None_False.vtr | 0 .../{Geom => Grid}/clean_4_None_True.vtr | 0 .../{Geom => Grid}/flip_directions_x-y-z.vtr | 0 .../{Geom => Grid}/flip_directions_x.vtr | 0 .../{Geom => Grid}/flip_directions_y-z.vtr | 0 .../{Geom => Grid}/flip_directions_z-x-y.vtr | 0 .../get_grain_boundaries_8g12x15x20.vtr | 0 ...et_grain_boundaries_8g12x15x20_x_False.vtu | 0 ...get_grain_boundaries_8g12x15x20_x_True.vtu | 0 ...t_grain_boundaries_8g12x15x20_xy_False.vtu | 0 ...et_grain_boundaries_8g12x15x20_xy_True.vtu | 0 ..._grain_boundaries_8g12x15x20_xyz_False.vtu | 0 ...t_grain_boundaries_8g12x15x20_xyz_True.vtu | 0 ...t_grain_boundaries_8g12x15x20_xz_False.vtu | 0 ...et_grain_boundaries_8g12x15x20_xz_True.vtu | 0 ...et_grain_boundaries_8g12x15x20_y_False.vtu | 0 ...get_grain_boundaries_8g12x15x20_y_True.vtu | 0 ...et_grain_boundaries_8g12x15x20_z_False.vtu | 0 ...get_grain_boundaries_8g12x15x20_z_True.vtu | 0 ...t_grain_boundaries_8g12x15x20_zy_False.vtu | 0 ...et_grain_boundaries_8g12x15x20_zy_True.vtu | 0 .../mirror_directions_x+reflect_False.vtr | 0 .../mirror_directions_x-y-z+reflect_True.vtr | 0 .../mirror_directions_y-z+reflect_False.vtr | 0 .../mirror_directions_z-x-y+reflect_False.vtr | 0 .../rotate_Eulers_0.0-32.0-240.0.vtr | 0 .../rotate_Eulers_32.0-68.0-21.0.vtr | 0 .../{Geom => Grid}/scale_grid_10-10-10.vtr | 0 .../{Geom => Grid}/scale_grid_10-11-10.vtr | 0 .../{Geom => Grid}/scale_grid_10-13-10.vtr | 0 .../{Geom => Grid}/scale_grid_10-20-2.vtr | 0 .../{Geom => Grid}/scale_grid_5-4-20.vtr | 0 .../{Geom => Grid}/scale_grid_8-10-12.vtr | 0 python/tests/{test_Geom.py => test_Grid.py} | 116 +++++++------- python/tests/test_seeds.py | 28 ++-- 74 files changed, 164 insertions(+), 164 deletions(-) rename python/damask/{_geom.py => _grid.py} (90%) rename python/tests/reference/{Geom => Grid}/clean_1_1+2+3_False.vtr (100%) rename python/tests/reference/{Geom => Grid}/clean_1_1+2+3_True.vtr (100%) rename python/tests/reference/{Geom => Grid}/clean_1_1_False.vtr (100%) rename python/tests/reference/{Geom => Grid}/clean_1_1_True.vtr (100%) rename python/tests/reference/{Geom => Grid}/clean_1_None_False.vtr (100%) rename python/tests/reference/{Geom => Grid}/clean_1_None_True.vtr (100%) rename python/tests/reference/{Geom => Grid}/clean_2_1+2+3_False.vtr (100%) rename python/tests/reference/{Geom => Grid}/clean_2_1+2+3_True.vtr (100%) rename python/tests/reference/{Geom => Grid}/clean_2_1_False.vtr (100%) rename python/tests/reference/{Geom => Grid}/clean_2_1_True.vtr (100%) rename python/tests/reference/{Geom => Grid}/clean_2_2_False.vtr (100%) rename python/tests/reference/{Geom => Grid}/clean_2_2_True.vtr (100%) rename python/tests/reference/{Geom => Grid}/clean_2_None_False.vtr (100%) rename python/tests/reference/{Geom => Grid}/clean_2_None_True.vtr (100%) rename python/tests/reference/{Geom => Grid}/clean_3_1+2+3_False.vtr (100%) rename python/tests/reference/{Geom => Grid}/clean_3_1+2+3_True.vtr (100%) rename python/tests/reference/{Geom => Grid}/clean_3_1_False.vtr (100%) rename python/tests/reference/{Geom => Grid}/clean_3_1_True.vtr (100%) rename python/tests/reference/{Geom => Grid}/clean_3_2_False.vtr (100%) rename python/tests/reference/{Geom => Grid}/clean_3_2_True.vtr (100%) rename python/tests/reference/{Geom => Grid}/clean_3_None_False.vtr (100%) rename python/tests/reference/{Geom => Grid}/clean_3_None_True.vtr (100%) rename python/tests/reference/{Geom => Grid}/clean_4_1+2+3_False.vtr (100%) rename python/tests/reference/{Geom => Grid}/clean_4_1+2+3_True.vtr (100%) rename python/tests/reference/{Geom => Grid}/clean_4_1_False.vtr (100%) rename python/tests/reference/{Geom => Grid}/clean_4_1_True.vtr (100%) rename python/tests/reference/{Geom => Grid}/clean_4_2_False.vtr (100%) rename python/tests/reference/{Geom => Grid}/clean_4_2_True.vtr (100%) rename python/tests/reference/{Geom => Grid}/clean_4_None_False.vtr (100%) rename python/tests/reference/{Geom => Grid}/clean_4_None_True.vtr (100%) rename python/tests/reference/{Geom => Grid}/flip_directions_x-y-z.vtr (100%) rename python/tests/reference/{Geom => Grid}/flip_directions_x.vtr (100%) rename python/tests/reference/{Geom => Grid}/flip_directions_y-z.vtr (100%) rename python/tests/reference/{Geom => Grid}/flip_directions_z-x-y.vtr (100%) rename python/tests/reference/{Geom => Grid}/get_grain_boundaries_8g12x15x20.vtr (100%) rename python/tests/reference/{Geom => Grid}/get_grain_boundaries_8g12x15x20_x_False.vtu (100%) rename python/tests/reference/{Geom => Grid}/get_grain_boundaries_8g12x15x20_x_True.vtu (100%) rename python/tests/reference/{Geom => Grid}/get_grain_boundaries_8g12x15x20_xy_False.vtu (100%) rename python/tests/reference/{Geom => Grid}/get_grain_boundaries_8g12x15x20_xy_True.vtu (100%) rename python/tests/reference/{Geom => Grid}/get_grain_boundaries_8g12x15x20_xyz_False.vtu (100%) rename python/tests/reference/{Geom => Grid}/get_grain_boundaries_8g12x15x20_xyz_True.vtu (100%) rename python/tests/reference/{Geom => Grid}/get_grain_boundaries_8g12x15x20_xz_False.vtu (100%) rename python/tests/reference/{Geom => Grid}/get_grain_boundaries_8g12x15x20_xz_True.vtu (100%) rename python/tests/reference/{Geom => Grid}/get_grain_boundaries_8g12x15x20_y_False.vtu (100%) rename python/tests/reference/{Geom => Grid}/get_grain_boundaries_8g12x15x20_y_True.vtu (100%) rename python/tests/reference/{Geom => Grid}/get_grain_boundaries_8g12x15x20_z_False.vtu (100%) rename python/tests/reference/{Geom => Grid}/get_grain_boundaries_8g12x15x20_z_True.vtu (100%) rename python/tests/reference/{Geom => Grid}/get_grain_boundaries_8g12x15x20_zy_False.vtu (100%) rename python/tests/reference/{Geom => Grid}/get_grain_boundaries_8g12x15x20_zy_True.vtu (100%) rename python/tests/reference/{Geom => Grid}/mirror_directions_x+reflect_False.vtr (100%) rename python/tests/reference/{Geom => Grid}/mirror_directions_x-y-z+reflect_True.vtr (100%) rename python/tests/reference/{Geom => Grid}/mirror_directions_y-z+reflect_False.vtr (100%) rename python/tests/reference/{Geom => Grid}/mirror_directions_z-x-y+reflect_False.vtr (100%) rename python/tests/reference/{Geom => Grid}/rotate_Eulers_0.0-32.0-240.0.vtr (100%) rename python/tests/reference/{Geom => Grid}/rotate_Eulers_32.0-68.0-21.0.vtr (100%) rename python/tests/reference/{Geom => Grid}/scale_grid_10-10-10.vtr (100%) rename python/tests/reference/{Geom => Grid}/scale_grid_10-11-10.vtr (100%) rename python/tests/reference/{Geom => Grid}/scale_grid_10-13-10.vtr (100%) rename python/tests/reference/{Geom => Grid}/scale_grid_10-20-2.vtr (100%) rename python/tests/reference/{Geom => Grid}/scale_grid_5-4-20.vtr (100%) rename python/tests/reference/{Geom => Grid}/scale_grid_8-10-12.vtr (100%) rename python/tests/{test_Geom.py => test_Grid.py} (83%) diff --git a/PRIVATE b/PRIVATE index fc27bbd6e..a0475c50b 160000 --- a/PRIVATE +++ b/PRIVATE @@ -1 +1 @@ -Subproject commit fc27bbd6e028aa73545327aebdb206840063e135 +Subproject commit a0475c50bfaf6f86f75345754188918a6e9d7134 diff --git a/processing/pre/geom_fromDREAM3D.py b/processing/pre/geom_fromDREAM3D.py index eb4fe443e..d51a2b51e 100755 --- a/processing/pre/geom_fromDREAM3D.py +++ b/processing/pre/geom_fromDREAM3D.py @@ -65,7 +65,7 @@ if filenames == []: parser.error('no input file specified.') for name in filenames: damask.util.report(scriptName,name) - geom = damask.Geom.load_DREAM3D(name,options.basegroup,options.pointwise) + geom = damask.Grid.load_DREAM3D(name,options.basegroup,options.pointwise) damask.util.croak(geom) geom.save_ASCII(os.path.splitext(name)[0]+'.geom') diff --git a/processing/pre/geom_fromOsteonGeometry.py b/processing/pre/geom_fromOsteonGeometry.py index 51aca3056..0bdf8aa7e 100755 --- a/processing/pre/geom_fromOsteonGeometry.py +++ b/processing/pre/geom_fromOsteonGeometry.py @@ -133,7 +133,7 @@ for i in range(3,np.max(microstructure)): header = [scriptID + ' ' + ' '.join(sys.argv[1:])]\ + config_header -geom = damask.Geom(microstructure.reshape(grid), +geom = damask.Grid(microstructure.reshape(grid), size,-size/2, comments=header) damask.util.croak(geom) diff --git a/processing/pre/geom_grainGrowth.py b/processing/pre/geom_grainGrowth.py index b49d7c126..23a46b668 100755 --- a/processing/pre/geom_grainGrowth.py +++ b/processing/pre/geom_grainGrowth.py @@ -62,7 +62,7 @@ if filenames == []: filenames = [None] for name in filenames: damask.util.report(scriptName,name) - geom = damask.Geom.load(StringIO(''.join(sys.stdin.read())) if name is None else name) + geom = damask.Grid.load(StringIO(''.join(sys.stdin.read())) if name is None else name) grid_original = geom.cells damask.util.croak(geom) @@ -169,7 +169,7 @@ for name in filenames: # undo any changes involving immutable materials material = np.where(immutable, material_original,material) - damask.Geom(material = material[0:grid_original[0],0:grid_original[1],0:grid_original[2]], + damask.Grid(material = material[0:grid_original[0],0:grid_original[1],0:grid_original[2]], size = geom.size, origin = geom.origin, comments = geom.comments + [scriptID + ' ' + ' '.join(sys.argv[1:])], diff --git a/processing/pre/mentat_spectralBox.py b/processing/pre/mentat_spectralBox.py index 5c7cc377f..d2c966f3f 100755 --- a/processing/pre/mentat_spectralBox.py +++ b/processing/pre/mentat_spectralBox.py @@ -196,7 +196,7 @@ if filenames == []: filenames = [None] for name in filenames: damask.util.report(scriptName,name) - geom = damask.Geom.load(StringIO(''.join(sys.stdin.read())) if name is None else name) + geom = damask.Grid.load(StringIO(''.join(sys.stdin.read())) if name is None else name) material = geom.material.flatten(order='F') cmds = [\ diff --git a/processing/pre/seeds_fromDistribution.py b/processing/pre/seeds_fromDistribution.py index 250e0c6ab..59d9f0213 100755 --- a/processing/pre/seeds_fromDistribution.py +++ b/processing/pre/seeds_fromDistribution.py @@ -91,7 +91,7 @@ class myThread (threading.Thread): perturbedSeedsTable.set('pos',coords).save(perturbedSeedsVFile,legacy=True) #--- do tesselation with perturbed seed file ------------------------------------------------------ - perturbedGeom = damask.Geom.from_Voronoi_tessellation(options.grid,np.ones(3),coords) + perturbedGeom = damask.Grid.from_Voronoi_tessellation(options.grid,np.ones(3),coords) #--- evaluate current seeds file ------------------------------------------------------------------ @@ -210,7 +210,7 @@ baseFile = os.path.splitext(os.path.basename(options.seedFile))[0] points = np.array(options.grid).prod().astype('float') # ----------- calculate target distribution and bin edges -targetGeom = damask.Geom.load_ASCII(os.path.splitext(os.path.basename(options.target))[0]+'.geom') +targetGeom = damask.Grid.load_ASCII(os.path.splitext(os.path.basename(options.target))[0]+'.geom') nMaterials = len(np.unique(targetGeom.material)) targetVolFrac = np.bincount(targetGeom.material.flatten())/targetGeom.cells.prod().astype(np.float) target = [] @@ -229,7 +229,7 @@ bestSeedsUpdate = time.time() # ----------- tessellate initial seed file to get and evaluate geom file bestSeedsVFile.seek(0) -initialGeom = damask.Geom.from_Voronoi_tessellation(options.grid,np.ones(3),initial_seeds) +initialGeom = damask.Grid.from_Voronoi_tessellation(options.grid,np.ones(3),initial_seeds) if len(np.unique(targetGeom.material)) != nMaterials: damask.util.croak('error. Material count mismatch') diff --git a/processing/pre/seeds_fromPokes.py b/processing/pre/seeds_fromPokes.py index 535ac0291..e6eee809a 100755 --- a/processing/pre/seeds_fromPokes.py +++ b/processing/pre/seeds_fromPokes.py @@ -52,7 +52,7 @@ options.box = np.array(options.box).reshape(3,2) for name in filenames: damask.util.report(scriptName,name) - geom = damask.Geom.load_ASCII(StringIO(''.join(sys.stdin.read())) if name is None else name) + geom = damask.Grid.load_ASCII(StringIO(''.join(sys.stdin.read())) if name is None else name) offset =(np.amin(options.box, axis=1)*geom.cells/geom.size).astype(int) box = np.amax(options.box, axis=1) \ diff --git a/python/damask/__init__.py b/python/damask/__init__.py index a1ccfa3f6..fa1af9f4f 100644 --- a/python/damask/__init__.py +++ b/python/damask/__init__.py @@ -32,7 +32,7 @@ from ._vtk import VTK # noqa from ._colormap import Colormap # noqa from ._config import Config # noqa from ._configmaterial import ConfigMaterial # noqa -from ._geom import Geom # noqa +from ._grid import Grid # noqa from ._result import Result # noqa diff --git a/python/damask/_geom.py b/python/damask/_grid.py similarity index 90% rename from python/damask/_geom.py rename to python/damask/_grid.py index 8ccde0843..2bd5a5f9e 100644 --- a/python/damask/_geom.py +++ b/python/damask/_grid.py @@ -16,21 +16,21 @@ from . import grid_filters from . import Rotation -class Geom: +class Grid: """Geometry definition for grid solvers.""" def __init__(self,material,size,origin=[0.0,0.0,0.0],comments=[]): """ - New geometry definition from array of materials, size, and origin. + New grid definition from array of materials, size, and origin. Parameters ---------- material : numpy.ndarray Material index array (3D). size : list or numpy.ndarray - Physical size of the geometry in meter. + Physical size of the grid in meter. origin : list or numpy.ndarray, optional - Physical origin of the geometry in meter. + Physical origin of the grid in meter. comments : list of str, optional Comment lines. @@ -42,7 +42,7 @@ class Geom: def __repr__(self): - """Basic information on geometry definition.""" + """Basic information on grid definition.""" return util.srepr([ f'cells a b c: {util.srepr(self.cells, " x ")}', f'size x y z: {util.srepr(self.size, " x ")}', @@ -53,12 +53,12 @@ class Geom: def __copy__(self): - """Copy geometry.""" + """Copy grid.""" return copy.deepcopy(self) def copy(self): - """Copy geometry.""" + """Copy grid.""" return self.__copy__() @@ -68,8 +68,8 @@ class Geom: Parameters ---------- - other : Geom - Geometry to compare self against. + other : damask.Grid + Grid to compare self against. """ message = [] @@ -117,7 +117,7 @@ class Geom: @property def size(self): - """Physical size of geometry in meter.""" + """Physical size of grid in meter.""" return self._size @size.setter @@ -129,7 +129,7 @@ class Geom: @property def origin(self): - """Coordinates of geometry origin in meter.""" + """Coordinates of grid origin in meter.""" return self._origin @origin.setter @@ -141,7 +141,7 @@ class Geom: @property def comments(self): - """Comments/history of geometry.""" + """Comments, e.g. history of operations.""" return self._comments @comments.setter @@ -157,7 +157,7 @@ class Geom: @property def N_materials(self): - """Number of (unique) material indices within geometry.""" + """Number of (unique) material indices within grid.""" return np.unique(self.material).size @@ -169,8 +169,8 @@ class Geom: Parameters ---------- fname : str or or pathlib.Path - Geometry file to read. - Valid extension is .vtr, which will be appended if not given. + Grid file to read. Valid extension is .vtr, which will be appended + if not given. """ v = VTK.load(fname if str(fname).endswith('.vtr') else str(fname)+'.vtr') @@ -178,7 +178,7 @@ class Geom: cells = np.array(v.vtk_data.GetDimensions())-1 bbox = np.array(v.vtk_data.GetBounds()).reshape(3,2).T - return Geom(material = v.get('material').reshape(cells,order='F'), + return Grid(material = v.get('material').reshape(cells,order='F'), size = bbox[1] - bbox[0], origin = bbox[0], comments=comments) @@ -248,7 +248,7 @@ class Geom: if not np.any(np.mod(material,1) != 0.0): # no float present material = material.astype('int') - (1 if material.min() > 0 else 0) - return Geom(material.reshape(cells,order='F'),size,origin,comments) + return Grid(material.reshape(cells,order='F'),size,origin,comments) @staticmethod @@ -282,7 +282,7 @@ class Geom: if point_data is None else \ np.reshape(f[path.join(root_dir,base_group,point_data,material)],cells.prod()) - return Geom(ma.reshape(cells,order='F'),size,origin,util.execution_stamp('Geom','load_DREAM3D')) + return Grid(ma.reshape(cells,order='F'),size,origin,util.execution_stamp('Grid','load_DREAM3D')) @staticmethod @@ -310,7 +310,7 @@ class Geom: ma = np.arange(cells.prod()) if len(unique) == cells.prod() else \ np.arange(unique.size)[np.argsort(pd.unique(unique_inverse))][unique_inverse] - return Geom(ma.reshape(cells,order='F'),size,origin,util.execution_stamp('Geom','from_table')) + return Grid(ma.reshape(cells,order='F'),size,origin,util.execution_stamp('Grid','from_table')) @staticmethod @@ -327,7 +327,7 @@ class Geom: cells : int numpy.ndarray of shape (3) Number of cells in x,y,z direction. size : list or numpy.ndarray of shape (3) - Physical size of the geometry in meter. + Physical size of the grid in meter. seeds : numpy.ndarray of shape (:,3) Position of the seed points in meter. All points need to lay within the box. weights : numpy.ndarray of shape (seeds.shape[0]) @@ -336,7 +336,7 @@ class Geom: Material ID of the seeds. Defaults to None, in which case materials are consecutively numbered. periodic : Boolean, optional - Perform a periodic tessellation. Defaults to True. + Assume grid to be periodic. Defaults to True. """ if periodic: @@ -351,7 +351,7 @@ class Geom: coords = grid_filters.coordinates0_point(cells,size).reshape(-1,3) pool = mp.Pool(processes = int(environment.options['DAMASK_NUM_THREADS'])) - result = pool.map_async(partial(Geom._find_closest_seed,seeds_p,weights_p), [coord for coord in coords]) + result = pool.map_async(partial(Grid._find_closest_seed,seeds_p,weights_p), [coord for coord in coords]) pool.close() pool.join() material_ = np.array(result.get()) @@ -362,9 +362,9 @@ class Geom: else: material_ = material_.reshape(cells) - return Geom(material = material_ if material is None else material[material_], + return Grid(material = material_ if material is None else material[material_], size = size, - comments = util.execution_stamp('Geom','from_Laguerre_tessellation'), + comments = util.execution_stamp('Grid','from_Laguerre_tessellation'), ) @@ -378,23 +378,23 @@ class Geom: cells : int numpy.ndarray of shape (3) Number of cells in x,y,z direction. size : list or numpy.ndarray of shape (3) - Physical size of the geometry in meter. + Physical size of the grid in meter. seeds : numpy.ndarray of shape (:,3) Position of the seed points in meter. All points need to lay within the box. material : numpy.ndarray of shape (seeds.shape[0]), optional Material ID of the seeds. Defaults to None, in which case materials are consecutively numbered. periodic : Boolean, optional - Perform a periodic tessellation. Defaults to True. + Assume grid to be periodic. Defaults to True. """ coords = grid_filters.coordinates0_point(cells,size).reshape(-1,3) KDTree = spatial.cKDTree(seeds,boxsize=size) if periodic else spatial.cKDTree(seeds) devNull,material_ = KDTree.query(coords) - return Geom(material = (material_ if material is None else material[material_]).reshape(cells), + return Grid(material = (material_ if material is None else material[material_]).reshape(cells), size = size, - comments = util.execution_stamp('Geom','from_Voronoi_tessellation'), + comments = util.execution_stamp('Grid','from_Voronoi_tessellation'), ) @@ -450,7 +450,7 @@ class Geom: cells : int numpy.ndarray of shape (3) Number of cells in x,y,z direction. size : list or numpy.ndarray of shape (3) - Physical size of the geometry in meter. + Physical size of the grid in meter. surface : str Type of the minimal surface. See notes for details. threshold : float, optional. @@ -497,9 +497,9 @@ class Geom: periods*2.0*np.pi*(np.arange(cells[1])+0.5)/cells[1], periods*2.0*np.pi*(np.arange(cells[2])+0.5)/cells[2], indexing='ij',sparse=True) - return Geom(material = np.where(threshold < Geom._minimal_surface[surface](x,y,z),materials[1],materials[0]), + return Grid(material = np.where(threshold < Grid._minimal_surface[surface](x,y,z),materials[1],materials[0]), size = size, - comments = util.execution_stamp('Geom','from_minimal_surface'), + comments = util.execution_stamp('Grid','from_minimal_surface'), ) @@ -583,7 +583,7 @@ class Geom: Retain original materials within primitive and fill outside. Defaults to False. periodic : Boolean, optional - Repeat primitive over boundaries. Defaults to True. + Assume grid to be periodic. Defaults to True. """ # radius and center @@ -604,23 +604,23 @@ class Geom: if periodic: # translate back to center mask = np.roll(mask,((c/self.size-0.5)*self.cells).round().astype(int),(0,1,2)) - return Geom(material = np.where(np.logical_not(mask) if inverse else mask, + return Grid(material = np.where(np.logical_not(mask) if inverse else mask, self.material, np.nanmax(self.material)+1 if fill is None else fill), size = self.size, origin = self.origin, - comments = self.comments+[util.execution_stamp('Geom','add_primitive')], + comments = self.comments+[util.execution_stamp('Grid','add_primitive')], ) def mirror(self,directions,reflect=False): """ - Mirror geometry along given directions. + Mirror grid along given directions. Parameters ---------- directions : iterable containing str - Direction(s) along which the geometry is mirrored. + Direction(s) along which the grid is mirrored. Valid entries are 'x', 'y', 'z'. reflect : bool, optional Reflect (include) outermost layers. Defaults to False. @@ -640,21 +640,21 @@ class Geom: if 'z' in directions: mat = np.concatenate([mat,mat[:,:,limits[0]:limits[1]:-1]],2) - return Geom(material = mat, + return Grid(material = mat, size = self.size/self.cells*np.asarray(mat.shape), origin = self.origin, - comments = self.comments+[util.execution_stamp('Geom','mirror')], + comments = self.comments+[util.execution_stamp('Grid','mirror')], ) def flip(self,directions): """ - Flip geometry along given directions. + Flip grid along given directions. Parameters ---------- directions : iterable containing str - Direction(s) along which the geometry is flipped. + Direction(s) along which the grid is flipped. Valid entries are 'x', 'y', 'z'. """ @@ -664,26 +664,26 @@ class Geom: mat = np.flip(self.material, (valid.index(d) for d in directions if d in valid)) - return Geom(material = mat, + return Grid(material = mat, size = self.size, origin = self.origin, - comments = self.comments+[util.execution_stamp('Geom','flip')], + comments = self.comments+[util.execution_stamp('Grid','flip')], ) def scale(self,cells,periodic=True): """ - Scale geometry to new cells. + Scale grid to new cells. Parameters ---------- cells : numpy.ndarray of shape (3) Number of cells in x,y,z direction. periodic : Boolean, optional - Assume geometry to be periodic. Defaults to True. + Assume grid to be periodic. Defaults to True. """ - return Geom(material = ndimage.interpolation.zoom( + return Grid(material = ndimage.interpolation.zoom( self.material, cells/self.cells, output=self.material.dtype, @@ -693,13 +693,13 @@ class Geom: ), size = self.size, origin = self.origin, - comments = self.comments+[util.execution_stamp('Geom','scale')], + comments = self.comments+[util.execution_stamp('Grid','scale')], ) def clean(self,stencil=3,selection=None,periodic=True): """ - Smooth geometry by selecting most frequent material index within given stencil at each location. + Smooth grid by selecting most frequent material index within given stencil at each location. Parameters ---------- @@ -708,7 +708,7 @@ class Geom: selection : list, optional Field values that can be altered. Defaults to all. periodic : Boolean, optional - Assume geometry to be periodic. Defaults to True. + Assume grid to be periodic. Defaults to True. """ def mostFrequent(arr,selection=None): @@ -719,7 +719,7 @@ class Geom: else: return me - return Geom(material = ndimage.filters.generic_filter( + return Grid(material = ndimage.filters.generic_filter( self.material, mostFrequent, size=(stencil if selection is None else stencil//2*2+1,)*3, @@ -728,7 +728,7 @@ class Geom: ).astype(self.material.dtype), size = self.size, origin = self.origin, - comments = self.comments+[util.execution_stamp('Geom','clean')], + comments = self.comments+[util.execution_stamp('Grid','clean')], ) @@ -736,21 +736,21 @@ class Geom: """Renumber sorted material indices as 0,...,N-1.""" _,renumbered = np.unique(self.material,return_inverse=True) - return Geom(material = renumbered.reshape(self.cells), + return Grid(material = renumbered.reshape(self.cells), size = self.size, origin = self.origin, - comments = self.comments+[util.execution_stamp('Geom','renumber')], + comments = self.comments+[util.execution_stamp('Grid','renumber')], ) def rotate(self,R,fill=None): """ - Rotate geometry (pad if required). + Rotate grid (pad if required). Parameters ---------- R : damask.Rotation - Rotation to apply to the geometry. + Rotation to apply to the grid. fill : int or float, optional Material index to fill the corners. Defaults to material.max() + 1. @@ -774,23 +774,23 @@ class Geom: origin = self.origin-(np.asarray(material_in.shape)-self.cells)*.5 * self.size/self.cells - return Geom(material = material_in, + return Grid(material = material_in, size = self.size/self.cells*np.asarray(material_in.shape), origin = origin, - comments = self.comments+[util.execution_stamp('Geom','rotate')], + comments = self.comments+[util.execution_stamp('Grid','rotate')], ) def canvas(self,cells=None,offset=None,fill=None): """ - Crop or enlarge/pad geometry. + Crop or enlarge/pad grid. Parameters ---------- cells : numpy.ndarray of shape (3) Number of cells x,y,z direction. offset : numpy.ndarray of shape (3) - Offset (measured in cells) from old to new geometry [0,0,0]. + Offset (measured in cells) from old to new grid [0,0,0]. fill : int or float, optional Material index to fill the background. Defaults to material.max() + 1. @@ -808,10 +808,10 @@ class Geom: canvas[ll[0]:ur[0],ll[1]:ur[1],ll[2]:ur[2]] = self.material[LL[0]:UR[0],LL[1]:UR[1],LL[2]:UR[2]] - return Geom(material = canvas, + return Grid(material = canvas, size = self.size/self.cells*np.asarray(canvas.shape), origin = self.origin+offset*self.size/self.cells, - comments = self.comments+[util.execution_stamp('Geom','canvas')], + comments = self.comments+[util.execution_stamp('Grid','canvas')], ) @@ -833,10 +833,10 @@ class Geom: mp = np.vectorize(mp) mapper = dict(zip(from_material,to_material)) - return Geom(material = mp(self.material,mapper).reshape(self.cells), + return Grid(material = mp(self.material,mapper).reshape(self.cells), size = self.size, origin = self.origin, - comments = self.comments+[util.execution_stamp('Geom','substitute')], + comments = self.comments+[util.execution_stamp('Grid','substitute')], ) @@ -847,10 +847,10 @@ class Geom: sort_idx = np.argsort(from_ma) ma = np.unique(a)[sort_idx][np.searchsorted(from_ma,a,sorter = sort_idx)] - return Geom(material = ma.reshape(self.cells,order='F'), + return Grid(material = ma.reshape(self.cells,order='F'), size = self.size, origin = self.origin, - comments = self.comments+[util.execution_stamp('Geom','sort')], + comments = self.comments+[util.execution_stamp('Grid','sort')], ) @@ -860,7 +860,7 @@ class Geom: Different from themselves (or listed as triggers) within a given (cubic) vicinity, i.e. within the region close to a grain/phase boundary. - ToDo: use include/exclude as in seeds.from_geom + ToDo: use include/exclude as in seeds.from_grid Parameters ---------- @@ -874,7 +874,7 @@ class Geom: List of material indices that trigger a change. Defaults to [], meaning that any different neighbor triggers a change. periodic : Boolean, optional - Assume geometry to be periodic. Defaults to True. + Assume grid to be periodic. Defaults to True. """ def tainted_neighborhood(stencil,trigger): @@ -891,10 +891,10 @@ class Geom: mode='wrap' if periodic else 'nearest', extra_keywords={'trigger':trigger}) - return Geom(material = np.where(mask, self.material + offset_,self.material), + return Grid(material = np.where(mask, self.material + offset_,self.material), size = self.size, origin = self.origin, - comments = self.comments+[util.execution_stamp('Geom','vicinity_offset')], + comments = self.comments+[util.execution_stamp('Grid','vicinity_offset')], ) @@ -904,10 +904,10 @@ class Geom: Parameters ---------- - periodic : bool, optional - Show boundaries across periodicity. Defaults to True. + periodic : Boolean, optional + Assume grid to be periodic. Defaults to True. directions : iterable containing str, optional - Direction(s) along which the geometry is mirrored. + Direction(s) along which the boundaries are determined. Valid entries are 'x', 'y', 'z'. Defaults to 'xyz'. """ diff --git a/python/damask/grid_filters.py b/python/damask/grid_filters.py index 8e930d69d..4a1709c75 100644 --- a/python/damask/grid_filters.py +++ b/python/damask/grid_filters.py @@ -4,7 +4,7 @@ Filters for operations on regular grids. Notes ----- The grids are defined as (x,y,z,...) where x is fastest and z is slowest. -This convention is consistent with the geom file format. +This convention is consistent with the layout in grid vtr files. When converting to/from a plain list (e.g. storage in ASCII table), the following operations are required for tensorial data: diff --git a/python/damask/seeds.py b/python/damask/seeds.py index d65cffd7f..cf0c0a006 100644 --- a/python/damask/seeds.py +++ b/python/damask/seeds.py @@ -77,14 +77,14 @@ def from_Poisson_disc(size,N_seeds,N_candidates,distance,periodic=True,rng_seed= return coords -def from_geom(geom,selection=None,invert=False,average=False,periodic=True): +def from_grid(grid,selection=None,invert=False,average=False,periodic=True): """ - Create seed from existing geometry description. + Create seed from existing grid description. Parameters ---------- - geom : damask.Geom - Geometry, from which the material IDs are used as seeds. + grid : damask.Grid + Grid, from which the material IDs are used as seeds. selection : iterable of integers, optional Material IDs to consider. invert : boolean, false @@ -95,10 +95,10 @@ def from_geom(geom,selection=None,invert=False,average=False,periodic=True): Center of gravity with periodic boundaries. """ - material = geom.material.reshape((-1,1),order='F') - mask = _np.full(geom.cells.prod(),True,dtype=bool) if selection is None else \ + material = grid.material.reshape((-1,1),order='F') + mask = _np.full(grid.cells.prod(),True,dtype=bool) if selection is None else \ _np.isin(material,selection,invert=invert).flatten() - coords = grid_filters.coordinates0_point(geom.cells,geom.size).reshape(-1,3,order='F') + coords = grid_filters.coordinates0_point(grid.cells,grid.size).reshape(-1,3,order='F') if not average: return (coords[mask],material[mask]) @@ -106,8 +106,8 @@ def from_geom(geom,selection=None,invert=False,average=False,periodic=True): materials = _np.unique(material[mask]) coords_ = _np.zeros((materials.size,3),dtype=float) for i,mat in enumerate(materials): - pc = (2*_np.pi*coords[material[:,0]==mat,:]-geom.origin)/geom.size - coords_[i] = geom.origin + geom.size / 2 / _np.pi * (_np.pi + + pc = (2*_np.pi*coords[material[:,0]==mat,:]-grid.origin)/grid.size + coords_[i] = grid.origin + grid.size / 2 / _np.pi * (_np.pi + _np.arctan2(-_np.average(_np.sin(pc),axis=0), -_np.average(_np.cos(pc),axis=0))) \ if periodic else \ diff --git a/python/tests/reference/Geom/clean_1_1+2+3_False.vtr b/python/tests/reference/Grid/clean_1_1+2+3_False.vtr similarity index 100% rename from python/tests/reference/Geom/clean_1_1+2+3_False.vtr rename to python/tests/reference/Grid/clean_1_1+2+3_False.vtr diff --git a/python/tests/reference/Geom/clean_1_1+2+3_True.vtr b/python/tests/reference/Grid/clean_1_1+2+3_True.vtr similarity index 100% rename from python/tests/reference/Geom/clean_1_1+2+3_True.vtr rename to python/tests/reference/Grid/clean_1_1+2+3_True.vtr diff --git a/python/tests/reference/Geom/clean_1_1_False.vtr b/python/tests/reference/Grid/clean_1_1_False.vtr similarity index 100% rename from python/tests/reference/Geom/clean_1_1_False.vtr rename to python/tests/reference/Grid/clean_1_1_False.vtr diff --git a/python/tests/reference/Geom/clean_1_1_True.vtr b/python/tests/reference/Grid/clean_1_1_True.vtr similarity index 100% rename from python/tests/reference/Geom/clean_1_1_True.vtr rename to python/tests/reference/Grid/clean_1_1_True.vtr diff --git a/python/tests/reference/Geom/clean_1_None_False.vtr b/python/tests/reference/Grid/clean_1_None_False.vtr similarity index 100% rename from python/tests/reference/Geom/clean_1_None_False.vtr rename to python/tests/reference/Grid/clean_1_None_False.vtr diff --git a/python/tests/reference/Geom/clean_1_None_True.vtr b/python/tests/reference/Grid/clean_1_None_True.vtr similarity index 100% rename from python/tests/reference/Geom/clean_1_None_True.vtr rename to python/tests/reference/Grid/clean_1_None_True.vtr diff --git a/python/tests/reference/Geom/clean_2_1+2+3_False.vtr b/python/tests/reference/Grid/clean_2_1+2+3_False.vtr similarity index 100% rename from python/tests/reference/Geom/clean_2_1+2+3_False.vtr rename to python/tests/reference/Grid/clean_2_1+2+3_False.vtr diff --git a/python/tests/reference/Geom/clean_2_1+2+3_True.vtr b/python/tests/reference/Grid/clean_2_1+2+3_True.vtr similarity index 100% rename from python/tests/reference/Geom/clean_2_1+2+3_True.vtr rename to python/tests/reference/Grid/clean_2_1+2+3_True.vtr diff --git a/python/tests/reference/Geom/clean_2_1_False.vtr b/python/tests/reference/Grid/clean_2_1_False.vtr similarity index 100% rename from python/tests/reference/Geom/clean_2_1_False.vtr rename to python/tests/reference/Grid/clean_2_1_False.vtr diff --git a/python/tests/reference/Geom/clean_2_1_True.vtr b/python/tests/reference/Grid/clean_2_1_True.vtr similarity index 100% rename from python/tests/reference/Geom/clean_2_1_True.vtr rename to python/tests/reference/Grid/clean_2_1_True.vtr diff --git a/python/tests/reference/Geom/clean_2_2_False.vtr b/python/tests/reference/Grid/clean_2_2_False.vtr similarity index 100% rename from python/tests/reference/Geom/clean_2_2_False.vtr rename to python/tests/reference/Grid/clean_2_2_False.vtr diff --git a/python/tests/reference/Geom/clean_2_2_True.vtr b/python/tests/reference/Grid/clean_2_2_True.vtr similarity index 100% rename from python/tests/reference/Geom/clean_2_2_True.vtr rename to python/tests/reference/Grid/clean_2_2_True.vtr diff --git a/python/tests/reference/Geom/clean_2_None_False.vtr b/python/tests/reference/Grid/clean_2_None_False.vtr similarity index 100% rename from python/tests/reference/Geom/clean_2_None_False.vtr rename to python/tests/reference/Grid/clean_2_None_False.vtr diff --git a/python/tests/reference/Geom/clean_2_None_True.vtr b/python/tests/reference/Grid/clean_2_None_True.vtr similarity index 100% rename from python/tests/reference/Geom/clean_2_None_True.vtr rename to python/tests/reference/Grid/clean_2_None_True.vtr diff --git a/python/tests/reference/Geom/clean_3_1+2+3_False.vtr b/python/tests/reference/Grid/clean_3_1+2+3_False.vtr similarity index 100% rename from python/tests/reference/Geom/clean_3_1+2+3_False.vtr rename to python/tests/reference/Grid/clean_3_1+2+3_False.vtr diff --git a/python/tests/reference/Geom/clean_3_1+2+3_True.vtr b/python/tests/reference/Grid/clean_3_1+2+3_True.vtr similarity index 100% rename from python/tests/reference/Geom/clean_3_1+2+3_True.vtr rename to python/tests/reference/Grid/clean_3_1+2+3_True.vtr diff --git a/python/tests/reference/Geom/clean_3_1_False.vtr b/python/tests/reference/Grid/clean_3_1_False.vtr similarity index 100% rename from python/tests/reference/Geom/clean_3_1_False.vtr rename to python/tests/reference/Grid/clean_3_1_False.vtr diff --git a/python/tests/reference/Geom/clean_3_1_True.vtr b/python/tests/reference/Grid/clean_3_1_True.vtr similarity index 100% rename from python/tests/reference/Geom/clean_3_1_True.vtr rename to python/tests/reference/Grid/clean_3_1_True.vtr diff --git a/python/tests/reference/Geom/clean_3_2_False.vtr b/python/tests/reference/Grid/clean_3_2_False.vtr similarity index 100% rename from python/tests/reference/Geom/clean_3_2_False.vtr rename to python/tests/reference/Grid/clean_3_2_False.vtr diff --git a/python/tests/reference/Geom/clean_3_2_True.vtr b/python/tests/reference/Grid/clean_3_2_True.vtr similarity index 100% rename from python/tests/reference/Geom/clean_3_2_True.vtr rename to python/tests/reference/Grid/clean_3_2_True.vtr diff --git a/python/tests/reference/Geom/clean_3_None_False.vtr b/python/tests/reference/Grid/clean_3_None_False.vtr similarity index 100% rename from python/tests/reference/Geom/clean_3_None_False.vtr rename to python/tests/reference/Grid/clean_3_None_False.vtr diff --git a/python/tests/reference/Geom/clean_3_None_True.vtr b/python/tests/reference/Grid/clean_3_None_True.vtr similarity index 100% rename from python/tests/reference/Geom/clean_3_None_True.vtr rename to python/tests/reference/Grid/clean_3_None_True.vtr diff --git a/python/tests/reference/Geom/clean_4_1+2+3_False.vtr b/python/tests/reference/Grid/clean_4_1+2+3_False.vtr similarity index 100% rename from python/tests/reference/Geom/clean_4_1+2+3_False.vtr rename to python/tests/reference/Grid/clean_4_1+2+3_False.vtr diff --git a/python/tests/reference/Geom/clean_4_1+2+3_True.vtr b/python/tests/reference/Grid/clean_4_1+2+3_True.vtr similarity index 100% rename from python/tests/reference/Geom/clean_4_1+2+3_True.vtr rename to python/tests/reference/Grid/clean_4_1+2+3_True.vtr diff --git a/python/tests/reference/Geom/clean_4_1_False.vtr b/python/tests/reference/Grid/clean_4_1_False.vtr similarity index 100% rename from python/tests/reference/Geom/clean_4_1_False.vtr rename to python/tests/reference/Grid/clean_4_1_False.vtr diff --git a/python/tests/reference/Geom/clean_4_1_True.vtr b/python/tests/reference/Grid/clean_4_1_True.vtr similarity index 100% rename from python/tests/reference/Geom/clean_4_1_True.vtr rename to python/tests/reference/Grid/clean_4_1_True.vtr diff --git a/python/tests/reference/Geom/clean_4_2_False.vtr b/python/tests/reference/Grid/clean_4_2_False.vtr similarity index 100% rename from python/tests/reference/Geom/clean_4_2_False.vtr rename to python/tests/reference/Grid/clean_4_2_False.vtr diff --git a/python/tests/reference/Geom/clean_4_2_True.vtr b/python/tests/reference/Grid/clean_4_2_True.vtr similarity index 100% rename from python/tests/reference/Geom/clean_4_2_True.vtr rename to python/tests/reference/Grid/clean_4_2_True.vtr diff --git a/python/tests/reference/Geom/clean_4_None_False.vtr b/python/tests/reference/Grid/clean_4_None_False.vtr similarity index 100% rename from python/tests/reference/Geom/clean_4_None_False.vtr rename to python/tests/reference/Grid/clean_4_None_False.vtr diff --git a/python/tests/reference/Geom/clean_4_None_True.vtr b/python/tests/reference/Grid/clean_4_None_True.vtr similarity index 100% rename from python/tests/reference/Geom/clean_4_None_True.vtr rename to python/tests/reference/Grid/clean_4_None_True.vtr diff --git a/python/tests/reference/Geom/flip_directions_x-y-z.vtr b/python/tests/reference/Grid/flip_directions_x-y-z.vtr similarity index 100% rename from python/tests/reference/Geom/flip_directions_x-y-z.vtr rename to python/tests/reference/Grid/flip_directions_x-y-z.vtr diff --git a/python/tests/reference/Geom/flip_directions_x.vtr b/python/tests/reference/Grid/flip_directions_x.vtr similarity index 100% rename from python/tests/reference/Geom/flip_directions_x.vtr rename to python/tests/reference/Grid/flip_directions_x.vtr diff --git a/python/tests/reference/Geom/flip_directions_y-z.vtr b/python/tests/reference/Grid/flip_directions_y-z.vtr similarity index 100% rename from python/tests/reference/Geom/flip_directions_y-z.vtr rename to python/tests/reference/Grid/flip_directions_y-z.vtr diff --git a/python/tests/reference/Geom/flip_directions_z-x-y.vtr b/python/tests/reference/Grid/flip_directions_z-x-y.vtr similarity index 100% rename from python/tests/reference/Geom/flip_directions_z-x-y.vtr rename to python/tests/reference/Grid/flip_directions_z-x-y.vtr diff --git a/python/tests/reference/Geom/get_grain_boundaries_8g12x15x20.vtr b/python/tests/reference/Grid/get_grain_boundaries_8g12x15x20.vtr similarity index 100% rename from python/tests/reference/Geom/get_grain_boundaries_8g12x15x20.vtr rename to python/tests/reference/Grid/get_grain_boundaries_8g12x15x20.vtr diff --git a/python/tests/reference/Geom/get_grain_boundaries_8g12x15x20_x_False.vtu b/python/tests/reference/Grid/get_grain_boundaries_8g12x15x20_x_False.vtu similarity index 100% rename from python/tests/reference/Geom/get_grain_boundaries_8g12x15x20_x_False.vtu rename to python/tests/reference/Grid/get_grain_boundaries_8g12x15x20_x_False.vtu diff --git a/python/tests/reference/Geom/get_grain_boundaries_8g12x15x20_x_True.vtu b/python/tests/reference/Grid/get_grain_boundaries_8g12x15x20_x_True.vtu similarity index 100% rename from python/tests/reference/Geom/get_grain_boundaries_8g12x15x20_x_True.vtu rename to python/tests/reference/Grid/get_grain_boundaries_8g12x15x20_x_True.vtu diff --git a/python/tests/reference/Geom/get_grain_boundaries_8g12x15x20_xy_False.vtu b/python/tests/reference/Grid/get_grain_boundaries_8g12x15x20_xy_False.vtu similarity index 100% rename from python/tests/reference/Geom/get_grain_boundaries_8g12x15x20_xy_False.vtu rename to python/tests/reference/Grid/get_grain_boundaries_8g12x15x20_xy_False.vtu diff --git a/python/tests/reference/Geom/get_grain_boundaries_8g12x15x20_xy_True.vtu b/python/tests/reference/Grid/get_grain_boundaries_8g12x15x20_xy_True.vtu similarity index 100% rename from python/tests/reference/Geom/get_grain_boundaries_8g12x15x20_xy_True.vtu rename to python/tests/reference/Grid/get_grain_boundaries_8g12x15x20_xy_True.vtu diff --git a/python/tests/reference/Geom/get_grain_boundaries_8g12x15x20_xyz_False.vtu b/python/tests/reference/Grid/get_grain_boundaries_8g12x15x20_xyz_False.vtu similarity index 100% rename from python/tests/reference/Geom/get_grain_boundaries_8g12x15x20_xyz_False.vtu rename to python/tests/reference/Grid/get_grain_boundaries_8g12x15x20_xyz_False.vtu diff --git a/python/tests/reference/Geom/get_grain_boundaries_8g12x15x20_xyz_True.vtu b/python/tests/reference/Grid/get_grain_boundaries_8g12x15x20_xyz_True.vtu similarity index 100% rename from python/tests/reference/Geom/get_grain_boundaries_8g12x15x20_xyz_True.vtu rename to python/tests/reference/Grid/get_grain_boundaries_8g12x15x20_xyz_True.vtu diff --git a/python/tests/reference/Geom/get_grain_boundaries_8g12x15x20_xz_False.vtu b/python/tests/reference/Grid/get_grain_boundaries_8g12x15x20_xz_False.vtu similarity index 100% rename from python/tests/reference/Geom/get_grain_boundaries_8g12x15x20_xz_False.vtu rename to python/tests/reference/Grid/get_grain_boundaries_8g12x15x20_xz_False.vtu diff --git a/python/tests/reference/Geom/get_grain_boundaries_8g12x15x20_xz_True.vtu b/python/tests/reference/Grid/get_grain_boundaries_8g12x15x20_xz_True.vtu similarity index 100% rename from python/tests/reference/Geom/get_grain_boundaries_8g12x15x20_xz_True.vtu rename to python/tests/reference/Grid/get_grain_boundaries_8g12x15x20_xz_True.vtu diff --git a/python/tests/reference/Geom/get_grain_boundaries_8g12x15x20_y_False.vtu b/python/tests/reference/Grid/get_grain_boundaries_8g12x15x20_y_False.vtu similarity index 100% rename from python/tests/reference/Geom/get_grain_boundaries_8g12x15x20_y_False.vtu rename to python/tests/reference/Grid/get_grain_boundaries_8g12x15x20_y_False.vtu diff --git a/python/tests/reference/Geom/get_grain_boundaries_8g12x15x20_y_True.vtu b/python/tests/reference/Grid/get_grain_boundaries_8g12x15x20_y_True.vtu similarity index 100% rename from python/tests/reference/Geom/get_grain_boundaries_8g12x15x20_y_True.vtu rename to python/tests/reference/Grid/get_grain_boundaries_8g12x15x20_y_True.vtu diff --git a/python/tests/reference/Geom/get_grain_boundaries_8g12x15x20_z_False.vtu b/python/tests/reference/Grid/get_grain_boundaries_8g12x15x20_z_False.vtu similarity index 100% rename from python/tests/reference/Geom/get_grain_boundaries_8g12x15x20_z_False.vtu rename to python/tests/reference/Grid/get_grain_boundaries_8g12x15x20_z_False.vtu diff --git a/python/tests/reference/Geom/get_grain_boundaries_8g12x15x20_z_True.vtu b/python/tests/reference/Grid/get_grain_boundaries_8g12x15x20_z_True.vtu similarity index 100% rename from python/tests/reference/Geom/get_grain_boundaries_8g12x15x20_z_True.vtu rename to python/tests/reference/Grid/get_grain_boundaries_8g12x15x20_z_True.vtu diff --git a/python/tests/reference/Geom/get_grain_boundaries_8g12x15x20_zy_False.vtu b/python/tests/reference/Grid/get_grain_boundaries_8g12x15x20_zy_False.vtu similarity index 100% rename from python/tests/reference/Geom/get_grain_boundaries_8g12x15x20_zy_False.vtu rename to python/tests/reference/Grid/get_grain_boundaries_8g12x15x20_zy_False.vtu diff --git a/python/tests/reference/Geom/get_grain_boundaries_8g12x15x20_zy_True.vtu b/python/tests/reference/Grid/get_grain_boundaries_8g12x15x20_zy_True.vtu similarity index 100% rename from python/tests/reference/Geom/get_grain_boundaries_8g12x15x20_zy_True.vtu rename to python/tests/reference/Grid/get_grain_boundaries_8g12x15x20_zy_True.vtu diff --git a/python/tests/reference/Geom/mirror_directions_x+reflect_False.vtr b/python/tests/reference/Grid/mirror_directions_x+reflect_False.vtr similarity index 100% rename from python/tests/reference/Geom/mirror_directions_x+reflect_False.vtr rename to python/tests/reference/Grid/mirror_directions_x+reflect_False.vtr diff --git a/python/tests/reference/Geom/mirror_directions_x-y-z+reflect_True.vtr b/python/tests/reference/Grid/mirror_directions_x-y-z+reflect_True.vtr similarity index 100% rename from python/tests/reference/Geom/mirror_directions_x-y-z+reflect_True.vtr rename to python/tests/reference/Grid/mirror_directions_x-y-z+reflect_True.vtr diff --git a/python/tests/reference/Geom/mirror_directions_y-z+reflect_False.vtr b/python/tests/reference/Grid/mirror_directions_y-z+reflect_False.vtr similarity index 100% rename from python/tests/reference/Geom/mirror_directions_y-z+reflect_False.vtr rename to python/tests/reference/Grid/mirror_directions_y-z+reflect_False.vtr diff --git a/python/tests/reference/Geom/mirror_directions_z-x-y+reflect_False.vtr b/python/tests/reference/Grid/mirror_directions_z-x-y+reflect_False.vtr similarity index 100% rename from python/tests/reference/Geom/mirror_directions_z-x-y+reflect_False.vtr rename to python/tests/reference/Grid/mirror_directions_z-x-y+reflect_False.vtr diff --git a/python/tests/reference/Geom/rotate_Eulers_0.0-32.0-240.0.vtr b/python/tests/reference/Grid/rotate_Eulers_0.0-32.0-240.0.vtr similarity index 100% rename from python/tests/reference/Geom/rotate_Eulers_0.0-32.0-240.0.vtr rename to python/tests/reference/Grid/rotate_Eulers_0.0-32.0-240.0.vtr diff --git a/python/tests/reference/Geom/rotate_Eulers_32.0-68.0-21.0.vtr b/python/tests/reference/Grid/rotate_Eulers_32.0-68.0-21.0.vtr similarity index 100% rename from python/tests/reference/Geom/rotate_Eulers_32.0-68.0-21.0.vtr rename to python/tests/reference/Grid/rotate_Eulers_32.0-68.0-21.0.vtr diff --git a/python/tests/reference/Geom/scale_grid_10-10-10.vtr b/python/tests/reference/Grid/scale_grid_10-10-10.vtr similarity index 100% rename from python/tests/reference/Geom/scale_grid_10-10-10.vtr rename to python/tests/reference/Grid/scale_grid_10-10-10.vtr diff --git a/python/tests/reference/Geom/scale_grid_10-11-10.vtr b/python/tests/reference/Grid/scale_grid_10-11-10.vtr similarity index 100% rename from python/tests/reference/Geom/scale_grid_10-11-10.vtr rename to python/tests/reference/Grid/scale_grid_10-11-10.vtr diff --git a/python/tests/reference/Geom/scale_grid_10-13-10.vtr b/python/tests/reference/Grid/scale_grid_10-13-10.vtr similarity index 100% rename from python/tests/reference/Geom/scale_grid_10-13-10.vtr rename to python/tests/reference/Grid/scale_grid_10-13-10.vtr diff --git a/python/tests/reference/Geom/scale_grid_10-20-2.vtr b/python/tests/reference/Grid/scale_grid_10-20-2.vtr similarity index 100% rename from python/tests/reference/Geom/scale_grid_10-20-2.vtr rename to python/tests/reference/Grid/scale_grid_10-20-2.vtr diff --git a/python/tests/reference/Geom/scale_grid_5-4-20.vtr b/python/tests/reference/Grid/scale_grid_5-4-20.vtr similarity index 100% rename from python/tests/reference/Geom/scale_grid_5-4-20.vtr rename to python/tests/reference/Grid/scale_grid_5-4-20.vtr diff --git a/python/tests/reference/Geom/scale_grid_8-10-12.vtr b/python/tests/reference/Grid/scale_grid_8-10-12.vtr similarity index 100% rename from python/tests/reference/Geom/scale_grid_8-10-12.vtr rename to python/tests/reference/Grid/scale_grid_8-10-12.vtr diff --git a/python/tests/test_Geom.py b/python/tests/test_Grid.py similarity index 83% rename from python/tests/test_Geom.py rename to python/tests/test_Grid.py index 670e1caf8..37f011676 100644 --- a/python/tests/test_Geom.py +++ b/python/tests/test_Grid.py @@ -2,7 +2,7 @@ import pytest import numpy as np from damask import VTK -from damask import Geom +from damask import Grid from damask import Table from damask import Rotation from damask import util @@ -10,7 +10,7 @@ from damask import seeds from damask import grid_filters -def geom_equal(a,b): +def grid_equal(a,b): return np.all(a.material == b.material) and \ np.all(a.cells == b.cells) and \ np.allclose(a.size, b.size) and \ @@ -23,15 +23,15 @@ def default(): np.arange(2,42), np.ones(40,dtype=int)*2, np.arange(1,41))).reshape(8,5,4,order='F') - return Geom(x,[8e-6,5e-6,4e-6]) + return Grid(x,[8e-6,5e-6,4e-6]) @pytest.fixture def ref_path(ref_path_base): """Directory containing reference results.""" - return ref_path_base/'Geom' + return ref_path_base/'Grid' -class TestGeom: +class TestGrid: @pytest.fixture(autouse=True) def _patch_execution_stamp(self, patch_execution_stamp): @@ -46,7 +46,7 @@ class TestGeom: def test_diff_not_equal(self,default): - new = Geom(default.material[1:,1:,1:]+1,default.size*.9,np.ones(3)-default.origin,comments=['modified']) + new = Grid(default.material[1:,1:,1:]+1,default.size*.9,np.ones(3)-default.origin,comments=['modified']) assert str(default.diff(new)) != '' def test_repr(self,default): @@ -54,36 +54,36 @@ class TestGeom: def test_read_write_vtr(self,default,tmp_path): default.save(tmp_path/'default') - new = Geom.load(tmp_path/'default.vtr') - assert geom_equal(new,default) + new = Grid.load(tmp_path/'default.vtr') + assert grid_equal(new,default) def test_invalid_vtr(self,tmp_path): v = VTK.from_rectilinear_grid(np.random.randint(5,10,3)*2,np.random.random(3) + 1.0) v.save(tmp_path/'no_materialpoint.vtr',parallel=False) with pytest.raises(ValueError): - Geom.load(tmp_path/'no_materialpoint.vtr') + Grid.load(tmp_path/'no_materialpoint.vtr') def test_invalid_material(self): with pytest.raises(TypeError): - Geom(np.zeros((3,3,3),dtype='complex'),np.ones(3)) + Grid(np.zeros((3,3,3),dtype='complex'),np.ones(3)) def test_cast_to_int(self): - g = Geom(np.zeros((3,3,3)),np.ones(3)) + g = Grid(np.zeros((3,3,3)),np.ones(3)) assert g.material.dtype in np.sctypes['int'] def test_invalid_size(self,default): with pytest.raises(ValueError): - Geom(default.material[1:,1:,1:], + Grid(default.material[1:,1:,1:], size=np.ones(2)) def test_save_load_ASCII(self,default,tmp_path): default.save_ASCII(tmp_path/'ASCII') default.material -= 1 - assert geom_equal(Geom.load_ASCII(tmp_path/'ASCII'),default) + assert grid_equal(Grid.load_ASCII(tmp_path/'ASCII'),default) def test_invalid_origin(self,default): with pytest.raises(ValueError): - Geom(default.material[1:,1:,1:], + Grid(default.material[1:,1:,1:], size=np.ones(3), origin=np.ones(4)) @@ -91,14 +91,14 @@ class TestGeom: def test_invalid_materials_shape(self,default): material = np.ones((3,3)) with pytest.raises(ValueError): - Geom(material, + Grid(material, size=np.ones(3)) def test_invalid_materials_type(self,default): material = np.random.randint(1,300,(3,4,5))==1 with pytest.raises(TypeError): - Geom(material) + Grid(material) @pytest.mark.parametrize('directions,reflect',[ @@ -113,7 +113,7 @@ class TestGeom: tag = f'directions_{"-".join(directions)}+reflect_{reflect}' reference = ref_path/f'mirror_{tag}.vtr' if update: modified.save(reference) - assert geom_equal(Geom.load(reference), + assert grid_equal(Grid.load(reference), modified) @@ -135,17 +135,17 @@ class TestGeom: tag = f'directions_{"-".join(directions)}' reference = ref_path/f'flip_{tag}.vtr' if update: modified.save(reference) - assert geom_equal(Geom.load(reference), + assert grid_equal(Grid.load(reference), modified) def test_flip_invariant(self,default): - assert geom_equal(default,default.flip([])) + assert grid_equal(default,default.flip([])) @pytest.mark.parametrize('direction',[['x'],['x','y']]) def test_flip_double(self,default,direction): - assert geom_equal(default,default.flip(direction).flip(direction)) + assert grid_equal(default,default.flip(direction).flip(direction)) @pytest.mark.parametrize('directions',[(1,2,'y'),('a','b','x'),[1]]) @@ -162,7 +162,7 @@ class TestGeom: reference = ref_path/f'clean_{stencil}_{"+".join(map(str,[None] if selection is None else selection))}_{periodic}' if update and stencil > 1: current.save(reference) - assert geom_equal(Geom.load(reference) if stencil > 1 else default, + assert grid_equal(Grid.load(reference) if stencil > 1 else default, current ) @@ -181,7 +181,7 @@ class TestGeom: tag = f'grid_{util.srepr(cells,"-")}' reference = ref_path/f'scale_{tag}.vtr' if update: modified.save(reference) - assert geom_equal(Geom.load(reference), + assert grid_equal(Grid.load(reference), modified) @@ -190,21 +190,21 @@ class TestGeom: for m in np.unique(material): material[material==m] = material.max() + np.random.randint(1,30) default.material -= 1 - modified = Geom(material, + modified = Grid(material, default.size, default.origin) - assert not geom_equal(modified,default) - assert geom_equal(default, + assert not grid_equal(modified,default) + assert grid_equal(default, modified.renumber()) def test_substitute(self,default): offset = np.random.randint(1,500) - modified = Geom(default.material + offset, + modified = Grid(default.material + offset, default.size, default.origin) - assert not geom_equal(modified,default) - assert geom_equal(default, + assert not grid_equal(modified,default) + assert grid_equal(default, modified.substitute(np.arange(default.material.max())+1+offset, np.arange(default.material.max())+1)) @@ -212,12 +212,12 @@ class TestGeom: f = np.unique(default.material.flatten())[:np.random.randint(1,default.material.max())] t = np.random.permutation(f) modified = default.substitute(f,t) - assert np.array_equiv(t,f) or (not geom_equal(modified,default)) - assert geom_equal(default, modified.substitute(t,f)) + assert np.array_equiv(t,f) or (not grid_equal(modified,default)) + assert grid_equal(default, modified.substitute(t,f)) def test_sort(self): cells = np.random.randint(5,20,3) - m = Geom(np.random.randint(1,20,cells)*3,np.ones(3)).sort().material.flatten(order='F') + m = Grid(np.random.randint(1,20,cells)*3,np.ones(3)).sort().material.flatten(order='F') for i,v in enumerate(m): assert i==0 or v > m[:i].max() or v in m[:i] @@ -227,7 +227,7 @@ class TestGeom: modified = default.copy() for i in range(np.rint(360/axis_angle[3]).astype(int)): modified.rotate(Rotation.from_axis_angle(axis_angle,degrees=True)) - assert geom_equal(default,modified) + assert grid_equal(default,modified) @pytest.mark.parametrize('Eulers',[[32.0,68.0,21.0], @@ -237,7 +237,7 @@ class TestGeom: tag = f'Eulers_{util.srepr(Eulers,"-")}' reference = ref_path/f'rotate_{tag}.vtr' if update: modified.save(reference) - assert geom_equal(Geom.load(reference), + assert grid_equal(Grid.load(reference), modified) @@ -263,8 +263,8 @@ class TestGeom: o = np.random.random(3)-.5 g = np.random.randint(8,32,(3)) s = np.random.random(3)+.5 - G_1 = Geom(np.ones(g,'i'),s,o).add_primitive(diameter,center1,exponent) - G_2 = Geom(np.ones(g,'i'),s,o).add_primitive(diameter,center2,exponent) + G_1 = Grid(np.ones(g,'i'),s,o).add_primitive(diameter,center1,exponent) + G_2 = Grid(np.ones(g,'i'),s,o).add_primitive(diameter,center2,exponent) assert np.count_nonzero(G_1.material!=2) == np.count_nonzero(G_2.material!=2) @@ -279,9 +279,9 @@ class TestGeom: g = np.random.randint(8,32,(3)) s = np.random.random(3)+.5 fill = np.random.randint(10)+2 - G_1 = Geom(np.ones(g,'i'),s).add_primitive(.3,center,1,fill,inverse=inverse,periodic=periodic) - G_2 = Geom(np.ones(g,'i'),s).add_primitive(.3,center,1,fill,Rotation.from_random(),inverse,periodic=periodic) - assert geom_equal(G_1,G_2) + G_1 = Grid(np.ones(g,'i'),s).add_primitive(.3,center,1,fill,inverse=inverse,periodic=periodic) + G_2 = Grid(np.ones(g,'i'),s).add_primitive(.3,center,1,fill,Rotation.from_random(),inverse,periodic=periodic) + assert grid_equal(G_1,G_2) @pytest.mark.parametrize('trigger',[[1],[]]) @@ -300,9 +300,9 @@ class TestGeom: if len(trigger) > 0: m2[m==1] = 1 - geom = Geom(m,np.random.rand(3)).vicinity_offset(vicinity,offset,trigger=trigger) + grid = Grid(m,np.random.rand(3)).vicinity_offset(vicinity,offset,trigger=trigger) - assert np.all(m2==geom.material) + assert np.all(m2==grid.material) @pytest.mark.parametrize('periodic',[True,False]) @@ -318,9 +318,9 @@ class TestGeom: size = np.random.random(3) + 1.0 N_seeds= np.random.randint(10,30) seeds = np.random.rand(N_seeds,3) * np.broadcast_to(size,(N_seeds,3)) - Voronoi = Geom.from_Voronoi_tessellation( cells,size,seeds, np.arange(N_seeds)+5,periodic) - Laguerre = Geom.from_Laguerre_tessellation(cells,size,seeds,np.ones(N_seeds),np.arange(N_seeds)+5,periodic) - assert geom_equal(Laguerre,Voronoi) + Voronoi = Grid.from_Voronoi_tessellation( cells,size,seeds, np.arange(N_seeds)+5,periodic) + Laguerre = Grid.from_Laguerre_tessellation(cells,size,seeds,np.ones(N_seeds),np.arange(N_seeds)+5,periodic) + assert grid_equal(Laguerre,Voronoi) def test_Laguerre_weights(self): @@ -331,7 +331,7 @@ class TestGeom: weights= np.full((N_seeds),-np.inf) ms = np.random.randint(N_seeds) weights[ms] = np.random.random() - Laguerre = Geom.from_Laguerre_tessellation(cells,size,seeds,weights,periodic=np.random.random()>0.5) + Laguerre = Grid.from_Laguerre_tessellation(cells,size,seeds,weights,periodic=np.random.random()>0.5) assert np.all(Laguerre.material == ms) @@ -343,10 +343,10 @@ class TestGeom: material = np.zeros(cells) material[:,cells[1]//2:,:] = 1 if approach == 'Laguerre': - geom = Geom.from_Laguerre_tessellation(cells,size,seeds,np.ones(2),periodic=np.random.random()>0.5) + grid = Grid.from_Laguerre_tessellation(cells,size,seeds,np.ones(2),periodic=np.random.random()>0.5) elif approach == 'Voronoi': - geom = Geom.from_Voronoi_tessellation(cells,size,seeds, periodic=np.random.random()>0.5) - assert np.all(geom.material == material) + grid = Grid.from_Voronoi_tessellation(cells,size,seeds, periodic=np.random.random()>0.5) + assert np.all(grid.material == material) @pytest.mark.parametrize('surface',['Schwarz P', @@ -368,9 +368,9 @@ class TestGeom: threshold = 2*np.random.rand()-1. periods = np.random.randint(2)+1 materials = np.random.randint(0,40,2) - geom = Geom.from_minimal_surface(cells,size,surface,threshold,periods,materials) - assert set(geom.material.flatten()) | set(materials) == set(materials) \ - and (geom.size == size).all() and (geom.cells == cells).all() + grid = Grid.from_minimal_surface(cells,size,surface,threshold,periods,materials) + assert set(grid.material.flatten()) | set(materials) == set(materials) \ + and (grid.size == size).all() and (grid.cells == cells).all() @pytest.mark.parametrize('surface,threshold',[('Schwarz P',0), ('Double Primitive',-1./6.), @@ -387,8 +387,8 @@ class TestGeom: ]) def test_minimal_surface_volume(self,surface,threshold): cells = np.ones(3,dtype=int)*64 - geom = Geom.from_minimal_surface(cells,np.ones(3),surface,threshold) - assert np.isclose(np.count_nonzero(geom.material==1)/np.prod(geom.cells),.5,rtol=1e-3) + grid = Grid.from_minimal_surface(cells,np.ones(3),surface,threshold) + assert np.isclose(np.count_nonzero(grid.material==1)/np.prod(grid.cells),.5,rtol=1e-3) def test_from_table(self): @@ -398,7 +398,7 @@ class TestGeom: z=np.ones(cells.prod()) z[cells[:2].prod()*int(cells[2]/2):]=0 t = Table(np.column_stack((coords,z)),{'coords':3,'z':1}) - g = Geom.from_table(t,'coords',['1_coords','z']) + g = Grid.from_table(t,'coords',['1_coords','z']) assert g.N_materials == g.cells[0]*2 and (g.material[:,:,-1]-g.material[:,:,0] == cells[0]).all() @@ -406,16 +406,16 @@ class TestGeom: cells = np.random.randint(60,100,3) size = np.ones(3)+np.random.rand(3) s = seeds.from_random(size,np.random.randint(60,100)) - geom = Geom.from_Voronoi_tessellation(cells,size,s) + grid = Grid.from_Voronoi_tessellation(cells,size,s) coords = grid_filters.coordinates0_point(cells,size) - t = Table(np.column_stack((coords.reshape(-1,3,order='F'),geom.material.flatten(order='F'))),{'c':3,'m':1}) - assert geom_equal(geom.sort().renumber(),Geom.from_table(t,'c',['m'])) + t = Table(np.column_stack((coords.reshape(-1,3,order='F'),grid.material.flatten(order='F'))),{'c':3,'m':1}) + assert grid_equal(grid.sort().renumber(),Grid.from_table(t,'c',['m'])) @pytest.mark.parametrize('periodic',[True,False]) @pytest.mark.parametrize('direction',['x','y','z',['x','y'],'zy','xz',['x','y','z']]) def test_get_grain_boundaries(self,update,ref_path,periodic,direction): - geom=Geom.load(ref_path/'get_grain_boundaries_8g12x15x20.vtr') - current=geom.get_grain_boundaries(periodic,direction) + grid=Grid.load(ref_path/'get_grain_boundaries_8g12x15x20.vtr') + current=grid.get_grain_boundaries(periodic,direction) if update: current.save(ref_path/f'get_grain_boundaries_8g12x15x20_{direction}_{periodic}.vtu',parallel=False) reference=VTK.load(ref_path/f'get_grain_boundaries_8g12x15x20_{"".join(direction)}_{periodic}.vtu') diff --git a/python/tests/test_seeds.py b/python/tests/test_seeds.py index 65624b51f..af27e74af 100644 --- a/python/tests/test_seeds.py +++ b/python/tests/test_seeds.py @@ -4,7 +4,7 @@ from scipy.spatial import cKDTree from damask import seeds from damask import grid_filters -from damask import Geom +from damask import Grid class TestSeeds: @@ -26,37 +26,37 @@ class TestSeeds: cKDTree(coords).query(coords, 2) assert (0<= coords).all() and (coords=distance - def test_from_geom_reconstruct(self): + def test_from_grid_reconstruct(self): cells = np.random.randint(10,20,3) N_seeds = np.random.randint(30,300) size = np.ones(3) + np.random.random(3) coords = seeds.from_random(size,N_seeds,cells) - geom_1 = Geom.from_Voronoi_tessellation(cells,size,coords) - coords,material = seeds.from_geom(geom_1) - geom_2 = Geom.from_Voronoi_tessellation(cells,size,coords,material) - assert (geom_2.material==geom_1.material).all() + grid_1 = Grid.from_Voronoi_tessellation(cells,size,coords) + coords,material = seeds.from_grid(grid_1) + grid_2 = Grid.from_Voronoi_tessellation(cells,size,coords,material) + assert (grid_2.material==grid_1.material).all() @pytest.mark.parametrize('periodic',[True,False]) @pytest.mark.parametrize('average',[True,False]) - def test_from_geom_grid(self,periodic,average): + def test_from_grid_grid(self,periodic,average): cells = np.random.randint(10,20,3) size = np.ones(3) + np.random.random(3) coords = grid_filters.coordinates0_point(cells,size).reshape(-1,3) np.random.shuffle(coords) - geom_1 = Geom.from_Voronoi_tessellation(cells,size,coords) - coords,material = seeds.from_geom(geom_1,average=average,periodic=periodic) - geom_2 = Geom.from_Voronoi_tessellation(cells,size,coords,material) - assert (geom_2.material==geom_1.material).all() + grid_1 = Grid.from_Voronoi_tessellation(cells,size,coords) + coords,material = seeds.from_grid(grid_1,average=average,periodic=periodic) + grid_2 = Grid.from_Voronoi_tessellation(cells,size,coords,material) + assert (grid_2.material==grid_1.material).all() @pytest.mark.parametrize('periodic',[True,False]) @pytest.mark.parametrize('average',[True,False]) @pytest.mark.parametrize('invert',[True,False]) - def test_from_geom_selection(self,periodic,average,invert): + def test_from_grid_selection(self,periodic,average,invert): cells = np.random.randint(10,20,3) N_seeds = np.random.randint(30,300) size = np.ones(3) + np.random.random(3) coords = seeds.from_random(size,N_seeds,cells) - geom = Geom.from_Voronoi_tessellation(cells,size,coords) + grid = Grid.from_Voronoi_tessellation(cells,size,coords) selection=np.random.randint(N_seeds)+1 - coords,material = seeds.from_geom(geom,average=average,periodic=periodic,invert=invert,selection=[selection]) + coords,material = seeds.from_grid(grid,average=average,periodic=periodic,invert=invert,selection=[selection]) assert selection not in material if invert else (selection==material).all() From c80e1c5420ef80ef5fa435dafe28207a93a01798 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 5 Dec 2020 10:47:42 +0100 Subject: [PATCH 007/148] less confusing in the standard case, more helpful in the special case --- python/damask/_grid.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/python/damask/_grid.py b/python/damask/_grid.py index 2bd5a5f9e..0440dc7d0 100644 --- a/python/damask/_grid.py +++ b/python/damask/_grid.py @@ -43,12 +43,15 @@ class Grid: def __repr__(self): """Basic information on grid definition.""" + mat_min = np.nanmin(self.material) + mat_max = np.nanmax(self.material) + mat_N = self.N_materials return util.srepr([ - f'cells a b c: {util.srepr(self.cells, " x ")}', - f'size x y z: {util.srepr(self.size, " x ")}', - f'origin x y z: {util.srepr(self.origin," ")}', - f'# materials: {self.N_materials}', - f'max material: {np.nanmax(self.material)}', + f'cells a b c: {util.srepr(self.cells, " x ")}', + f'size x y z: {util.srepr(self.size, " x ")}', + f'origin x y z: {util.srepr(self.origin," ")}', + f'# materials: {mat_N}' + ('' if mat_min == 0 and mat_max+1 == mat_N else + f' (min: {mat_min}, max: {mat_max})') ]) From 42eb8021268a60a31203f021ae7860e8cc4e24d0 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 5 Dec 2020 11:29:23 +0100 Subject: [PATCH 008/148] not needed anymore --- src/grid/discretization_grid.f90 | 162 ------------------------------- 1 file changed, 162 deletions(-) diff --git a/src/grid/discretization_grid.f90 b/src/grid/discretization_grid.f90 index e4b64c9c0..93fd4d82b 100644 --- a/src/grid/discretization_grid.f90 +++ b/src/grid/discretization_grid.f90 @@ -149,168 +149,6 @@ subroutine discretization_grid_init(restart) end subroutine discretization_grid_init -!-------------------------------------------------------------------------------------------------- -!> @brief Parses geometry file -!> @details important variables have an implicit "save" attribute. Therefore, this function is -! supposed to be called only once! -!-------------------------------------------------------------------------------------------------- -subroutine readGeom(grid,geomSize,origin,material) - - integer, dimension(3), intent(out) :: & - grid ! grid (across all processes!) - real(pReal), dimension(3), intent(out) :: & - geomSize, & ! size (across all processes!) - origin ! origin (across all processes!) - integer, dimension(:), intent(out), allocatable :: & - material - - character(len=:), allocatable :: rawData - character(len=65536) :: line - integer, allocatable, dimension(:) :: chunkPos - integer :: & - headerLength = -1, & !< length of header (in lines) - fileLength, & !< length of the geom file (in characters) - fileUnit, & - startPos, endPos, & - myStat, & - l, & !< line counter - c, & !< counter for # materials in line - o, & !< order of "to" packing - e, & !< "element", i.e. spectral collocation point - i, j - - grid = -1 - geomSize = -1.0_pReal - -!-------------------------------------------------------------------------------------------------- -! read raw data as stream - inquire(file = trim(interface_geomFile), size=fileLength) - open(newunit=fileUnit, file=trim(interface_geomFile), access='stream',& - status='old', position='rewind', action='read',iostat=myStat) - if(myStat /= 0) call IO_error(100,ext_msg=trim(interface_geomFile)) - allocate(character(len=fileLength)::rawData) - read(fileUnit) rawData - close(fileUnit) - -!-------------------------------------------------------------------------------------------------- -! get header length - endPos = index(rawData,IO_EOL) - if(endPos <= index(rawData,'head')) then ! ToDo: Should be 'header' - startPos = len(rawData) - call IO_error(error_ID=841, ext_msg='readGeom') - else - chunkPos = IO_stringPos(rawData(1:endPos)) - if (chunkPos(1) < 2) call IO_error(error_ID=841, ext_msg='readGeom') - headerLength = IO_intValue(rawData(1:endPos),chunkPos,1) - startPos = endPos + 1 - endif - -!-------------------------------------------------------------------------------------------------- -! read and interpret header - origin = 0.0_pReal - l = 0 - do while (l < headerLength .and. startPos < len(rawData)) - endPos = startPos + index(rawData(startPos:),IO_EOL) - 1 - if (endPos < startPos) endPos = len(rawData) ! end of file without new line - line = rawData(startPos:endPos) - startPos = endPos + 1 - l = l + 1 - - chunkPos = IO_stringPos(trim(line)) - if (chunkPos(1) < 2) cycle ! need at least one keyword value pair - - select case (IO_lc(IO_StringValue(trim(line),chunkPos,1)) ) - case ('grid') - if (chunkPos(1) > 6) then - do j = 2,6,2 - select case (IO_lc(IO_stringValue(line,chunkPos,j))) - case('a') - grid(1) = IO_intValue(line,chunkPos,j+1) - case('b') - grid(2) = IO_intValue(line,chunkPos,j+1) - case('c') - grid(3) = IO_intValue(line,chunkPos,j+1) - end select - enddo - endif - - case ('size') - if (chunkPos(1) > 6) then - do j = 2,6,2 - select case (IO_lc(IO_stringValue(line,chunkPos,j))) - case('x') - geomSize(1) = IO_floatValue(line,chunkPos,j+1) - case('y') - geomSize(2) = IO_floatValue(line,chunkPos,j+1) - case('z') - geomSize(3) = IO_floatValue(line,chunkPos,j+1) - end select - enddo - endif - - case ('origin') - if (chunkPos(1) > 6) then - do j = 2,6,2 - select case (IO_lc(IO_stringValue(line,chunkPos,j))) - case('x') - origin(1) = IO_floatValue(line,chunkPos,j+1) - case('y') - origin(2) = IO_floatValue(line,chunkPos,j+1) - case('z') - origin(3) = IO_floatValue(line,chunkPos,j+1) - end select - enddo - endif - - end select - - enddo - -!-------------------------------------------------------------------------------------------------- -! sanity checks - if(any(grid < 1)) & - call IO_error(error_ID = 842, ext_msg='grid (readGeom)') - if(any(geomSize < 0.0_pReal)) & - call IO_error(error_ID = 842, ext_msg='size (readGeom)') - - allocate(material(product(grid)), source = -1) ! too large in case of MPI (shrink later, not very elegant) - -!-------------------------------------------------------------------------------------------------- -! read and interpret content - e = 1 - do while (startPos < len(rawData)) - endPos = startPos + index(rawData(startPos:),IO_EOL) - 1 - if (endPos < startPos) endPos = len(rawData) ! end of file without new line - line = rawData(startPos:endPos) - startPos = endPos + 1 - l = l + 1 - chunkPos = IO_stringPos(trim(line)) - - noCompression: if (chunkPos(1) /= 3) then - c = chunkPos(1) - material(e:e+c-1) = [(IO_intValue(line,chunkPos,i+1), i=0, c-1)] - else noCompression - compression: if (IO_lc(IO_stringValue(line,chunkPos,2)) == 'of') then - c = IO_intValue(line,chunkPos,1) - material(e:e+c-1) = [(IO_intValue(line,chunkPos,3),i = 1,IO_intValue(line,chunkPos,1))] - else if (IO_lc(IO_stringValue(line,chunkPos,2)) == 'to') then compression - c = abs(IO_intValue(line,chunkPos,3) - IO_intValue(line,chunkPos,1)) + 1 - o = merge(+1, -1, IO_intValue(line,chunkPos,3) > IO_intValue(line,chunkPos,1)) - material(e:e+c-1) = [(i, i = IO_intValue(line,chunkPos,1),IO_intValue(line,chunkPos,3),o)] - else compression - c = chunkPos(1) - material(e:e+c-1) = [(IO_intValue(line,chunkPos,i+1), i=0, c-1)] - endif compression - endif noCompression - - e = e+c - end do - - if (e-1 /= product(grid)) call IO_error(error_ID = 843, el=e) - -end subroutine readGeom - - !-------------------------------------------------------------------------------------------------- !> @brief Parse vtk rectilinear grid (.vtr) !> @details https://vtk.org/Wiki/VTK_XML_Formats From 78a246b44ac78276d5586e52c413925ec5a033b4 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 5 Dec 2020 12:46:48 +0100 Subject: [PATCH 009/148] avoid constant reallocation, it is slow for large vtr files --- src/grid/discretization_grid.f90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/grid/discretization_grid.f90 b/src/grid/discretization_grid.f90 index 93fd4d82b..1b3700c14 100644 --- a/src/grid/discretization_grid.f90 +++ b/src/grid/discretization_grid.f90 @@ -404,12 +404,12 @@ subroutine readVTR(grid,geomSize,origin,material) size_deflated = temp(4:) bytes_inflated = base64_to_bytes(base64_str(base64_nChar(headerLen)+1_pI64:)) - allocate(bytes(0)) + allocate(bytes(sum(size_inflated))) e = 0_pI64 do b = 1, nBlock s = e + 1_pI64 e = s + size_deflated(b) - 1_pI64 - bytes = [bytes,zlib_inflate(bytes_inflated(s:e),size_inflated(b))] + bytes(sum(size_inflated(:b-1))+1_pI64:sum(size_inflated(:b))) = zlib_inflate(bytes_inflated(s:e),size_inflated(b)) enddo end function asBytes_compressed From 000de75617e46c9bbf179ed0b67f0c4aabc413d7 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 6 Dec 2020 08:32:45 +0100 Subject: [PATCH 010/148] write orientation as plain array, not derived type --- python/damask/_result.py | 7 +++++-- src/crystallite.f90 | 15 ++++++++------- src/results.f90 | 2 +- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/python/damask/_result.py b/python/damask/_result.py index afeea568f..32970e523 100644 --- a/python/damask/_result.py +++ b/python/damask/_result.py @@ -46,7 +46,7 @@ class Result: self.version_major = f.attrs['DADF5_version_major'] self.version_minor = f.attrs['DADF5_version_minor'] - if self.version_major != 0 or not 7 <= self.version_minor <= 10: + if self.version_major != 0 or not 7 <= self.version_minor <= 11: raise TypeError(f'Unsupported DADF5 version {self.version_major}.{self.version_minor}') self.structured = 'grid' in f['geometry'].attrs.keys() or \ @@ -790,7 +790,10 @@ class Result: lattice = {'fcc':'cF','bcc':'cI','hex':'hP'}[q['meta']['Lattice']] except KeyError: lattice = q['meta']['Lattice'] - o = Orientation(rotation = (rfn.structured_to_unstructured(q['data'])),lattice=lattice) + try: + o = Orientation(rotation = (rfn.structured_to_unstructured(q['data'])),lattice=lattice) + except ValueError: + o = Orientation(rotation = q['data'],lattice=lattice) return { 'data': np.uint8(o.IPF_color(l)*255), diff --git a/src/crystallite.f90 b/src/crystallite.f90 index da349bbcd..273d5397b 100644 --- a/src/crystallite.f90 +++ b/src/crystallite.f90 @@ -734,9 +734,9 @@ end function crystallite_push33ToRef subroutine crystallite_results integer :: p,o - real(pReal), allocatable, dimension(:,:,:) :: selected_tensors - type(rotation), allocatable, dimension(:) :: selected_rotations - character(len=:), allocatable :: group,structureLabel + real(pReal), allocatable, dimension(:,:,:) :: selected_tensors + real(pReal), allocatable, dimension(:,:) :: selected_rotations + character(len=:), allocatable :: group,structureLabel do p=1,size(material_name_phase) group = trim('current/phase')//'/'//trim(material_name_phase(p))//'/mechanics' @@ -794,7 +794,8 @@ subroutine crystallite_results end select selected_rotations = select_rotations(crystallite_orientation,p) call results_writeDataset(group,selected_rotations,output_constituent(p)%label(o),& - 'crystal orientation as quaternion',structureLabel) + 'crystal orientation as quaternion') + call results_addAttribute('Lattice',structureLabel,group//'/'//output_constituent(p)%label(o)) end select enddo enddo @@ -835,10 +836,10 @@ subroutine crystallite_results integer, intent(in) :: instance type(rotation), dimension(:,:,:), intent(in) :: dataset - type(rotation), allocatable, dimension(:) :: select_rotations + real(pReal), allocatable, dimension(:,:) :: select_rotations integer :: e,i,c,j - allocate(select_rotations(count(material_phaseAt==instance)*homogenization_maxNconstituents*discretization_nIPs)) + allocate(select_rotations(4,count(material_phaseAt==instance)*homogenization_maxNconstituents*discretization_nIPs)) j=0 do e = 1, size(material_phaseAt,2) @@ -846,7 +847,7 @@ subroutine crystallite_results do c = 1, size(material_phaseAt,1) !ToDo: this needs to be changed for varying Ngrains if (material_phaseAt(c,e) == instance) then j = j + 1 - select_rotations(j) = dataset(c,i,e) + select_rotations(1:4,j) = dataset(c,i,e)%asQuaternion() endif enddo enddo diff --git a/src/results.f90 b/src/results.f90 index 524a65eaf..ab4e244ba 100644 --- a/src/results.f90 +++ b/src/results.f90 @@ -74,7 +74,7 @@ subroutine results_init(restart) if(.not. restart) then resultsFile = HDF5_openFile(trim(getSolverJobName())//'.hdf5','w',.true.) call results_addAttribute('DADF5_version_major',0) - call results_addAttribute('DADF5_version_minor',10) + call results_addAttribute('DADF5_version_minor',11) call results_addAttribute('DAMASK_version',DAMASKVERSION) call get_command(commandLine) call results_addAttribute('Call',trim(commandLine)) From 52e3fb50bc8e0a6b6b2bc0001248e6b587f1ff29 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 6 Dec 2020 10:20:32 +0100 Subject: [PATCH 011/148] compress. Datasets are chunked along first timension. Chunk size (1MB for real) is probably not optimal --- python/damask/_result.py | 10 ++++++++- src/HDF5_utilities.f90 | 47 ++++++++++++++++++++++++++++++++-------- 2 files changed, 47 insertions(+), 10 deletions(-) diff --git a/python/damask/_result.py b/python/damask/_result.py index 32970e523..6d83c8872 100644 --- a/python/damask/_result.py +++ b/python/damask/_result.py @@ -1132,6 +1132,7 @@ class Result: Arguments parsed to func. """ + chunk_size = 1024**2//8 num_threads = damask.environment.options['DAMASK_NUM_THREADS'] pool = mp.Pool(int(num_threads) if num_threads is not None else None) lock = mp.Manager().Lock() @@ -1155,7 +1156,14 @@ class Result: dataset.attrs['Overwritten'] = 'Yes' if h5py3 else \ 'Yes'.encode() else: - dataset = f[result[0]].create_dataset(result[1]['label'],data=result[1]['data']) + if result[1]['data'].size >= chunk_size*2: + shape = result[1]['data'].shape + chunks = (chunk_size//np.prod(shape[1:]),)+shape[1:] + dataset = f[result[0]].create_dataset(result[1]['label'],data=result[1]['data'], + maxshape=shape,chunks=chunks,compression = 'gzip') + else: + dataset = f[result[0]].create_dataset(result[1]['label'],data=result[1]['data'], + maxshape=result[1]['data'].shape) now = datetime.datetime.now().astimezone() dataset.attrs['Created'] = now.strftime('%Y-%m-%d %H:%M:%S%z') if h5py3 else \ diff --git a/src/HDF5_utilities.f90 b/src/HDF5_utilities.f90 index 47f4243e7..48b98812b 100644 --- a/src/HDF5_utilities.f90 +++ b/src/HDF5_utilities.f90 @@ -1789,7 +1789,7 @@ subroutine initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_ !-------------------------------------------------------------------------------------------------- ! creating a property list for IO and set it to collective call h5pcreate_f(H5P_DATASET_ACCESS_F, aplist_id, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if(hdferr < 0) error stop 'HDF5 error' #ifdef PETSc call h5pset_all_coll_metadata_ops_f(aplist_id, .true., hdferr) if(hdferr < 0) error stop 'HDF5 error' @@ -1815,7 +1815,7 @@ end subroutine initialize_read !-------------------------------------------------------------------------------------------------- subroutine finalize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id) - integer(HID_T), intent(in) :: dset_id, filespace_id, memspace_id, plist_id, aplist_id + integer(HID_T), intent(in) :: dset_id, filespace_id, memspace_id, plist_id, aplist_id integer :: hdferr call h5pclose_f(plist_id, hdferr) @@ -1836,8 +1836,8 @@ end subroutine finalize_read !> @brief initialize HDF5 handles, determines global shape and start for parallel write !-------------------------------------------------------------------------------------------------- subroutine initialize_write(dset_id, filespace_id, memspace_id, plist_id, & - myStart, totalShape, & - loc_id,myShape,datasetName,datatype,parallel) + myStart, totalShape, & + loc_id,myShape,datasetName,datatype,parallel) integer(HID_T), intent(in) :: loc_id !< file or group handle character(len=*), intent(in) :: datasetName !< name of the dataset in the file @@ -1850,10 +1850,10 @@ subroutine initialize_write(dset_id, filespace_id, memspace_id, plist_id, & totalShape !< shape of the dataset (all processes) integer(HID_T), intent(out) :: dset_id, filespace_id, memspace_id, plist_id - integer, dimension(worldsize) :: & - writeSize !< contribution of all processes - integer :: ierr - integer :: hdferr + integer, dimension(worldsize) :: writeSize !< contribution of all processes + integer(HID_T) :: dcpl + integer :: ierr, hdferr + integer(HSIZE_T), parameter :: chunkSize = 1024_HSIZE_T**2/8_HSIZE_T !------------------------------------------------------------------------------------------------- ! creating a property list for transfer properties (is collective when reading in parallel) @@ -1880,6 +1880,17 @@ subroutine initialize_write(dset_id, filespace_id, memspace_id, plist_id, & myStart(ubound(myStart)) = int(sum(writeSize(1:worldrank)),HSIZE_T) totalShape = [myShape(1:ubound(myShape,1)-1),int(sum(writeSize),HSIZE_T)] +!-------------------------------------------------------------------------------------------------- +! compress (and chunk) larger datasets + call h5pcreate_f(H5P_DATASET_CREATE_F, dcpl, hdferr) + if(hdferr < 0) error stop 'HDF5 error' + if(product(totalShape) >= chunkSize*2_HSIZE_T) then + call h5pset_chunk_f(dcpl, size(totalShape), getChunks(totalShape,chunkSize), hdferr) + if(hdferr < 0) error stop 'HDF5 error' + call h5pset_deflate_f(dcpl, 6, hdferr) + if(hdferr < 0) error stop 'HDF5 error' + endif + !-------------------------------------------------------------------------------------------------- ! create dataspace in memory (local shape) and in file (global shape) call h5screate_simple_f(size(myShape), myShape, memspace_id, hdferr, myShape) @@ -1889,11 +1900,14 @@ subroutine initialize_write(dset_id, filespace_id, memspace_id, plist_id, & !-------------------------------------------------------------------------------------------------- ! create dataset in the file and select a hyperslab from it (the portion of the current process) - call h5dcreate_f(loc_id, trim(datasetName), datatype, filespace_id, dset_id, hdferr) + call h5dcreate_f(loc_id, trim(datasetName), datatype, filespace_id, dset_id, hdferr, dcpl) if(hdferr < 0) error stop 'HDF5 error' call h5sselect_hyperslab_f(filespace_id, H5S_SELECT_SET_F, myStart, myShape, hdferr) if(hdferr < 0) error stop 'HDF5 error' + call h5pclose_f(dcpl , hdferr) + if(hdferr < 0) error stop 'HDF5 error' + end subroutine initialize_write @@ -1916,4 +1930,19 @@ subroutine finalize_write(plist_id, dset_id, filespace_id, memspace_id) end subroutine finalize_write + +!-------------------------------------------------------------------------------------------------- +!> @brief determine chunk layout +!-------------------------------------------------------------------------------------------------- +pure function getChunks(totalShape,chunkSize) + + integer(HSIZE_T), dimension(:), intent(in) :: totalShape + integer(HSIZE_T), intent(in) :: chunkSize + integer(HSIZE_T), dimension(size(totalShape)) :: getChunks + + getChunks = [totalShape(1:size(totalShape)-1),& + chunkSize/product(totalShape(1:size(totalShape)-1))] + +end function getChunks + end module HDF5_Utilities From bc4361c2aef4ead0f975c32b37e900ba6e50cd1e Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 6 Dec 2020 13:32:20 +0100 Subject: [PATCH 012/148] use variable string length for array, padding is needed to get same length --- src/HDF5_utilities.f90 | 2 +- src/constitutive_mech.f90 | 4 ++-- src/material.f90 | 18 +++++++++++++----- src/results.f90 | 14 ++++++-------- 4 files changed, 22 insertions(+), 16 deletions(-) diff --git a/src/HDF5_utilities.f90 b/src/HDF5_utilities.f90 index 48b98812b..a2c023ef5 100644 --- a/src/HDF5_utilities.f90 +++ b/src/HDF5_utilities.f90 @@ -175,7 +175,7 @@ end subroutine HDF5_closeFile !-------------------------------------------------------------------------------------------------- integer(HID_T) function HDF5_addGroup(fileHandle,groupName) - integer(HID_T), intent(in) :: fileHandle + integer(HID_T), intent(in) :: fileHandle character(len=*), intent(in) :: groupName integer :: hdferr diff --git a/src/constitutive_mech.f90 b/src/constitutive_mech.f90 index 2a6bf97eb..dc3a935e3 100644 --- a/src/constitutive_mech.f90 +++ b/src/constitutive_mech.f90 @@ -454,10 +454,10 @@ end subroutine constitutive_plastic_LpAndItsTangents module subroutine plastic_results integer :: p - character(len=pStringLen) :: group + character(len=:), allocatable :: group plasticityLoop: do p=1,size(material_name_phase) - group = trim('current/phase')//'/'//trim(material_name_phase(p)) + group = '/current/phase/'//trim(material_name_phase(p)) call results_closeGroup(results_addGroup(group)) group = trim(group)//'/plastic' diff --git a/src/material.f90 b/src/material.f90 index 8679afdc4..94548e052 100644 --- a/src/material.f90 +++ b/src/material.f90 @@ -52,7 +52,7 @@ module material HOMOGENIZATION_RGC_ID end enum - character(len=pStringLen), public, protected, allocatable, dimension(:) :: & + character(len=:), public, protected, allocatable, dimension(:) :: & material_name_phase, & !< name of each phase material_name_homogenization !< name of each homogenization @@ -392,13 +392,21 @@ end subroutine sanityCheck function getKeys(dict) class(tNode), intent(in) :: dict - character(len=pStringLen), dimension(:), allocatable :: getKeys + character(len=:), dimension(:), allocatable :: getKeys + character(len=pStringLen), dimension(:), allocatable :: temp - integer :: i + integer :: i,l - allocate(getKeys(dict%length)) + allocate(temp(dict%length)) + l = 0 do i=1, dict%length - getKeys(i) = dict%getKey(i) + temp(i) = dict%getKey(i) + l = max(len_trim(temp(i)),l) + enddo + + allocate(character(l)::getKeys(dict%length)) + do i=1, dict%length + getKeys(i) = trim(temp(i)) enddo end function getKeys diff --git a/src/results.f90 b/src/results.f90 index ab4e244ba..8b097179b 100644 --- a/src/results.f90 +++ b/src/results.f90 @@ -503,8 +503,8 @@ end subroutine results_writeScalarDataset_rotation subroutine results_mapping_constituent(phaseAt,memberAtLocal,label) integer, dimension(:,:), intent(in) :: phaseAt !< phase section at (constituent,element) - integer, dimension(:,:,:), intent(in) :: memberAtLocal !< phase member at (constituent,IP,element) - character(len=pStringLen), dimension(:), intent(in) :: label !< label of each phase section + integer, dimension(:,:,:), intent(in) :: memberAtLocal !< phase member at (constituent,IP,element) + character(len=*), dimension(:), intent(in) :: label !< label of each phase section integer, dimension(size(memberAtLocal,1),size(memberAtLocal,2),size(memberAtLocal,3)) :: & phaseAtMaterialpoint, & @@ -527,7 +527,6 @@ subroutine results_mapping_constituent(phaseAt,memberAtLocal,label) plist_id, & dt_id - integer(SIZE_T) :: type_size_string, type_size_int integer :: hdferr, ierr, i @@ -571,10 +570,10 @@ subroutine results_mapping_constituent(phaseAt,memberAtLocal,label) if(hdferr < 0) error stop 'HDF5 error' memberOffset = 0 do i=1, size(label) - memberOffset(i,worldrank) = count(phaseAt == i)*size(memberAtLocal,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 writeSize = 0 - writeSize(worldrank) = size(memberAtLocal(1,:,:)) ! total number of points by this process + writeSize(worldrank) = size(memberAtLocal(1,:,:)) ! total number of points by this process !-------------------------------------------------------------------------------------------------- ! MPI settings and communication @@ -658,8 +657,8 @@ end subroutine results_mapping_constituent subroutine results_mapping_homogenization(homogenizationAt,memberAtLocal,label) integer, dimension(:), intent(in) :: homogenizationAt !< homogenization section at (element) - integer, dimension(:,:), intent(in) :: memberAtLocal !< homogenization member at (IP,element) - character(len=pStringLen), dimension(:), intent(in) :: label !< label of each homogenization section + integer, dimension(:,:), intent(in) :: memberAtLocal !< homogenization member at (IP,element) + character(len=*), dimension(:), intent(in) :: label !< label of each homogenization section integer, dimension(size(memberAtLocal,1),size(memberAtLocal,2)) :: & homogenizationAtMaterialpoint, & @@ -682,7 +681,6 @@ subroutine results_mapping_homogenization(homogenizationAt,memberAtLocal,label) plist_id, & dt_id - integer(SIZE_T) :: type_size_string, type_size_int integer :: hdferr, ierr, i From 429b84004d193e3216ab68f1fa77c712260beac8 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 6 Dec 2020 19:57:00 +0100 Subject: [PATCH 013/148] more filters - shuffle: significanlty better compression - Fletcher32: checksum to detect errors computational overhead is very small --- python/damask/_result.py | 7 ++++--- src/HDF5_utilities.f90 | 4 ++++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/python/damask/_result.py b/python/damask/_result.py index 6d83c8872..600469e79 100644 --- a/python/damask/_result.py +++ b/python/damask/_result.py @@ -1160,10 +1160,11 @@ class Result: shape = result[1]['data'].shape chunks = (chunk_size//np.prod(shape[1:]),)+shape[1:] dataset = f[result[0]].create_dataset(result[1]['label'],data=result[1]['data'], - maxshape=shape,chunks=chunks,compression = 'gzip') + maxshape=shape, chunks=chunks, + compression='gzip', compression_opts=6, + shuffle=True,fletcher32=True) else: - dataset = f[result[0]].create_dataset(result[1]['label'],data=result[1]['data'], - maxshape=result[1]['data'].shape) + dataset = f[result[0]].create_dataset(result[1]['label'],data=result[1]['data']) now = datetime.datetime.now().astimezone() dataset.attrs['Created'] = now.strftime('%Y-%m-%d %H:%M:%S%z') if h5py3 else \ diff --git a/src/HDF5_utilities.f90 b/src/HDF5_utilities.f90 index a2c023ef5..f976ad106 100644 --- a/src/HDF5_utilities.f90 +++ b/src/HDF5_utilities.f90 @@ -1887,8 +1887,12 @@ subroutine initialize_write(dset_id, filespace_id, memspace_id, plist_id, & if(product(totalShape) >= chunkSize*2_HSIZE_T) then call h5pset_chunk_f(dcpl, size(totalShape), getChunks(totalShape,chunkSize), hdferr) if(hdferr < 0) error stop 'HDF5 error' + call h5pset_shuffle_f(dcpl, hdferr) + if(hdferr < 0) error stop 'HDF5 error' call h5pset_deflate_f(dcpl, 6, hdferr) if(hdferr < 0) error stop 'HDF5 error' + call h5pset_Fletcher32_f(dcpl,hdferr) + if(hdferr < 0) error stop 'HDF5 error' endif !-------------------------------------------------------------------------------------------------- From 97ee7e6ee59e2a98548707f568284848600165fb Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Mon, 7 Dec 2020 17:26:50 +0100 Subject: [PATCH 014/148] not needed anymore --- src/HDF5_utilities.f90 | 81 -------------------- src/crystallite.f90 | 2 +- src/grid/grid_mech_FEM.f90 | 1 + src/grid/grid_mech_spectral_basic.f90 | 1 + src/grid/grid_mech_spectral_polarisation.f90 | 1 + src/results.f90 | 39 ---------- 6 files changed, 4 insertions(+), 121 deletions(-) diff --git a/src/HDF5_utilities.f90 b/src/HDF5_utilities.f90 index f976ad106..6f45516e6 100644 --- a/src/HDF5_utilities.f90 +++ b/src/HDF5_utilities.f90 @@ -12,7 +12,6 @@ module HDF5_utilities use prec use parallelization - use rotations implicit none public @@ -37,7 +36,6 @@ module HDF5_utilities module procedure HDF5_read_int5 module procedure HDF5_read_int6 module procedure HDF5_read_int7 - end interface HDF5_read !-------------------------------------------------------------------------------------------------- @@ -60,9 +58,6 @@ module HDF5_utilities module procedure HDF5_write_int5 module procedure HDF5_write_int6 module procedure HDF5_write_int7 - - module procedure HDF5_write_rotation - end interface HDF5_write !-------------------------------------------------------------------------------------------------- @@ -1663,82 +1658,6 @@ subroutine HDF5_write_int7(loc_id,dataset,datasetName,parallel) end subroutine HDF5_write_int7 -!-------------------------------------------------------------------------------------------------- -!> @brief writes a scalar orientation dataset -! ToDo: It might be possible to write the dataset as a whole -! ToDo: We could optionally write out other representations (axis angle, euler, ...) -!-------------------------------------------------------------------------------------------------- -subroutine HDF5_write_rotation(loc_id,dataset,datasetName,parallel) - - type(rotation), intent(in), dimension(:) :: dataset !< data written to file - integer(HID_T), intent(in) :: loc_id !< file or group handle - character(len=*), intent(in) :: datasetName !< name of the dataset in the file - logical, intent(in), optional :: parallel - - integer :: hdferr - real(pReal), dimension(4,size(dataset)) :: dataset_asArray - integer(HID_T) :: dset_id, filespace_id, memspace_id, plist_id,dtype_id,w_id,x_id,y_id,z_id - integer(HSIZE_T), dimension(size(shape(dataset))) :: & - myStart, & - myShape, & !< shape of the dataset (this process) - totalShape !< shape of the dataset (all processes) - integer(SIZE_T) :: type_size_real - integer :: i - - do i = 1, size(dataset) - dataset_asArray(1:4,i) = dataset(i)%asQuaternion() - enddo - -!--------------------------------------------------------------------------------------------------- -! determine shape of dataset - myShape = int(shape(dataset),HSIZE_T) - -!--------------------------------------------------------------------------------------------------- -! compound type: name of each quaternion component - call h5tget_size_f(H5T_NATIVE_DOUBLE, type_size_real, hdferr) - - call h5tcreate_f(H5T_COMPOUND_F, type_size_real*4_SIZE_T, dtype_id, hdferr) - call h5tinsert_f(dtype_id, "w", type_size_real*0_SIZE_T, H5T_NATIVE_DOUBLE, hdferr) - call h5tinsert_f(dtype_id, "x", type_size_real*1_SIZE_T, H5T_NATIVE_DOUBLE, hdferr) - call h5tinsert_f(dtype_id, "y", type_size_real*2_SIZE_T, H5T_NATIVE_DOUBLE, hdferr) - call h5tinsert_f(dtype_id, "z", type_size_real*3_SIZE_T, H5T_NATIVE_DOUBLE, hdferr) - - if (present(parallel)) then - call initialize_write(dset_id, filespace_id, memspace_id, plist_id, & - myStart, totalShape, loc_id,myShape,datasetName,dtype_id,parallel) - else - call initialize_write(dset_id, filespace_id, memspace_id, plist_id, & - myStart, totalShape, loc_id,myShape,datasetName,dtype_id,.false.) - endif - - call h5pset_preserve_f(plist_id, .TRUE., hdferr) - - if (product(totalShape) /= 0) then - call h5tcreate_f(H5T_COMPOUND_F, type_size_real, x_id, hdferr) - call h5tinsert_f(x_id, "x", 0_SIZE_T, H5T_NATIVE_DOUBLE, hdferr) - call h5tcreate_f(H5T_COMPOUND_F, type_size_real, w_id, hdferr) - call h5tinsert_f(w_id, "w", 0_SIZE_T, H5T_NATIVE_DOUBLE, hdferr) - call h5tcreate_f(H5T_COMPOUND_F, type_size_real, y_id, hdferr) - call h5tinsert_f(y_id, "y", 0_SIZE_T, H5T_NATIVE_DOUBLE, hdferr) - call h5tcreate_f(H5T_COMPOUND_F, type_size_real, z_id, hdferr) - call h5tinsert_f(z_id, "z", 0_SIZE_T, H5T_NATIVE_DOUBLE, hdferr) - - call h5dwrite_f(dset_id, w_id,dataset_asArray(1,:),int(totalShape,HSIZE_T), hdferr,& - file_space_id = filespace_id, mem_space_id = memspace_id, xfer_prp = plist_id) - call h5dwrite_f(dset_id, x_id,dataset_asArray(2,:),int(totalShape,HSIZE_T), hdferr,& - file_space_id = filespace_id, mem_space_id = memspace_id, xfer_prp = plist_id) - call h5dwrite_f(dset_id, y_id,dataset_asArray(3,:),int(totalShape,HSIZE_T), hdferr,& - file_space_id = filespace_id, mem_space_id = memspace_id, xfer_prp = plist_id) - call h5dwrite_f(dset_id, z_id,dataset_asArray(4,:),int(totalShape,HSIZE_T), hdferr,& - file_space_id = filespace_id, mem_space_id = memspace_id, xfer_prp = plist_id) - if(hdferr < 0) error stop 'HDF5 error' - endif - - call finalize_write(plist_id, dset_id, filespace_id, memspace_id) - -end subroutine HDF5_write_rotation - - !-------------------------------------------------------------------------------------------------- !> @brief initialize HDF5 handles, determines global shape and start for parallel read !-------------------------------------------------------------------------------------------------- diff --git a/src/crystallite.f90 b/src/crystallite.f90 index 273d5397b..66c1df607 100644 --- a/src/crystallite.f90 +++ b/src/crystallite.f90 @@ -794,7 +794,7 @@ subroutine crystallite_results end select selected_rotations = select_rotations(crystallite_orientation,p) call results_writeDataset(group,selected_rotations,output_constituent(p)%label(o),& - 'crystal orientation as quaternion') + 'crystal orientation as quaternion','q_0 ') call results_addAttribute('Lattice',structureLabel,group//'/'//output_constituent(p)%label(o)) end select enddo diff --git a/src/grid/grid_mech_FEM.f90 b/src/grid/grid_mech_FEM.f90 index 7d0830f67..4394b6f81 100644 --- a/src/grid/grid_mech_FEM.f90 +++ b/src/grid/grid_mech_FEM.f90 @@ -16,6 +16,7 @@ module grid_mech_FEM use IO use HDF5_utilities use math + use rotations use spectral_utilities use FEsolving use config diff --git a/src/grid/grid_mech_spectral_basic.f90 b/src/grid/grid_mech_spectral_basic.f90 index 8677a998f..563b25162 100644 --- a/src/grid/grid_mech_spectral_basic.f90 +++ b/src/grid/grid_mech_spectral_basic.f90 @@ -16,6 +16,7 @@ module grid_mech_spectral_basic use IO use HDF5_utilities use math + use rotations use spectral_utilities use FEsolving use config diff --git a/src/grid/grid_mech_spectral_polarisation.f90 b/src/grid/grid_mech_spectral_polarisation.f90 index 053d958ad..03780f2e0 100644 --- a/src/grid/grid_mech_spectral_polarisation.f90 +++ b/src/grid/grid_mech_spectral_polarisation.f90 @@ -16,6 +16,7 @@ module grid_mech_spectral_polarisation use IO use HDF5_utilities use math + use rotations use spectral_utilities use FEsolving use config diff --git a/src/results.f90 b/src/results.f90 index 8b097179b..f15ad4e4a 100644 --- a/src/results.f90 +++ b/src/results.f90 @@ -8,7 +8,6 @@ module results use DAMASK_interface use parallelization use IO - use rotations use HDF5_utilities #ifdef PETSc use PETSC @@ -20,27 +19,21 @@ module results integer(HID_T) :: resultsFile interface results_writeDataset - module procedure results_writeTensorDataset_real module procedure results_writeVectorDataset_real module procedure results_writeScalarDataset_real module procedure results_writeTensorDataset_int module procedure results_writeVectorDataset_int - - module procedure results_writeScalarDataset_rotation - end interface results_writeDataset interface results_addAttribute - module procedure results_addAttribute_real module procedure results_addAttribute_int module procedure results_addAttribute_str module procedure results_addAttribute_int_array module procedure results_addAttribute_real_array - end interface results_addAttribute public :: & @@ -465,38 +458,6 @@ subroutine results_writeTensorDataset_int(group,dataset,label,description,SIunit end subroutine results_writeTensorDataset_int -!-------------------------------------------------------------------------------------------------- -!> @brief stores a scalar dataset in a group -!-------------------------------------------------------------------------------------------------- -subroutine results_writeScalarDataset_rotation(group,dataset,label,description,lattice_structure) - - character(len=*), intent(in) :: label,group,description - character(len=*), intent(in), optional :: lattice_structure - type(rotation), intent(inout), dimension(:) :: dataset - - integer(HID_T) :: groupHandle - - groupHandle = results_openGroup(group) - -#ifdef PETSc - call HDF5_write(groupHandle,dataset,label,.true.) -#else - call HDF5_write(groupHandle,dataset,label,.false.) -#endif - - if (HDF5_objectExists(groupHandle,label)) & - call HDF5_addAttribute(groupHandle,'Description',description,label) - if (HDF5_objectExists(groupHandle,label) .and. present(lattice_structure)) & - call HDF5_addAttribute(groupHandle,'Lattice',lattice_structure,label) - if (HDF5_objectExists(groupHandle,label)) & - call HDF5_addAttribute(groupHandle,'Creator','DAMASK '//DAMASKVERSION,label) - if (HDF5_objectExists(groupHandle,label)) & - call HDF5_addAttribute(groupHandle,'Created',now(),label) - call HDF5_closeGroup(groupHandle) - -end subroutine results_writeScalarDataset_rotation - - !-------------------------------------------------------------------------------------------------- !> @brief adds the unique mapping from spatial position and constituent ID to results !-------------------------------------------------------------------------------------------------- From 78192ef3fd1c7b6398cb9f6aa4efcf11bd4c37a7 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Mon, 7 Dec 2020 17:49:37 +0100 Subject: [PATCH 015/148] clearer naming + better comments, thanks to @p.eisenlohr --- python/damask/_grid.py | 2 +- python/damask/_rotation.py | 2 +- python/damask/grid_filters.py | 30 +++++++++++++++--------------- python/damask/seeds.py | 6 +++--- python/tests/test_grid_filters.py | 20 ++++++++++---------- 5 files changed, 30 insertions(+), 30 deletions(-) diff --git a/python/damask/_grid.py b/python/damask/_grid.py index 2bd5a5f9e..a01c7754f 100644 --- a/python/damask/_grid.py +++ b/python/damask/_grid.py @@ -302,7 +302,7 @@ class Grid: Each unique combintation of values results in one material ID. """ - cells,size,origin = grid_filters.cellSizeOrigin_coordinates0_point(table.get(coordinates)) + cells,size,origin = grid_filters.cellsSizeOrigin_coordinates0_point(table.get(coordinates)) labels_ = [labels] if isinstance(labels,str) else labels unique,unique_inverse = np.unique(np.hstack([table.get(l) for l in labels_]),return_inverse=True,axis=0) diff --git a/python/damask/_rotation.py b/python/damask/_rotation.py index e7bf50bd1..f4d2cf248 100644 --- a/python/damask/_rotation.py +++ b/python/damask/_rotation.py @@ -763,7 +763,7 @@ class Rotation: def _dg(eu,deg): """Return infinitesimal Euler space volume of bin(s).""" phi_sorted = eu[np.lexsort((eu[:,0],eu[:,1],eu[:,2]))] - steps,size,_ = grid_filters.cellSizeOrigin_coordinates0_point(phi_sorted) + steps,size,_ = grid_filters.cellsSizeOrigin_coordinates0_point(phi_sorted) delta = np.radians(size/steps) if deg else size/steps return delta[0]*2.0*np.sin(delta[1]/2.0)*delta[2] / 8.0 / np.pi**2 * np.sin(np.radians(eu[:,1]) if deg else eu[:,1]) diff --git a/python/damask/grid_filters.py b/python/damask/grid_filters.py index 4a1709c75..9e06e075a 100644 --- a/python/damask/grid_filters.py +++ b/python/damask/grid_filters.py @@ -208,7 +208,7 @@ def coordinates_point(size,F,origin=_np.zeros(3)): return coordinates0_point(F.shape[:3],size,origin) + displacement_point(size,F) -def cellSizeOrigin_coordinates0_point(coordinates0,ordered=True): +def cellsSizeOrigin_coordinates0_point(coordinates0,ordered=True): """ Return grid 'DNA', i.e. cells, size, and origin from 1D array of point positions. @@ -218,6 +218,7 @@ def cellSizeOrigin_coordinates0_point(coordinates0,ordered=True): Undeformed cell coordinates. ordered : bool, optional Expect coordinates0 data to be ordered (x fast, z slow). + Defaults to True. """ coords = [_np.unique(coordinates0[:,i]) for i in range(3)] @@ -242,7 +243,7 @@ def cellSizeOrigin_coordinates0_point(coordinates0,ordered=True): if not (_np.allclose(coords[0],_np.linspace(start[0],end[0],cells[0]),atol=atol) and \ _np.allclose(coords[1],_np.linspace(start[1],end[1],cells[1]),atol=atol) and \ _np.allclose(coords[2],_np.linspace(start[2],end[2],cells[2]),atol=atol)): - raise ValueError('Regular cells spacing violated.') + raise ValueError('Regular cell spacing violated.') if ordered and not _np.allclose(coordinates0.reshape(tuple(cells)+(3,),order='F'), coordinates0_point(cells,size,origin),atol=atol): @@ -261,7 +262,7 @@ def coordinates0_check(coordinates0): Array of undeformed cell coordinates. """ - cellSizeOrigin_coordinates0_point(coordinates0,ordered=True) + cellsSizeOrigin_coordinates0_point(coordinates0,ordered=True) def coordinates0_node(cells,size,origin=_np.zeros(3)): @@ -296,7 +297,7 @@ def displacement_fluct_node(size,F): Deformation gradient field. """ - return point_2_node(displacement_fluct_point(size,F)) + return point_to_node(displacement_fluct_point(size,F)) def displacement_avg_node(size,F): @@ -347,7 +348,7 @@ def coordinates_node(size,F,origin=_np.zeros(3)): return coordinates0_node(F.shape[:3],size,origin) + displacement_node(size,F) -def point_2_node(cell_data): +def point_to_node(cell_data): """Interpolate periodic point data to nodal data.""" n = ( cell_data + _np.roll(cell_data,1,(0,1,2)) + _np.roll(cell_data,1,(0,)) + _np.roll(cell_data,1,(1,)) + _np.roll(cell_data,1,(2,)) @@ -365,7 +366,7 @@ def node_2_point(node_data): return c[1:,1:,1:] -def cellSizeOrigin_coordinates0_node(coordinates0,ordered=True): +def cellsSizeOrigin_coordinates0_node(coordinates0,ordered=True): """ Return grid 'DNA', i.e. cells, size, and origin from 1D array of nodal positions. @@ -375,6 +376,7 @@ def cellSizeOrigin_coordinates0_node(coordinates0,ordered=True): Undeformed nodal coordinates. ordered : bool, optional Expect coordinates0 data to be ordered (x fast, z slow). + Defaults to True. """ coords = [_np.unique(coordinates0[:,i]) for i in range(3)] @@ -391,7 +393,7 @@ def cellSizeOrigin_coordinates0_node(coordinates0,ordered=True): if not (_np.allclose(coords[0],_np.linspace(mincorner[0],maxcorner[0],cells[0]+1),atol=atol) and \ _np.allclose(coords[1],_np.linspace(mincorner[1],maxcorner[1],cells[1]+1),atol=atol) and \ _np.allclose(coords[2],_np.linspace(mincorner[2],maxcorner[2],cells[2]+1),atol=atol)): - raise ValueError('Regular cells spacing violated.') + raise ValueError('Regular cell spacing violated.') if ordered and not _np.allclose(coordinates0.reshape(tuple(cells+1)+(3,),order='F'), coordinates0_node(cells,size,origin),atol=atol): @@ -400,9 +402,9 @@ def cellSizeOrigin_coordinates0_node(coordinates0,ordered=True): return (cells,size,origin) -def regrid(size,F,cells_new): +def regrid(size,F,cells): """ - Return mapping from coordinates in deformed configuration to a regular cells. + Return mapping from coordinates in deformed configuration to a regular grid. Parameters ---------- @@ -410,13 +412,11 @@ def regrid(size,F,cells_new): Physical size. F : numpy.ndarray of shape (:,:,:,3,3) Deformation gradient field. - cells_new : numpy.ndarray of shape (3) - New cells for undeformed coordinates. + cells : numpy.ndarray of shape (3) + Cell count along x,y,z of remapping grid. """ - c = coordinates0_point(F.shape[:3],size) \ - + displacement_avg_point(size,F) \ - + displacement_fluct_point(size,F) + c = coordinates_point(size,F) outer = _np.dot(_np.average(F,axis=(0,1,2)),size) for d in range(3): @@ -424,4 +424,4 @@ def regrid(size,F,cells_new): c[_np.where(c[:,:,:,d]>outer[d])] -= outer[d] tree = _spatial.cKDTree(c.reshape(-1,3),boxsize=outer) - return tree.query(coordinates0_point(cells_new,outer))[1].flatten() + return tree.query(coordinates0_point(cells,outer))[1].flatten() diff --git a/python/damask/seeds.py b/python/damask/seeds.py index cf0c0a006..8693e3549 100644 --- a/python/damask/seeds.py +++ b/python/damask/seeds.py @@ -18,8 +18,8 @@ def from_random(size,N_seeds,cells=None,rng_seed=None): N_seeds : int Number of seeds. cells : numpy.ndarray of shape (3), optional. - If given, ensures that all seeds initiate one grain if using a - standard Voronoi tessellation. + If given, ensures that each seed results in a grain for a standard + Voronoi tessellation. rng_seed : {None, int, array_like[ints], SeedSequence, BitGenerator, Generator}, optional A seed to initialize the BitGenerator. Defaults to None. If None, then fresh, unpredictable entropy will be pulled from the OS. @@ -51,7 +51,7 @@ def from_Poisson_disc(size,N_seeds,N_candidates,distance,periodic=True,rng_seed= distance : float Minimum acceptable distance to other seeds. periodic : boolean, optional - Calculate minimum distance for periodically repeated cells. + Calculate minimum distance for periodically repeated grid. rng_seed : {None, int, array_like[ints], SeedSequence, BitGenerator, Generator}, optional A seed to initialize the BitGenerator. Defaults to None. If None, then fresh, unpredictable entropy will be pulled from the OS. diff --git a/python/tests/test_grid_filters.py b/python/tests/test_grid_filters.py index c48ab39d0..d43e94c3c 100644 --- a/python/tests/test_grid_filters.py +++ b/python/tests/test_grid_filters.py @@ -26,12 +26,12 @@ class TestGridFilters: @pytest.mark.parametrize('mode',['point','node']) def test_grid_DNA(self,mode): - """Ensure that cellSizeOrigin_coordinates0_xx is the inverse of coordinates0_xx.""" + """Ensure that cellsSizeOrigin_coordinates0_xx is the inverse of coordinates0_xx.""" cells = np.random.randint(8,32,(3)) size = np.random.random(3) origin = np.random.random(3) coord0 = eval(f'grid_filters.coordinates0_{mode}(cells,size,origin)') # noqa - _cells,_size,_origin = eval(f'grid_filters.cellSizeOrigin_coordinates0_{mode}(coord0.reshape(-1,3,order="F"))') + _cells,_size,_origin = eval(f'grid_filters.cellsSizeOrigin_coordinates0_{mode}(coord0.reshape(-1,3,order="F"))') assert np.allclose(cells,_cells) and np.allclose(size,_size) and np.allclose(origin,_origin) def test_displacement_fluct_equivalence(self): @@ -40,14 +40,14 @@ class TestGridFilters: cells = np.random.randint(8,32,(3)) F = np.random.random(tuple(cells)+(3,3)) assert np.allclose(grid_filters.displacement_fluct_node(size,F), - grid_filters.point_2_node(grid_filters.displacement_fluct_point(size,F))) + grid_filters.point_to_node(grid_filters.displacement_fluct_point(size,F))) def test_interpolation_to_node(self): size = np.random.random(3) cells = np.random.randint(8,32,(3)) F = np.random.random(tuple(cells)+(3,3)) assert np.allclose(grid_filters.coordinates_node(size,F) [1:-1,1:-1,1:-1], - grid_filters.point_2_node(grid_filters.coordinates_point(size,F))[1:-1,1:-1,1:-1]) + grid_filters.point_to_node(grid_filters.coordinates_point(size,F))[1:-1,1:-1,1:-1]) def test_interpolation_to_cell(self): cells = np.random.randint(1,30,(3)) @@ -94,15 +94,15 @@ class TestGridFilters: assert np.allclose(function(size,F),0.0) @pytest.mark.parametrize('function',[grid_filters.coordinates0_check, - grid_filters.cellSizeOrigin_coordinates0_node, - grid_filters.cellSizeOrigin_coordinates0_point]) + grid_filters.cellsSizeOrigin_coordinates0_node, + grid_filters.cellsSizeOrigin_coordinates0_point]) def test_invalid_coordinates(self,function): invalid_coordinates = np.random.random((np.random.randint(12,52),3)) with pytest.raises(ValueError): function(invalid_coordinates) - @pytest.mark.parametrize('function',[grid_filters.cellSizeOrigin_coordinates0_node, - grid_filters.cellSizeOrigin_coordinates0_point]) + @pytest.mark.parametrize('function',[grid_filters.cellsSizeOrigin_coordinates0_node, + grid_filters.cellsSizeOrigin_coordinates0_point]) def test_uneven_spaced_coordinates(self,function): start = np.random.random(3) end = np.random.random(3)*10. + start @@ -116,8 +116,8 @@ class TestGridFilters: @pytest.mark.parametrize('mode',[True,False]) - @pytest.mark.parametrize('function',[grid_filters.cellSizeOrigin_coordinates0_node, - grid_filters.cellSizeOrigin_coordinates0_point]) + @pytest.mark.parametrize('function',[grid_filters.cellsSizeOrigin_coordinates0_node, + grid_filters.cellsSizeOrigin_coordinates0_point]) def test_unordered_coordinates(self,function,mode): origin = np.random.random(3) size = np.random.random(3)*10.+origin From de1708b20affdba30165fc89a8a3d27c985d8296 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Tue, 8 Dec 2020 00:36:41 +0100 Subject: [PATCH 016/148] missing renames + better help --- processing/post/addCompatibilityMismatch.py | 2 +- processing/post/addCurl.py | 2 +- processing/post/addDisplacement.py | 2 +- processing/post/addDivergence.py | 2 +- processing/post/addEuclideanDistance.py | 2 +- processing/post/addGradient.py | 2 +- python/damask/seeds.py | 4 ++-- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/processing/post/addCompatibilityMismatch.py b/processing/post/addCompatibilityMismatch.py index e3219d839..d06eca72e 100755 --- a/processing/post/addCompatibilityMismatch.py +++ b/processing/post/addCompatibilityMismatch.py @@ -71,7 +71,7 @@ for name in filenames: damask.util.report(scriptName,name) table = damask.Table.load(StringIO(''.join(sys.stdin.read())) if name is None else name) - grid,size,origin = damask.grid_filters.cellSizeOrigin_coordinates0_point(table.get(options.pos)) + grid,size,origin = damask.grid_filters.cellsSizeOrigin_coordinates0_point(table.get(options.pos)) F = table.get(options.defgrad).reshape(tuple(grid)+(-1,),order='F').reshape(tuple(grid)+(3,3)) nodes = damask.grid_filters.coordinates_node(size,F) diff --git a/processing/post/addCurl.py b/processing/post/addCurl.py index a6de51445..2e45631e7 100755 --- a/processing/post/addCurl.py +++ b/processing/post/addCurl.py @@ -44,7 +44,7 @@ for name in filenames: damask.util.report(scriptName,name) table = damask.Table.load(StringIO(''.join(sys.stdin.read())) if name is None else name) - grid,size,origin = damask.grid_filters.cellSizeOrigin_coordinates0_point(table.get(options.pos)) + grid,size,origin = damask.grid_filters.cellsSizeOrigin_coordinates0_point(table.get(options.pos)) for label in options.labels: field = table.get(label) diff --git a/processing/post/addDisplacement.py b/processing/post/addDisplacement.py index 3d24d6f0c..6fe577ec7 100755 --- a/processing/post/addDisplacement.py +++ b/processing/post/addDisplacement.py @@ -48,7 +48,7 @@ for name in filenames: damask.util.report(scriptName,name) table = damask.Table.load(StringIO(''.join(sys.stdin.read())) if name is None else name) - grid,size,origin = damask.grid_filters.cellSizeOrigin_coordinates0_point(table.get(options.pos)) + grid,size,origin = damask.grid_filters.cellsSizeOrigin_coordinates0_point(table.get(options.pos)) F = table.get(options.f).reshape(tuple(grid)+(-1,),order='F').reshape(tuple(grid)+(3,3)) if options.nodal: diff --git a/processing/post/addDivergence.py b/processing/post/addDivergence.py index e6bf1caa0..25023e015 100755 --- a/processing/post/addDivergence.py +++ b/processing/post/addDivergence.py @@ -44,7 +44,7 @@ for name in filenames: damask.util.report(scriptName,name) table = damask.Table.load(StringIO(''.join(sys.stdin.read())) if name is None else name) - grid,size,origin = damask.grid_filters.cellSizeOrigin_coordinates0_point(table.get(options.pos)) + grid,size,origin = damask.grid_filters.cellsSizeOrigin_coordinates0_point(table.get(options.pos)) for label in options.labels: field = table.get(label) diff --git a/processing/post/addEuclideanDistance.py b/processing/post/addEuclideanDistance.py index f35f5285a..86eb46ec7 100755 --- a/processing/post/addEuclideanDistance.py +++ b/processing/post/addEuclideanDistance.py @@ -143,7 +143,7 @@ for name in filenames: damask.util.report(scriptName,name) table = damask.Table.load(StringIO(''.join(sys.stdin.read())) if name is None else name) - grid,size,origin = damask.grid_filters.cellSizeOrigin_coordinates0_point(table.get(options.pos)) + grid,size,origin = damask.grid_filters.cellsSizeOrigin_coordinates0_point(table.get(options.pos)) neighborhood = neighborhoods[options.neighborhood] diffToNeighbor = np.empty(list(grid+2)+[len(neighborhood)],'i') diff --git a/processing/post/addGradient.py b/processing/post/addGradient.py index 66b122082..bd6173e6e 100755 --- a/processing/post/addGradient.py +++ b/processing/post/addGradient.py @@ -44,7 +44,7 @@ for name in filenames: damask.util.report(scriptName,name) table = damask.Table.load(StringIO(''.join(sys.stdin.read())) if name is None else name) - grid,size,origin = damask.grid_filters.cellSizeOrigin_coordinates0_point(table.get(options.pos)) + grid,size,origin = damask.grid_filters.cellsSizeOrigin_coordinates0_point(table.get(options.pos)) for label in options.labels: field = table.get(label) diff --git a/python/damask/seeds.py b/python/damask/seeds.py index 8693e3549..9ab148a82 100644 --- a/python/damask/seeds.py +++ b/python/damask/seeds.py @@ -18,8 +18,8 @@ def from_random(size,N_seeds,cells=None,rng_seed=None): N_seeds : int Number of seeds. cells : numpy.ndarray of shape (3), optional. - If given, ensures that each seed results in a grain for a standard - Voronoi tessellation. + If given, ensures that each seed results in a grain when a standard Voronoi + tessellation is performed using the given grid resolution (i.e. size/cells). rng_seed : {None, int, array_like[ints], SeedSequence, BitGenerator, Generator}, optional A seed to initialize the BitGenerator. Defaults to None. If None, then fresh, unpredictable entropy will be pulled from the OS. From 14bb947c36d9a73f4a779f1793a5a0c422ab4aa5 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Tue, 8 Dec 2020 08:15:27 +0100 Subject: [PATCH 017/148] updated documentation --- PRIVATE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PRIVATE b/PRIVATE index a0475c50b..faf1d3700 160000 --- a/PRIVATE +++ b/PRIVATE @@ -1 +1 @@ -Subproject commit a0475c50bfaf6f86f75345754188918a6e9d7134 +Subproject commit faf1d370002e0ac2496bb9b8c869d8ac0defea90 From 98328c94506cdf38ad5e8bd112860096a1408ffd Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Tue, 8 Dec 2020 20:49:04 +0100 Subject: [PATCH 018/148] PRIVATE-master has one extra merge commit --- PRIVATE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PRIVATE b/PRIVATE index faf1d3700..fd99d76d1 160000 --- a/PRIVATE +++ b/PRIVATE @@ -1 +1 @@ -Subproject commit faf1d370002e0ac2496bb9b8c869d8ac0defea90 +Subproject commit fd99d76d1eaa42fd36971ff2f79a59d98534fc27 From 92d21ca8887b37d16c751a95a817375b4781cb37 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Tue, 8 Dec 2020 23:08:40 +0100 Subject: [PATCH 019/148] doxygen documentation does not exist anymore --- .gitlab-ci.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index b7f7f8b0b..062813323 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -353,7 +353,6 @@ backupData: - mkdir $BACKUP/${CI_PIPELINE_ID}_${CI_COMMIT_SHA} - mv $LOCAL_HOME/performance/time.png $BACKUP/${CI_PIPELINE_ID}_${CI_COMMIT_SHA}/ - mv $LOCAL_HOME/performance/memory.png $BACKUP/${CI_PIPELINE_ID}_${CI_COMMIT_SHA}/ - - mv $DAMASKROOT/PRIVATE/documenting/DAMASK_* $BACKUP/${CI_PIPELINE_ID}_${CI_COMMIT_SHA}/ only: - development From 170b9a27d2a464fcb95beae5331790da1d3cd5a0 Mon Sep 17 00:00:00 2001 From: Test User Date: Wed, 9 Dec 2020 01:18:48 +0100 Subject: [PATCH 020/148] [skip ci] updated version information after successful test of v3.0.0-alpha-930-g92d21ca88 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index d04d76024..0a5280b61 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v3.0.0-alpha-920-gccf1a849f +v3.0.0-alpha-930-g92d21ca88 From ed57bfecf201088b9e35f368a8933c6484b04f3e Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Wed, 9 Dec 2020 07:46:16 +0100 Subject: [PATCH 021/148] preparing second 3.0 series alpha release --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 0a5280b61..aa6647e80 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v3.0.0-alpha-930-g92d21ca88 +v3.0.0-alpha2 From 3ad741dbeb5285bf0346d795830e731b7f5a00c3 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Thu, 10 Dec 2020 00:31:58 +0100 Subject: [PATCH 022/148] only used in one function --- src/HDF5_utilities.f90 | 29 +++++++++++++++-------------- src/material.f90 | 2 +- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/src/HDF5_utilities.f90 b/src/HDF5_utilities.f90 index 6f45516e6..88b8d960d 100644 --- a/src/HDF5_utilities.f90 +++ b/src/HDF5_utilities.f90 @@ -1831,6 +1831,21 @@ subroutine initialize_write(dset_id, filespace_id, memspace_id, plist_id, & call h5pclose_f(dcpl , hdferr) if(hdferr < 0) error stop 'HDF5 error' + contains + !------------------------------------------------------------------------------------------------ + !> @brief determine chunk layout + !------------------------------------------------------------------------------------------------ + pure function getChunks(totalShape,chunkSize) + + integer(HSIZE_T), dimension(:), intent(in) :: totalShape + integer(HSIZE_T), intent(in) :: chunkSize + integer(HSIZE_T), dimension(size(totalShape)) :: getChunks + + getChunks = [totalShape(1:size(totalShape)-1),& + chunkSize/product(totalShape(1:size(totalShape)-1))] + + end function getChunks + end subroutine initialize_write @@ -1854,18 +1869,4 @@ subroutine finalize_write(plist_id, dset_id, filespace_id, memspace_id) end subroutine finalize_write -!-------------------------------------------------------------------------------------------------- -!> @brief determine chunk layout -!-------------------------------------------------------------------------------------------------- -pure function getChunks(totalShape,chunkSize) - - integer(HSIZE_T), dimension(:), intent(in) :: totalShape - integer(HSIZE_T), intent(in) :: chunkSize - integer(HSIZE_T), dimension(size(totalShape)) :: getChunks - - getChunks = [totalShape(1:size(totalShape)-1),& - chunkSize/product(totalShape(1:size(totalShape)-1))] - -end function getChunks - end module HDF5_Utilities diff --git a/src/material.f90 b/src/material.f90 index 94548e052..223ea6ed8 100644 --- a/src/material.f90 +++ b/src/material.f90 @@ -403,7 +403,7 @@ function getKeys(dict) temp(i) = dict%getKey(i) l = max(len_trim(temp(i)),l) enddo - + allocate(character(l)::getKeys(dict%length)) do i=1, dict%length getKeys(i) = trim(temp(i)) From f5f2cdba7be1eb6adcd4ae0b2acc55d9c1659afe Mon Sep 17 00:00:00 2001 From: Test User Date: Thu, 10 Dec 2020 19:03:03 +0100 Subject: [PATCH 023/148] [skip ci] updated version information after successful test of v3.0.0-alpha2-8-gbda5a50ff --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index aa6647e80..8a0d1aa23 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v3.0.0-alpha2 +v3.0.0-alpha2-8-gbda5a50ff From 32c2de6b91739b3b2e24e9616d15ed5b1ccbfa90 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Thu, 10 Dec 2020 20:53:11 +0100 Subject: [PATCH 024/148] Ensuring regular spacing for grid --- python/damask/_grid.py | 29 +++++++++++++++++------------ python/tests/test_Grid.py | 13 +++++++++++-- 2 files changed, 28 insertions(+), 14 deletions(-) diff --git a/python/damask/_grid.py b/python/damask/_grid.py index 584a34b51..8380bbc5b 100644 --- a/python/damask/_grid.py +++ b/python/damask/_grid.py @@ -7,7 +7,8 @@ import warnings import numpy as np import pandas as pd import h5py -from scipy import ndimage,spatial +from scipy import ndimage, spatial +from vtk.util.numpy_support import vtk_to_numpy as vtk_to_np from . import environment from . import VTK @@ -50,8 +51,8 @@ class Grid: f'cells a b c: {util.srepr(self.cells, " x ")}', f'size x y z: {util.srepr(self.size, " x ")}', f'origin x y z: {util.srepr(self.origin," ")}', - f'# materials: {mat_N}' + ('' if mat_min == 0 and mat_max+1 == mat_N else - f' (min: {mat_min}, max: {mat_max})') + f'# materials: {mat_N}' + ('' if mat_min == 0 and mat_max+1 == mat_N else + f' (min: {mat_min}, max: {mat_max})') ]) @@ -107,9 +108,9 @@ class Grid: @material.setter def material(self,material): if len(material.shape) != 3: - raise ValueError(f'Invalid material shape {material.shape}.') + raise ValueError(f'invalid material shape {material.shape}') elif material.dtype not in np.sctypes['float'] + np.sctypes['int']: - raise TypeError(f'Invalid material data type {material.dtype}.') + raise TypeError(f'invalid material data type {material.dtype}') else: self._material = np.copy(material) @@ -126,7 +127,7 @@ class Grid: @size.setter def size(self,size): if len(size) != 3 or any(np.array(size) <= 0): - raise ValueError(f'Invalid size {size}.') + raise ValueError(f'invalid size {size}') else: self._size = np.array(size) @@ -138,7 +139,7 @@ class Grid: @origin.setter def origin(self,origin): if len(origin) != 3: - raise ValueError(f'Invalid origin {origin}.') + raise ValueError(f'invalid origin {origin}') else: self._origin = np.array(origin) @@ -181,6 +182,10 @@ class Grid: cells = np.array(v.vtk_data.GetDimensions())-1 bbox = np.array(v.vtk_data.GetBounds()).reshape(3,2).T + for i,c in enumerate([v.vtk_data.GetXCoordinates(),v.vtk_data.GetYCoordinates(),v.vtk_data.GetZCoordinates()]): + if not np.allclose(vtk_to_np(c),np.linspace(bbox[0][i],bbox[1][i],cells[i]+1)): + raise ValueError('regular grid spacing violated') + return Grid(material = v.get('material').reshape(cells,order='F'), size = bbox[1] - bbox[0], origin = bbox[0], @@ -214,7 +219,7 @@ class Grid: except ValueError: header_length,keyword = (-1, 'invalid') if not keyword.startswith('head') or header_length < 3: - raise TypeError('Header length information missing or invalid') + raise TypeError('header length information missing or invalid') comments = [] content = f.readlines() @@ -246,7 +251,7 @@ class Grid: i += len(items) if i != cells.prod(): - raise TypeError(f'Invalid file: expected {cells.prod()} entries, found {i}') + raise TypeError(f'invalid file: expected {cells.prod()} entries, found {i}') if not np.any(np.mod(material,1) != 0.0): # no float present material = material.astype('int') - (1 if material.min() > 0 else 0) @@ -631,7 +636,7 @@ class Grid: """ valid = ['x','y','z'] if not set(directions).issubset(valid): - raise ValueError(f'Invalid direction {set(directions).difference(valid)} specified.') + raise ValueError(f'invalid direction {set(directions).difference(valid)} specified') limits = [None,None] if reflect else [-2,0] mat = self.material.copy() @@ -663,7 +668,7 @@ class Grid: """ valid = ['x','y','z'] if not set(directions).issubset(valid): - raise ValueError(f'Invalid direction {set(directions).difference(valid)} specified.') + raise ValueError(f'invalid direction {set(directions).difference(valid)} specified') mat = np.flip(self.material, (valid.index(d) for d in directions if d in valid)) @@ -916,7 +921,7 @@ class Grid: """ valid = ['x','y','z'] if not set(directions).issubset(valid): - raise ValueError(f'Invalid direction {set(directions).difference(valid)} specified.') + raise ValueError(f'invalid direction {set(directions).difference(valid)} specified') o = [[0, self.cells[0]+1, np.prod(self.cells[:2]+1)+self.cells[0]+1, np.prod(self.cells[:2]+1)], [0, np.prod(self.cells[:2]+1), np.prod(self.cells[:2]+1)+1, 1], diff --git a/python/tests/test_Grid.py b/python/tests/test_Grid.py index 37f011676..48831f917 100644 --- a/python/tests/test_Grid.py +++ b/python/tests/test_Grid.py @@ -1,5 +1,6 @@ import pytest import numpy as np +from vtk.util.numpy_support import numpy_to_vtk as np_to_vtk from damask import VTK from damask import Grid @@ -57,13 +58,21 @@ class TestGrid: new = Grid.load(tmp_path/'default.vtr') assert grid_equal(new,default) - def test_invalid_vtr(self,tmp_path): + def test_invalid_no_material(self,tmp_path): v = VTK.from_rectilinear_grid(np.random.randint(5,10,3)*2,np.random.random(3) + 1.0) v.save(tmp_path/'no_materialpoint.vtr',parallel=False) with pytest.raises(ValueError): Grid.load(tmp_path/'no_materialpoint.vtr') - def test_invalid_material(self): + def test_invalid_spacing(self,tmp_path,default): + default.save(tmp_path/'spacing_ok.vtr') + vtk = VTK.load(tmp_path/'spacing_ok.vtr') + vtk.vtk_data.SetXCoordinates(np_to_vtk(np.sort(np.random.random(default.cells[0])))) + vtk.save(tmp_path/'invalid_spacing.vtr',parallel=False) + with pytest.raises(ValueError): + Grid.load(tmp_path/'invalid_spacing.vtr') + + def test_invalid_material_type(self): with pytest.raises(TypeError): Grid(np.zeros((3,3,3),dtype='complex'),np.ones(3)) From b0c8024e017ee85fd16c648cdf5d995e9f697c28 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Thu, 10 Dec 2020 22:50:23 +0100 Subject: [PATCH 025/148] include updates to release scripts --- PRIVATE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PRIVATE b/PRIVATE index fd99d76d1..08f8aea46 160000 --- a/PRIVATE +++ b/PRIVATE @@ -1 +1 @@ -Subproject commit fd99d76d1eaa42fd36971ff2f79a59d98534fc27 +Subproject commit 08f8aea465a1b5e476b584bcae7927d113919b1d From 2e28bc127acae295a288a4d3ff9f21c596e2326a Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Thu, 10 Dec 2020 23:44:54 +0100 Subject: [PATCH 026/148] better message in case that GUI is not possible --- python/damask/_colormap.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/damask/_colormap.py b/python/damask/_colormap.py index 7deaf4ca4..5a22f049b 100644 --- a/python/damask/_colormap.py +++ b/python/damask/_colormap.py @@ -57,7 +57,7 @@ class Colormap(mpl.colors.ListedColormap): ax1.imshow(np.linspace(0,1,self.N).reshape(1,-1), aspect='auto', cmap=self, interpolation='nearest') plt.show(block = False) - return self.name + return 'Colormap: '+self.name @staticmethod From 8c8dd9ba0aac858b0bbbfeafaf975cac81c8d72d Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Fri, 11 Dec 2020 00:14:59 +0100 Subject: [PATCH 027/148] simplified --- Makefile | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/Makefile b/Makefile index 418d70507..102b954bd 100644 --- a/Makefile +++ b/Makefile @@ -2,27 +2,20 @@ SHELL = /bin/sh ######################################################################################## # Makefile for the installation of DAMASK ######################################################################################## -DAMASK_ROOT = $(shell python3 -c "import os,sys; print(os.path.normpath(os.path.realpath(os.path.expanduser('$(pwd)'))))") .PHONY: all all: grid mesh processing .PHONY: grid -grid: build/grid - @(cd build/grid;make -j${DAMASK_NUM_THREADS} all install;) +grid: + @cmake -B build/grid -DDAMASK_SOLVER=GRID -DCMAKE_INSTALL_PREFIX=${PWD} -DCMAKE_BUILD_TYPE=${BUILD_TYPE} -DBUILDCMD_POST=${BUILDCMD_POST} -DBUILDCMD_PRE=${BUILDCMD_PRE} -DOPTIMIZATION=${OPTIMIZATION} -DOPENMP=${OPENMP} + @cmake --build build/grid --parallel ${DAMASK_NUM_THRADS} + @cmake --install build/grid .PHONY: mesh -mesh: build/mesh - @(cd build/mesh; make -j${DAMASK_NUM_THREADS} all install;) - -.PHONY: build/grid -build/grid: - @mkdir -p build/grid - @(cd build/grid; cmake -Wno-dev -DDAMASK_SOLVER=GRID -DCMAKE_INSTALL_PREFIX=${DAMASK_ROOT} -DCMAKE_BUILD_TYPE=${BUILD_TYPE} -DBUILDCMD_POST=${BUILDCMD_POST} -DBUILDCMD_PRE=${BUILDCMD_PRE} -DOPTIMIZATION=${OPTIMIZATION} -DOPENMP=${OPENMP} ../../;) - -.PHONY: build/mesh -build/mesh: - @mkdir -p build/mesh - @(cd build/mesh; cmake -Wno-dev -DDAMASK_SOLVER=MESH -DCMAKE_INSTALL_PREFIX=${DAMASK_ROOT} -DCMAKE_BUILD_TYPE=${BUILD_TYPE} -DBUILDCMD_POST=${BUILDCMD_POST} -DBUILDCMD_PRE=${BUILDCMD_PRE} -DOPTIMIZATION=${OPTIMIZATION} -DOPENMP=${OPENMP} ../../;) +mesh: + @cmake -B build/mesh -DDAMASK_SOLVER=MESH -DCMAKE_INSTALL_PREFIX=${PWD} -DCMAKE_BUILD_TYPE=${BUILD_TYPE} -DBUILDCMD_POST=${BUILDCMD_POST} -DBUILDCMD_PRE=${BUILDCMD_PRE} -DOPTIMIZATION=${OPTIMIZATION} -DOPENMP=${OPENMP} + @cmake --build build/mesh --parallel ${DAMASK_NUM_THRADS} + @cmake --install build/mesh .PHONY: clean clean: From 6aa600b6873e010ea7829aafa3a09a6cd0927f77 Mon Sep 17 00:00:00 2001 From: Test User Date: Fri, 11 Dec 2020 22:48:03 +0100 Subject: [PATCH 028/148] [skip ci] updated version information after successful test of v3.0.0-alpha2-22-gca71b7379 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 8a0d1aa23..c48c07a45 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v3.0.0-alpha2-8-gbda5a50ff +v3.0.0-alpha2-22-gca71b7379 From 36e4042f0b8ff257e08132a5ee608d890f371c68 Mon Sep 17 00:00:00 2001 From: Philip Eisenlohr Date: Fri, 11 Dec 2020 19:31:19 -0500 Subject: [PATCH 029/148] removed "where" method from Table class --- python/damask/_table.py | 9 --------- python/tests/test_Table.py | 6 ------ 2 files changed, 15 deletions(-) diff --git a/python/damask/_table.py b/python/damask/_table.py index 43a8a3ebf..993a21039 100644 --- a/python/damask/_table.py +++ b/python/damask/_table.py @@ -49,15 +49,6 @@ class Table: """Copy Table.""" return self.__copy__() - def where(self,expression): - """ - Return boolean array corresponding to interpolated expression being True. - - Table columns are addressed as #column# and will have appropriate shapes. - - """ - return eval(re.sub('#(.+?)#',r'self.get("\1")',expression)) - def _label_discrete(self): """Label data individually, e.g. v v v ==> 1_v 2_v 3_v.""" diff --git a/python/tests/test_Table.py b/python/tests/test_Table.py index b1d7684fd..4aac9a940 100644 --- a/python/tests/test_Table.py +++ b/python/tests/test_Table.py @@ -44,12 +44,6 @@ class TestTable: def test_getitem(self,N): assert len(Table(np.random.rand(N,1),{'X':1})[:N//2]) == N//2 - @pytest.mark.parametrize('N',[10,40]) - @pytest.mark.parametrize('limit',[0.1,0.6]) - def test_where(self,N,limit): - r = Table(np.random.rand(N,1),{'X':1}) - assert np.all(r[r.where(f'#X# > {limit}')].get('X') > limit) - @pytest.mark.parametrize('mode',['str','path']) def test_write_read(self,default,tmp_path,mode): default.save(tmp_path/'default.txt') From b1a547279425fbd700e4812a1d7af086c2390140 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 12 Dec 2020 16:30:14 +0100 Subject: [PATCH 030/148] new PETSc (including bugfix for Krylov solver) --- .gitlab-ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 062813323..4e90638c5 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -60,11 +60,11 @@ variables: MPI_Intel: "$IMPI2020Intel19_1" MPI_GNU: "$OMPI4_0GNU10" # ++++++++++++ PETSc ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - PETSc3_14_0IMPI2020Intel19_1: "Libraries/PETSc/3.14.0/Intel-19.1.2-IntelMPI-2019" - PETSc3_14_0OMPI4_0GNU10: "Libraries/PETSc/3.14.0/GNU-10-OpenMPI-4.0.5" + PETSc3_14_2IMPI2020Intel19_1: "Libraries/PETSc/3.14.2/Intel-19.1.2-IntelMPI-2019" + PETSc3_14_2OMPI4_0GNU10: "Libraries/PETSc/3.14.2/GNU-10-OpenMPI-4.0.5" # ------------ Defaults ---------------------------------------------- - PETSc_Intel: "$PETSc3_14_0IMPI2020Intel19_1" - PETSc_GNU: "$PETSc3_14_0OMPI4_0GNU10" + PETSc_Intel: "$PETSc3_14_2IMPI2020Intel19_1" + PETSc_GNU: "$PETSc3_14_2OMPI4_0GNU10" # ++++++++++++ commercial FEM ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ MSC2020: "FEM/MSC/2020" # ------------ Defaults ---------------------------------------------- From 1aaec9c5d20a77fae0c91b5923db5043aa431e79 Mon Sep 17 00:00:00 2001 From: Test User Date: Sat, 12 Dec 2020 22:08:46 +0100 Subject: [PATCH 031/148] [skip ci] updated version information after successful test of v3.0.0-alpha2-26-gaad123f41 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index c48c07a45..5cc60b5dd 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v3.0.0-alpha2-22-gca71b7379 +v3.0.0-alpha2-26-gaad123f41 From 511bc6005379549e14fdea6c992ebcffa3839006 Mon Sep 17 00:00:00 2001 From: Test User Date: Sun, 13 Dec 2020 00:22:50 +0100 Subject: [PATCH 032/148] [skip ci] updated version information after successful test of v3.0.0-alpha2-28-g279ec65f9 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index c48c07a45..d18625598 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v3.0.0-alpha2-22-gca71b7379 +v3.0.0-alpha2-28-g279ec65f9 From 610c233fb68b1a87ef48d98d103ee66e4872799d Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 13 Dec 2020 08:45:08 +0100 Subject: [PATCH 033/148] ensure correct shape --- python/tests/test_Table.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/tests/test_Table.py b/python/tests/test_Table.py index ac5859ecb..8f617aff5 100644 --- a/python/tests/test_Table.py +++ b/python/tests/test_Table.py @@ -22,7 +22,7 @@ class TestTable: @pytest.mark.parametrize('N',[10,40]) def test_len(self,N): - len(Table(np.random.rand(N,3),{'X':3})) == N + assert len(Table(np.random.rand(N,3),{'X':3})) == N def test_get_scalar(self,default): d = default.get('s') From 0e8082860cac913bc5739ff7ce9436295a257546 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 13 Dec 2020 08:45:44 +0100 Subject: [PATCH 034/148] Fortran standard is 2018 will not work for older compilers --- cmake/Compiler-Intel.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/Compiler-Intel.cmake b/cmake/Compiler-Intel.cmake index 719ed885b..5b551069e 100644 --- a/cmake/Compiler-Intel.cmake +++ b/cmake/Compiler-Intel.cmake @@ -20,7 +20,7 @@ endif () # -assume std_mod_proc_name (included in -standard-semantics) causes problems if other modules # (PETSc, HDF5) are not compiled with this option (https://software.intel.com/en-us/forums/intel-fortran-compiler-for-linux-and-mac-os-x/topic/62172) -set (STANDARD_CHECK "-stand f15 -standard-semantics -assume nostd_mod_proc_name") +set (STANDARD_CHECK "-stand f18 -standard-semantics -assume nostd_mod_proc_name") set (LINKER_FLAGS "${LINKER_FLAGS} -shared-intel") # Link against shared Intel libraries instead of static ones From b6d00e2fb836a8324b85da3159a93234415d01ce Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 13 Dec 2020 08:48:04 +0100 Subject: [PATCH 035/148] limit access to public variables to one function not sure if the 'volatile' attribute is needed --- src/DAMASK_interface.f90 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/DAMASK_interface.f90 b/src/DAMASK_interface.f90 index 41f421eb8..f664eb458 100644 --- a/src/DAMASK_interface.f90 +++ b/src/DAMASK_interface.f90 @@ -392,7 +392,7 @@ end function makeRelativePath subroutine catchSIGTERM(signal) bind(C) integer(C_INT), value :: signal - interface_SIGTERM = .true. + call interface_setSIGTERM(.true.) print'(a,i0,a)', ' received signal ',signal, ', set SIGTERM=TRUE' @@ -417,7 +417,7 @@ end subroutine interface_setSIGTERM subroutine catchSIGUSR1(signal) bind(C) integer(C_INT), value :: signal - interface_SIGUSR1 = .true. + call interface_setSIGUSR1(.true.) print'(a,i0,a)', ' received signal ',signal, ', set SIGUSR1=TRUE' @@ -442,7 +442,7 @@ end subroutine interface_setSIGUSR1 subroutine catchSIGUSR2(signal) bind(C) integer(C_INT), value :: signal - interface_SIGUSR2 = .true. + call interface_setSIGUSR2(.true.) print'(a,i0,a)', ' received signal ',signal, ', set SIGUSR2=TRUE' From 189597dbffd4a33bc64b55d4bce9ac49f638aa90 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 13 Dec 2020 08:55:07 +0100 Subject: [PATCH 036/148] drop support for old PETSc versions --- src/DAMASK_interface.f90 | 2 +- src/mesh/mesh_mech_FEM.f90 | 29 +---------------------------- 2 files changed, 2 insertions(+), 29 deletions(-) diff --git a/src/DAMASK_interface.f90 b/src/DAMASK_interface.f90 index f664eb458..d38020225 100644 --- a/src/DAMASK_interface.f90 +++ b/src/DAMASK_interface.f90 @@ -10,7 +10,7 @@ !> and working directory. !-------------------------------------------------------------------------------------------------- #define PETSC_MAJOR 3 -#define PETSC_MINOR_MIN 10 +#define PETSC_MINOR_MIN 12 #define PETSC_MINOR_MAX 14 module DAMASK_interface diff --git a/src/mesh/mesh_mech_FEM.f90 b/src/mesh/mesh_mech_FEM.f90 index 8aa084ac8..a4fa29204 100644 --- a/src/mesh/mesh_mech_FEM.f90 +++ b/src/mesh/mesh_mech_FEM.f90 @@ -147,14 +147,9 @@ subroutine FEM_mech_init(fieldBC) call PetscFESetQuadrature(mechFE,mechQuad,ierr); CHKERRQ(ierr) call PetscFEGetDimension(mechFE,nBasis,ierr); CHKERRQ(ierr) nBasis = nBasis/nc -#if (PETSC_VERSION_MINOR > 10) call DMAddField(mech_mesh,PETSC_NULL_DMLABEL,mechFE,ierr); CHKERRQ(ierr) call DMCreateDS(mech_mesh,ierr); CHKERRQ(ierr) -#endif call DMGetDS(mech_mesh,mechDS,ierr); CHKERRQ(ierr) -#if (PETSC_VERSION_MINOR < 11) - call PetscDSAddDiscretization(mechDS,mechFE,ierr); CHKERRQ(ierr) -#endif call PetscDSGetTotalDimension(mechDS,cellDof,ierr); CHKERRQ(ierr) call PetscFEDestroy(mechFE,ierr); CHKERRQ(ierr) call PetscQuadratureDestroy(mechQuad,ierr); CHKERRQ(ierr) @@ -163,11 +158,7 @@ subroutine FEM_mech_init(fieldBC) ! Setup FEM mech boundary conditions call DMGetLabel(mech_mesh,'Face Sets',BCLabel,ierr); CHKERRQ(ierr) call DMPlexLabelComplete(mech_mesh,BCLabel,ierr); CHKERRQ(ierr) -#if (PETSC_VERSION_MINOR < 12) - call DMGetSection(mech_mesh,section,ierr); CHKERRQ(ierr) -#else call DMGetLocalSection(mech_mesh,section,ierr); CHKERRQ(ierr) -#endif allocate(pnumComp(1), source=dimPlex) allocate(pnumDof(0:dimPlex), source = 0) do topologDim = 0, dimPlex @@ -205,14 +196,8 @@ subroutine FEM_mech_init(fieldBC) endif endif enddo; enddo -#if (PETSC_VERSION_MINOR < 11) - call DMPlexCreateSection(mech_mesh,dimPlex,1,pNumComp,pNumDof, & - numBC,pBcField,pBcComps,pBcPoints,PETSC_NULL_IS,section,ierr) -#else call DMPlexCreateSection(mech_mesh,nolabel,pNumComp,pNumDof, & numBC,pBcField,pBcComps,pBcPoints,PETSC_NULL_IS,section,ierr) - -#endif CHKERRQ(ierr) call DMSetSection(mech_mesh,section,ierr); CHKERRQ(ierr) do faceSet = 1, numBC @@ -267,11 +252,7 @@ subroutine FEM_mech_init(fieldBC) x_scal(basis+1:basis+dimPlex) = pV0 + matmul(transpose(cellJMat),nodalPointsP + 1.0_pReal) enddo px_scal => x_scal -#if (PETSC_VERSION_MINOR < 11) - call DMPlexVecSetClosure(mech_mesh,section,solution_local,cell,px_scal,INSERT_ALL_VALUES,ierr) -#else - call DMPlexVecSetClosure(mech_mesh,section,solution_local,cell,px_scal,5,ierr) ! PETSc: cbee0a90b60958e5c50c89b1e41f4451dfa6008c -#endif + call DMPlexVecSetClosure(mech_mesh,section,solution_local,cell,px_scal,5,ierr) CHKERRQ(ierr) enddo @@ -355,11 +336,7 @@ subroutine FEM_mech_formResidual(dm_local,xx_local,f_local,dummy,ierr) allocate(pinvcellJ(dimPlex**2)) allocate(x_scal(cellDof)) -#if (PETSC_VERSION_MINOR < 12) - call DMGetSection(dm_local,section,ierr); CHKERRQ(ierr) -#else call DMGetLocalSection(dm_local,section,ierr); CHKERRQ(ierr) -#endif call DMGetDS(dm_local,prob,ierr); CHKERRQ(ierr) call PetscDSGetTabulation(prob,0,basisField,basisFieldDer,ierr) CHKERRQ(ierr) @@ -502,11 +479,7 @@ subroutine FEM_mech_formJacobian(dm_local,xx_local,Jac_pre,Jac,dummy,ierr) call MatZeroEntries(Jac,ierr); CHKERRQ(ierr) call DMGetDS(dm_local,prob,ierr); CHKERRQ(ierr) call PetscDSGetTabulation(prob,0,basisField,basisFieldDer,ierr) -#if (PETSC_VERSION_MINOR < 12) - call DMGetSection(dm_local,section,ierr); CHKERRQ(ierr) -#else call DMGetLocalSection(dm_local,section,ierr); CHKERRQ(ierr) -#endif call DMGetGlobalSection(dm_local,gSection,ierr); CHKERRQ(ierr) call DMGetLocalVector(dm_local,x_local,ierr); CHKERRQ(ierr) From 104fa167bdcbdce00b32b31170b5e82a5f1f4e55 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 13 Dec 2020 19:30:34 +0100 Subject: [PATCH 037/148] missing rename: constituent -> phase meaningfull order --- src/material.f90 | 2 +- src/results.f90 | 169 ++++++++++++++++++++++++----------------------- 2 files changed, 87 insertions(+), 84 deletions(-) diff --git a/src/material.f90 b/src/material.f90 index 223ea6ed8..b05979298 100644 --- a/src/material.f90 +++ b/src/material.f90 @@ -176,7 +176,7 @@ subroutine material_init(restart) if (.not. restart) then call results_openJobFile - call results_mapping_constituent(material_phaseAt,material_phaseMemberAt,material_name_phase) + call results_mapping_phase(material_phaseAt,material_phaseMemberAt,material_name_phase) call results_mapping_homogenization(material_homogenizationAt,material_homogenizationMemberAt,material_name_homogenization) call results_closeJobFile endif diff --git a/src/results.f90 b/src/results.f90 index f15ad4e4a..ea9fd62d4 100644 --- a/src/results.f90 +++ b/src/results.f90 @@ -49,7 +49,7 @@ module results results_setLink, & results_addAttribute, & results_removeLink, & - results_mapping_constituent, & + results_mapping_phase, & results_mapping_homogenization contains @@ -461,7 +461,7 @@ end subroutine results_writeTensorDataset_int !-------------------------------------------------------------------------------------------------- !> @brief adds the unique mapping from spatial position and constituent ID to results !-------------------------------------------------------------------------------------------------- -subroutine results_mapping_constituent(phaseAt,memberAtLocal,label) +subroutine results_mapping_phase(phaseAt,memberAtLocal,label) integer, dimension(:,:), intent(in) :: phaseAt !< phase section at (constituent,element) integer, dimension(:,:,:), intent(in) :: memberAtLocal !< phase member at (constituent,IP,element) @@ -491,6 +491,47 @@ subroutine results_mapping_constituent(phaseAt,memberAtLocal,label) integer(SIZE_T) :: type_size_string, type_size_int integer :: hdferr, ierr, i +!-------------------------------------------------------------------------------------------------- +! prepare MPI communication (transparent for non-MPI runs) + call h5pcreate_f(H5P_DATASET_XFER_F, plist_id, hdferr) + if(hdferr < 0) error stop 'HDF5 error' + memberOffset = 0 + do i=1, size(label) + memberOffset(i,worldrank) = count(phaseAt == i)*size(memberAtLocal,2) ! number of points/instance of this process + enddo + writeSize = 0 + writeSize(worldrank) = size(memberAtLocal(1,:,:)) ! total number of points by this process + +!-------------------------------------------------------------------------------------------------- +! MPI settings and communication +#ifdef PETSc + call h5pset_dxpl_mpio_f(plist_id, H5FD_MPIO_COLLECTIVE_F, hdferr) + if(hdferr < 0) error stop 'HDF5 error' + + call MPI_allreduce(MPI_IN_PLACE,writeSize,worldsize,MPI_INT,MPI_SUM,PETSC_COMM_WORLD,ierr) ! get output at each process + if(ierr /= 0) error stop 'MPI error' + + call MPI_allreduce(MPI_IN_PLACE,memberOffset,size(memberOffset),MPI_INT,MPI_SUM,PETSC_COMM_WORLD,ierr)! get offset at each process + if(ierr /= 0) error stop 'MPI error' +#endif + + myShape = int([size(phaseAt,1),writeSize(worldrank)], HSIZE_T) + myOffset = int([0,sum(writeSize(0:worldrank-1))], HSIZE_T) + totalShape = int([size(phaseAt,1),sum(writeSize)], HSIZE_T) + + +!--------------------------------------------------------------------------------------------------- +! expand phaseAt to consider IPs (is not stored per IP) + do i = 1, size(phaseAtMaterialpoint,2) + phaseAtMaterialpoint(:,i,:) = phaseAt + enddo + +!--------------------------------------------------------------------------------------------------- +! renumber member from my process to all processes + do i = 1, size(label) + where(phaseAtMaterialpoint == i) memberAtGlobal = memberAtLocal + sum(memberOffset(i,0:worldrank-1)) -1 ! convert to 0-based + enddo + !--------------------------------------------------------------------------------------------------- ! compound type: name of phase section + position/index within results array call h5tcopy_f(H5T_NATIVE_CHARACTER, dt_id, hdferr) @@ -525,34 +566,6 @@ subroutine results_mapping_constituent(phaseAt,memberAtLocal,label) call h5tclose_f(dt_id, hdferr) if(hdferr < 0) error stop 'HDF5 error' -!-------------------------------------------------------------------------------------------------- -! prepare MPI communication (transparent for non-MPI runs) - call h5pcreate_f(H5P_DATASET_XFER_F, plist_id, hdferr) - if(hdferr < 0) error stop 'HDF5 error' - memberOffset = 0 - do i=1, size(label) - memberOffset(i,worldrank) = count(phaseAt == i)*size(memberAtLocal,2) ! number of points/instance of this process - enddo - writeSize = 0 - writeSize(worldrank) = size(memberAtLocal(1,:,:)) ! total number of points by this process - -!-------------------------------------------------------------------------------------------------- -! MPI settings and communication -#ifdef PETSc - call h5pset_dxpl_mpio_f(plist_id, H5FD_MPIO_COLLECTIVE_F, hdferr) - if(hdferr < 0) error stop 'HDF5 error' - - call MPI_allreduce(MPI_IN_PLACE,writeSize,worldsize,MPI_INT,MPI_SUM,PETSC_COMM_WORLD,ierr) ! get output at each process - if(ierr /= 0) error stop 'MPI error' - - call MPI_allreduce(MPI_IN_PLACE,memberOffset,size(memberOffset),MPI_INT,MPI_SUM,PETSC_COMM_WORLD,ierr)! get offset at each process - if(ierr /= 0) error stop 'MPI error' -#endif - - myShape = int([size(phaseAt,1),writeSize(worldrank)], HSIZE_T) - myOffset = int([0,sum(writeSize(0:worldrank-1))], HSIZE_T) - totalShape = int([size(phaseAt,1),sum(writeSize)], HSIZE_T) - !-------------------------------------------------------------------------------------------------- ! create dataspace in memory (local shape = hyperslab) and in file (global shape) call h5screate_simple_f(2,myShape,memspace_id,hdferr,myShape) @@ -564,18 +577,6 @@ subroutine results_mapping_constituent(phaseAt,memberAtLocal,label) call h5sselect_hyperslab_f(filespace_id, H5S_SELECT_SET_F, myOffset, myShape, hdferr) if(hdferr < 0) error stop 'HDF5 error' -!--------------------------------------------------------------------------------------------------- -! expand phaseAt to consider IPs (is not stored per IP) - do i = 1, size(phaseAtMaterialpoint,2) - phaseAtMaterialpoint(:,i,:) = phaseAt - enddo - -!--------------------------------------------------------------------------------------------------- -! renumber member from my process to all processes - do i = 1, size(label) - where(phaseAtMaterialpoint == i) memberAtGlobal = memberAtLocal + sum(memberOffset(i,0:worldrank-1)) -1 ! convert to 0-based - enddo - !-------------------------------------------------------------------------------------------------- ! write the components of the compound type individually call h5pset_preserve_f(plist_id, .TRUE., hdferr) @@ -609,7 +610,7 @@ subroutine results_mapping_constituent(phaseAt,memberAtLocal,label) if(hdferr < 0) error stop 'HDF5 error' call h5tclose_f(position_id, hdferr) -end subroutine results_mapping_constituent +end subroutine results_mapping_phase !-------------------------------------------------------------------------------------------------- @@ -645,6 +646,48 @@ subroutine results_mapping_homogenization(homogenizationAt,memberAtLocal,label) integer(SIZE_T) :: type_size_string, type_size_int integer :: hdferr, ierr, i + +!-------------------------------------------------------------------------------------------------- +! prepare MPI communication (transparent for non-MPI runs) + call h5pcreate_f(H5P_DATASET_XFER_F, plist_id, hdferr) + if(hdferr < 0) error stop 'HDF5 error' + memberOffset = 0 + do i=1, size(label) + memberOffset(i,worldrank) = count(homogenizationAt == i)*size(memberAtLocal,1) ! number of points/instance of this process + enddo + writeSize = 0 + writeSize(worldrank) = size(memberAtLocal) ! total number of points by this process + +!-------------------------------------------------------------------------------------------------- +! MPI settings and communication +#ifdef PETSc + call h5pset_dxpl_mpio_f(plist_id, H5FD_MPIO_COLLECTIVE_F, hdferr) + if(hdferr < 0) error stop 'HDF5 error' + + call MPI_allreduce(MPI_IN_PLACE,writeSize,worldsize,MPI_INT,MPI_SUM,PETSC_COMM_WORLD,ierr) ! get output at each process + if(ierr /= 0) error stop 'MPI error' + + call MPI_allreduce(MPI_IN_PLACE,memberOffset,size(memberOffset),MPI_INT,MPI_SUM,PETSC_COMM_WORLD,ierr)! get offset at each process + if(ierr /= 0) error stop 'MPI error' +#endif + + myShape = int([writeSize(worldrank)], HSIZE_T) + myOffset = int([sum(writeSize(0:worldrank-1))], HSIZE_T) + totalShape = int([sum(writeSize)], HSIZE_T) + + +!--------------------------------------------------------------------------------------------------- +! expand phaseAt to consider IPs (is not stored per IP) + do i = 1, size(homogenizationAtMaterialpoint,1) + homogenizationAtMaterialpoint(i,:) = homogenizationAt + enddo + +!--------------------------------------------------------------------------------------------------- +! renumber member from my process to all processes + do i = 1, size(label) + where(homogenizationAtMaterialpoint == i) memberAtGlobal = memberAtLocal + sum(memberOffset(i,0:worldrank-1)) - 1 ! convert to 0-based + enddo + !--------------------------------------------------------------------------------------------------- ! compound type: name of phase section + position/index within results array call h5tcopy_f(H5T_NATIVE_CHARACTER, dt_id, hdferr) @@ -679,34 +722,6 @@ subroutine results_mapping_homogenization(homogenizationAt,memberAtLocal,label) call h5tclose_f(dt_id, hdferr) if(hdferr < 0) error stop 'HDF5 error' -!-------------------------------------------------------------------------------------------------- -! prepare MPI communication (transparent for non-MPI runs) - call h5pcreate_f(H5P_DATASET_XFER_F, plist_id, hdferr) - if(hdferr < 0) error stop 'HDF5 error' - memberOffset = 0 - do i=1, size(label) - memberOffset(i,worldrank) = count(homogenizationAt == i)*size(memberAtLocal,1) ! number of points/instance of this process - enddo - writeSize = 0 - writeSize(worldrank) = size(memberAtLocal) ! total number of points by this process - -!-------------------------------------------------------------------------------------------------- -! MPI settings and communication -#ifdef PETSc - call h5pset_dxpl_mpio_f(plist_id, H5FD_MPIO_COLLECTIVE_F, hdferr) - if(hdferr < 0) error stop 'HDF5 error' - - call MPI_allreduce(MPI_IN_PLACE,writeSize,worldsize,MPI_INT,MPI_SUM,PETSC_COMM_WORLD,ierr) ! get output at each process - if(ierr /= 0) error stop 'MPI error' - - call MPI_allreduce(MPI_IN_PLACE,memberOffset,size(memberOffset),MPI_INT,MPI_SUM,PETSC_COMM_WORLD,ierr)! get offset at each process - if(ierr /= 0) error stop 'MPI error' -#endif - - myShape = int([writeSize(worldrank)], HSIZE_T) - myOffset = int([sum(writeSize(0:worldrank-1))], HSIZE_T) - totalShape = int([sum(writeSize)], HSIZE_T) - !-------------------------------------------------------------------------------------------------- ! create dataspace in memory (local shape = hyperslab) and in file (global shape) call h5screate_simple_f(1,myShape,memspace_id,hdferr,myShape) @@ -718,18 +733,6 @@ subroutine results_mapping_homogenization(homogenizationAt,memberAtLocal,label) call h5sselect_hyperslab_f(filespace_id, H5S_SELECT_SET_F, myOffset, myShape, hdferr) if(hdferr < 0) error stop 'HDF5 error' -!--------------------------------------------------------------------------------------------------- -! expand phaseAt to consider IPs (is not stored per IP) - do i = 1, size(homogenizationAtMaterialpoint,1) - homogenizationAtMaterialpoint(i,:) = homogenizationAt - enddo - -!--------------------------------------------------------------------------------------------------- -! renumber member from my process to all processes - do i = 1, size(label) - where(homogenizationAtMaterialpoint == i) memberAtGlobal = memberAtLocal + sum(memberOffset(i,0:worldrank-1)) - 1 ! convert to 0-based - enddo - !-------------------------------------------------------------------------------------------------- ! write the components of the compound type individually call h5pset_preserve_f(plist_id, .TRUE., hdferr) From 8100f3ebfaa78da64f473d721016dc0e84abd8de Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 13 Dec 2020 22:29:36 +0100 Subject: [PATCH 038/148] not required for cmake > 2.4 --- CMakeLists.txt | 2 +- PRIVATE | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index dd2348fd1..d8eb2cbf0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ ######################################################################################## # Compiler options for building DAMASK -cmake_minimum_required (VERSION 3.10.0 FATAL_ERROR) +cmake_minimum_required (VERSION 3.10.0) #--------------------------------------------------------------------------------------- # Find PETSc from system environment diff --git a/PRIVATE b/PRIVATE index 08f8aea46..6b8ba6d84 160000 --- a/PRIVATE +++ b/PRIVATE @@ -1 +1 @@ -Subproject commit 08f8aea465a1b5e476b584bcae7927d113919b1d +Subproject commit 6b8ba6d844b70695233b02eae85f4300315f339d From b95eb6f604dfef0bb08b4d7936f857f635342212 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Mon, 14 Dec 2020 13:01:52 +0100 Subject: [PATCH 039/148] simplified (using pkg-config module of PETSc) might be possible to use pkg-config for FFTW and HDF5 in future --- CMakeLists.txt | 53 ++++++++++++++++---------------------------------- 1 file changed, 17 insertions(+), 36 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d8eb2cbf0..553c42400 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,18 @@ -######################################################################################## -# Compiler options for building DAMASK cmake_minimum_required (VERSION 3.10.0) +include (FindPkgConfig REQUIRED) + +# Dummy project to determine compiler names and version +project (Prerequisites LANGUAGES) +set(ENV{PKG_CONFIG_PATH} "$ENV{PETSC_DIR}/$ENV{PETSC_ARCH}/lib/pkgconfig") +pkg_search_module (PETSC REQUIRED PETSc>3.12.0) +pkg_get_variable (CMAKE_Fortran_COMPILER PETSc fcompiler) +pkg_get_variable (CMAKE_C_COMPILER PETSc ccompiler) + +find_program (CAT_EXECUTABLE NAMES cat) +execute_process (COMMAND ${CAT_EXECUTABLE} ${PROJECT_SOURCE_DIR}/VERSION + RESULT_VARIABLE DAMASK_VERSION_RETURN + OUTPUT_VARIABLE DAMASK_VERSION + OUTPUT_STRIP_TRAILING_WHITESPACE) #--------------------------------------------------------------------------------------- # Find PETSc from system environment @@ -28,17 +40,11 @@ include ${petsc_conf_rules} include ${petsc_conf_variables} INCLUDE_DIRS := \${PETSC_FC_INCLUDES} LIBRARIES := \${PETSC_WITH_EXTERNAL_LIB} -COMPILERF := \${FC} -COMPILERC := \${CC} LINKERNAME := \${FLINKER} includes: \t@echo \${INCLUDE_DIRS} extlibs: \t@echo \${LIBRARIES} -compilerf: -\t@echo \${COMPILERF} -compilerc: -\t@echo \${COMPILERC} linker: \t@echo \${LINKERNAME} ") @@ -57,16 +63,6 @@ execute_process (COMMAND ${MAKE_EXECUTABLE} --no-print-directory -f ${petsc_conf RESULT_VARIABLE PETSC_EXTERNAL_LIB_RETURN OUTPUT_VARIABLE petsc_external_lib OUTPUT_STRIP_TRAILING_WHITESPACE) -# PETSc specified fortran compiler -execute_process (COMMAND ${MAKE_EXECUTABLE} --no-print-directory -f ${petsc_config_makefile} "compilerf" - RESULT_VARIABLE PETSC_MPIFC_RETURN - OUTPUT_VARIABLE PETSC_MPIFC - OUTPUT_STRIP_TRAILING_WHITESPACE) -# PETSc specified C compiler -execute_process (COMMAND ${MAKE_EXECUTABLE} --no-print-directory -f ${petsc_config_makefile} "compilerc" - RESULT_VARIABLE PETSC_MPICC_RETURN - OUTPUT_VARIABLE PETSC_MPICC - OUTPUT_STRIP_TRAILING_WHITESPACE) # PETSc specified linker (Fortran compiler + PETSc linking flags) execute_process (COMMAND ${MAKE_EXECUTABLE} --no-print-directory -f ${petsc_config_makefile} "linker" RESULT_VARIABLE PETSC_LINKER_RETURN @@ -91,13 +87,6 @@ message ("Found PETSC_DIR:\n${PETSC_DIR}\n" ) message ("Found PETSC_INCLUDES:\n${PETSC_INCLUDES}\n" ) message ("Found PETSC_EXTERNAL_LIB:\n${PETSC_EXTERNAL_LIB}\n") message ("Found PETSC_LINKER:\n${PETSC_LINKER}\n" ) -message ("Found MPI Fortran Compiler:\n${PETSC_MPIFC}\n" ) -message ("Found MPI C Compiler:\n${PETSC_MPICC}\n" ) - -# set compiler commands to match PETSc (needs to be done before defining the project) -# https://cmake.org/Wiki/CMake_FAQ#How_do_I_use_a_different_compiler.3F -set (CMAKE_Fortran_COMPILER "${PETSC_MPIFC}") -set (CMAKE_C_COMPILER "${PETSC_MPICC}") #--------------------------------------------------------------------------------------- # Now start to care about DAMASK @@ -115,7 +104,8 @@ elseif (DAMASK_SOLVER STREQUAL "mesh") else () message (FATAL_ERROR "Build target (DAMASK_SOLVER) is not defined") endif () -list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake) +add_definitions (-DDAMASKVERSION="${DAMASK_VERSION}") +add_definitions (-DPETSc) if (CMAKE_BUILD_TYPE STREQUAL "") set (CMAKE_BUILD_TYPE "RELEASE") @@ -153,17 +143,8 @@ if (CMAKE_BUILD_TYPE STREQUAL "SYNTAXONLY") set (BUILDCMD_POST "${BUILDCMD_POST} -fsyntax-only") endif () -# Parse DAMASK version from VERSION file -find_program (CAT_EXECUTABLE NAMES cat) -execute_process (COMMAND ${CAT_EXECUTABLE} ${PROJECT_SOURCE_DIR}/VERSION - RESULT_VARIABLE DAMASK_VERSION_RETURN - OUTPUT_VARIABLE DAMASK_V - OUTPUT_STRIP_TRAILING_WHITESPACE) -add_definitions (-DDAMASKVERSION="${DAMASK_V}") - -# definition of other macros -add_definitions (-DPETSc) +list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake) if (CMAKE_Fortran_COMPILER_ID STREQUAL "Intel") include (Compiler-Intel) elseif(CMAKE_Fortran_COMPILER_ID STREQUAL "GNU") From 168d6e85e1ddd948d53b7825470b9ba1f7f7bd59 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Mon, 14 Dec 2020 17:44:31 +0100 Subject: [PATCH 040/148] simplified --- CMakeLists.txt | 21 +++++---------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 553c42400..8db6dd0c0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -40,13 +40,10 @@ include ${petsc_conf_rules} include ${petsc_conf_variables} INCLUDE_DIRS := \${PETSC_FC_INCLUDES} LIBRARIES := \${PETSC_WITH_EXTERNAL_LIB} -LINKERNAME := \${FLINKER} includes: \t@echo \${INCLUDE_DIRS} extlibs: \t@echo \${LIBRARIES} -linker: -\t@echo \${LINKERNAME} ") # CMake will execute each target in the ${petsc_config_makefile} @@ -58,16 +55,10 @@ execute_process (COMMAND ${MAKE_EXECUTABLE} --no-print-directory -f ${petsc_conf OUTPUT_VARIABLE petsc_includes OUTPUT_STRIP_TRAILING_WHITESPACE) # Find the PETSc external linking directory settings -# required for final linking, must be appended after the executable execute_process (COMMAND ${MAKE_EXECUTABLE} --no-print-directory -f ${petsc_config_makefile} "extlibs" RESULT_VARIABLE PETSC_EXTERNAL_LIB_RETURN OUTPUT_VARIABLE petsc_external_lib OUTPUT_STRIP_TRAILING_WHITESPACE) -# PETSc specified linker (Fortran compiler + PETSc linking flags) -execute_process (COMMAND ${MAKE_EXECUTABLE} --no-print-directory -f ${petsc_config_makefile} "linker" - RESULT_VARIABLE PETSC_LINKER_RETURN - OUTPUT_VARIABLE PETSC_LINKER - OUTPUT_STRIP_TRAILING_WHITESPACE) # Remove temporary makefile, no need to keep it anymore. file (REMOVE_RECURSE ${TEMPDIR}) @@ -86,7 +77,6 @@ endforeach (exlib) message ("Found PETSC_DIR:\n${PETSC_DIR}\n" ) message ("Found PETSC_INCLUDES:\n${PETSC_INCLUDES}\n" ) message ("Found PETSC_EXTERNAL_LIB:\n${PETSC_EXTERNAL_LIB}\n") -message ("Found PETSC_LINKER:\n${PETSC_LINKER}\n" ) #--------------------------------------------------------------------------------------- # Now start to care about DAMASK @@ -94,19 +84,19 @@ message ("Found PETSC_LINKER:\n${PETSC_LINKER}\n" ) # DAMASK solver defines project to build string(TOLOWER ${DAMASK_SOLVER} DAMASK_SOLVER) if (DAMASK_SOLVER STREQUAL "grid") - project (damask-grid Fortran C) + project (damask-grid HOMEPAGE_URL https://damask.mpie.de LANGUAGES Fortran C) add_definitions (-DGrid) - message ("Building Grid Solver\n") elseif (DAMASK_SOLVER STREQUAL "mesh") - project (damask-mesh Fortran C) + project (damask-mesh HOMEPAGE_URL https://damask.mpie.de LANGUAGES Fortran C) add_definitions (-DMesh) - message ("Building Mesh Solver\n") else () message (FATAL_ERROR "Build target (DAMASK_SOLVER) is not defined") endif () add_definitions (-DDAMASKVERSION="${DAMASK_VERSION}") add_definitions (-DPETSc) +message ("\nBuilding ${CMAKE_PROJECT_NAME}\n") + if (CMAKE_BUILD_TYPE STREQUAL "") set (CMAKE_BUILD_TYPE "RELEASE") endif () @@ -155,9 +145,8 @@ else () message (FATAL_ERROR "Compiler type (CMAKE_Fortran_COMPILER_ID) not recognized") endif () - set (CMAKE_Fortran_FLAGS_${CMAKE_BUILD_TYPE} "${BUILDCMD_PRE} ${OPENMP_FLAGS} ${STANDARD_CHECK} ${OPTIMIZATION_FLAGS} ${COMPILE_FLAGS} ${PRECISION_FLAGS}") -set (CMAKE_Fortran_LINK_EXECUTABLE "${BUILDCMD_PRE} ${PETSC_LINKER} ${OPENMP_FLAGS} ${OPTIMIZATION_FLAGS} ${LINKER_FLAGS}") +set (CMAKE_Fortran_LINK_EXECUTABLE "${BUILDCMD_PRE} ${CMAKE_Fortran_COMPILER} ${OPENMP_FLAGS} ${OPTIMIZATION_FLAGS} ${LINKER_FLAGS}") if (CMAKE_BUILD_TYPE STREQUAL "DEBUG") set (CMAKE_Fortran_FLAGS_${CMAKE_BUILD_TYPE} "${CMAKE_Fortran_FLAGS_${CMAKE_BUILD_TYPE}} ${DEBUG_FLAGS}") From 8fbadef52476d4e523acf2689e5ebdba396876df Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Mon, 14 Dec 2020 22:37:14 +0100 Subject: [PATCH 041/148] print instead of write --- src/grid/grid_damage_spectral.f90 | 3 +-- src/grid/grid_mech_FEM.f90 | 9 ++++---- src/grid/grid_mech_spectral_basic.f90 | 9 ++++---- src/grid/grid_mech_spectral_polarisation.f90 | 9 ++++---- src/grid/grid_thermal_spectral.f90 | 3 +-- src/grid/spectral_utilities.f90 | 23 +++++++++----------- src/mesh/mesh_mech_FEM.f90 | 4 ++-- 7 files changed, 26 insertions(+), 34 deletions(-) diff --git a/src/grid/grid_damage_spectral.f90 b/src/grid/grid_damage_spectral.f90 index 4c014f3c0..79437945b 100644 --- a/src/grid/grid_damage_spectral.f90 +++ b/src/grid/grid_damage_spectral.f90 @@ -203,8 +203,7 @@ function grid_damage_spectral_solution(timeinc) result(solution) call VecMax(solution_vec,devNull,phi_max,ierr); CHKERRQ(ierr) if (solution%converged) & print'(/,a)', ' ... nonlocal damage converged .....................................' - write(IO_STDOUT,'(/,a,f8.6,2x,f8.6,2x,e11.4,/)',advance='no') ' Minimum|Maximum|Delta Damage = ',& - phi_min, phi_max, stagNorm + print'(/,a,f8.6,2x,f8.6,2x,e11.4)', ' Minimum|Maximum|Delta Damage = ', phi_min, phi_max, stagNorm print'(/,a)', ' ===========================================================================' flush(IO_STDOUT) diff --git a/src/grid/grid_mech_FEM.f90 b/src/grid/grid_mech_FEM.f90 index 4394b6f81..8874b0cf3 100644 --- a/src/grid/grid_mech_FEM.f90 +++ b/src/grid/grid_mech_FEM.f90 @@ -510,11 +510,10 @@ subroutine formResidual(da_local,x_local, & newIteration: if (totalIter <= PETScIter) then totalIter = totalIter + 1 print'(1x,a,3(a,i0))', trim(incInfo), ' @ Iteration ', num%itmin, '≤',totalIter+1, '≤', num%itmax - if (debugRotation) & - write(IO_STDOUT,'(/,a,/,3(3(f12.7,1x)/))',advance='no') & - ' deformation gradient aim (lab) =', transpose(params%rotation_BC%rotate(F_aim,active=.true.)) - write(IO_STDOUT,'(/,a,/,3(3(f12.7,1x)/))',advance='no') & - ' deformation gradient aim =', transpose(F_aim) + if (debugRotation) print'(/,a,/,2(3(f12.7,1x)/),3(f12.7,1x))', & + ' deformation gradient aim (lab) =', transpose(params%rotation_BC%rotate(F_aim,active=.true.)) + print'(/,a,/,2(3(f12.7,1x)/),3(f12.7,1x))', & + ' deformation gradient aim =', transpose(F_aim) flush(IO_STDOUT) endif newIteration diff --git a/src/grid/grid_mech_spectral_basic.f90 b/src/grid/grid_mech_spectral_basic.f90 index 563b25162..05986f32e 100644 --- a/src/grid/grid_mech_spectral_basic.f90 +++ b/src/grid/grid_mech_spectral_basic.f90 @@ -472,11 +472,10 @@ subroutine formResidual(in, F, & newIteration: if (totalIter <= PETScIter) then totalIter = totalIter + 1 print'(1x,a,3(a,i0))', trim(incInfo), ' @ Iteration ', num%itmin, '≤',totalIter, '≤', num%itmax - if (debugRotation) & - write(IO_STDOUT,'(/,a,/,3(3(f12.7,1x)/))',advance='no') & - ' deformation gradient aim (lab) =', transpose(params%rotation_BC%rotate(F_aim,active=.true.)) - write(IO_STDOUT,'(/,a,/,3(3(f12.7,1x)/))',advance='no') & - ' deformation gradient aim =', transpose(F_aim) + if (debugRotation) print'(/,a,/,2(3(f12.7,1x)/),3(f12.7,1x))', & + ' deformation gradient aim (lab) =', transpose(params%rotation_BC%rotate(F_aim,active=.true.)) + print'(/,a,/,2(3(f12.7,1x)/),3(f12.7,1x))', & + ' deformation gradient aim =', transpose(F_aim) flush(IO_STDOUT) endif newIteration diff --git a/src/grid/grid_mech_spectral_polarisation.f90 b/src/grid/grid_mech_spectral_polarisation.f90 index 03780f2e0..832441a4c 100644 --- a/src/grid/grid_mech_spectral_polarisation.f90 +++ b/src/grid/grid_mech_spectral_polarisation.f90 @@ -555,11 +555,10 @@ subroutine formResidual(in, FandF_tau, & newIteration: if (totalIter <= PETScIter) then totalIter = totalIter + 1 print'(1x,a,3(a,i0))', trim(incInfo), ' @ Iteration ', num%itmin, '≤',totalIter, '≤', num%itmax - if(debugRotation) & - write(IO_STDOUT,'(/,a,/,3(3(f12.7,1x)/))',advance='no') & - ' deformation gradient aim (lab) =', transpose(params%rotation_BC%rotate(F_aim,active=.true.)) - write(IO_STDOUT,'(/,a,/,3(3(f12.7,1x)/))',advance='no') & - ' deformation gradient aim =', transpose(F_aim) + if (debugRotation) print'(/,a,/,2(3(f12.7,1x)/),3(f12.7,1x))', & + ' deformation gradient aim (lab) =', transpose(params%rotation_BC%rotate(F_aim,active=.true.)) + print'(/,a,/,2(3(f12.7,1x)/),3(f12.7,1x))', & + ' deformation gradient aim =', transpose(F_aim) flush(IO_STDOUT) endif newIteration diff --git a/src/grid/grid_thermal_spectral.f90 b/src/grid/grid_thermal_spectral.f90 index 68a1c5ed1..f5d1a33bc 100644 --- a/src/grid/grid_thermal_spectral.f90 +++ b/src/grid/grid_thermal_spectral.f90 @@ -197,8 +197,7 @@ function grid_thermal_spectral_solution(timeinc) result(solution) call VecMax(solution_vec,devNull,T_max,ierr); CHKERRQ(ierr) if (solution%converged) & print'(/,a)', ' ... thermal conduction converged ..................................' - write(IO_STDOUT,'(/,a,f8.4,2x,f8.4,2x,f8.4,/)',advance='no') ' Minimum|Maximum|Delta Temperature / K = ',& - T_min, T_max, stagNorm + print'(/,a,f8.4,2x,f8.4,2x,f8.4)', ' Minimum|Maximum|Delta Temperature / K = ', T_min, T_max, stagNorm print'(/,a)', ' ===========================================================================' flush(IO_STDOUT) diff --git a/src/grid/spectral_utilities.f90 b/src/grid/spectral_utilities.f90 index 1e1608d7c..27fe7fd6e 100644 --- a/src/grid/spectral_utilities.f90 +++ b/src/grid/spectral_utilities.f90 @@ -688,8 +688,8 @@ function utilities_maskedCompliance(rot_BC,mask_stress,C) if(debugGeneral) then print'(/,a)', ' ... updating masked compliance ............................................' - write(IO_STDOUT,'(/,a,/,9(9(2x,f12.7,1x)/))',advance='no') ' Stiffness C (load) / GPa =',& - transpose(temp99_Real)*1.0e-9_pReal + print'(/,a,/,8(9(2x,f12.7,1x)/),9(2x,f12.7,1x))', & + ' Stiffness C (load) / GPa =', transpose(temp99_Real)*1.0e-9_pReal flush(IO_STDOUT) endif @@ -709,9 +709,8 @@ function utilities_maskedCompliance(rot_BC,mask_stress,C) if (debugGeneral .or. errmatinv) then write(formatString, '(i2)') size_reduced formatString = '(/,a,/,'//trim(formatString)//'('//trim(formatString)//'(2x,es9.2,1x)/))' - write(IO_STDOUT,trim(formatString),advance='no') ' C * S (load) ', & - transpose(matmul(c_reduced,s_reduced)) - write(IO_STDOUT,trim(formatString),advance='no') ' S (load) ', transpose(s_reduced) + print trim(formatString), ' C * S (load) ', transpose(matmul(c_reduced,s_reduced)) + print trim(formatString), ' S (load) ', transpose(s_reduced) if(errmatinv) error stop 'matrix inversion error' endif temp99_real = reshape(unpack(reshape(s_reduced,[size_reduced**2]),reshape(mask,[81]),0.0_pReal),[9,9]) @@ -722,7 +721,7 @@ function utilities_maskedCompliance(rot_BC,mask_stress,C) utilities_maskedCompliance = math_99to3333(temp99_Real) if(debugGeneral) then - write(IO_STDOUT,'(/,a,/,9(9(2x,f10.5,1x)/),/)',advance='no') & + print'(/,a,/,9(9(2x,f10.5,1x)/),9(2x,f10.5,1x))', & ' Masked Compliance (load) * GPa =', transpose(temp99_Real)*1.0e9_pReal flush(IO_STDOUT) endif @@ -818,13 +817,11 @@ subroutine utilities_constitutiveResponse(P,P_av,C_volAvg,C_minmaxAvg,& P = reshape(homogenization_P, [3,3,grid(1),grid(2),grid3]) 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) - if (debugRotation) & - write(IO_STDOUT,'(/,a,/,3(3(2x,f12.4,1x)/))',advance='no') ' Piola--Kirchhoff stress (lab) / MPa =',& - transpose(P_av)*1.e-6_pReal - if(present(rotation_BC)) & - P_av = rotation_BC%rotate(P_av) - write(IO_STDOUT,'(/,a,/,3(3(2x,f12.4,1x)/))',advance='no') ' Piola--Kirchhoff stress / MPa =',& - transpose(P_av)*1.e-6_pReal + if (debugRotation) print'(/,a,/,2(3(2x,f12.4,1x)/),3(2x,f12.4,1x))', & + ' Piola--Kirchhoff stress (lab) / MPa =', transpose(P_av)*1.e-6_pReal + if(present(rotation_BC)) P_av = rotation_BC%rotate(P_av) + print'(/,a,/,2(3(2x,f12.4,1x)/),3(2x,f12.4,1x))', & + ' Piola--Kirchhoff stress / MPa =', transpose(P_av)*1.e-6_pReal flush(IO_STDOUT) dPdF_max = 0.0_pReal diff --git a/src/mesh/mesh_mech_FEM.f90 b/src/mesh/mesh_mech_FEM.f90 index a4fa29204..14ce1f38f 100644 --- a/src/mesh/mesh_mech_FEM.f90 +++ b/src/mesh/mesh_mech_FEM.f90 @@ -659,8 +659,8 @@ subroutine FEM_mech_converged(snes_local,PETScIter,xnorm,snorm,fnorm,reason,dumm print'(/,1x,a,a,i0,a,i0,f0.3)', trim(incInfo), & ' @ Iteration ',PETScIter,' mechanical residual norm = ', & int(fnorm/divTol),fnorm/divTol-int(fnorm/divTol) - write(IO_STDOUT,'(/,a,/,3(3(2x,f12.4,1x)/))',advance='no') ' Piola--Kirchhoff stress / MPa =',& - transpose(P_av)*1.e-6_pReal + print'(/,a,/,2(3(2x,f12.4,1x)/),3(2x,f12.4,1x))', & + ' Piola--Kirchhoff stress / MPa =',transpose(P_av)*1.e-6_pReal flush(IO_STDOUT) end subroutine FEM_mech_converged From 2dd520b4a289a437f37f396fcf1f529688743948 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Tue, 15 Dec 2020 08:06:50 +0100 Subject: [PATCH 042/148] P_aim should be independent from P_av P_av is not defined after restart or cutback. Restart with change of load case is probably still an issue --- PRIVATE | 2 +- python/damask/grid_filters.py | 4 +- src/grid/DAMASK_grid.f90 | 111 +++++++++-------- src/grid/grid_mech_FEM.f90 | 123 +++++++++---------- src/grid/grid_mech_spectral_basic.f90 | 97 ++++++++------- src/grid/grid_mech_spectral_polarisation.f90 | 107 ++++++++-------- src/grid/spectral_utilities.f90 | 2 +- src/mesh/mesh_mech_FEM.f90 | 2 - 8 files changed, 224 insertions(+), 224 deletions(-) diff --git a/PRIVATE b/PRIVATE index 08f8aea46..de65e1df5 160000 --- a/PRIVATE +++ b/PRIVATE @@ -1 +1 @@ -Subproject commit 08f8aea465a1b5e476b584bcae7927d113919b1d +Subproject commit de65e1df5a76362de93667e9820dbf330b56f96d diff --git a/python/damask/grid_filters.py b/python/damask/grid_filters.py index 9e06e075a..ee929b3bf 100644 --- a/python/damask/grid_filters.py +++ b/python/damask/grid_filters.py @@ -234,7 +234,7 @@ def cellsSizeOrigin_coordinates0_point(coordinates0,ordered=True): origin[_np.where(cells==1)] = 0.0 if cells.prod() != len(coordinates0): - raise ValueError('Data count {len(coordinates0)} does not match cells {cells}.') + raise ValueError(f'Data count {len(coordinates0)} does not match cells {cells}.') start = origin + delta*.5 end = origin - delta*.5 + size @@ -387,7 +387,7 @@ def cellsSizeOrigin_coordinates0_node(coordinates0,ordered=True): origin = mincorner if (cells+1).prod() != len(coordinates0): - raise ValueError('Data count {len(coordinates0)} does not match cells {cells}.') + raise ValueError(f'Data count {len(coordinates0)} does not match cells {cells}.') atol = _np.max(size)*5e-2 if not (_np.allclose(coords[0],_np.linspace(mincorner[0],maxcorner[0],cells[0]+1),atol=atol) and \ diff --git a/src/grid/DAMASK_grid.f90 b/src/grid/DAMASK_grid.f90 index a8271cffc..514443dbb 100644 --- a/src/grid/DAMASK_grid.f90 +++ b/src/grid/DAMASK_grid.f90 @@ -42,8 +42,8 @@ program DAMASK_grid !-------------------------------------------------------------------------------------------------- ! variables related to information from load case and geom file - real(pReal), dimension(9) :: temp_valueVector = 0.0_pReal !< temporarily from loadcase file when reading in tensors (initialize to 0.0) - logical, dimension(9) :: temp_maskVector = .false. !< temporarily from loadcase file when reading in tensors + real(pReal), dimension(9) :: temp_valueVector !< temporarily from loadcase file when reading in tensors (initialize to 0.0) + logical, dimension(9) :: temp_maskVector !< temporarily from loadcase file when reading in tensors !-------------------------------------------------------------------------------------------------- ! loop variables, convergence etc. @@ -143,8 +143,6 @@ program DAMASK_grid mech_restartWrite => grid_mech_spectral_basic_restartWrite case ('Polarisation') - if(debug_grid%contains('basic')) & - call IO_warning(42, ext_msg='debug Divergence') mech_init => grid_mech_spectral_polarisation_init mech_forward => grid_mech_spectral_polarisation_forward mech_solution => grid_mech_spectral_polarisation_solution @@ -152,8 +150,6 @@ program DAMASK_grid mech_restartWrite => grid_mech_spectral_polarisation_restartWrite case ('FEM') - if(debug_grid%contains('basic')) & - call IO_warning(42, ext_msg='debug Divergence') mech_init => grid_mech_FEM_init mech_forward => grid_mech_FEM_forward mech_solution => grid_mech_FEM_solution @@ -178,11 +174,11 @@ program DAMASK_grid allocate(loadCases(l)%ID(nActiveFields)) field = 1 loadCases(l)%ID(field) = FIELD_MECH_ID ! mechanical active by default - thermalActive: if (any(thermal_type == THERMAL_conduction_ID)) then + thermalActive: if (any(thermal_type == THERMAL_conduction_ID)) then field = field + 1 loadCases(l)%ID(field) = FIELD_THERMAL_ID endif thermalActive - damageActive: if (any(damage_type == DAMAGE_nonlocal_ID)) then + damageActive: if (any(damage_type == DAMAGE_nonlocal_ID)) then field = field + 1 loadCases(l)%ID(field) = FIELD_DAMAGE_ID endif damageActive @@ -190,33 +186,35 @@ program DAMASK_grid load_step => load_steps%get(l) step_mech => load_step%get('mechanics') - loadCases(l)%stress%myType='P' + loadCases(l)%stress%myType='' readMech: do m = 1, step_mech%length select case (step_mech%getKey(m)) - case('dot_F','L','F') ! assign values for the deformation BC matrix + case ('L','dot_F','F') ! assign values for the deformation BC matrix loadCases(l)%deformation%myType = step_mech%getKey(m) - temp_valueVector = 0.0_pReal - step_deformation => step_mech%get(m) - do j = 1, 9 - temp_maskVector(j) = step_deformation%get_asString(j) /= 'x' ! true if not a 'x' - if (temp_maskVector(j)) temp_valueVector(j) = step_deformation%get_asFloat(j) ! read value where applicable - enddo - loadCases(l)%deformation%mask = transpose(reshape(temp_maskVector,[ 3,3])) ! mask in 3x3 notation - loadCases(l)%deformation%values = math_9to33(temp_valueVector) ! values in 3x3 notation - case('P') + temp_valueVector = 0.0_pReal - step_stress => step_mech%get(m) do j = 1, 9 - temp_maskVector(j) = step_stress%get_asString(j) /= 'x' ! true if not a 'x' - if (temp_maskVector(j)) temp_valueVector(j) = step_stress%get_asFloat(j) ! read value where applicable + temp_maskVector(j) = step_deformation%get_asString(j) /= 'x' + if (temp_maskVector(j)) temp_valueVector(j) = step_deformation%get_asFloat(j) enddo - loadCases(l)%stress%mask = transpose(reshape(temp_maskVector,[ 3,3])) + loadCases(l)%deformation%mask = transpose(reshape(temp_maskVector,[3,3])) + loadCases(l)%deformation%values = math_9to33(temp_valueVector) + case ('dot_P','P') + loadCases(l)%stress%myType = step_mech%getKey(m) + step_stress => step_mech%get(m) + + temp_valueVector = 0.0_pReal + do j = 1, 9 + temp_maskVector(j) = step_stress%get_asString(j) /= 'x' + if (temp_maskVector(j)) temp_valueVector(j) = step_stress%get_asFloat(j) + enddo + loadCases(l)%stress%mask = transpose(reshape(temp_maskVector,[3,3])) loadCases(l)%stress%values = math_9to33(temp_valueVector) end select call loadCases(l)%rot%fromAxisAngle(step_mech%get_asFloats('R',defaultVal = real([0.0,0.0,1.0,0.0],pReal)),degrees=.true.) enddo readMech - if (.not. allocated(loadCases(l)%deformation%myType)) call IO_error(error_ID=837,ext_msg = 'L/F/dot_F missing') + if (.not. allocated(loadCases(l)%deformation%myType)) call IO_error(error_ID=837,ext_msg = 'L/dot_F/F missing') step_discretization => load_step%get('discretization') if(.not. step_discretization%contains('t')) call IO_error(error_ID=837,ext_msg = 't missing') @@ -239,50 +237,60 @@ program DAMASK_grid if (any(loadCases(l)%deformation%mask(j,1:3) .eqv. .true.) .and. & any(loadCases(l)%deformation%mask(j,1:3) .eqv. .false.)) errorID = 832 ! each row should be either fully or not at all defined enddo - print*, ' L:' - else if (loadCases(l)%deformation%myType == 'F') then + endif + if (loadCases(l)%deformation%myType == 'F') then print*, ' F:' - else if (loadCases(l)%deformation%myType == 'dot_F') then - print*, ' dot_F:' + else + print*, ' '//loadCases(l)%deformation%myType//' / 1/s:' endif do i = 1, 3; do j = 1, 3 - if(loadCases(l)%deformation%mask(i,j)) then + if (loadCases(l)%deformation%mask(i,j)) then write(IO_STDOUT,'(2x,f12.7)',advance='no') loadCases(l)%deformation%values(i,j) - else - write(IO_STDOUT,'(2x,12a)',advance='no') ' x ' - endif - enddo; write(IO_STDOUT,'(/)',advance='no') - enddo - if (any(loadCases(l)%stress%mask .eqv. loadCases(l)%deformation%mask)) errorID = 831 ! exclusive or masking only - if (any(loadCases(l)%stress%mask .and. transpose(loadCases(l)%stress%mask) .and. (math_I3<1))) & - errorID = 838 ! no rotation is allowed by stress BC - print*, ' P / MPa:' - do i = 1, 3; do j = 1, 3 - if(loadCases(l)%stress%mask(i,j)) then - write(IO_STDOUT,'(2x,f12.4)',advance='no') loadCases(l)%stress%values(i,j)*1e-6_pReal else write(IO_STDOUT,'(2x,12a)',advance='no') ' x ' endif enddo; write(IO_STDOUT,'(/)',advance='no') enddo + if (any(loadCases(l)%stress%mask .eqv. loadCases(l)%deformation%mask)) errorID = 831 + if (any(loadCases(l)%stress%mask .and. transpose(loadCases(l)%stress%mask) .and. (math_I3<1))) & + errorID = 838 ! no rotation is allowed by stress BC + + if (loadCases(l)%stress%myType == 'P') print*, ' P / MPa:' + if (loadCases(l)%stress%myType == 'dot_P') print*, ' dot_P / MPa/s:' + + if (loadCases(l)%stress%myType /= '') then + do i = 1, 3; do j = 1, 3 + if (loadCases(l)%stress%mask(i,j)) then + write(IO_STDOUT,'(2x,f12.4)',advance='no') loadCases(l)%stress%values(i,j)*1e-6_pReal + else + write(IO_STDOUT,'(2x,12a)',advance='no') ' x ' + endif + enddo; write(IO_STDOUT,'(/)',advance='no') + enddo + endif if (any(dNeq(loadCases(l)%rot%asMatrix(), math_I3))) & write(IO_STDOUT,'(2x,a,/,3(3(3x,f12.7,1x)/))',advance='no') 'R:',& transpose(loadCases(l)%rot%asMatrix()) - if (loadCases(l)%t < 0.0_pReal) errorID = 834 - print'(a,f0.3)', ' t: ', loadCases(l)%t - if (loadCases(l)%N < 1) errorID = 835 - print'(a,i0)', ' N: ', loadCases(l)%N - if (loadCases(l)%f_out < 1) errorID = 836 - print'(a,i0)', ' f_out: ', loadCases(l)%f_out - if (loadCases(l)%r <= 0.0) errorID = 833 - print'(a,f0.3)', ' r: ', loadCases(l)%r - + if (loadCases(l)%r <= 0.0) errorID = 833 + if (loadCases(l)%t < 0.0_pReal) errorID = 834 + if (loadCases(l)%N < 1) errorID = 835 + if (loadCases(l)%f_out < 1) errorID = 836 if (loadCases(l)%f_restart < 1) errorID = 839 + + if (dEq(loadCases(l)%r,1.0_pReal,1.e-9_pReal)) then + print'(a)', ' r: 1 (constant step widths)' + else + print'(a,f0.3)', ' r: ', loadCases(l)%r + endif + print'(a,f0.3)', ' t: ', loadCases(l)%t + print'(a,i0)', ' N: ', loadCases(l)%N + print'(a,i0)', ' f_out: ', loadCases(l)%f_out if (loadCases(l)%f_restart < huge(0)) & print'(a,i0)', ' f_restart: ', loadCases(l)%f_restart if (errorID > 0) call IO_error(error_ID = errorID, ext_msg = loadcase_string) ! exit with error message + endif reportAndCheck enddo @@ -309,8 +317,6 @@ program DAMASK_grid writeHeader: if (interface_restartInc < 1) then open(newunit=statUnit,file=trim(getSolverJobName())//'.sta',form='FORMATTED',status='REPLACE') write(statUnit,'(a)') 'Increment Time CutbackLevel Converged IterationsNeeded' ! statistics file - if (debug_grid%contains('basic')) print'(/,a)', ' header of statistics file written out' - flush(IO_STDOUT) else writeHeader open(newunit=statUnit,file=trim(getSolverJobName())//& '.sta',form='FORMATTED', position='APPEND', status='OLD') @@ -319,6 +325,7 @@ program DAMASK_grid writeUndeformed: if (interface_restartInc < 1) then print'(/,a)', ' ... writing initial configuration to file ........................' + flush(IO_STDOUT) call CPFEM_results(0,0.0_pReal) endif writeUndeformed diff --git a/src/grid/grid_mech_FEM.f90 b/src/grid/grid_mech_FEM.f90 index 4394b6f81..146f28567 100644 --- a/src/grid/grid_mech_FEM.f90 +++ b/src/grid/grid_mech_FEM.f90 @@ -31,16 +31,16 @@ module grid_mech_FEM type :: tNumerics integer :: & - itmin, & !< minimum number of iterations - itmax !< maximum number of iterations + itmin, & !< minimum number of iterations + itmax !< maximum number of iterations real(pReal) :: & - eps_div_atol, & !< absolute tolerance for equilibrium - eps_div_rtol, & !< relative tolerance for equilibrium - eps_stress_atol, & !< absolute tolerance for fullfillment of stress BC - eps_stress_rtol !< relative tolerance for fullfillment of stress BC + eps_div_atol, & !< absolute tolerance for equilibrium + eps_div_rtol, & !< relative tolerance for equilibrium + eps_stress_atol, & !< absolute tolerance for fullfillment of stress BC + eps_stress_rtol !< relative tolerance for fullfillment of stress BC end type tNumerics - type(tNumerics) :: num ! numerics parameters. Better name? + type(tNumerics) :: num ! numerics parameters. Better name? logical :: debugRotation @@ -64,7 +64,7 @@ module grid_mech_FEM real(pReal), dimension(3,3) :: & F_aimDot = 0.0_pReal, & !< assumed rate of average deformation gradient F_aim = math_I3, & !< current prescribed deformation gradient - F_aim_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_aim = 0.0_pReal character(len=:), allocatable :: incInfo !< time and increment information @@ -93,10 +93,8 @@ contains !-------------------------------------------------------------------------------------------------- subroutine grid_mech_FEM_init - real(pReal) :: HGCoeff = 0.0e-2_pReal - real(pReal), dimension(3,3) :: & - temp33_Real = 0.0_pReal - real(pReal), dimension(4,8) :: & + real(pReal), parameter :: HGCoeff = 0.0e-2_pReal + real(pReal), parameter, dimension(4,8) :: & HGcomp = reshape([ 1.0_pReal, 1.0_pReal, 1.0_pReal,-1.0_pReal, & 1.0_pReal,-1.0_pReal,-1.0_pReal, 1.0_pReal, & -1.0_pReal, 1.0_pReal,-1.0_pReal, 1.0_pReal, & @@ -121,18 +119,19 @@ subroutine grid_mech_FEM_init !------------------------------------------------------------------------------------------------- ! debugging options - debug_grid => config_debug%get('grid', defaultVal=emptyList) + debug_grid => config_debug%get('grid',defaultVal=emptyList) debugRotation = debug_grid%contains('rotation') !------------------------------------------------------------------------------------------------- ! read numerical parameters and do sanity checks num_grid => config_numerics%get('grid',defaultVal=emptyDict) + num%eps_div_atol = num_grid%get_asFloat('eps_div_atol', defaultVal=1.0e-4_pReal) num%eps_div_rtol = num_grid%get_asFloat('eps_div_rtol', defaultVal=5.0e-4_pReal) num%eps_stress_atol = num_grid%get_asFloat('eps_stress_atol',defaultVal=1.0e3_pReal) num%eps_stress_rtol = num_grid%get_asFloat('eps_stress_rtol',defaultVal=1.0e-3_pReal) - num%itmin = num_grid%get_asInt ('itmin', defaultVal=1) - num%itmax = num_grid%get_asInt ('itmax', defaultVal=250) + num%itmin = num_grid%get_asInt ('itmin',defaultVal=1) + num%itmax = num_grid%get_asInt ('itmax',defaultVal=250) if (num%eps_div_atol <= 0.0_pReal) call IO_error(301,ext_msg='eps_div_atol') if (num%eps_div_rtol < 0.0_pReal) call IO_error(301,ext_msg='eps_div_rtol') @@ -225,6 +224,7 @@ subroutine grid_mech_FEM_init fileHandle = HDF5_openFile(fileName) groupHandle = HDF5_openGroup(fileHandle,'solver') + call HDF5_read(groupHandle,P_aim, 'P_aim') call HDF5_read(groupHandle,F_aim, 'F_aim') call HDF5_read(groupHandle,F_aim_lastInc,'F_aim_lastInc') call HDF5_read(groupHandle,F_aimDot, 'F_aimDot') @@ -238,9 +238,9 @@ subroutine grid_mech_FEM_init F = spread(spread(spread(math_I3,3,grid(1)),4,grid(2)),5,grid3) endif restartRead - homogenization_F0 = reshape(F_lastInc, [3,3,1,product(grid(1:2))*grid3]) ! set starting condition for materialpoint_stressAndItsTangent + homogenization_F0 = reshape(F_lastInc, [3,3,1,product(grid(1:2))*grid3]) ! set starting condition for materialpoint_stressAndItsTangent call utilities_updateCoords(F) - call utilities_constitutiveResponse(P_current,temp33_Real,C_volAvg,devNull, & ! stress field, stress avg, global average of stiffness and (min+max)/2 + call utilities_constitutiveResponse(P_current,P_av,C_volAvg,devNull, & ! stress field, stress avg, global average of stiffness and (min+max)/2 F, & ! target F 0.0_pReal) ! time increment call DMDAVecRestoreArrayF90(mech_grid,solution_current,u_current,ierr) @@ -295,6 +295,7 @@ function grid_mech_FEM_solution(incInfoIn) result(solution) solution%iterationsNeeded = totalIter solution%termIll = terminallyIll terminallyIll = .false. + P_aim = merge(P_aim,P_av,params%stress_mask) end function grid_mech_FEM_solution @@ -302,34 +303,26 @@ end function grid_mech_FEM_solution !-------------------------------------------------------------------------------------------------- !> @brief forwarding routine !> @details find new boundary conditions and best F estimate for end of current timestep -!> possibly writing restart information, triggering of state increment in DAMASK, and updating of IPcoordinates !-------------------------------------------------------------------------------------------------- -subroutine grid_mech_FEM_forward(cutBack,guess,timeinc,timeinc_old,loadCaseTime,& +subroutine grid_mech_FEM_forward(cutBack,guess,Delta_t,Delta_t_old,t_remaining,& deformation_BC,stress_BC,rotation_BC) - logical, intent(in) :: & + logical, intent(in) :: & cutBack, & guess - real(pReal), intent(in) :: & - timeinc_old, & - timeinc, & - loadCaseTime !< remaining time of current load case - type(tBoundaryCondition), intent(in) :: & + real(pReal), intent(in) :: & + Delta_t_old, & + Delta_t, & + t_remaining !< remaining time of current load case + type(tBoundaryCondition), intent(in) :: & stress_BC, & deformation_BC - type(rotation), intent(in) :: & + type(rotation), intent(in) :: & rotation_BC PetscErrorCode :: ierr PetscScalar, pointer, dimension(:,:,:,:) :: & u_current,u_lastInc -!-------------------------------------------------------------------------------------------------- -! set module wide available data - params%stress_mask = stress_BC%mask - params%rotation_BC = rotation_BC - params%timeinc = timeinc - params%timeincOld = timeinc_old - call DMDAVecGetArrayF90(mech_grid,solution_current,u_current,ierr); CHKERRQ(ierr) call DMDAVecGetArrayF90(mech_grid,solution_lastInc,u_lastInc,ierr); CHKERRQ(ierr) @@ -339,7 +332,7 @@ subroutine grid_mech_FEM_forward(cutBack,guess,timeinc,timeinc_old,loadCaseTime, else C_volAvgLastInc = C_volAvg - F_aimDot = merge(merge((F_aim-F_aim_lastInc)/timeinc_old,0.0_pReal,stress_BC%mask), 0.0_pReal, guess) + F_aimDot = merge(merge((F_aim-F_aim_lastInc)/Delta_t_old,0.0_pReal,stress_BC%mask), 0.0_pReal, guess) ! estimate deformation rate for prescribed stress components F_aim_lastInc = F_aim !----------------------------------------------------------------------------------------------- @@ -347,18 +340,18 @@ subroutine grid_mech_FEM_forward(cutBack,guess,timeinc,timeinc_old,loadCaseTime, if (deformation_BC%myType=='L') then ! calculate F_aimDot from given L and current F F_aimDot = F_aimDot & + merge(matmul(deformation_BC%values, F_aim_lastInc),.0_pReal,deformation_BC%mask) - elseif(deformation_BC%myType=='dot_F') then ! F_aimDot is prescribed - F_aimDot = F_aimDot & + elseif (deformation_BC%myType=='dot_F') then ! F_aimDot is prescribed + F_aimDot = F_aimDot & + merge(deformation_BC%values,.0_pReal,deformation_BC%mask) elseif (deformation_BC%myType=='F') then ! aim at end of load case is prescribed F_aimDot = F_aimDot & - + merge((deformation_BC%values - F_aim_lastInc)/loadCaseTime,.0_pReal,deformation_BC%mask) + + merge((deformation_BC%values - F_aim_lastInc)/t_remaining,.0_pReal,deformation_BC%mask) endif if (guess) then call VecWAXPY(solution_rate,-1.0_pReal,solution_lastInc,solution_current,ierr) CHKERRQ(ierr) - call VecScale(solution_rate,1.0_pReal/timeinc_old,ierr); CHKERRQ(ierr) + call VecScale(solution_rate,1.0_pReal/Delta_t_old,ierr); CHKERRQ(ierr) else call VecSet(solution_rate,0.0_pReal,ierr); CHKERRQ(ierr) endif @@ -371,23 +364,28 @@ subroutine grid_mech_FEM_forward(cutBack,guess,timeinc,timeinc_old,loadCaseTime, !-------------------------------------------------------------------------------------------------- ! update average and local deformation gradients - F_aim = F_aim_lastInc + F_aimDot * timeinc - if (stress_BC%myType=='P') then - P_aim = P_aim + merge((stress_BC%values - P_aim)/loadCaseTime*timeinc,.0_pReal,stress_BC%mask) - elseif (stress_BC%myType=='dot_P') then !UNTESTED - P_aim = P_aim + merge(stress_BC%values*timeinc,.0_pReal,stress_BC%mask) - endif + F_aim = F_aim_lastInc + F_aimDot * Delta_t + if (stress_BC%myType=='P') P_aim = P_aim & + + merge((stress_BC%values - P_aim)/t_remaining,0.0_pReal,stress_BC%mask)*Delta_t + if (stress_BC%myType=='dot_P') P_aim = P_aim & + + merge(stress_BC%values,0.0_pReal,stress_BC%mask)*Delta_t - call VecAXPY(solution_current,timeinc,solution_rate,ierr); CHKERRQ(ierr) + call VecAXPY(solution_current,Delta_t,solution_rate,ierr); CHKERRQ(ierr) - call DMDAVecRestoreArrayF90(mech_grid,solution_current,u_current,ierr);CHKERRQ(ierr) - call DMDAVecRestoreArrayF90(mech_grid,solution_lastInc,u_lastInc,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) + +!-------------------------------------------------------------------------------------------------- +! set module wide available data + params%stress_mask = stress_BC%mask + params%rotation_BC = rotation_BC + params%timeinc = Delta_t end subroutine grid_mech_FEM_forward !-------------------------------------------------------------------------------------------------- -!> @brief Age +!> @brief Update coordinates !-------------------------------------------------------------------------------------------------- subroutine grid_mech_FEM_updateCoords @@ -415,6 +413,7 @@ subroutine grid_mech_FEM_restartWrite fileHandle = HDF5_openFile(fileName,'w') groupHandle = HDF5_addGroup(fileHandle,'solver') + call HDF5_write(groupHandle,P_aim, 'P_aim') call HDF5_write(groupHandle,F_aim, 'F_aim') call HDF5_write(groupHandle,F_aim_lastInc,'F_aim_lastInc') call HDF5_write(groupHandle,F_aimDot, 'F_aimDot') @@ -441,11 +440,11 @@ end subroutine grid_mech_FEM_restartWrite subroutine converged(snes_local,PETScIter,devNull1,devNull2,fnorm,reason,dummy,ierr) SNES :: snes_local - PetscInt, intent(in) :: PETScIter - PetscReal, intent(in) :: & - devNull1, & - devNull2, & - fnorm + PetscInt, intent(in) :: PETScIter + PetscReal, intent(in) :: & + devNull1, & + devNull2, & + fnorm SNESConvergedReason :: reason PetscObject :: dummy PetscErrorCode :: ierr @@ -458,10 +457,10 @@ subroutine converged(snes_local,PETScIter,devNull1,devNull2,fnorm,reason,dummy,i divTol = max(maxval(abs(P_av))*num%eps_div_rtol ,num%eps_div_atol) BCTol = max(maxval(abs(P_av))*num%eps_stress_rtol,num%eps_stress_atol) - if ((totalIter >= num%itmin .and. & - all([ err_div/divTol, & - err_BC /BCTol ] < 1.0_pReal)) & - .or. terminallyIll) then + if (terminallyIll .or. & + (totalIter >= num%itmin .and. & + all([ err_div/divTol, & + err_BC /BCTol ] < 1.0_pReal))) then reason = 1 elseif (totalIter >= num%itmax) then reason = -1 @@ -666,16 +665,16 @@ subroutine formJacobian(da_local,x_local,Jac_pre,Jac,dummy,ierr) C_volAvg(3,3,3,3)/delta(3)**2.0_pReal)*detJ call MatZeroRowsColumns(Jac,size(rows),rows,diag,PETSC_NULL_VEC,PETSC_NULL_VEC,ierr) CHKERRQ(ierr) - call DMGetGlobalVector(da_local,coordinates,ierr);CHKERRQ(ierr) - call DMDAVecGetArrayF90(da_local,coordinates,x_scal,ierr);CHKERRQ(ierr) + call DMGetGlobalVector(da_local,coordinates,ierr); CHKERRQ(ierr) + call DMDAVecGetArrayF90(da_local,coordinates,x_scal,ierr); CHKERRQ(ierr) ele = 0 do k = zstart, zend; do j = ystart, yend; do i = xstart, xend ele = ele + 1 x_scal(0:2,i,j,k) = discretization_IPcoords(1:3,ele) enddo; enddo; enddo - call DMDAVecRestoreArrayF90(da_local,coordinates,x_scal,ierr);CHKERRQ(ierr) ! initialize to undeformed coordinates (ToDo: use ip coordinates) - call MatNullSpaceCreateRigidBody(coordinates,matnull,ierr);CHKERRQ(ierr) ! get rigid body deformation modes - call DMRestoreGlobalVector(da_local,coordinates,ierr);CHKERRQ(ierr) + call DMDAVecRestoreArrayF90(da_local,coordinates,x_scal,ierr); CHKERRQ(ierr) ! initialize to undeformed coordinates (ToDo: use ip coordinates) + call MatNullSpaceCreateRigidBody(coordinates,matnull,ierr); CHKERRQ(ierr) ! get rigid body deformation modes + call DMRestoreGlobalVector(da_local,coordinates,ierr); CHKERRQ(ierr) call MatSetNullSpace(Jac,matnull,ierr); CHKERRQ(ierr) call MatSetNearNullSpace(Jac,matnull,ierr); CHKERRQ(ierr) call MatNullSpaceDestroy(matnull,ierr); CHKERRQ(ierr) diff --git a/src/grid/grid_mech_spectral_basic.f90 b/src/grid/grid_mech_spectral_basic.f90 index 563b25162..4f5ceff61 100644 --- a/src/grid/grid_mech_spectral_basic.f90 +++ b/src/grid/grid_mech_spectral_basic.f90 @@ -94,8 +94,6 @@ contains subroutine grid_mech_spectral_basic_init real(pReal), dimension(3,3,grid(1),grid(2),grid3) :: P - real(pReal), dimension(3,3) :: & - temp33_Real = 0.0_pReal PetscErrorCode :: ierr PetscScalar, pointer, dimension(:,:,:,:) :: & F ! pointer to solution data @@ -118,20 +116,20 @@ subroutine grid_mech_spectral_basic_init !------------------------------------------------------------------------------------------------- ! debugging options - debug_grid => config_debug%get('grid', defaultVal=emptyList) + debug_grid => config_debug%get('grid',defaultVal=emptyList) debugRotation = debug_grid%contains('rotation') - + !------------------------------------------------------------------------------------------------- ! read numerical parameters and do sanity checks num_grid => config_numerics%get('grid',defaultVal=emptyDict) - num%update_gamma = num_grid%get_asBool ('update_gamma', defaultVal=.false.) - num%eps_div_atol = num_grid%get_asFloat ('eps_div_atol', defaultVal=1.0e-4_pReal) - num%eps_div_rtol = num_grid%get_asFloat ('eps_div_rtol', defaultVal=5.0e-4_pReal) - num%eps_stress_atol = num_grid%get_asFloat ('eps_stress_atol',defaultVal=1.0e3_pReal) - num%eps_stress_rtol = num_grid%get_asFloat ('eps_stress_rtol',defaultVal=1.0e-3_pReal) - num%itmin = num_grid%get_asInt ('itmin',defaultVal=1) - num%itmax = num_grid%get_asInt ('itmax',defaultVal=250) + num%update_gamma = num_grid%get_asBool ('update_gamma', defaultVal=.false.) + num%eps_div_atol = num_grid%get_asFloat('eps_div_atol', defaultVal=1.0e-4_pReal) + num%eps_div_rtol = num_grid%get_asFloat('eps_div_rtol', defaultVal=5.0e-4_pReal) + num%eps_stress_atol = num_grid%get_asFloat('eps_stress_atol',defaultVal=1.0e3_pReal) + num%eps_stress_rtol = num_grid%get_asFloat('eps_stress_rtol',defaultVal=1.0e-3_pReal) + num%itmin = num_grid%get_asInt ('itmin',defaultVal=1) + num%itmax = num_grid%get_asInt ('itmax',defaultVal=250) if (num%eps_div_atol <= 0.0_pReal) call IO_error(301,ext_msg='eps_div_atol') if (num%eps_div_rtol < 0.0_pReal) call IO_error(301,ext_msg='eps_div_rtol') @@ -139,7 +137,7 @@ subroutine grid_mech_spectral_basic_init if (num%eps_stress_rtol < 0.0_pReal) call IO_error(301,ext_msg='eps_stress_rtol') if (num%itmax <= 1) call IO_error(301,ext_msg='itmax') if (num%itmin > num%itmax .or. num%itmin < 1) call IO_error(301,ext_msg='itmin') - + !-------------------------------------------------------------------------------------------------- ! set default and user defined options for PETSc call PetscOptionsInsertString(PETSC_NULL_OPTIONS,'-mech_snes_type ngmres',ierr) @@ -149,14 +147,14 @@ subroutine grid_mech_spectral_basic_init !-------------------------------------------------------------------------------------------------- ! allocate global fields - 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(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) !-------------------------------------------------------------------------------------------------- ! initialize solver specific parts of PETSc call SNESCreate(PETSC_COMM_WORLD,snes,ierr); CHKERRQ(ierr) call SNESSetOptionsPrefix(snes,'mech_',ierr);CHKERRQ(ierr) - localK = 0 + localK = 0 localK(worldrank) = grid3 call MPI_Allreduce(MPI_IN_PLACE,localK,worldsize,MPI_INTEGER,MPI_SUM,PETSC_COMM_WORLD,ierr) call DMDACreate3d(PETSC_COMM_WORLD, & @@ -189,6 +187,7 @@ subroutine grid_mech_spectral_basic_init fileHandle = HDF5_openFile(fileName) groupHandle = HDF5_openGroup(fileHandle,'solver') + call HDF5_read(groupHandle,P_aim, 'P_aim') call HDF5_read(groupHandle,F_aim, 'F_aim') call HDF5_read(groupHandle,F_aim_lastInc,'F_aim_lastInc') call HDF5_read(groupHandle,F_aimDot, 'F_aimDot') @@ -200,9 +199,9 @@ subroutine grid_mech_spectral_basic_init F = reshape(F_lastInc,[9,grid(1),grid(2),grid3]) endif restartRead - homogenization_F0 = reshape(F_lastInc, [3,3,1,product(grid(1:2))*grid3]) ! set starting condition for materialpoint_stressAndItsTangent + homogenization_F0 = reshape(F_lastInc, [3,3,1,product(grid(1:2))*grid3]) ! set starting condition for materialpoint_stressAndItsTangent call utilities_updateCoords(reshape(F,shape(F_lastInc))) - call utilities_constitutiveResponse(P,temp33_Real,C_volAvg,C_minMaxAvg, & ! stress field, stress avg, global average of stiffness and (min+max)/2 + call utilities_constitutiveResponse(P,P_av,C_volAvg,C_minMaxAvg, & ! stress field, stress avg, global average of stiffness and (min+max)/2 reshape(F,shape(F_lastInc)), & ! target F 0.0_pReal) ! time increment call DMDAVecRestoreArrayF90(da,solution_vec,F,ierr); CHKERRQ(ierr) ! deassociate pointer @@ -262,6 +261,7 @@ function grid_mech_spectral_basic_solution(incInfoIn) result(solution) solution%iterationsNeeded = totalIter solution%termIll = terminallyIll terminallyIll = .false. + P_aim = merge(P_aim,P_av,params%stress_mask) end function grid_mech_spectral_basic_solution @@ -269,32 +269,25 @@ end function grid_mech_spectral_basic_solution !-------------------------------------------------------------------------------------------------- !> @brief forwarding routine !> @details find new boundary conditions and best F estimate for end of current timestep -!> possibly writing restart information, triggering of state increment in DAMASK, and updating of IPcoordinates !-------------------------------------------------------------------------------------------------- -subroutine grid_mech_spectral_basic_forward(cutBack,guess,timeinc,timeinc_old,loadCaseTime,& +subroutine grid_mech_spectral_basic_forward(cutBack,guess,Delta_t,Delta_t_old,t_remaining,& deformation_BC,stress_BC,rotation_BC) - logical, intent(in) :: & + logical, intent(in) :: & cutBack, & guess - real(pReal), intent(in) :: & - timeinc_old, & - timeinc, & - loadCaseTime !< remaining time of current load case - type(tBoundaryCondition), intent(in) :: & + real(pReal), intent(in) :: & + Delta_t_old, & + Delta_t, & + t_remaining !< remaining time of current load case + type(tBoundaryCondition), intent(in) :: & stress_BC, & deformation_BC - type(rotation), intent(in) :: & + type(rotation), intent(in) :: & rotation_BC PetscErrorCode :: ierr PetscScalar, pointer, dimension(:,:,:,:) :: F -!-------------------------------------------------------------------------------------------------- -! set module wide available data - params%stress_mask = stress_BC%mask - params%rotation_BC = rotation_BC - params%timeinc = timeinc - params%timeincOld = timeinc_old call DMDAVecGetArrayF90(da,solution_vec,F,ierr); CHKERRQ(ierr) @@ -305,7 +298,7 @@ subroutine grid_mech_spectral_basic_forward(cutBack,guess,timeinc,timeinc_old,lo C_volAvgLastInc = C_volAvg C_minMaxAvgLastInc = C_minMaxAvg - F_aimDot = merge(merge((F_aim-F_aim_lastInc)/timeinc_old,0.0_pReal,stress_BC%mask), 0.0_pReal, guess) + F_aimDot = merge(merge((F_aim-F_aim_lastInc)/Delta_t_old,0.0_pReal,stress_BC%mask), 0.0_pReal, guess) ! estimate deformation rate for prescribed stress components F_aim_lastInc = F_aim !----------------------------------------------------------------------------------------------- @@ -313,40 +306,45 @@ subroutine grid_mech_spectral_basic_forward(cutBack,guess,timeinc,timeinc_old,lo if (deformation_BC%myType=='L') then ! calculate F_aimDot from given L and current F F_aimDot = F_aimDot & + merge(matmul(deformation_BC%values, F_aim_lastInc),.0_pReal,deformation_BC%mask) - elseif(deformation_BC%myType=='dot_F') then ! F_aimDot is prescribed - F_aimDot = F_aimDot & + elseif (deformation_BC%myType=='dot_F') then ! F_aimDot is prescribed + F_aimDot = F_aimDot & + merge(deformation_BC%values,.0_pReal,deformation_BC%mask) elseif (deformation_BC%myType=='F') then ! aim at end of load case is prescribed F_aimDot = F_aimDot & - + merge((deformation_BC%values - F_aim_lastInc)/loadCaseTime,.0_pReal,deformation_BC%mask) + + merge((deformation_BC%values - F_aim_lastInc)/t_remaining,.0_pReal,deformation_BC%mask) endif 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]),Delta_t_old, & rotation_BC%rotate(F_aimDot,active=.true.)) F_lastInc = reshape(F,[3,3,grid(1),grid(2),grid3]) - homogenization_F0 = reshape(F, [3,3,1,product(grid(1:2))*grid3]) + homogenization_F0 = reshape(F,[3,3,1,product(grid(1:2))*grid3]) endif !-------------------------------------------------------------------------------------------------- ! update average and local deformation gradients - F_aim = F_aim_lastInc + F_aimDot * timeinc - if (stress_BC%myType=='P') then - P_aim = P_aim + merge((stress_BC%values - P_aim)/loadCaseTime*timeinc,.0_pReal,stress_BC%mask) - elseif (stress_BC%myType=='dot_P') then !UNTESTED - P_aim = P_aim + merge(stress_BC%values*timeinc,.0_pReal,stress_BC%mask) - endif - - F = reshape(utilities_forwardField(timeinc,F_lastInc,Fdot, & ! estimate of F at end of time+timeinc that matches rotated F_aim on average + F_aim = F_aim_lastInc + F_aimDot * Delta_t + if (stress_BC%myType=='P') P_aim = P_aim & + + merge((stress_BC%values - P_aim)/t_remaining,0.0_pReal,stress_BC%mask)*Delta_t + if (stress_BC%myType=='dot_P') P_aim = P_aim & + + merge(stress_BC%values,0.0_pReal,stress_BC%mask)*Delta_t + + F = reshape(utilities_forwardField(Delta_t,F_lastInc,Fdot, & ! estimate of F at end of time+Delta_t that matches rotated F_aim on average rotation_BC%rotate(F_aim,active=.true.)),[9,grid(1),grid(2),grid3]) call DMDAVecRestoreArrayF90(da,solution_vec,F,ierr); CHKERRQ(ierr) +!-------------------------------------------------------------------------------------------------- +! set module wide available data + params%stress_mask = stress_BC%mask + params%rotation_BC = rotation_BC + params%timeinc = Delta_t + end subroutine grid_mech_spectral_basic_forward !-------------------------------------------------------------------------------------------------- -!> @brief Age +!> @brief Update coordinates !-------------------------------------------------------------------------------------------------- subroutine grid_mech_spectral_basic_updateCoords @@ -378,6 +376,7 @@ subroutine grid_mech_spectral_basic_restartWrite fileHandle = HDF5_openFile(fileName,'w') groupHandle = HDF5_addGroup(fileHandle,'solver') + call HDF5_write(groupHandle,P_aim, 'P_aim') call HDF5_write(groupHandle,F_aim, 'F_aim') call HDF5_write(groupHandle,F_aim_lastInc,'F_aim_lastInc') call HDF5_write(groupHandle,F_aimDot, 'F_aimDot') @@ -463,7 +462,7 @@ subroutine formResidual(in, F, & PetscErrorCode :: ierr call SNESGetNumberFunctionEvals(snes,nfuncs,ierr); CHKERRQ(ierr) - call SNESGetIterationNumber(snes,PETScIter,ierr); CHKERRQ(ierr) + call SNESGetIterationNumber(snes,PETScIter,ierr); CHKERRQ(ierr) if (nfuncs == 0 .and. PETScIter == 0) totalIter = -1 ! new increment @@ -472,7 +471,7 @@ subroutine formResidual(in, F, & newIteration: if (totalIter <= PETScIter) then totalIter = totalIter + 1 print'(1x,a,3(a,i0))', trim(incInfo), ' @ Iteration ', num%itmin, '≤',totalIter, '≤', num%itmax - if (debugRotation) & + if(debugRotation) & write(IO_STDOUT,'(/,a,/,3(3(f12.7,1x)/))',advance='no') & ' deformation gradient aim (lab) =', transpose(params%rotation_BC%rotate(F_aim,active=.true.)) write(IO_STDOUT,'(/,a,/,3(3(f12.7,1x)/))',advance='no') & diff --git a/src/grid/grid_mech_spectral_polarisation.f90 b/src/grid/grid_mech_spectral_polarisation.f90 index 03780f2e0..d09b7fcb2 100644 --- a/src/grid/grid_mech_spectral_polarisation.f90 +++ b/src/grid/grid_mech_spectral_polarisation.f90 @@ -105,8 +105,6 @@ contains subroutine grid_mech_spectral_polarisation_init real(pReal), dimension(3,3,grid(1),grid(2),grid3) :: P - real(pReal), dimension(3,3) :: & - temp33_Real = 0.0_pReal PetscErrorCode :: ierr PetscScalar, pointer, dimension(:,:,:,:) :: & FandF_tau, & ! overall pointer to solution data @@ -147,16 +145,16 @@ subroutine grid_mech_spectral_polarisation_init num%alpha = num_grid%get_asFloat('alpha', defaultVal=1.0_pReal) num%beta = num_grid%get_asFloat('beta', defaultVal=1.0_pReal) - if (num%eps_div_atol <= 0.0_pReal) call IO_error(301,ext_msg='eps_div_atol') - if (num%eps_div_rtol < 0.0_pReal) call IO_error(301,ext_msg='eps_div_rtol') - if (num%eps_curl_atol <= 0.0_pReal) call IO_error(301,ext_msg='eps_curl_atol') - if (num%eps_curl_rtol < 0.0_pReal) call IO_error(301,ext_msg='eps_curl_rtol') - if (num%eps_stress_atol <= 0.0_pReal) call IO_error(301,ext_msg='eps_stress_atol') - if (num%eps_stress_rtol < 0.0_pReal) call IO_error(301,ext_msg='eps_stress_rtol') - if (num%itmax <= 1) call IO_error(301,ext_msg='itmax') - if (num%itmin > num%itmax .or. num%itmin < 1) call IO_error(301,ext_msg='itmin') - if (num%alpha <= 0.0_pReal .or. num%alpha > 2.0_pReal) call IO_error(301,ext_msg='alpha') - if (num%beta < 0.0_pReal .or. num%beta > 2.0_pReal) call IO_error(301,ext_msg='beta') + if (num%eps_div_atol <= 0.0_pReal) call IO_error(301,ext_msg='eps_div_atol') + if (num%eps_div_rtol < 0.0_pReal) call IO_error(301,ext_msg='eps_div_rtol') + if (num%eps_curl_atol <= 0.0_pReal) call IO_error(301,ext_msg='eps_curl_atol') + if (num%eps_curl_rtol < 0.0_pReal) call IO_error(301,ext_msg='eps_curl_rtol') + if (num%eps_stress_atol <= 0.0_pReal) call IO_error(301,ext_msg='eps_stress_atol') + if (num%eps_stress_rtol < 0.0_pReal) call IO_error(301,ext_msg='eps_stress_rtol') + if (num%itmax <= 1) call IO_error(301,ext_msg='itmax') + if (num%itmin > num%itmax .or. num%itmin < 1) call IO_error(301,ext_msg='itmin') + if (num%alpha <= 0.0_pReal .or. num%alpha > 2.0_pReal) call IO_error(301,ext_msg='alpha') + if (num%beta < 0.0_pReal .or. num%beta > 2.0_pReal) call IO_error(301,ext_msg='beta') !-------------------------------------------------------------------------------------------------- ! set default and user defined options for PETSc @@ -211,6 +209,7 @@ subroutine grid_mech_spectral_polarisation_init fileHandle = HDF5_openFile(fileName) groupHandle = HDF5_openGroup(fileHandle,'solver') + call HDF5_read(groupHandle,P_aim, 'P_aim') call HDF5_read(groupHandle,F_aim, 'F_aim') call HDF5_read(groupHandle,F_aim_lastInc,'F_aim_lastInc') call HDF5_read(groupHandle,F_aimDot, 'F_aimDot') @@ -226,9 +225,9 @@ subroutine grid_mech_spectral_polarisation_init F_tau_lastInc = 2.0_pReal*F_lastInc endif restartRead - homogenization_F0 = reshape(F_lastInc, [3,3,1,product(grid(1:2))*grid3]) ! set starting condition for materialpoint_stressAndItsTangent + homogenization_F0 = reshape(F_lastInc, [3,3,1,product(grid(1:2))*grid3]) ! set starting condition for materialpoint_stressAndItsTangent call utilities_updateCoords(reshape(F,shape(F_lastInc))) - call utilities_constitutiveResponse(P,temp33_Real,C_volAvg,C_minMaxAvg, & ! stress field, stress avg, global average of stiffness and (min+max)/2 + call utilities_constitutiveResponse(P,P_av,C_volAvg,C_minMaxAvg, & ! stress field, stress avg, global average of stiffness and (min+max)/2 reshape(F,shape(F_lastInc)), & ! target F 0.0_pReal) ! time increment call DMDAVecRestoreArrayF90(da,solution_vec,FandF_tau,ierr); CHKERRQ(ierr) ! deassociate pointer @@ -294,6 +293,7 @@ function grid_mech_spectral_polarisation_solution(incInfoIn) result(solution) solution%iterationsNeeded = totalIter solution%termIll = terminallyIll terminallyIll = .false. + P_aim = merge(P_aim,P_av,params%stress_mask) end function grid_mech_spectral_polarisation_solution @@ -301,34 +301,27 @@ end function grid_mech_spectral_polarisation_solution !-------------------------------------------------------------------------------------------------- !> @brief forwarding routine !> @details find new boundary conditions and best F estimate for end of current timestep -!> possibly writing restart information, triggering of state increment in DAMASK, and updating of IPcoordinates !-------------------------------------------------------------------------------------------------- -subroutine grid_mech_spectral_polarisation_forward(cutBack,guess,timeinc,timeinc_old,loadCaseTime,& +subroutine grid_mech_spectral_polarisation_forward(cutBack,guess,Delta_t,Delta_t_old,t_remaining,& deformation_BC,stress_BC,rotation_BC) - logical, intent(in) :: & + logical, intent(in) :: & cutBack, & guess - real(pReal), intent(in) :: & - timeinc_old, & - timeinc, & - loadCaseTime !< remaining time of current load case - type(tBoundaryCondition), intent(in) :: & + real(pReal), intent(in) :: & + Delta_t_old, & + Delta_t, & + t_remaining !< remaining time of current load case + type(tBoundaryCondition), intent(in) :: & stress_BC, & deformation_BC - type(rotation), intent(in) :: & + type(rotation), intent(in) :: & rotation_BC PetscErrorCode :: ierr PetscScalar, pointer, dimension(:,:,:,:) :: FandF_tau, F, F_tau integer :: i, j, k real(pReal), dimension(3,3) :: F_lambda33 -!-------------------------------------------------------------------------------------------------- -! set module wide available data - params%stress_mask = stress_BC%mask - params%rotation_BC = rotation_BC - params%timeinc = timeinc - params%timeincOld = timeinc_old call DMDAVecGetArrayF90(da,solution_vec,FandF_tau,ierr); CHKERRQ(ierr) F => FandF_tau(0: 8,:,:,:) @@ -341,7 +334,7 @@ subroutine grid_mech_spectral_polarisation_forward(cutBack,guess,timeinc,timeinc C_volAvgLastInc = C_volAvg C_minMaxAvgLastInc = C_minMaxAvg - F_aimDot = merge(merge((F_aim-F_aim_lastInc)/timeinc_old,0.0_pReal,stress_BC%mask), 0.0_pReal, guess) + F_aimDot = merge(merge((F_aim-F_aim_lastInc)/Delta_t_old,0.0_pReal,stress_BC%mask), 0.0_pReal, guess) ! estimate deformation rate for prescribed stress components F_aim_lastInc = F_aim !----------------------------------------------------------------------------------------------- @@ -349,19 +342,19 @@ subroutine grid_mech_spectral_polarisation_forward(cutBack,guess,timeinc,timeinc if (deformation_BC%myType=='L') then ! calculate F_aimDot from given L and current F F_aimDot = F_aimDot & + merge(matmul(deformation_BC%values, F_aim_lastInc),.0_pReal,deformation_BC%mask) - elseif(deformation_BC%myType=='dot_F') then ! F_aimDot is prescribed - F_aimDot = F_aimDot & + elseif (deformation_BC%myType=='dot_F') then ! F_aimDot is prescribed + F_aimDot = F_aimDot & + merge(deformation_BC%values,.0_pReal,deformation_BC%mask) elseif (deformation_BC%myType=='F') then ! aim at end of load case is prescribed F_aimDot = F_aimDot & - + merge((deformation_BC%values - F_aim_lastInc)/loadCaseTime,.0_pReal,deformation_BC%mask) + + merge((deformation_BC%values - F_aim_lastInc)/t_remaining,.0_pReal,deformation_BC%mask) endif 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]),Delta_t_old, & rotation_BC%rotate(F_aimDot,active=.true.)) 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]), Delta_t_old, & rotation_BC%rotate(F_aimDot,active=.true.)) F_lastInc = reshape(F, [3,3,grid(1),grid(2),grid3]) F_tau_lastInc = reshape(F_tau,[3,3,grid(1),grid(2),grid3]) @@ -371,38 +364,41 @@ subroutine grid_mech_spectral_polarisation_forward(cutBack,guess,timeinc,timeinc !-------------------------------------------------------------------------------------------------- ! update average and local deformation gradients - F_aim = F_aim_lastInc + F_aimDot * timeinc - if (stress_BC%myType=='P') then - P_aim = P_aim + merge((stress_BC%values - P_aim)/loadCaseTime*timeinc,.0_pReal,stress_BC%mask) - elseif (stress_BC%myType=='dot_P') then !UNTESTED - P_aim = P_aim + merge(stress_BC%values*timeinc,.0_pReal,stress_BC%mask) - endif + F_aim = F_aim_lastInc + F_aimDot * Delta_t + if(stress_BC%myType=='P') P_aim = P_aim & + + merge((stress_BC%values - P_aim)/t_remaining,0.0_pReal,stress_BC%mask)*Delta_t + if(stress_BC%myType=='dot_P') P_aim = P_aim & + + merge(stress_BC%values,0.0_pReal,stress_BC%mask)*Delta_t - 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(Delta_t,F_lastInc,Fdot, & ! estimate of F at end of time+Delta_t that matches rotated F_aim on average rotation_BC%rotate(F_aim,active=.true.)),& [9,grid(1),grid(2),grid3]) if (guess) then - F_tau = reshape(Utilities_forwardField(timeinc,F_tau_lastInc,F_taudot), & + F_tau = reshape(Utilities_forwardField(Delta_t,F_tau_lastInc,F_taudot), & [9,grid(1),grid(2),grid3]) ! does not have any average value as boundary condition else do k = 1, grid3; do j = 1, grid(2); do i = 1, grid(1) F_lambda33 = reshape(F_tau(1:9,i,j,k)-F(1:9,i,j,k),[3,3]) - F_lambda33 = math_mul3333xx33(S_scale,matmul(F_lambda33, & - math_mul3333xx33(C_scale,& - matmul(transpose(F_lambda33),& - F_lambda33)-math_I3))*0.5_pReal) & - + math_I3 + F_lambda33 = math_I3 & + + math_mul3333xx33(S_scale,0.5_pReal*matmul(F_lambda33, & + math_mul3333xx33(C_scale,matmul(transpose(F_lambda33),F_lambda33)-math_I3))) F_tau(1:9,i,j,k) = reshape(F_lambda33,[9])+F(1:9,i,j,k) enddo; enddo; enddo endif call DMDAVecRestoreArrayF90(da,solution_vec,FandF_tau,ierr); CHKERRQ(ierr) +!-------------------------------------------------------------------------------------------------- +! set module wide available data + params%stress_mask = stress_BC%mask + params%rotation_BC = rotation_BC + params%timeinc = Delta_t + end subroutine grid_mech_spectral_polarisation_forward !-------------------------------------------------------------------------------------------------- -!> @brief Age +!> @brief Update coordinates !-------------------------------------------------------------------------------------------------- subroutine grid_mech_spectral_polarisation_updateCoords @@ -436,6 +432,7 @@ subroutine grid_mech_spectral_polarisation_restartWrite fileHandle = HDF5_openFile(fileName,'w') groupHandle = HDF5_addGroup(fileHandle,'solver') + call HDF5_write(groupHandle,F_aim, 'P_aim') call HDF5_write(groupHandle,F_aim, 'F_aim') call HDF5_write(groupHandle,F_aim_lastInc,'F_aim_lastInc') call HDF5_write(groupHandle,F_aimDot, 'F_aimDot') @@ -480,11 +477,11 @@ subroutine converged(snes_local,PETScIter,devNull1,devNull2,devNull3,reason,dumm divTol = max(maxval(abs(P_av)) *num%eps_div_rtol ,num%eps_div_atol) BCTol = max(maxval(abs(P_av)) *num%eps_stress_rtol,num%eps_stress_atol) - if ((totalIter >= num%itmin .and. & - all([ err_div /divTol, & - err_curl/curlTol, & - err_BC /BCTol ] < 1.0_pReal)) & - .or. terminallyIll) then + if (terminallyIll .or. & + (totalIter >= num%itmin .and. & + all([ err_div /divTol, & + err_curl/curlTol, & + err_BC /BCTol ] < 1.0_pReal))) then reason = 1 elseif (totalIter >= num%itmax) then reason = -1 @@ -555,7 +552,7 @@ subroutine formResidual(in, FandF_tau, & newIteration: if (totalIter <= PETScIter) then totalIter = totalIter + 1 print'(1x,a,3(a,i0))', trim(incInfo), ' @ Iteration ', num%itmin, '≤',totalIter, '≤', num%itmax - if(debugRotation) & + if (debugRotation) & write(IO_STDOUT,'(/,a,/,3(3(f12.7,1x)/))',advance='no') & ' deformation gradient aim (lab) =', transpose(params%rotation_BC%rotate(F_aim,active=.true.)) write(IO_STDOUT,'(/,a,/,3(3(f12.7,1x)/))',advance='no') & diff --git a/src/grid/spectral_utilities.f90 b/src/grid/spectral_utilities.f90 index 1e1608d7c..6d6e26cae 100644 --- a/src/grid/spectral_utilities.f90 +++ b/src/grid/spectral_utilities.f90 @@ -93,7 +93,7 @@ module spectral_utilities real(pReal), dimension(3,3) :: stress_BC logical, dimension(3,3) :: stress_mask type(rotation) :: rotation_BC - real(pReal) :: timeinc, timeincOld + real(pReal) :: timeinc end type tSolutionParams type :: tNumerics diff --git a/src/mesh/mesh_mech_FEM.f90 b/src/mesh/mesh_mech_FEM.f90 index 8aa084ac8..b6ce1e175 100644 --- a/src/mesh/mesh_mech_FEM.f90 +++ b/src/mesh/mesh_mech_FEM.f90 @@ -32,7 +32,6 @@ module mesh_mech_FEM type tSolutionParams type(tFieldBC) :: fieldBC real(pReal) :: timeinc - real(pReal) :: timeincOld end type tSolutionParams type(tSolutionParams) :: params @@ -302,7 +301,6 @@ type(tSolutionState) function FEM_mech_solution( & !-------------------------------------------------------------------------------------------------- ! set module wide availabe data params%timeinc = timeinc - params%timeincOld = timeinc_old params%fieldBC = fieldBC call SNESSolve(mech_snes,PETSC_NULL_VEC,solution,ierr); CHKERRQ(ierr) ! solve mech_snes based on solution guess (result in solution) From b0301239808676eac5bc59e7a41c3b629b5b7737 Mon Sep 17 00:00:00 2001 From: Test User Date: Tue, 15 Dec 2020 10:16:44 +0100 Subject: [PATCH 043/148] [skip ci] updated version information after successful test of v3.0.0-alpha2-35-g1ebd10745 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 5cc60b5dd..b7128c9af 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v3.0.0-alpha2-26-gaad123f41 +v3.0.0-alpha2-35-g1ebd10745 From 872ceac855fa1e5e50d388f0a0fb8de992b41baf Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Tue, 15 Dec 2020 11:26:31 +0100 Subject: [PATCH 044/148] not needed --- src/crystallite.f90 | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/crystallite.f90 b/src/crystallite.f90 index 66c1df607..3e8b90c38 100644 --- a/src/crystallite.f90 +++ b/src/crystallite.f90 @@ -135,7 +135,6 @@ contains !-------------------------------------------------------------------------------------------------- subroutine crystallite_init - logical, dimension(discretization_nIPs,discretization_Nelems) :: devNull integer :: & c, & !< counter in integration point component loop i, & !< counter in integration point loop @@ -288,8 +287,6 @@ subroutine crystallite_init enddo !$OMP END PARALLEL DO - devNull = crystallite_stress() - #ifdef DEBUG if (debugCrystallite%basic) then print'(a42,1x,i10)', ' # of elements: ', eMax @@ -321,14 +318,11 @@ function crystallite_stress() subLp0,& !< plastic velocity grad at start of crystallite inc subLi0 !< intermediate velocity grad at start of crystallite inc - todo = .false. subLp0 = crystallite_partitionedLp0 subLi0 = crystallite_partitionedLi0 - - !-------------------------------------------------------------------------------------------------- ! initialize to starting condition crystallite_subStep = 0.0_pReal @@ -435,8 +429,6 @@ function crystallite_stress() ! integrate --- requires fully defined state array (basic + dependent state) where(.not. crystallite_converged .and. crystallite_subStep > num%subStepMinCryst) & ! do not try non-converged but fully cutbacked any further todo = .true. ! TODO: again unroll this into proper elementloop to avoid N^2 for single point evaluation - - enddo cutbackLooping ! return whether converged or not @@ -471,10 +463,10 @@ subroutine crystallite_initializeRestorationPoints(i,e) crystallite_partitionedS0(1:3,1:3,c,i,e) = crystallite_S0(1:3,1:3,c,i,e) plasticState(material_phaseAt(c,e))%partitionedState0(:,material_phasememberAt(c,i,e)) = & - plasticState(material_phaseAt(c,e))%state0( :,material_phasememberAt(c,i,e)) + plasticState(material_phaseAt(c,e))%state0( :,material_phasememberAt(c,i,e)) do s = 1, phase_Nsources(material_phaseAt(c,e)) sourceState(material_phaseAt(c,e))%p(s)%partitionedState0(:,material_phasememberAt(c,i,e)) = & - sourceState(material_phaseAt(c,e))%p(s)%state0( :,material_phasememberAt(c,i,e)) + sourceState(material_phaseAt(c,e))%p(s)%state0( :,material_phasememberAt(c,i,e)) enddo enddo From d7f035235c5052125ddd384d952a301ed30998a7 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Tue, 15 Dec 2020 14:01:39 +0100 Subject: [PATCH 045/148] do initialization later --- src/CPFEM.f90 | 1 + src/CPFEM2.f90 | 1 + src/crystallite.f90 | 44 +++++++++++++++++++++++++++----------------- 3 files changed, 29 insertions(+), 17 deletions(-) diff --git a/src/CPFEM.f90 b/src/CPFEM.f90 index c49ecbcb6..58c17554a 100644 --- a/src/CPFEM.f90 +++ b/src/CPFEM.f90 @@ -93,6 +93,7 @@ subroutine CPFEM_initAll call homogenization_init call CPFEM_init call config_deallocate + call crystallite_setInitialValues ! ToDo: MD More general approach needed end subroutine CPFEM_initAll diff --git a/src/CPFEM2.f90 b/src/CPFEM2.f90 index 994859758..5d9d24149 100644 --- a/src/CPFEM2.f90 +++ b/src/CPFEM2.f90 @@ -67,6 +67,7 @@ subroutine CPFEM_initAll call homogenization_init call CPFEM_init call config_deallocate + call crystallite_setInitialValues ! ToDo: MD More general approach needed end subroutine CPFEM_initAll diff --git a/src/crystallite.f90 b/src/crystallite.f90 index 3e8b90c38..0fcade113 100644 --- a/src/crystallite.f90 +++ b/src/crystallite.f90 @@ -115,6 +115,7 @@ module crystallite public :: & crystallite_init, & + crystallite_setInitialValues, & crystallite_stress, & crystallite_stressTangent, & crystallite_orientations, & @@ -136,9 +137,7 @@ contains subroutine crystallite_init integer :: & - c, & !< counter in integration point component loop - i, & !< counter in integration point loop - e, & !< counter in element loop + p, & cMax, & !< maximum number of integration point components iMax, & !< maximum number of integration points eMax !< maximum number of elements @@ -237,19 +236,38 @@ subroutine crystallite_init phases => config_material%get('phase') allocate(output_constituent(phases%length)) - do c = 1, phases%length - phase => phases%get(c) + do p = 1, phases%length + phase => phases%get(p) mech => phase%get('mechanics',defaultVal = emptyDict) #if defined(__GFORTRAN__) - output_constituent(c)%label = output_asStrings(mech) + output_constituent(p)%label = output_asStrings(mech) #else - output_constituent(c)%label = mech%get_asStrings('output',defaultVal=emptyStringArray) + output_constituent(p)%label = mech%get_asStrings('output',defaultVal=emptyStringArray) #endif enddo +#ifdef DEBUG + if (debugCrystallite%basic) then + print'(a42,1x,i10)', ' # of elements: ', eMax + print'(a42,1x,i10)', ' # of integration points/element: ', iMax + print'(a42,1x,i10)', 'max # of constituents/integration point: ', cMax + flush(IO_STDOUT) + endif +#endif + +end subroutine crystallite_init + !-------------------------------------------------------------------------------------------------- -! initialize +!> @brief Set initial values +!-------------------------------------------------------------------------------------------------- +subroutine crystallite_setInitialValues + + integer :: & + c, & !< counter in integration point component loop + i, & !< counter in integration point loop + e !< counter in element loop + !$OMP PARALLEL DO PRIVATE(i,c) do e = FEsolving_execElem(1),FEsolving_execElem(2) do i = FEsolving_execIP(1), FEsolving_execIP(2); do c = 1, homogenization_Nconstituents(material_homogenizationAt(e)) @@ -287,16 +305,8 @@ subroutine crystallite_init enddo !$OMP END PARALLEL DO -#ifdef DEBUG - if (debugCrystallite%basic) then - print'(a42,1x,i10)', ' # of elements: ', eMax - print'(a42,1x,i10)', ' # of integration points/element: ', iMax - print'(a42,1x,i10)', 'max # of constituents/integration point: ', cMax - flush(IO_STDOUT) - endif -#endif -end subroutine crystallite_init +end subroutine crystallite_setInitialValues !-------------------------------------------------------------------------------------------------- From f8756ad95ae71128c7c9fca0239f9cf9887c72bb Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Tue, 15 Dec 2020 17:45:11 +0100 Subject: [PATCH 046/148] simplifying no extral handling for homogeneous temperature (the memory that was saved was consumed by the extra mapping) --- src/CPFEM.f90 | 2 +- src/constitutive.f90 | 24 ++++++++++------------- src/constitutive_mech.f90 | 10 ++++++++-- src/damage_local.f90 | 8 +++----- src/damage_none.f90 | 5 +++-- src/damage_nonlocal.f90 | 8 +++----- src/grid/grid_thermal_spectral.f90 | 3 +-- src/kinematics_thermal_expansion.f90 | 4 ++-- src/material.f90 | 29 +++------------------------- src/thermal_adiabatic.f90 | 11 ++++------- src/thermal_conduction.f90 | 5 +---- src/thermal_isothermal.f90 | 7 +++---- 12 files changed, 42 insertions(+), 74 deletions(-) diff --git a/src/CPFEM.f90 b/src/CPFEM.f90 index 58c17554a..eb3243576 100644 --- a/src/CPFEM.f90 +++ b/src/CPFEM.f90 @@ -182,7 +182,7 @@ subroutine CPFEM_general(mode, ffn, ffn1, temperature_inp, dt, elFE, ip, cauchyS chosenThermal1: select case (thermal_type(material_homogenizationAt(elCP))) case (THERMAL_conduction_ID) chosenThermal1 - temperature(material_homogenizationAt(elCP))%p(thermalMapping(material_homogenizationAt(elCP))%p(ip,elCP)) = & + temperature(material_homogenizationAt(elCP))%p(material_homogenizationMemberAt(ip,elCP)) = & temperature_inp end select chosenThermal1 homogenization_F0(1:3,1:3,ip,elCP) = ffn diff --git a/src/constitutive.f90 b/src/constitutive.f90 index 470ac4dc7..a60352f81 100644 --- a/src/constitutive.f90 +++ b/src/constitutive.f90 @@ -19,25 +19,21 @@ module constitutive implicit none private - integer(kind(ELASTICITY_undefined_ID)), dimension(:), allocatable :: & !ToDo: old intel compiler complains about protected - phase_elasticity !< elasticity of each phase - - integer(kind(PLASTICITY_undefined_ID)), dimension(:), allocatable :: & !ToDo: old intel compiler complains about protected + integer(kind(PLASTICITY_undefined_ID)), dimension(:), allocatable :: & phase_plasticity !< plasticity of each phase - integer(kind(SOURCE_undefined_ID)), dimension(:,:), allocatable :: & ! ToDo: old intel compiler complains about protected + integer(kind(SOURCE_undefined_ID)), dimension(:,:), allocatable :: & phase_source, & !< active sources mechanisms of each phase - phase_kinematics, & !< active kinematic mechanisms of each phase - phase_stiffnessDegradation !< active stiffness degradation mechanisms of each phase + phase_kinematics !< active kinematic mechanisms of each phase - integer, dimension(:), allocatable, public :: & ! ToDo: old intel compiler complains about protected + integer, dimension(:), allocatable, public :: & !< ToDo: should be protected (bug in Intel compiler) phase_Nsources, & !< number of source mechanisms active in each phase phase_Nkinematics, & !< number of kinematic mechanisms active in each phase phase_NstiffnessDegradations, & !< number of stiffness degradation mechanisms active in each phase phase_plasticityInstance, & !< instance of particular plasticity of each phase phase_elasticityInstance !< instance of particular elasticity of each phase - logical, dimension(:), allocatable, public :: & ! ToDo: old intel compiler complains about protected + logical, dimension(:), allocatable, public :: & ! ToDo: should be protected (bug in Intel Compiler) phase_localPlasticity !< flags phases with local constitutive law type(tPlasticState), allocatable, dimension(:), public :: & @@ -634,10 +630,10 @@ pure function constitutive_initialFi(ipc, ip, el) KinematicsLoop: do k = 1, phase_Nkinematics(phase) !< Warning: small initial strain assumption kinematicsType: select case (phase_kinematics(k,phase)) case (KINEMATICS_thermal_expansion_ID) kinematicsType - homog = material_homogenizationAt(el) - offset = thermalMapping(homog)%p(ip,el) - constitutive_initialFi = & - constitutive_initialFi + kinematics_thermal_expansion_initialStrain(homog,phase,offset) + homog = material_homogenizationAt(el) + offset = material_homogenizationMemberAt(ip,el) + constitutive_initialFi = constitutive_initialFi & + + kinematics_thermal_expansion_initialStrain(homog,phase,offset) end select kinematicsType enddo KinematicsLoop @@ -674,7 +670,7 @@ function constitutive_collectDotState(S, FArray, Fi, FpArray, subdt, ipc, ip, el logical :: broken ho = material_homogenizationAt(el) - tme = thermalMapping(ho)%p(ip,el) + tme = material_homogenizationMemberAt(ip,el) instance = phase_plasticityInstance(phase) Mp = matmul(matmul(transpose(Fi),Fi),S) diff --git a/src/constitutive_mech.f90 b/src/constitutive_mech.f90 index dc3a935e3..d64ea327c 100644 --- a/src/constitutive_mech.f90 +++ b/src/constitutive_mech.f90 @@ -3,6 +3,12 @@ !---------------------------------------------------------------------------------------------------- submodule(constitutive) constitutive_mech + integer(kind(ELASTICITY_undefined_ID)), dimension(:), allocatable :: & + phase_elasticity !< elasticity of each phase + integer(kind(SOURCE_undefined_ID)), dimension(:,:), allocatable :: & + phase_stiffnessDegradation !< active stiffness degradation mechanisms of each phase + + interface module function plastic_none_init() result(myPlasticity) @@ -360,7 +366,7 @@ module subroutine constitutive_plastic_dependentState(F, Fp, ipc, ip, el) instance, of ho = material_homogenizationAt(el) - tme = thermalMapping(ho)%p(ip,el) + tme = material_homogenizationMemberAt(ip,el) of = material_phasememberAt(ipc,ip,el) instance = phase_plasticityInstance(material_phaseAt(ipc,el)) @@ -407,7 +413,7 @@ module subroutine constitutive_plastic_LpAndItsTangents(Lp, dLp_dS, dLp_dFi, & i, j, instance, of ho = material_homogenizationAt(el) - tme = thermalMapping(ho)%p(ip,el) + tme = material_homogenizationMemberAt(ip,el) Mp = matmul(matmul(transpose(Fi),Fi),S) of = material_phasememberAt(ipc,ip,el) diff --git a/src/damage_local.f90 b/src/damage_local.f90 index e63db90b0..0003bb2a8 100644 --- a/src/damage_local.f90 +++ b/src/damage_local.f90 @@ -75,13 +75,11 @@ subroutine damage_local_init Nmaterialpoints = count(material_homogenizationAt == h) damageState(h)%sizeState = 1 - allocate(damageState(h)%state0 (1,Nmaterialpoints), source=damage_initialPhi(h)) - allocate(damageState(h)%subState0(1,Nmaterialpoints), source=damage_initialPhi(h)) - allocate(damageState(h)%state (1,Nmaterialpoints), source=damage_initialPhi(h)) + allocate(damageState(h)%state0 (1,Nmaterialpoints), source=1.0_pReal) + allocate(damageState(h)%subState0(1,Nmaterialpoints), source=1.0_pReal) + allocate(damageState(h)%state (1,Nmaterialpoints), source=1.0_pReal) - nullify(damageMapping(h)%p) damageMapping(h)%p => material_homogenizationMemberAt - deallocate(damage(h)%p) damage(h)%p => damageState(h)%state(1,:) end associate diff --git a/src/damage_none.f90 b/src/damage_none.f90 index 2279bc06b..1cf3de6de 100644 --- a/src/damage_none.f90 +++ b/src/damage_none.f90 @@ -3,6 +3,7 @@ !> @brief material subroutine for constant damage field !-------------------------------------------------------------------------------------------------- module damage_none + use prec use config use material @@ -29,8 +30,8 @@ subroutine damage_none_init allocate(damageState(h)%subState0(0,Nmaterialpoints)) allocate(damageState(h)%state (0,Nmaterialpoints)) - deallocate(damage(h)%p) - allocate (damage(h)%p(1), source=damage_initialPhi(h)) + damageMapping(h)%p => material_homogenizationMemberAt + allocate (damage(h)%p(Nmaterialpoints), source=1.0_pReal) enddo diff --git a/src/damage_nonlocal.f90 b/src/damage_nonlocal.f90 index 24a51cf54..ce97ec24a 100644 --- a/src/damage_nonlocal.f90 +++ b/src/damage_nonlocal.f90 @@ -78,13 +78,11 @@ subroutine damage_nonlocal_init Nmaterialpoints = count(material_homogenizationAt == h) damageState(h)%sizeState = 1 - allocate(damageState(h)%state0 (1,Nmaterialpoints), source=damage_initialPhi(h)) - allocate(damageState(h)%subState0(1,Nmaterialpoints), source=damage_initialPhi(h)) - allocate(damageState(h)%state (1,Nmaterialpoints), source=damage_initialPhi(h)) + allocate(damageState(h)%state0 (1,Nmaterialpoints), source=1.0_pReal) + allocate(damageState(h)%subState0(1,Nmaterialpoints), source=1.0_pReal) + allocate(damageState(h)%state (1,Nmaterialpoints), source=1.0_pReal) - nullify(damageMapping(h)%p) damageMapping(h)%p => material_homogenizationMemberAt - deallocate(damage(h)%p) damage(h)%p => damageState(h)%state(1,:) end associate diff --git a/src/grid/grid_thermal_spectral.f90 b/src/grid/grid_thermal_spectral.f90 index f5d1a33bc..259b45f33 100644 --- a/src/grid/grid_thermal_spectral.f90 +++ b/src/grid/grid_thermal_spectral.f90 @@ -131,8 +131,7 @@ subroutine grid_thermal_spectral_init cell = 0 do k = 1, grid3; do j = 1, grid(2); do i = 1,grid(1) cell = cell + 1 - T_current(i,j,k) = temperature(material_homogenizationAt(cell))% & - p(thermalMapping(material_homogenizationAt(cell))%p(1,cell)) + T_current(i,j,k) = temperature(material_homogenizationAt(cell))%p(material_homogenizationMemberAt(1,cell)) T_lastInc(i,j,k) = T_current(i,j,k) T_stagInc(i,j,k) = T_current(i,j,k) enddo; enddo; enddo diff --git a/src/kinematics_thermal_expansion.f90 b/src/kinematics_thermal_expansion.f90 index 2b8b04d85..36a882a48 100644 --- a/src/kinematics_thermal_expansion.f90 +++ b/src/kinematics_thermal_expansion.f90 @@ -126,8 +126,8 @@ module subroutine kinematics_thermal_expansion_LiAndItsTangent(Li, dLi_dTstar, i phase = material_phaseAt(ipc,el) homog = material_homogenizationAt(el) - T = temperature(homog)%p(thermalMapping(homog)%p(ip,el)) - TDot = temperatureRate(homog)%p(thermalMapping(homog)%p(ip,el)) + T = temperature(homog)%p(material_homogenizationMemberAt(ip,el)) + TDot = temperatureRate(homog)%p(material_homogenizationMemberAt(ip,el)) associate(prm => param(kinematics_thermal_expansion_instance(phase))) Li = TDot * ( & diff --git a/src/material.f90 b/src/material.f90 index b05979298..33b64e6df 100644 --- a/src/material.f90 +++ b/src/material.f90 @@ -64,17 +64,16 @@ module material homogenization_type !< type of each homogenization integer, public, protected :: & - homogenization_maxNconstituents !< max number of grains in any USED homogenization + homogenization_maxNconstituents !< max number of grains in any USED homogenization integer, dimension(:), allocatable, public, protected :: & - homogenization_Nconstituents, & !< number of grains in each homogenization + homogenization_Nconstituents, & !< number of grains in each homogenization homogenization_typeInstance, & !< instance of particular type of each homogenization thermal_typeInstance, & !< instance of particular type of each thermal transport damage_typeInstance !< instance of particular type of each nonlocal damage real(pReal), dimension(:), allocatable, public, protected :: & - thermal_initialT, & !< initial temperature per each homogenization - damage_initialPhi !< initial damage per each homogenization + thermal_initialT !< initial temperature per each homogenization integer, dimension(:), allocatable, public, protected :: & ! (elem) material_homogenizationAt !< homogenization ID of each element @@ -93,12 +92,7 @@ module material type(Rotation), dimension(:,:,:), allocatable, public, protected :: & material_orientation0 !< initial orientation of each grain,IP,element -! BEGIN DEPRECATED - integer, dimension(:,:), allocatable, private, target :: mappingHomogenizationConst !< mapping from material points to offset in constant state/field -! END DEPRECATED - type(tHomogMapping), allocatable, dimension(:), public :: & - thermalMapping, & !< mapping for thermal state/fields damageMapping !< mapping for damage state/fields type(group_float), allocatable, dimension(:), public :: & @@ -165,7 +159,6 @@ subroutine material_init(restart) allocate(thermalState (size(material_name_homogenization))) allocate(damageState (size(material_name_homogenization))) - allocate(thermalMapping (size(material_name_homogenization))) allocate(damageMapping (size(material_name_homogenization))) allocate(temperature (size(material_name_homogenization))) @@ -181,20 +174,6 @@ subroutine material_init(restart) call results_closeJobFile endif -!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -! BEGIN DEPRECATED - allocate(mappingHomogenizationConst( discretization_nIPs,discretization_Nelems),source=1) - -! hack needed to initialize field values used during constitutive initialization - do myHomog = 1, size(material_name_homogenization) - thermalMapping (myHomog)%p => mappingHomogenizationConst - damageMapping (myHomog)%p => mappingHomogenizationConst - allocate(temperature (myHomog)%p(1), source=thermal_initialT(myHomog)) - allocate(damage (myHomog)%p(1), source=damage_initialPhi(myHomog)) - allocate(temperatureRate (myHomog)%p(1), source=0.0_pReal) - enddo -! END DEPRECATED - end subroutine material_init @@ -222,7 +201,6 @@ subroutine material_parseHomogenization allocate(thermal_typeInstance(size(material_name_homogenization)), source=0) allocate(damage_typeInstance(size(material_name_homogenization)), source=0) allocate(thermal_initialT(size(material_name_homogenization)), source=300.0_pReal) - allocate(damage_initialPhi(size(material_name_homogenization)), source=1.0_pReal) do h=1, size(material_name_homogenization) homog => material_homogenization%get(h) @@ -258,7 +236,6 @@ subroutine material_parseHomogenization if(homog%contains('damage')) then homogDamage => homog%get('damage') - damage_initialPhi(h) = homogDamage%get_asFloat('phi_0',defaultVal=1.0_pReal) select case (homogDamage%get_asString('type')) case('none') damage_type(h) = DAMAGE_none_ID diff --git a/src/thermal_adiabatic.f90 b/src/thermal_adiabatic.f90 index aa807924c..c67d004bf 100644 --- a/src/thermal_adiabatic.f90 +++ b/src/thermal_adiabatic.f90 @@ -72,12 +72,9 @@ subroutine thermal_adiabatic_init allocate(thermalState(h)%state0 (1,Nmaterialpoints), source=thermal_initialT(h)) allocate(thermalState(h)%subState0(1,Nmaterialpoints), source=thermal_initialT(h)) allocate(thermalState(h)%state (1,Nmaterialpoints), source=thermal_initialT(h)) - - thermalMapping(h)%p => material_homogenizationMemberAt - deallocate(temperature(h)%p) + temperature(h)%p => thermalState(h)%state(1,:) - deallocate(temperatureRate(h)%p) - allocate (temperatureRate(h)%p(Nmaterialpoints), source=0.0_pReal) + allocate(temperatureRate(h)%p(Nmaterialpoints),source = 0.0_pReal) end associate enddo @@ -117,8 +114,8 @@ function thermal_adiabatic_updateState(subdt, ip, el) <= 1.0e-6_pReal*abs(thermalState(homog)%state(1,offset)), & .true.] - temperature (homog)%p(thermalMapping(homog)%p(ip,el)) = T - temperatureRate(homog)%p(thermalMapping(homog)%p(ip,el)) = & + temperature (homog)%p(material_homogenizationMemberAt(ip,el)) = T + temperatureRate(homog)%p(material_homogenizationMemberAt(ip,el)) = & (thermalState(homog)%state(1,offset) - thermalState(homog)%subState0(1,offset))/(subdt+tiny(0.0_pReal)) end function thermal_adiabatic_updateState diff --git a/src/thermal_conduction.f90 b/src/thermal_conduction.f90 index daa7391a9..602bdab35 100644 --- a/src/thermal_conduction.f90 +++ b/src/thermal_conduction.f90 @@ -71,10 +71,7 @@ subroutine thermal_conduction_init allocate(thermalState(h)%subState0(0,Nmaterialpoints)) allocate(thermalState(h)%state (0,Nmaterialpoints)) - thermalMapping(h)%p => material_homogenizationMemberAt - deallocate(temperature (h)%p) allocate (temperature (h)%p(Nmaterialpoints), source=thermal_initialT(h)) - deallocate(temperatureRate(h)%p) allocate (temperatureRate(h)%p(Nmaterialpoints), source=0.0_pReal) end associate @@ -205,7 +202,7 @@ subroutine thermal_conduction_putTemperatureAndItsRate(T,Tdot,ip,el) offset homog = material_homogenizationAt(el) - offset = thermalMapping(homog)%p(ip,el) + offset = material_homogenizationMemberAt(ip,el) temperature (homog)%p(offset) = T temperatureRate(homog)%p(offset) = Tdot diff --git a/src/thermal_isothermal.f90 b/src/thermal_isothermal.f90 index 39c8efe91..adf2257de 100644 --- a/src/thermal_isothermal.f90 +++ b/src/thermal_isothermal.f90 @@ -3,6 +3,7 @@ !> @brief material subroutine for isothermal temperature field !-------------------------------------------------------------------------------------------------- module thermal_isothermal + use prec use config use material @@ -29,10 +30,8 @@ subroutine thermal_isothermal_init allocate(thermalState(h)%subState0(0,Nmaterialpoints)) allocate(thermalState(h)%state (0,Nmaterialpoints)) - deallocate(temperature (h)%p) - allocate (temperature (h)%p(1), source=thermal_initialT(h)) - deallocate(temperatureRate(h)%p) - allocate (temperatureRate(h)%p(1)) + allocate(temperature (h)%p(Nmaterialpoints),source=thermal_initialT(h)) + allocate(temperatureRate(h)%p(Nmaterialpoints),source = 0.0_pReal) enddo From f8e3cfe91d0334073d7a2a1c193883e5c913a13e Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Tue, 15 Dec 2020 19:41:47 +0100 Subject: [PATCH 047/148] not needed (was stored as restart data) --- src/CPFEM2.f90 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/CPFEM2.f90 b/src/CPFEM2.f90 index 5d9d24149..a76f018f7 100644 --- a/src/CPFEM2.f90 +++ b/src/CPFEM2.f90 @@ -67,7 +67,8 @@ subroutine CPFEM_initAll call homogenization_init call CPFEM_init call config_deallocate - call crystallite_setInitialValues ! ToDo: MD More general approach needed + if (interface_restartInc==0) & + call crystallite_setInitialValues ! ToDo: MD More general approach needed end subroutine CPFEM_initAll From 710c217d8a472e9496e6ffd073965a5088c341df Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Tue, 15 Dec 2020 19:55:55 +0100 Subject: [PATCH 048/148] no extra mapping for damage --- src/constitutive_mech.f90 | 2 +- src/damage_local.f90 | 1 - src/damage_none.f90 | 1 - src/damage_nonlocal.f90 | 3 +-- src/kinematics_cleavage_opening.f90 | 2 +- src/kinematics_slipplane_opening.f90 | 2 +- src/material.f90 | 8 +------- src/prec.f90 | 6 +----- src/source_damage_anisoBrittle.f90 | 2 +- src/source_damage_anisoDuctile.f90 | 2 +- src/source_damage_isoDuctile.f90 | 2 +- 11 files changed, 9 insertions(+), 22 deletions(-) diff --git a/src/constitutive_mech.f90 b/src/constitutive_mech.f90 index d64ea327c..6b3c6fce6 100644 --- a/src/constitutive_mech.f90 +++ b/src/constitutive_mech.f90 @@ -332,7 +332,7 @@ module subroutine constitutive_hooke_SandItsTangents(S, dS_dFe, dS_dFi, & DegradationLoop: do d = 1, phase_NstiffnessDegradations(material_phaseAt(ipc,el)) degradationType: select case(phase_stiffnessDegradation(d,material_phaseAt(ipc,el))) case (STIFFNESS_DEGRADATION_damage_ID) degradationType - C = C * damage(ho)%p(damageMapping(ho)%p(ip,el))**2 + C = C * damage(ho)%p(material_homogenizationMemberAt(ip,el))**2 end select degradationType enddo DegradationLoop diff --git a/src/damage_local.f90 b/src/damage_local.f90 index 0003bb2a8..97eaf9a8c 100644 --- a/src/damage_local.f90 +++ b/src/damage_local.f90 @@ -79,7 +79,6 @@ subroutine damage_local_init allocate(damageState(h)%subState0(1,Nmaterialpoints), source=1.0_pReal) allocate(damageState(h)%state (1,Nmaterialpoints), source=1.0_pReal) - damageMapping(h)%p => material_homogenizationMemberAt damage(h)%p => damageState(h)%state(1,:) end associate diff --git a/src/damage_none.f90 b/src/damage_none.f90 index 1cf3de6de..3f1144833 100644 --- a/src/damage_none.f90 +++ b/src/damage_none.f90 @@ -30,7 +30,6 @@ subroutine damage_none_init allocate(damageState(h)%subState0(0,Nmaterialpoints)) allocate(damageState(h)%state (0,Nmaterialpoints)) - damageMapping(h)%p => material_homogenizationMemberAt allocate (damage(h)%p(Nmaterialpoints), source=1.0_pReal) enddo diff --git a/src/damage_nonlocal.f90 b/src/damage_nonlocal.f90 index ce97ec24a..c4426f185 100644 --- a/src/damage_nonlocal.f90 +++ b/src/damage_nonlocal.f90 @@ -82,7 +82,6 @@ subroutine damage_nonlocal_init allocate(damageState(h)%subState0(1,Nmaterialpoints), source=1.0_pReal) allocate(damageState(h)%state (1,Nmaterialpoints), source=1.0_pReal) - damageMapping(h)%p => material_homogenizationMemberAt damage(h)%p => damageState(h)%state(1,:) end associate @@ -179,7 +178,7 @@ subroutine damage_nonlocal_putNonLocalDamage(phi,ip,el) offset homog = material_homogenizationAt(el) - offset = damageMapping(homog)%p(ip,el) + offset = material_homogenizationMemberAt(ip,el) damage(homog)%p(offset) = phi end subroutine damage_nonlocal_putNonLocalDamage diff --git a/src/kinematics_cleavage_opening.f90 b/src/kinematics_cleavage_opening.f90 index 66bce6a92..6fe8ed7f6 100644 --- a/src/kinematics_cleavage_opening.f90 +++ b/src/kinematics_cleavage_opening.f90 @@ -120,7 +120,7 @@ module subroutine kinematics_cleavage_opening_LiAndItsTangent(Ld, dLd_dTstar, S, udotd, dudotd_dt, udott, dudott_dt, udotn, dudotn_dt homog = material_homogenizationAt(el) - damageOffset = damageMapping(homog)%p(ip,el) + damageOffset = material_homogenizationMemberAt(ip,el) Ld = 0.0_pReal dLd_dTstar = 0.0_pReal diff --git a/src/kinematics_slipplane_opening.f90 b/src/kinematics_slipplane_opening.f90 index aa0bdfbde..b7adb6807 100644 --- a/src/kinematics_slipplane_opening.f90 +++ b/src/kinematics_slipplane_opening.f90 @@ -141,7 +141,7 @@ module subroutine kinematics_slipplane_opening_LiAndItsTangent(Ld, dLd_dTstar, S phase = material_phaseAt(ipc,el) instance = kinematics_slipplane_opening_instance(phase) homog = material_homogenizationAt(el) - damageOffset = damageMapping(homog)%p(ip,el) + damageOffset = material_homogenizationMemberAt(ip,el) associate(prm => param(instance)) Ld = 0.0_pReal diff --git a/src/material.f90 b/src/material.f90 index 33b64e6df..574da0d51 100644 --- a/src/material.f90 +++ b/src/material.f90 @@ -77,7 +77,7 @@ module material integer, dimension(:), allocatable, public, protected :: & ! (elem) material_homogenizationAt !< homogenization ID of each element - integer, dimension(:,:), allocatable, public, target :: & ! (ip,elem) ToDo: ugly target for mapping hack + integer, dimension(:,:), allocatable, public, protected :: & ! (ip,elem) material_homogenizationMemberAt !< position of the element within its homogenization instance integer, dimension(:,:), allocatable, public, protected :: & ! (constituent,elem) material_phaseAt !< phase ID of each element @@ -92,9 +92,6 @@ module material type(Rotation), dimension(:,:,:), allocatable, public, protected :: & material_orientation0 !< initial orientation of each grain,IP,element - type(tHomogMapping), allocatable, dimension(:), public :: & - damageMapping !< mapping for damage state/fields - type(group_float), allocatable, dimension(:), public :: & temperature, & !< temperature field damage, & !< damage field @@ -159,11 +156,8 @@ subroutine material_init(restart) allocate(thermalState (size(material_name_homogenization))) allocate(damageState (size(material_name_homogenization))) - allocate(damageMapping (size(material_name_homogenization))) - allocate(temperature (size(material_name_homogenization))) allocate(damage (size(material_name_homogenization))) - allocate(temperatureRate (size(material_name_homogenization))) diff --git a/src/prec.f90 b/src/prec.f90 index 738775e3b..95b1116cd 100644 --- a/src/prec.f90 +++ b/src/prec.f90 @@ -54,7 +54,7 @@ module prec type, extends(tState) :: tPlasticState logical :: & nonlocal = .false. - real(pReal), pointer, dimension(:,:) :: & + real(pReal), pointer, dimension(:,:) :: & slipRate !< slip rate end type @@ -62,10 +62,6 @@ module prec type(tState), dimension(:), allocatable :: p !< tState for each active source mechanism in a phase end type - type :: tHomogMapping - integer, pointer, dimension(:,:) :: p - end type - real(pReal), private, parameter :: PREAL_EPSILON = epsilon(0.0_pReal) !< minimum positive number such that 1.0 + EPSILON /= 1.0. real(pReal), private, parameter :: PREAL_MIN = tiny(0.0_pReal) !< smallest normalized floating point number diff --git a/src/source_damage_anisoBrittle.f90 b/src/source_damage_anisoBrittle.f90 index ca8d6ec2b..55d5546fc 100644 --- a/src/source_damage_anisoBrittle.f90 +++ b/src/source_damage_anisoBrittle.f90 @@ -143,7 +143,7 @@ module subroutine source_damage_anisoBrittle_dotState(S, ipc, ip, el) constituent = material_phasememberAt(ipc,ip,el) sourceOffset = source_damage_anisoBrittle_offset(phase) homog = material_homogenizationAt(el) - damageOffset = damageMapping(homog)%p(ip,el) + damageOffset = material_homogenizationMemberAt(ip,el) associate(prm => param(source_damage_anisoBrittle_instance(phase))) sourceState(phase)%p(sourceOffset)%dotState(1,constituent) = 0.0_pReal diff --git a/src/source_damage_anisoDuctile.f90 b/src/source_damage_anisoDuctile.f90 index 601ec2531..912fe1387 100644 --- a/src/source_damage_anisoDuctile.f90 +++ b/src/source_damage_anisoDuctile.f90 @@ -125,7 +125,7 @@ module subroutine source_damage_anisoDuctile_dotState(ipc, ip, el) constituent = material_phasememberAt(ipc,ip,el) sourceOffset = source_damage_anisoDuctile_offset(phase) homog = material_homogenizationAt(el) - damageOffset = damageMapping(homog)%p(ip,el) + damageOffset = material_homogenizationMemberAt(ip,el) associate(prm => param(source_damage_anisoDuctile_instance(phase))) sourceState(phase)%p(sourceOffset)%dotState(1,constituent) & diff --git a/src/source_damage_isoDuctile.f90 b/src/source_damage_isoDuctile.f90 index 1bff20570..b66e220d9 100644 --- a/src/source_damage_isoDuctile.f90 +++ b/src/source_damage_isoDuctile.f90 @@ -116,7 +116,7 @@ module subroutine source_damage_isoDuctile_dotState(ipc, ip, el) constituent = material_phasememberAt(ipc,ip,el) sourceOffset = source_damage_isoDuctile_offset(phase) homog = material_homogenizationAt(el) - damageOffset = damageMapping(homog)%p(ip,el) + damageOffset = material_homogenizationMemberAt(ip,el) associate(prm => param(source_damage_isoDuctile_instance(phase))) sourceState(phase)%p(sourceOffset)%dotState(1,constituent) = & From d7889aff12f6aefcd7270fb31756124fff0bbed2 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Wed, 16 Dec 2020 09:13:13 +0100 Subject: [PATCH 049/148] extra function not (yet) needed --- src/CPFEM.f90 | 3 +-- src/CPFEM2.f90 | 4 +--- src/crystallite.f90 | 23 ++++++----------------- 3 files changed, 8 insertions(+), 22 deletions(-) diff --git a/src/CPFEM.f90 b/src/CPFEM.f90 index eb3243576..76522fb16 100644 --- a/src/CPFEM.f90 +++ b/src/CPFEM.f90 @@ -89,11 +89,10 @@ subroutine CPFEM_initAll call lattice_init call material_init(.false.) call constitutive_init - call crystallite_init call homogenization_init + call crystallite_init call CPFEM_init call config_deallocate - call crystallite_setInitialValues ! ToDo: MD More general approach needed end subroutine CPFEM_initAll diff --git a/src/CPFEM2.f90 b/src/CPFEM2.f90 index a76f018f7..54e381d34 100644 --- a/src/CPFEM2.f90 +++ b/src/CPFEM2.f90 @@ -63,12 +63,10 @@ subroutine CPFEM_initAll #endif call material_init(restart=interface_restartInc>0) call constitutive_init - call crystallite_init call homogenization_init + call crystallite_init call CPFEM_init call config_deallocate - if (interface_restartInc==0) & - call crystallite_setInitialValues ! ToDo: MD More general approach needed end subroutine CPFEM_initAll diff --git a/src/crystallite.f90 b/src/crystallite.f90 index 0fcade113..31a6bde2d 100644 --- a/src/crystallite.f90 +++ b/src/crystallite.f90 @@ -69,9 +69,9 @@ module crystallite real(pReal), dimension(:,:,:,:,:), allocatable, public :: & crystallite_partitionedF !< def grad to be reached at end of homog inc - logical, dimension(:,:,:), allocatable, public :: & + logical, dimension(:,:,:), allocatable, public :: & crystallite_requested !< used by upper level (homogenization) to request crystallite calculation - logical, dimension(:,:,:), allocatable :: & + logical, dimension(:,:,:), allocatable :: & crystallite_converged !< convergence flag type :: tOutput !< new requested output (per phase) @@ -115,7 +115,6 @@ module crystallite public :: & crystallite_init, & - crystallite_setInitialValues, & crystallite_stress, & crystallite_stressTangent, & crystallite_orientations, & @@ -138,6 +137,9 @@ subroutine crystallite_init integer :: & p, & + c, & !< counter in integration point component loop + i, & !< counter in integration point loop + e, & !< counter in element loop cMax, & !< maximum number of integration point components iMax, & !< maximum number of integration points eMax !< maximum number of elements @@ -255,19 +257,6 @@ subroutine crystallite_init endif #endif -end subroutine crystallite_init - - -!-------------------------------------------------------------------------------------------------- -!> @brief Set initial values -!-------------------------------------------------------------------------------------------------- -subroutine crystallite_setInitialValues - - integer :: & - c, & !< counter in integration point component loop - i, & !< counter in integration point loop - e !< counter in element loop - !$OMP PARALLEL DO PRIVATE(i,c) do e = FEsolving_execElem(1),FEsolving_execElem(2) do i = FEsolving_execIP(1), FEsolving_execIP(2); do c = 1, homogenization_Nconstituents(material_homogenizationAt(e)) @@ -306,7 +295,7 @@ subroutine crystallite_setInitialValues !$OMP END PARALLEL DO -end subroutine crystallite_setInitialValues +end subroutine crystallite_init !-------------------------------------------------------------------------------------------------- From 5d9c931008f56a5c01a4fb8b6d97a0ccee86372e Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Wed, 16 Dec 2020 11:21:24 +0100 Subject: [PATCH 050/148] code follows structure --- src/commercialFEM_fileList.f90 | 1 + src/homogenization.f90 | 214 ++++++-------------------- src/homogenization_mech.f90 | 199 ++++++++++++++++++++++++ src/homogenization_mech_RGC.f90 | 2 +- src/homogenization_mech_isostrain.f90 | 2 +- src/homogenization_mech_none.f90 | 4 +- 6 files changed, 252 insertions(+), 170 deletions(-) create mode 100644 src/homogenization_mech.f90 diff --git a/src/commercialFEM_fileList.f90 b/src/commercialFEM_fileList.f90 index d161b36eb..beabfcae1 100644 --- a/src/commercialFEM_fileList.f90 +++ b/src/commercialFEM_fileList.f90 @@ -52,6 +52,7 @@ #include "damage_local.f90" #include "damage_nonlocal.f90" #include "homogenization.f90" +#include "homogenization_mech.f90" #include "homogenization_mech_none.f90" #include "homogenization_mech_isostrain.f90" #include "homogenization_mech_RGC.f90" diff --git a/src/homogenization.f90 b/src/homogenization.f90 index 347634212..5958f35fa 100644 --- a/src/homogenization.f90 +++ b/src/homogenization.f90 @@ -31,13 +31,15 @@ module homogenization !-------------------------------------------------------------------------------------------------- ! General variables for the homogenization at a material point real(pReal), dimension(:,:,:,:), allocatable, public :: & - homogenization_F0, & !< def grad of IP at start of FE increment - homogenization_F !< def grad of IP to be reached at end of FE increment - real(pReal), dimension(:,:,:,:), allocatable, public, protected :: & - homogenization_P !< first P--K stress of IP - real(pReal), dimension(:,:,:,:,:,:), allocatable, public, protected :: & - homogenization_dPdF !< tangent of first P--K stress at IP + homogenization_F0, & !< def grad of IP at start of FE increment + homogenization_F !< def grad of IP to be reached at end of FE increment + real(pReal), dimension(:,:,:,:), allocatable, public :: & !, protected :: & ! Issue with ifort + homogenization_P !< first P--K stress of IP + real(pReal), dimension(:,:,:,:,:,:), allocatable, public :: & !, protected :: & + homogenization_dPdF !< tangent of first P--K stress at IP + +!-------------------------------------------------------------------------------------------------- type :: tNumerics integer :: & nMPstate !< materialpoint state loop limit @@ -62,52 +64,37 @@ module homogenization type(tDebugOptions) :: debugHomog + +!-------------------------------------------------------------------------------------------------- interface - module subroutine mech_none_init - end subroutine mech_none_init - - module subroutine mech_isostrain_init - end subroutine mech_isostrain_init - - module subroutine mech_RGC_init(num_homogMech) + module subroutine mech_init(num_homog) class(tNode), pointer, intent(in) :: & - num_homogMech !< pointer to mechanical homogenization numerics data - end subroutine mech_RGC_init + num_homog !< pointer to mechanical homogenization numerics data + end subroutine mech_init + module subroutine mech_partition(subF,ip,el) + real(pReal), intent(in), dimension(3,3) :: & + subF + integer, intent(in) :: & + ip, & !< integration point + el !< element number + end subroutine mech_partition - module subroutine mech_isostrain_partitionDeformation(F,avgF) - real(pReal), dimension (:,:,:), intent(out) :: F !< partitioned deformation gradient - real(pReal), dimension (3,3), intent(in) :: avgF !< average deformation gradient at material point - end subroutine mech_isostrain_partitionDeformation + module subroutine mech_homogenize(ip,el) + integer, intent(in) :: & + ip, & !< integration point + el !< element number + end subroutine mech_homogenize - module subroutine mech_RGC_partitionDeformation(F,avgF,instance,of) - real(pReal), dimension (:,:,:), intent(out) :: F !< partitioned deformation gradient - real(pReal), dimension (3,3), intent(in) :: avgF !< average deformation gradient at material point - integer, intent(in) :: & - instance, & - of - end subroutine mech_RGC_partitionDeformation + module subroutine mech_results(group_base,h) + character(len=*), intent(in) :: group_base + integer, intent(in) :: h - module subroutine mech_isostrain_averageStressAndItsTangent(avgP,dAvgPdAvgF,P,dPdF,instance) - real(pReal), dimension (3,3), intent(out) :: avgP !< average stress at material point - real(pReal), dimension (3,3,3,3), intent(out) :: dAvgPdAvgF !< average stiffness at material point - - real(pReal), dimension (:,:,:), intent(in) :: P !< partitioned stresses - real(pReal), dimension (:,:,:,:,:), intent(in) :: dPdF !< partitioned stiffnesses - integer, intent(in) :: instance - end subroutine mech_isostrain_averageStressAndItsTangent - - module subroutine mech_RGC_averageStressAndItsTangent(avgP,dAvgPdAvgF,P,dPdF,instance) - real(pReal), dimension (3,3), intent(out) :: avgP !< average stress at material point - real(pReal), dimension (3,3,3,3), intent(out) :: dAvgPdAvgF !< average stiffness at material point - - real(pReal), dimension (:,:,:), intent(in) :: P !< partitioned stresses - real(pReal), dimension (:,:,:,:,:), intent(in) :: dPdF !< partitioned stiffnesses - integer, intent(in) :: instance - end subroutine mech_RGC_averageStressAndItsTangent + end subroutine mech_results +! -------- ToDo --------------------------------------------------------- module function mech_RGC_updateState(P,F,F0,avgF,dt,dPdF,ip,el) logical, dimension(2) :: mech_RGC_updateState real(pReal), dimension(:,:,:), intent(in) :: & @@ -122,13 +109,8 @@ module homogenization el !< element number end function mech_RGC_updateState - - module subroutine mech_RGC_results(instance,group) - integer, intent(in) :: instance !< homogenization instance - character(len=*), intent(in) :: group !< group name in HDF5 file - end subroutine mech_RGC_results - end interface +! ----------------------------------------------------------------------- public :: & homogenization_init, & @@ -145,10 +127,11 @@ subroutine homogenization_init class (tNode) , pointer :: & num_homog, & - num_homogMech, & num_homogGeneric, & debug_homogenization + print'(/,a)', ' <<<+- homogenization init -+>>>'; flush(IO_STDOUT) + debug_homogenization => config_debug%get('homogenization', defaultVal=emptyList) debugHomog%basic = debug_homogenization%contains('basic') debugHomog%extensive = debug_homogenization%contains('extensive') @@ -163,31 +146,8 @@ subroutine homogenization_init num_homog => config_numerics%get('homogenization',defaultVal=emptyDict) - num_homogMech => num_homog%get('mech',defaultVal=emptyDict) num_homogGeneric => num_homog%get('generic',defaultVal=emptyDict) - if (any(homogenization_type == HOMOGENIZATION_NONE_ID)) call mech_none_init - if (any(homogenization_type == HOMOGENIZATION_ISOSTRAIN_ID)) call mech_isostrain_init - if (any(homogenization_type == HOMOGENIZATION_RGC_ID)) call mech_RGC_init(num_homogMech) - - if (any(thermal_type == THERMAL_isothermal_ID)) call thermal_isothermal_init - if (any(thermal_type == THERMAL_adiabatic_ID)) call thermal_adiabatic_init - if (any(thermal_type == THERMAL_conduction_ID)) call thermal_conduction_init - - if (any(damage_type == DAMAGE_none_ID)) call damage_none_init - if (any(damage_type == DAMAGE_local_ID)) call damage_local_init - if (any(damage_type == DAMAGE_nonlocal_ID)) call damage_nonlocal_init - - -!-------------------------------------------------------------------------------------------------- -! allocate and initialize global variables - allocate(homogenization_dPdF(3,3,3,3,discretization_nIPs,discretization_Nelems), source=0.0_pReal) - homogenization_F0 = spread(spread(math_I3,3,discretization_nIPs),4,discretization_Nelems) ! initialize to identity - homogenization_F = homogenization_F0 ! initialize to identity - allocate(homogenization_P(3,3,discretization_nIPs,discretization_Nelems), source=0.0_pReal) - - print'(/,a)', ' <<<+- homogenization init -+>>>'; flush(IO_STDOUT) - num%nMPstate = num_homogGeneric%get_asInt ('nMPstate', defaultVal=10) num%subStepMinHomog = num_homogGeneric%get_asFloat('subStepMin', defaultVal=1.0e-3_pReal) num%subStepSizeHomog = num_homogGeneric%get_asFloat('subStepSize', defaultVal=0.25_pReal) @@ -198,6 +158,18 @@ subroutine homogenization_init if (num%subStepSizeHomog <= 0.0_pReal) call IO_error(301,ext_msg='subStepSizeHomog') if (num%stepIncreaseHomog <= 0.0_pReal) call IO_error(301,ext_msg='stepIncreaseHomog') + + call mech_init(num_homog) + + if (any(thermal_type == THERMAL_isothermal_ID)) call thermal_isothermal_init + if (any(thermal_type == THERMAL_adiabatic_ID)) call thermal_adiabatic_init + if (any(thermal_type == THERMAL_conduction_ID)) call thermal_conduction_init + + if (any(damage_type == DAMAGE_none_ID)) call damage_none_init + if (any(damage_type == DAMAGE_local_ID)) call damage_local_init + if (any(damage_type == DAMAGE_nonlocal_ID)) call damage_nonlocal_init + + end subroutine homogenization_init @@ -330,7 +302,7 @@ subroutine materialpoint_stressAndItsTangent(dt) myNgrains = homogenization_Nconstituents(material_homogenizationAt(e)) IpLooping2: do i = FEsolving_execIP(1),FEsolving_execIP(2) if(requested(i,e) .and. .not. doneAndHappy(1,i,e)) then ! requested but not yet done - call partitionDeformation(homogenization_F0(1:3,1:3,i,e) & + call mech_partition(homogenization_F0(1:3,1:3,i,e) & + (homogenization_F(1:3,1:3,i,e)-homogenization_F0(1:3,1:3,i,e))& *(subStep(i,e)+subFrac(i,e)), & i,e) @@ -379,7 +351,7 @@ subroutine materialpoint_stressAndItsTangent(dt) !$OMP PARALLEL DO elementLooping4: do e = FEsolving_execElem(1),FEsolving_execElem(2) IpLooping4: do i = FEsolving_execIP(1),FEsolving_execIP(2) - call averageStressAndItsTangent(i,e) + call mech_homogenize(i,e) enddo IpLooping4 enddo elementLooping4 !$OMP END PARALLEL DO @@ -390,38 +362,6 @@ subroutine materialpoint_stressAndItsTangent(dt) end subroutine materialpoint_stressAndItsTangent -!-------------------------------------------------------------------------------------------------- -!> @brief partition material point def grad onto constituents -!-------------------------------------------------------------------------------------------------- -subroutine partitionDeformation(subF,ip,el) - - real(pReal), intent(in), dimension(3,3) :: & - subF - integer, intent(in) :: & - ip, & !< integration point - el !< element number - - chosenHomogenization: select case(homogenization_type(material_homogenizationAt(el))) - - case (HOMOGENIZATION_NONE_ID) chosenHomogenization - crystallite_partitionedF(1:3,1:3,1,ip,el) = subF - - case (HOMOGENIZATION_ISOSTRAIN_ID) chosenHomogenization - call mech_isostrain_partitionDeformation(& - crystallite_partitionedF(1:3,1:3,1:homogenization_Nconstituents(material_homogenizationAt(el)),ip,el), & - subF) - - case (HOMOGENIZATION_RGC_ID) chosenHomogenization - call mech_RGC_partitionDeformation(& - crystallite_partitionedF(1:3,1:3,1:homogenization_Nconstituents(material_homogenizationAt(el)),ip,el), & - subF,& - ip, & - el) - end select chosenHomogenization - -end subroutine partitionDeformation - - !-------------------------------------------------------------------------------------------------- !> @brief update the internal state of the homogenization scheme and tell whether "done" and !> "happy" with result @@ -478,49 +418,6 @@ function updateState(subdt,subF,ip,el) end function updateState -!-------------------------------------------------------------------------------------------------- -!> @brief derive average stress and stiffness from constituent quantities -!-------------------------------------------------------------------------------------------------- -subroutine averageStressAndItsTangent(ip,el) - - integer, intent(in) :: & - ip, & !< integration point - el !< element number - integer :: c - real(pReal) :: dPdFs(3,3,3,3,homogenization_Nconstituents(material_homogenizationAt(el))) - - - chosenHomogenization: select case(homogenization_type(material_homogenizationAt(el))) - case (HOMOGENIZATION_NONE_ID) chosenHomogenization - homogenization_P(1:3,1:3,ip,el) = crystallite_P(1:3,1:3,1,ip,el) - homogenization_dPdF(1:3,1:3,1:3,1:3,ip,el) = crystallite_stressTangent(1,ip,el) - - case (HOMOGENIZATION_ISOSTRAIN_ID) chosenHomogenization - do c = 1, homogenization_Nconstituents(material_homogenizationAt(el)) - dPdFs(:,:,:,:,c) = crystallite_stressTangent(c,ip,el) - enddo - call mech_isostrain_averageStressAndItsTangent(& - homogenization_P(1:3,1:3,ip,el), & - homogenization_dPdF(1:3,1:3,1:3,1:3,ip,el),& - crystallite_P(1:3,1:3,1:homogenization_Nconstituents(material_homogenizationAt(el)),ip,el), & - dPdFs, & - homogenization_typeInstance(material_homogenizationAt(el))) - - case (HOMOGENIZATION_RGC_ID) chosenHomogenization - do c = 1, homogenization_Nconstituents(material_homogenizationAt(el)) - dPdFs(:,:,:,:,c) = crystallite_stressTangent(c,ip,el) - enddo - call mech_RGC_averageStressAndItsTangent(& - homogenization_P(1:3,1:3,ip,el), & - homogenization_dPdF(1:3,1:3,1:3,1:3,ip,el),& - crystallite_P(1:3,1:3,1:homogenization_Nconstituents(material_homogenizationAt(el)),ip,el), & - dPdFs, & - homogenization_typeInstance(material_homogenizationAt(el))) - end select chosenHomogenization - -end subroutine averageStressAndItsTangent - - !-------------------------------------------------------------------------------------------------- !> @brief writes homogenization results to HDF5 output file !-------------------------------------------------------------------------------------------------- @@ -531,27 +428,12 @@ subroutine homogenization_results integer :: p character(len=:), allocatable :: group_base,group - !real(pReal), dimension(:,:,:), allocatable :: temp do p=1,size(material_name_homogenization) group_base = 'current/homogenization/'//trim(material_name_homogenization(p)) call results_closeGroup(results_addGroup(group_base)) - group = trim(group_base)//'/generic' - call results_closeGroup(results_addGroup(group)) - !temp = reshape(homogenization_F,[3,3,discretization_nIPs*discretization_Nelems]) - !call results_writeDataset(group,temp,'F',& - ! 'deformation gradient','1') - !temp = reshape(homogenization_P,[3,3,discretization_nIPs*discretization_Nelems]) - !call results_writeDataset(group,temp,'P',& - ! '1st Piola-Kirchhoff stress','Pa') - - group = trim(group_base)//'/mech' - call results_closeGroup(results_addGroup(group)) - select case(material_homogenization_type(p)) - case(HOMOGENIZATION_rgc_ID) - call mech_RGC_results(homogenization_typeInstance(p),group) - end select + call mech_results(group_base,p) group = trim(group_base)//'/damage' call results_closeGroup(results_addGroup(group)) diff --git a/src/homogenization_mech.f90 b/src/homogenization_mech.f90 new file mode 100644 index 000000000..40d26df51 --- /dev/null +++ b/src/homogenization_mech.f90 @@ -0,0 +1,199 @@ +!-------------------------------------------------------------------------------------------------- +!> @author Martin Diehl, KU Leuven +!> @brief Partition F and homogenize P/dPdF +!-------------------------------------------------------------------------------------------------- +submodule(homogenization) homogenization_mech + + interface + + module subroutine mech_none_init + end subroutine mech_none_init + + module subroutine mech_isostrain_init + end subroutine mech_isostrain_init + + module subroutine mech_RGC_init(num_homogMech) + class(tNode), pointer, intent(in) :: & + num_homogMech !< pointer to mechanical homogenization numerics data + end subroutine mech_RGC_init + + + module subroutine mech_isostrain_partitionDeformation(F,avgF) + real(pReal), dimension (:,:,:), intent(out) :: F !< partitioned deformation gradient + real(pReal), dimension (3,3), intent(in) :: avgF !< average deformation gradient at material point + end subroutine mech_isostrain_partitionDeformation + + module subroutine mech_RGC_partitionDeformation(F,avgF,instance,of) + real(pReal), dimension (:,:,:), intent(out) :: F !< partitioned deformation gradient + real(pReal), dimension (3,3), intent(in) :: avgF !< average deformation gradient at material point + integer, intent(in) :: & + instance, & + of + end subroutine mech_RGC_partitionDeformation + + + module subroutine mech_isostrain_averageStressAndItsTangent(avgP,dAvgPdAvgF,P,dPdF,instance) + real(pReal), dimension (3,3), intent(out) :: avgP !< average stress at material point + real(pReal), dimension (3,3,3,3), intent(out) :: dAvgPdAvgF !< average stiffness at material point + + real(pReal), dimension (:,:,:), intent(in) :: P !< partitioned stresses + real(pReal), dimension (:,:,:,:,:), intent(in) :: dPdF !< partitioned stiffnesses + integer, intent(in) :: instance + end subroutine mech_isostrain_averageStressAndItsTangent + + module subroutine mech_RGC_averageStressAndItsTangent(avgP,dAvgPdAvgF,P,dPdF,instance) + real(pReal), dimension (3,3), intent(out) :: avgP !< average stress at material point + real(pReal), dimension (3,3,3,3), intent(out) :: dAvgPdAvgF !< average stiffness at material point + + real(pReal), dimension (:,:,:), intent(in) :: P !< partitioned stresses + real(pReal), dimension (:,:,:,:,:), intent(in) :: dPdF !< partitioned stiffnesses + integer, intent(in) :: instance + end subroutine mech_RGC_averageStressAndItsTangent + + + module subroutine mech_RGC_results(instance,group) + integer, intent(in) :: instance !< homogenization instance + character(len=*), intent(in) :: group !< group name in HDF5 file + end subroutine mech_RGC_results + + end interface + +contains + +!-------------------------------------------------------------------------------------------------- +!> @brief Allocate variables and set parameters. +!-------------------------------------------------------------------------------------------------- +module subroutine mech_init(num_homog) + + class(tNode), pointer, intent(in) :: & + num_homog + + class(tNode), pointer :: & + num_homogMech + + print'(/,a)', ' <<<+- homogenization_mech init -+>>>' + + allocate(homogenization_dPdF(3,3,3,3,discretization_nIPs,discretization_Nelems), source=0.0_pReal) + homogenization_F0 = spread(spread(math_I3,3,discretization_nIPs),4,discretization_Nelems) ! initialize to identity + homogenization_F = homogenization_F0 ! initialize to identity + allocate(homogenization_P(3,3,discretization_nIPs,discretization_Nelems), source=0.0_pReal) + + num_homogMech => num_homog%get('mech',defaultVal=emptyDict) + if (any(homogenization_type == HOMOGENIZATION_NONE_ID)) call mech_none_init + if (any(homogenization_type == HOMOGENIZATION_ISOSTRAIN_ID)) call mech_isostrain_init + if (any(homogenization_type == HOMOGENIZATION_RGC_ID)) call mech_RGC_init(num_homogMech) + +end subroutine mech_init + + +!-------------------------------------------------------------------------------------------------- +!> @brief Partition F onto the individual constituents. +!-------------------------------------------------------------------------------------------------- +module subroutine mech_partition(subF,ip,el) + + real(pReal), intent(in), dimension(3,3) :: & + subF + integer, intent(in) :: & + ip, & !< integration point + el !< element number + + chosenHomogenization: select case(homogenization_type(material_homogenizationAt(el))) + + case (HOMOGENIZATION_NONE_ID) chosenHomogenization + crystallite_partitionedF(1:3,1:3,1,ip,el) = subF + + case (HOMOGENIZATION_ISOSTRAIN_ID) chosenHomogenization + call mech_isostrain_partitionDeformation(& + crystallite_partitionedF(1:3,1:3,1:homogenization_Nconstituents(material_homogenizationAt(el)),ip,el), & + subF) + + case (HOMOGENIZATION_RGC_ID) chosenHomogenization + call mech_RGC_partitionDeformation(& + crystallite_partitionedF(1:3,1:3,1:homogenization_Nconstituents(material_homogenizationAt(el)),ip,el), & + subF,& + ip, & + el) + + end select chosenHomogenization + +end subroutine mech_partition + + +!-------------------------------------------------------------------------------------------------- +!> @brief Average P and dPdF from the individual constituents. +!-------------------------------------------------------------------------------------------------- +module subroutine mech_homogenize(ip,el) + + integer, intent(in) :: & + ip, & !< integration point + el !< element number + integer :: c + real(pReal) :: dPdFs(3,3,3,3,homogenization_Nconstituents(material_homogenizationAt(el))) + + + chosenHomogenization: select case(homogenization_type(material_homogenizationAt(el))) + + case (HOMOGENIZATION_NONE_ID) chosenHomogenization + homogenization_P(1:3,1:3,ip,el) = crystallite_P(1:3,1:3,1,ip,el) + homogenization_dPdF(1:3,1:3,1:3,1:3,ip,el) = crystallite_stressTangent(1,ip,el) + + case (HOMOGENIZATION_ISOSTRAIN_ID) chosenHomogenization + do c = 1, homogenization_Nconstituents(material_homogenizationAt(el)) + dPdFs(:,:,:,:,c) = crystallite_stressTangent(c,ip,el) + enddo + call mech_isostrain_averageStressAndItsTangent(& + homogenization_P(1:3,1:3,ip,el), & + homogenization_dPdF(1:3,1:3,1:3,1:3,ip,el),& + crystallite_P(1:3,1:3,1:homogenization_Nconstituents(material_homogenizationAt(el)),ip,el), & + dPdFs, & + homogenization_typeInstance(material_homogenizationAt(el))) + + case (HOMOGENIZATION_RGC_ID) chosenHomogenization + do c = 1, homogenization_Nconstituents(material_homogenizationAt(el)) + dPdFs(:,:,:,:,c) = crystallite_stressTangent(c,ip,el) + enddo + call mech_RGC_averageStressAndItsTangent(& + homogenization_P(1:3,1:3,ip,el), & + homogenization_dPdF(1:3,1:3,1:3,1:3,ip,el),& + crystallite_P(1:3,1:3,1:homogenization_Nconstituents(material_homogenizationAt(el)),ip,el), & + dPdFs, & + homogenization_typeInstance(material_homogenizationAt(el))) + + end select chosenHomogenization + +end subroutine mech_homogenize + + +!-------------------------------------------------------------------------------------------------- +!> @brief Write results to file. +!-------------------------------------------------------------------------------------------------- +module subroutine mech_results(group_base,h) + use material, only: & + material_homogenization_type => homogenization_type + + character(len=*), intent(in) :: group_base + integer, intent(in) :: h + + character(len=:), allocatable :: group + + group = trim(group_base)//'/mech' + call results_closeGroup(results_addGroup(group)) + + select case(material_homogenization_type(h)) + + case(HOMOGENIZATION_rgc_ID) + call mech_RGC_results(homogenization_typeInstance(h),group) + + end select + + !temp = reshape(homogenization_F,[3,3,discretization_nIPs*discretization_Nelems]) + !call results_writeDataset(group,temp,'F',& + ! 'deformation gradient','1') + !temp = reshape(homogenization_P,[3,3,discretization_nIPs*discretization_Nelems]) + !call results_writeDataset(group,temp,'P',& + ! '1st Piola-Kirchhoff stress','Pa') + +end subroutine mech_results + + +end submodule homogenization_mech diff --git a/src/homogenization_mech_RGC.f90 b/src/homogenization_mech_RGC.f90 index 585752469..0a9d0ac92 100644 --- a/src/homogenization_mech_RGC.f90 +++ b/src/homogenization_mech_RGC.f90 @@ -6,7 +6,7 @@ !> @brief Relaxed grain cluster (RGC) homogenization scheme !> N_constituents is defined as p x q x r (cluster) !-------------------------------------------------------------------------------------------------- -submodule(homogenization) homogenization_mech_RGC +submodule(homogenization:homogenization_mech) homogenization_mech_RGC use rotations type :: tParameters diff --git a/src/homogenization_mech_isostrain.f90 b/src/homogenization_mech_isostrain.f90 index 751518e09..a56104647 100644 --- a/src/homogenization_mech_isostrain.f90 +++ b/src/homogenization_mech_isostrain.f90 @@ -4,7 +4,7 @@ !> @author Philip Eisenlohr, Max-Planck-Institut für Eisenforschung GmbH !> @brief Isostrain (full constraint Taylor assuption) homogenization scheme !-------------------------------------------------------------------------------------------------- -submodule(homogenization) homogenization_mech_isostrain +submodule(homogenization:homogenization_mech) homogenization_mech_isostrain enum, bind(c); enumerator :: & parallel_ID, & diff --git a/src/homogenization_mech_none.f90 b/src/homogenization_mech_none.f90 index 5b12247cd..d434d1ca0 100644 --- a/src/homogenization_mech_none.f90 +++ b/src/homogenization_mech_none.f90 @@ -4,7 +4,7 @@ !> @author Martin Diehl, Max-Planck-Institut für Eisenforschung GmbH !> @brief dummy homogenization homogenization scheme for 1 constituent per material point !-------------------------------------------------------------------------------------------------- -submodule(homogenization) homogenization_mech_none +submodule(homogenization:homogenization_mech) homogenization_mech_none contains @@ -28,7 +28,7 @@ module subroutine mech_none_init if(homogenization_Nconstituents(h) /= 1) & call IO_error(211,ext_msg='N_constituents (mech_none)') - + Nmaterialpoints = count(material_homogenizationAt == h) homogState(h)%sizeState = 0 allocate(homogState(h)%state0 (0,Nmaterialpoints)) From 3884549e194c5f5e25e71c7d510d659132c7035e Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Wed, 16 Dec 2020 12:48:45 +0100 Subject: [PATCH 051/148] store field variables as 1D array first step of simplifying layout: 1) Solver translates from ip,el tuple (FEM) or cells(1),cells(2),cells(3) triple to list. 2) DAMASK iterates over all points 3) homogenization knows mapping (point,constituent) -> (instance,member) --- src/CPFEM.f90 | 18 ++++---- src/grid/grid_mech_FEM.f90 | 30 +++++++------- src/grid/grid_mech_spectral_basic.f90 | 4 +- src/grid/grid_mech_spectral_polarisation.f90 | 6 +-- src/grid/spectral_utilities.f90 | 16 ++++---- src/homogenization.f90 | 23 ++++++----- src/homogenization_mech.f90 | 23 ++++++----- src/material.f90 | 1 - src/mesh/FEM_utilities.f90 | 2 +- src/mesh/mesh_mech_FEM.f90 | 43 ++++++++++---------- 10 files changed, 86 insertions(+), 80 deletions(-) diff --git a/src/CPFEM.f90 b/src/CPFEM.f90 index 76522fb16..a19a70432 100644 --- a/src/CPFEM.f90 +++ b/src/CPFEM.f90 @@ -153,7 +153,7 @@ subroutine CPFEM_general(mode, ffn, ffn1, temperature_inp, dt, elFE, ip, cauchyS H integer(pInt) elCP, & ! crystal plasticity element number - i, j, k, l, m, n, ph, homog, mySource + i, j, k, l, m, n, ph, homog, mySource,ma real(pReal), parameter :: ODD_STRESS = 1e15_pReal, & !< return value for stress if terminallyIll ODD_JACOBIAN = 1e50_pReal !< return value for jacobian if terminallyIll @@ -161,6 +161,8 @@ subroutine CPFEM_general(mode, ffn, ffn1, temperature_inp, dt, elFE, ip, cauchyS elCP = mesh_FEM2DAMASK_elem(elFE) + ma = (elCP-1) * discretization_nIPs + ip + if (debugCPFEM%basic .and. elCP == debugCPFEM%element .and. ip == debugCPFEM%ip) then print'(/,a)', '#############################################' print'(a1,a22,1x,i8,a13)', '#','element', elCP, '#' @@ -184,8 +186,8 @@ subroutine CPFEM_general(mode, ffn, ffn1, temperature_inp, dt, elFE, ip, cauchyS temperature(material_homogenizationAt(elCP))%p(material_homogenizationMemberAt(ip,elCP)) = & temperature_inp end select chosenThermal1 - homogenization_F0(1:3,1:3,ip,elCP) = ffn - homogenization_F(1:3,1:3,ip,elCP) = ffn1 + homogenization_F0(1:3,1:3,ma) = ffn + homogenization_F(1:3,1:3,ma) = ffn1 if (iand(mode, CPFEM_CALCRESULTS) /= 0_pInt) then @@ -212,17 +214,17 @@ subroutine CPFEM_general(mode, ffn, ffn1, temperature_inp, dt, elFE, ip, cauchyS else terminalIllness ! translate from P to sigma - Kirchhoff = matmul(homogenization_P(1:3,1:3,ip,elCP), transpose(homogenization_F(1:3,1:3,ip,elCP))) - J_inverse = 1.0_pReal / math_det33(homogenization_F(1:3,1:3,ip,elCP)) + Kirchhoff = matmul(homogenization_P(1:3,1:3,ma), transpose(homogenization_F(1:3,1:3,ma))) + J_inverse = 1.0_pReal / math_det33(homogenization_F(1:3,1:3,ma)) CPFEM_cs(1:6,ip,elCP) = math_sym33to6(J_inverse * Kirchhoff,weighted=.false.) ! translate from dP/dF to dCS/dE H = 0.0_pReal do i=1,3; do j=1,3; do k=1,3; do l=1,3; do m=1,3; do n=1,3 H(i,j,k,l) = H(i,j,k,l) & - + homogenization_F(j,m,ip,elCP) * homogenization_F(l,n,ip,elCP) & - * homogenization_dPdF(i,m,k,n,ip,elCP) & - - math_delta(j,l) * homogenization_F(i,m,ip,elCP) * homogenization_P(k,m,ip,elCP) & + + homogenization_F(j,m,ma) * homogenization_F(l,n,ma) & + * homogenization_dPdF(i,m,k,n,ma) & + - math_delta(j,l) * homogenization_F(i,m,ma) * homogenization_P(k,m,ma) & + 0.5_pReal * ( Kirchhoff(j,l)*math_delta(i,k) + Kirchhoff(i,k)*math_delta(j,l) & + Kirchhoff(j,k)*math_delta(i,l) + Kirchhoff(i,l)*math_delta(j,k)) enddo; enddo; enddo; enddo; enddo; enddo diff --git a/src/grid/grid_mech_FEM.f90 b/src/grid/grid_mech_FEM.f90 index 741ce404a..cdf806b35 100644 --- a/src/grid/grid_mech_FEM.f90 +++ b/src/grid/grid_mech_FEM.f90 @@ -238,7 +238,7 @@ subroutine grid_mech_FEM_init F = spread(spread(spread(math_I3,3,grid(1)),4,grid(2)),5,grid3) endif restartRead - homogenization_F0 = reshape(F_lastInc, [3,3,1,product(grid(1:2))*grid3]) ! set starting condition for materialpoint_stressAndItsTangent + homogenization_F0 = reshape(F_lastInc, [3,3,product(grid(1:2))*grid3]) ! set starting condition for materialpoint_stressAndItsTangent call utilities_updateCoords(F) call utilities_constitutiveResponse(P_current,P_av,C_volAvg,devNull, & ! stress field, stress avg, global average of stiffness and (min+max)/2 F, & ! target F @@ -359,7 +359,7 @@ subroutine grid_mech_FEM_forward(cutBack,guess,Delta_t,Delta_t_old,t_remaining,& F_lastInc = F - homogenization_F0 = reshape(F, [3,3,1,product(grid(1:2))*grid3]) + homogenization_F0 = reshape(F, [3,3,product(grid(1:2))*grid3]) endif !-------------------------------------------------------------------------------------------------- @@ -557,9 +557,9 @@ subroutine formResidual(da_local,x_local, & ii = i-xstart+1; jj = j-ystart+1; kk = k-zstart+1 ele = ele + 1 f_elem = matmul(transpose(BMat),transpose(P_current(1:3,1:3,ii,jj,kk)))*detJ + & - matmul(HGMat,x_elem)*(homogenization_dPdF(1,1,1,1,1,ele) + & - homogenization_dPdF(2,2,2,2,1,ele) + & - homogenization_dPdF(3,3,3,3,1,ele))/3.0_pReal + matmul(HGMat,x_elem)*(homogenization_dPdF(1,1,1,1,ele) + & + homogenization_dPdF(2,2,2,2,ele) + & + homogenization_dPdF(3,3,3,3,ele))/3.0_pReal ctr = 0 do kk = 0, 1; do jj = 0, 1; do ii = 0, 1 ctr = ctr + 1 @@ -636,18 +636,18 @@ subroutine formJacobian(da_local,x_local,Jac_pre,Jac,dummy,ierr) row = col ele = ele + 1 K_ele = 0.0 - K_ele(1 :8 ,1 :8 ) = HGMat*(homogenization_dPdF(1,1,1,1,1,ele) + & - homogenization_dPdF(2,2,2,2,1,ele) + & - homogenization_dPdF(3,3,3,3,1,ele))/3.0_pReal - K_ele(9 :16,9 :16) = HGMat*(homogenization_dPdF(1,1,1,1,1,ele) + & - homogenization_dPdF(2,2,2,2,1,ele) + & - homogenization_dPdF(3,3,3,3,1,ele))/3.0_pReal - K_ele(17:24,17:24) = HGMat*(homogenization_dPdF(1,1,1,1,1,ele) + & - homogenization_dPdF(2,2,2,2,1,ele) + & - homogenization_dPdF(3,3,3,3,1,ele))/3.0_pReal + K_ele(1 :8 ,1 :8 ) = HGMat*(homogenization_dPdF(1,1,1,1,ele) + & + homogenization_dPdF(2,2,2,2,ele) + & + homogenization_dPdF(3,3,3,3,ele))/3.0_pReal + K_ele(9 :16,9 :16) = HGMat*(homogenization_dPdF(1,1,1,1,ele) + & + homogenization_dPdF(2,2,2,2,ele) + & + homogenization_dPdF(3,3,3,3,ele))/3.0_pReal + K_ele(17:24,17:24) = HGMat*(homogenization_dPdF(1,1,1,1,ele) + & + homogenization_dPdF(2,2,2,2,ele) + & + homogenization_dPdF(3,3,3,3,ele))/3.0_pReal K_ele = K_ele + & matmul(transpose(BMatFull), & - matmul(reshape(reshape(homogenization_dPdF(1:3,1:3,1:3,1:3,1,ele), & + matmul(reshape(reshape(homogenization_dPdF(1:3,1:3,1:3,1:3,ele), & shape=[3,3,3,3], order=[2,1,4,3]),shape=[9,9]),BMatFull))*detJ call MatSetValuesStencil(Jac,24,row,24,col,K_ele,ADD_VALUES,ierr) CHKERRQ(ierr) diff --git a/src/grid/grid_mech_spectral_basic.f90 b/src/grid/grid_mech_spectral_basic.f90 index d87a22fb7..ebaaf3b55 100644 --- a/src/grid/grid_mech_spectral_basic.f90 +++ b/src/grid/grid_mech_spectral_basic.f90 @@ -199,7 +199,7 @@ subroutine grid_mech_spectral_basic_init F = reshape(F_lastInc,[9,grid(1),grid(2),grid3]) endif restartRead - homogenization_F0 = reshape(F_lastInc, [3,3,1,product(grid(1:2))*grid3]) ! set starting condition for materialpoint_stressAndItsTangent + homogenization_F0 = reshape(F_lastInc, [3,3,product(grid(1:2))*grid3]) ! set starting condition for materialpoint_stressAndItsTangent call utilities_updateCoords(reshape(F,shape(F_lastInc))) call utilities_constitutiveResponse(P,P_av,C_volAvg,C_minMaxAvg, & ! stress field, stress avg, global average of stiffness and (min+max)/2 reshape(F,shape(F_lastInc)), & ! target F @@ -319,7 +319,7 @@ subroutine grid_mech_spectral_basic_forward(cutBack,guess,Delta_t,Delta_t_old,t_ rotation_BC%rotate(F_aimDot,active=.true.)) F_lastInc = reshape(F,[3,3,grid(1),grid(2),grid3]) - homogenization_F0 = reshape(F,[3,3,1,product(grid(1:2))*grid3]) + homogenization_F0 = reshape(F,[3,3,product(grid(1:2))*grid3]) endif !-------------------------------------------------------------------------------------------------- diff --git a/src/grid/grid_mech_spectral_polarisation.f90 b/src/grid/grid_mech_spectral_polarisation.f90 index 9bbb40a53..9f2a17c97 100644 --- a/src/grid/grid_mech_spectral_polarisation.f90 +++ b/src/grid/grid_mech_spectral_polarisation.f90 @@ -225,7 +225,7 @@ subroutine grid_mech_spectral_polarisation_init F_tau_lastInc = 2.0_pReal*F_lastInc endif restartRead - homogenization_F0 = reshape(F_lastInc, [3,3,1,product(grid(1:2))*grid3]) ! set starting condition for materialpoint_stressAndItsTangent + homogenization_F0 = reshape(F_lastInc, [3,3,product(grid(1:2))*grid3]) ! set starting condition for materialpoint_stressAndItsTangent call utilities_updateCoords(reshape(F,shape(F_lastInc))) call utilities_constitutiveResponse(P,P_av,C_volAvg,C_minMaxAvg, & ! stress field, stress avg, global average of stiffness and (min+max)/2 reshape(F,shape(F_lastInc)), & ! target F @@ -359,7 +359,7 @@ subroutine grid_mech_spectral_polarisation_forward(cutBack,guess,Delta_t,Delta_t F_lastInc = reshape(F, [3,3,grid(1),grid(2),grid3]) F_tau_lastInc = reshape(F_tau,[3,3,grid(1),grid(2),grid3]) - homogenization_F0 = reshape(F,[3,3,1,product(grid(1:2))*grid3]) + homogenization_F0 = reshape(F,[3,3,product(grid(1:2))*grid3]) endif !-------------------------------------------------------------------------------------------------- @@ -604,7 +604,7 @@ subroutine formResidual(in, FandF_tau, & do k = 1, grid3; do j = 1, grid(2); do i = 1, grid(1) e = e + 1 residual_F(1:3,1:3,i,j,k) = & - math_mul3333xx33(math_invSym3333(homogenization_dPdF(1:3,1:3,1:3,1:3,1,e) + C_scale), & + math_mul3333xx33(math_invSym3333(homogenization_dPdF(1:3,1:3,1:3,1:3,e) + C_scale), & residual_F(1:3,1:3,i,j,k) - 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))) & + residual_F_tau(1:3,1:3,i,j,k) diff --git a/src/grid/spectral_utilities.f90 b/src/grid/spectral_utilities.f90 index 989448dc3..c0c84233d 100644 --- a/src/grid/spectral_utilities.f90 +++ b/src/grid/spectral_utilities.f90 @@ -810,7 +810,7 @@ subroutine utilities_constitutiveResponse(P,P_av,C_volAvg,C_minmaxAvg,& print'(/,a)', ' ... evaluating constitutive response ......................................' flush(IO_STDOUT) - homogenization_F = reshape(F,[3,3,1,product(grid(1:2))*grid3]) ! set materialpoint target F to estimated field + homogenization_F = reshape(F,[3,3,product(grid(1:2))*grid3]) ! set materialpoint target F to estimated field call materialpoint_stressAndItsTangent(timeinc) ! calculate P field @@ -829,13 +829,13 @@ subroutine utilities_constitutiveResponse(P,P_av,C_volAvg,C_minmaxAvg,& dPdF_min = huge(1.0_pReal) dPdF_norm_min = huge(1.0_pReal) do i = 1, product(grid(1:2))*grid3 - if (dPdF_norm_max < sum(homogenization_dPdF(1:3,1:3,1:3,1:3,1,i)**2.0_pReal)) then - dPdF_max = homogenization_dPdF(1:3,1:3,1:3,1:3,1,i) - dPdF_norm_max = sum(homogenization_dPdF(1:3,1:3,1:3,1:3,1,i)**2.0_pReal) + if (dPdF_norm_max < sum(homogenization_dPdF(1:3,1:3,1:3,1:3,i)**2.0_pReal)) then + dPdF_max = homogenization_dPdF(1:3,1:3,1:3,1:3,i) + dPdF_norm_max = sum(homogenization_dPdF(1:3,1:3,1:3,1:3,i)**2.0_pReal) endif - if (dPdF_norm_min > sum(homogenization_dPdF(1:3,1:3,1:3,1:3,1,i)**2.0_pReal)) then - dPdF_min = homogenization_dPdF(1:3,1:3,1:3,1:3,1,i) - dPdF_norm_min = sum(homogenization_dPdF(1:3,1:3,1:3,1:3,1,i)**2.0_pReal) + if (dPdF_norm_min > sum(homogenization_dPdF(1:3,1:3,1:3,1:3,i)**2.0_pReal)) then + dPdF_min = homogenization_dPdF(1:3,1:3,1:3,1:3,i) + dPdF_norm_min = sum(homogenization_dPdF(1:3,1:3,1:3,1:3,i)**2.0_pReal) endif end do @@ -853,7 +853,7 @@ subroutine utilities_constitutiveResponse(P,P_av,C_volAvg,C_minmaxAvg,& C_minmaxAvg = 0.5_pReal*(dPdF_max + dPdF_min) - C_volAvg = sum(sum(homogenization_dPdF,dim=6),dim=5) + C_volAvg = sum(homogenization_dPdF,dim=5) call MPI_Allreduce(MPI_IN_PLACE,C_volAvg,81,MPI_DOUBLE,MPI_SUM,PETSC_COMM_WORLD,ierr) if (ierr /= 0) error stop 'MPI error' C_volAvg = C_volAvg * wgt diff --git a/src/homogenization.f90 b/src/homogenization.f90 index 5958f35fa..57478e039 100644 --- a/src/homogenization.f90 +++ b/src/homogenization.f90 @@ -30,12 +30,12 @@ module homogenization !-------------------------------------------------------------------------------------------------- ! General variables for the homogenization at a material point - real(pReal), dimension(:,:,:,:), allocatable, public :: & + real(pReal), dimension(:,:,:), allocatable, public :: & homogenization_F0, & !< def grad of IP at start of FE increment homogenization_F !< def grad of IP to be reached at end of FE increment - real(pReal), dimension(:,:,:,:), allocatable, public :: & !, protected :: & ! Issue with ifort + real(pReal), dimension(:,:,:), allocatable, public :: & !, protected :: & Issue with ifort homogenization_P !< first P--K stress of IP - real(pReal), dimension(:,:,:,:,:,:), allocatable, public :: & !, protected :: & + real(pReal), dimension(:,:,:,:,:), allocatable, public :: & !, protected :: & homogenization_dPdF !< tangent of first P--K stress at IP @@ -193,6 +193,7 @@ subroutine materialpoint_stressAndItsTangent(dt) converged logical, dimension(2,discretization_nIPs,discretization_Nelems) :: & doneAndHappy + integer :: m !-------------------------------------------------------------------------------------------------- @@ -227,7 +228,7 @@ subroutine materialpoint_stressAndItsTangent(dt) any(subStep(FEsolving_execIP(1):FEsolving_execIP(2),& FEsolving_execElem(1):FEsolving_execElem(2)) > num%subStepMinHomog)) - !$OMP PARALLEL DO + !$OMP PARALLEL DO PRIVATE(m) elementLooping1: do e = FEsolving_execElem(1),FEsolving_execElem(2) myNgrains = homogenization_Nconstituents(material_homogenizationAt(e)) IpLooping1: do i = FEsolving_execIP(1),FEsolving_execIP(2) @@ -297,13 +298,14 @@ subroutine materialpoint_stressAndItsTangent(dt) !-------------------------------------------------------------------------------------------------- ! deformation partitioning - !$OMP PARALLEL DO PRIVATE(myNgrains) + !$OMP PARALLEL DO PRIVATE(myNgrains,m) elementLooping2: do e = FEsolving_execElem(1),FEsolving_execElem(2) myNgrains = homogenization_Nconstituents(material_homogenizationAt(e)) IpLooping2: do i = FEsolving_execIP(1),FEsolving_execIP(2) if(requested(i,e) .and. .not. doneAndHappy(1,i,e)) then ! requested but not yet done - call mech_partition(homogenization_F0(1:3,1:3,i,e) & - + (homogenization_F(1:3,1:3,i,e)-homogenization_F0(1:3,1:3,i,e))& + m = (e-1)*discretization_nIPs + i + call mech_partition(homogenization_F0(1:3,1:3,m) & + + (homogenization_F(1:3,1:3,m)-homogenization_F0(1:3,1:3,m))& *(subStep(i,e)+subFrac(i,e)), & i,e) crystallite_dt(1:myNgrains,i,e) = dt*subStep(i,e) ! propagate materialpoint dt to grains @@ -321,16 +323,17 @@ subroutine materialpoint_stressAndItsTangent(dt) !-------------------------------------------------------------------------------------------------- ! state update - !$OMP PARALLEL DO + !$OMP PARALLEL DO PRIVATE(m) elementLooping3: do e = FEsolving_execElem(1),FEsolving_execElem(2) IpLooping3: do i = FEsolving_execIP(1),FEsolving_execIP(2) if (requested(i,e) .and. .not. doneAndHappy(1,i,e)) then if (.not. converged(i,e)) then doneAndHappy(1:2,i,e) = [.true.,.false.] else + m = (e-1)*discretization_nIPs + i doneAndHappy(1:2,i,e) = updateState(dt*subStep(i,e), & - homogenization_F0(1:3,1:3,i,e) & - + (homogenization_F(1:3,1:3,i,e)-homogenization_F0(1:3,1:3,i,e)) & + homogenization_F0(1:3,1:3,m) & + + (homogenization_F(1:3,1:3,m)-homogenization_F0(1:3,1:3,m)) & *(subStep(i,e)+subFrac(i,e)), & i,e) converged(i,e) = all(doneAndHappy(1:2,i,e)) ! converged if done and happy diff --git a/src/homogenization_mech.f90 b/src/homogenization_mech.f90 index 40d26df51..b0641be07 100644 --- a/src/homogenization_mech.f90 +++ b/src/homogenization_mech.f90 @@ -73,10 +73,10 @@ module subroutine mech_init(num_homog) print'(/,a)', ' <<<+- homogenization_mech init -+>>>' - allocate(homogenization_dPdF(3,3,3,3,discretization_nIPs,discretization_Nelems), source=0.0_pReal) - homogenization_F0 = spread(spread(math_I3,3,discretization_nIPs),4,discretization_Nelems) ! initialize to identity - homogenization_F = homogenization_F0 ! initialize to identity - allocate(homogenization_P(3,3,discretization_nIPs,discretization_Nelems), source=0.0_pReal) + allocate(homogenization_dPdF(3,3,3,3,discretization_nIPs*discretization_Nelems), source=0.0_pReal) + homogenization_F0 = spread(math_I3,3,discretization_nIPs*discretization_Nelems) ! initialize to identity + homogenization_F = homogenization_F0 ! initialize to identity + allocate(homogenization_P(3,3,discretization_nIPs*discretization_Nelems), source=0.0_pReal) num_homogMech => num_homog%get('mech',defaultVal=emptyDict) if (any(homogenization_type == HOMOGENIZATION_NONE_ID)) call mech_none_init @@ -127,23 +127,24 @@ module subroutine mech_homogenize(ip,el) integer, intent(in) :: & ip, & !< integration point el !< element number - integer :: c + integer :: c,m real(pReal) :: dPdFs(3,3,3,3,homogenization_Nconstituents(material_homogenizationAt(el))) + m = (el-1)* discretization_nIPs + ip chosenHomogenization: select case(homogenization_type(material_homogenizationAt(el))) case (HOMOGENIZATION_NONE_ID) chosenHomogenization - homogenization_P(1:3,1:3,ip,el) = crystallite_P(1:3,1:3,1,ip,el) - homogenization_dPdF(1:3,1:3,1:3,1:3,ip,el) = crystallite_stressTangent(1,ip,el) + homogenization_P(1:3,1:3,m) = crystallite_P(1:3,1:3,1,ip,el) + homogenization_dPdF(1:3,1:3,1:3,1:3,m) = crystallite_stressTangent(1,ip,el) case (HOMOGENIZATION_ISOSTRAIN_ID) chosenHomogenization do c = 1, homogenization_Nconstituents(material_homogenizationAt(el)) dPdFs(:,:,:,:,c) = crystallite_stressTangent(c,ip,el) enddo call mech_isostrain_averageStressAndItsTangent(& - homogenization_P(1:3,1:3,ip,el), & - homogenization_dPdF(1:3,1:3,1:3,1:3,ip,el),& + homogenization_P(1:3,1:3,m), & + homogenization_dPdF(1:3,1:3,1:3,1:3,m),& crystallite_P(1:3,1:3,1:homogenization_Nconstituents(material_homogenizationAt(el)),ip,el), & dPdFs, & homogenization_typeInstance(material_homogenizationAt(el))) @@ -153,8 +154,8 @@ module subroutine mech_homogenize(ip,el) dPdFs(:,:,:,:,c) = crystallite_stressTangent(c,ip,el) enddo call mech_RGC_averageStressAndItsTangent(& - homogenization_P(1:3,1:3,ip,el), & - homogenization_dPdF(1:3,1:3,1:3,1:3,ip,el),& + homogenization_P(1:3,1:3,m), & + homogenization_dPdF(1:3,1:3,1:3,1:3,m),& crystallite_P(1:3,1:3,1:homogenization_Nconstituents(material_homogenizationAt(el)),ip,el), & dPdFs, & homogenization_typeInstance(material_homogenizationAt(el))) diff --git a/src/material.f90 b/src/material.f90 index 574da0d51..bb5f484f6 100644 --- a/src/material.f90 +++ b/src/material.f90 @@ -140,7 +140,6 @@ contains subroutine material_init(restart) logical, intent(in) :: restart - integer :: myHomog print'(/,a)', ' <<<+- material init -+>>>'; flush(IO_STDOUT) diff --git a/src/mesh/FEM_utilities.f90 b/src/mesh/FEM_utilities.f90 index 118735e89..cb81f1f0c 100644 --- a/src/mesh/FEM_utilities.f90 +++ b/src/mesh/FEM_utilities.f90 @@ -164,7 +164,7 @@ subroutine utilities_constitutiveResponse(timeinc,P_av,forwardData) cutBack = .false. ! reset cutBack status - P_av = sum(sum(homogenization_P,dim=4),dim=3) * wgt ! average of P + P_av = sum(homogenization_P,dim=3) * wgt call MPI_Allreduce(MPI_IN_PLACE,P_av,9,MPI_DOUBLE,MPI_SUM,PETSC_COMM_WORLD,ierr) end subroutine utilities_constitutiveResponse diff --git a/src/mesh/mesh_mech_FEM.f90 b/src/mesh/mesh_mech_FEM.f90 index eb5f862c2..e19c35998 100644 --- a/src/mesh/mesh_mech_FEM.f90 +++ b/src/mesh/mesh_mech_FEM.f90 @@ -316,16 +316,16 @@ subroutine FEM_mech_formResidual(dm_local,xx_local,f_local,dummy,ierr) Vec :: x_local, f_local, xx_local PetscSection :: section PetscScalar, dimension(:), pointer :: x_scal, pf_scal - PetscScalar, target :: f_scal(cellDof) - PetscReal :: detJ, IcellJMat(dimPlex,dimPlex) - PetscReal, pointer,dimension(:) :: pV0, pCellJ, pInvcellJ, basisField, basisFieldDer + PetscScalar, dimension(cellDof), target :: f_scal + PetscReal :: IcellJMat(dimPlex,dimPlex) + PetscReal, dimension(:),pointer :: pV0, pCellJ, pInvcellJ, basisField, basisFieldDer PetscInt :: cellStart, cellEnd, cell, field, face, & qPt, basis, comp, cidx, & - numFields - PetscReal :: detFAvg - PetscReal :: BMat(dimPlex*dimPlex,cellDof) + numFields, & + bcSize,m + PetscReal :: detFAvg, detJ + PetscReal, dimension(dimPlex*dimPlex,cellDof) :: BMat - PetscInt :: bcSize IS :: bcPoints @@ -366,6 +366,7 @@ subroutine FEM_mech_formResidual(dm_local,xx_local,f_local,dummy,ierr) CHKERRQ(ierr) IcellJMat = reshape(pInvcellJ,shape=[dimPlex,dimPlex]) do qPt = 0, nQuadrature-1 + m = cell*nQuadrature + qPt+1 BMat = 0.0 do basis = 0, nBasis-1 do comp = 0, dimPlex-1 @@ -375,15 +376,14 @@ subroutine FEM_mech_formResidual(dm_local,xx_local,f_local,dummy,ierr) (((qPt*nBasis + basis)*dimPlex + comp)*dimPlex+comp+1)*dimPlex)) enddo enddo - homogenization_F(1:dimPlex,1:dimPlex,qPt+1,cell+1) = & - reshape(matmul(BMat,x_scal),shape=[dimPlex,dimPlex], order=[2,1]) + homogenization_F(1:dimPlex,1:dimPlex,m) = reshape(matmul(BMat,x_scal),shape=[dimPlex,dimPlex], order=[2,1]) enddo if (num%BBarStabilisation) then - detFAvg = math_det33(sum(homogenization_F(1:3,1:3,1:nQuadrature,cell+1),dim=3)/real(nQuadrature)) - do qPt = 1, nQuadrature - homogenization_F(1:dimPlex,1:dimPlex,qPt,cell+1) = & - homogenization_F(1:dimPlex,1:dimPlex,qPt,cell+1)* & - (detFAvg/math_det33(homogenization_F(1:3,1:3,qPt,cell+1)))**(1.0/real(dimPlex)) + detFAvg = math_det33(sum(homogenization_F(1:3,1:3,cell*nQuadrature+1:(cell+1)*nQuadrature),dim=3)/real(nQuadrature)) + do qPt = 0, nQuadrature-1 + m = cell*nQuadrature + qPt+1 + homogenization_F(1:dimPlex,1:dimPlex,m) = homogenization_F(1:dimPlex,1:dimPlex,m) & + * (detFAvg/math_det33(homogenization_F(1:3,1:3,m)))**(1.0/real(dimPlex)) enddo endif @@ -407,6 +407,7 @@ subroutine FEM_mech_formResidual(dm_local,xx_local,f_local,dummy,ierr) IcellJMat = reshape(pInvcellJ,shape=[dimPlex,dimPlex]) f_scal = 0.0 do qPt = 0, nQuadrature-1 + m = cell*nQuadrature + qPt+1 BMat = 0.0 do basis = 0, nBasis-1 do comp = 0, dimPlex-1 @@ -418,7 +419,7 @@ subroutine FEM_mech_formResidual(dm_local,xx_local,f_local,dummy,ierr) enddo f_scal = f_scal + & matmul(transpose(BMat), & - reshape(transpose(homogenization_P(1:dimPlex,1:dimPlex,qPt+1,cell+1)), & + reshape(transpose(homogenization_P(1:dimPlex,1:dimPlex,m)), & shape=[dimPlex*dimPlex]))*qWeights(qPt+1) enddo f_scal = f_scal*abs(detJ) @@ -463,7 +464,7 @@ subroutine FEM_mech_formJacobian(dm_local,xx_local,Jac_pre,Jac,dummy,ierr) K_eB PetscInt :: cellStart, cellEnd, cell, field, face, & - qPt, basis, comp, cidx,bcSize + qPt, basis, comp, cidx,bcSize, m IS :: bcPoints @@ -506,6 +507,7 @@ subroutine FEM_mech_formJacobian(dm_local,xx_local,Jac_pre,Jac,dummy,ierr) FAvg = 0.0 BMatAvg = 0.0 do qPt = 0, nQuadrature-1 + m = cell*nQuadrature + qPt + 1 BMat = 0.0 do basis = 0, nBasis-1 do comp = 0, dimPlex-1 @@ -516,7 +518,7 @@ subroutine FEM_mech_formJacobian(dm_local,xx_local,Jac_pre,Jac,dummy,ierr) (((qPt*nBasis + basis)*dimPlex + comp)*dimPlex+comp+1)*dimPlex)) enddo enddo - MatA = matmul(reshape(reshape(homogenization_dPdF(1:dimPlex,1:dimPlex,1:dimPlex,1:dimPlex,qPt+1,cell+1), & + MatA = matmul(reshape(reshape(homogenization_dPdF(1:dimPlex,1:dimPlex,1:dimPlex,1:dimPlex,m), & shape=[dimPlex,dimPlex,dimPlex,dimPlex], order=[2,1,4,3]), & shape=[dimPlex*dimPlex,dimPlex*dimPlex]),BMat)*qWeights(qPt+1) if (num%BBarStabilisation) then @@ -524,12 +526,11 @@ subroutine FEM_mech_formJacobian(dm_local,xx_local,Jac_pre,Jac,dummy,ierr) FInv = math_inv33(F) K_eA = K_eA + matmul(transpose(BMat),MatA)*math_det33(FInv)**(1.0/real(dimPlex)) K_eB = K_eB - & - matmul(transpose(matmul(reshape(homogenization_F(1:dimPlex,1:dimPlex,qPt+1,cell+1), & - shape=[dimPlex*dimPlex,1]), & + matmul(transpose(matmul(reshape(homogenization_F(1:dimPlex,1:dimPlex,m),shape=[dimPlex*dimPlex,1]), & matmul(reshape(FInv(1:dimPlex,1:dimPlex), & shape=[1,dimPlex*dimPlex],order=[2,1]),BMat))),MatA) - MatB = MatB + & - matmul(reshape(homogenization_F(1:dimPlex,1:dimPlex,qPt+1,cell+1),shape=[1,dimPlex*dimPlex]),MatA) + MatB = MatB & + + matmul(reshape(homogenization_F(1:dimPlex,1:dimPlex,m),shape=[1,dimPlex*dimPlex]),MatA) FAvg = FAvg + F BMatAvg = BMatAvg + BMat else From e11be7e6007581f349de3172b5584a4574921a06 Mon Sep 17 00:00:00 2001 From: Philip Eisenlohr Date: Thu, 17 Dec 2020 10:47:56 -0500 Subject: [PATCH 052/148] preinitialize a ConfigMaterial object with 'constituents','homogenization','phase' keys --- python/damask/_configmaterial.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/python/damask/_configmaterial.py b/python/damask/_configmaterial.py index 6de2283f4..17d8c796d 100644 --- a/python/damask/_configmaterial.py +++ b/python/damask/_configmaterial.py @@ -9,6 +9,13 @@ from . import Orientation class ConfigMaterial(Config): """Material configuration.""" + def __init__(self): + """Initialize object with all required dictionary keys.""" + super().__init__() + self['material'] = [] + self['homogenization'] = {} + self['phase'] = {} + def save(self,fname='material.yaml',**kwargs): """ Save to yaml file. @@ -274,6 +281,7 @@ class ConfigMaterial(Config): c = [{} for _ in range(length)] if constituents is None else \ [{'constituents':u} for u in ConfigMaterial._constituents(**constituents)] + if len(c) == 1: c = [copy.deepcopy(c[0]) for _ in range(length)] if length != 1 and length != len(c): From 1f021880eb62b8013620e973aaa51886f0490feb Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Thu, 17 Dec 2020 21:52:12 +0100 Subject: [PATCH 053/148] pytest for temperature now fully working --- PRIVATE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PRIVATE b/PRIVATE index e1a1048e1..24828314c 160000 --- a/PRIVATE +++ b/PRIVATE @@ -1 +1 @@ -Subproject commit e1a1048e1f593683b4b432d41455bd236008c3ad +Subproject commit 24828314c82a8bb2f011b060965cea79660c6f09 From 5b67cadb5173a65275f218c0de78ed9d17ffa2ec Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Thu, 17 Dec 2020 21:58:51 +0100 Subject: [PATCH 054/148] test not needed anymore --- .gitlab-ci.yml | 7 ------- PRIVATE | 2 +- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 4e90638c5..c67516ce2 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -269,13 +269,6 @@ Thermal: - master - release -Nonlocal_Damage_DetectChanges: - stage: grid - script: Nonlocal_Damage_DetectChanges/test.py - except: - - master - - release - Plasticity_DetectChanges: stage: grid script: Plasticity_DetectChanges/test.py diff --git a/PRIVATE b/PRIVATE index 24828314c..b6e6d9202 160000 --- a/PRIVATE +++ b/PRIVATE @@ -1 +1 @@ -Subproject commit 24828314c82a8bb2f011b060965cea79660c6f09 +Subproject commit b6e6d9202f27e7e5aee2a38c3529bbf9c7bdaeab From 2b54c074167005594e40c0b9a2cade10a575f569 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Thu, 17 Dec 2020 22:02:27 +0100 Subject: [PATCH 055/148] not needed anymore --- .gitlab-ci.yml | 7 ------- PRIVATE | 2 +- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index c67516ce2..ca1b2959a 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -262,13 +262,6 @@ Pytest_grid: - master - release -Thermal: - stage: grid - script: Thermal/test.py - except: - - master - - release - Plasticity_DetectChanges: stage: grid script: Plasticity_DetectChanges/test.py diff --git a/PRIVATE b/PRIVATE index b6e6d9202..9a184b4a9 160000 --- a/PRIVATE +++ b/PRIVATE @@ -1 +1 @@ -Subproject commit b6e6d9202f27e7e5aee2a38c3529bbf9c7bdaeab +Subproject commit 9a184b4a906d0a239febd72e50b06fb9d31fb765 From 403ac693dab87d752961bd8732ea77c8f9213204 Mon Sep 17 00:00:00 2001 From: Philip Eisenlohr Date: Thu, 17 Dec 2020 18:08:55 -0500 Subject: [PATCH 056/148] need to pass init argument to dict superclass --- python/damask/_configmaterial.py | 15 +++++++++------ .../tests/reference/ConfigMaterial/material.yaml | 10 +++++----- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/python/damask/_configmaterial.py b/python/damask/_configmaterial.py index 17d8c796d..ed72aa27d 100644 --- a/python/damask/_configmaterial.py +++ b/python/damask/_configmaterial.py @@ -9,12 +9,15 @@ from . import Orientation class ConfigMaterial(Config): """Material configuration.""" - def __init__(self): - """Initialize object with all required dictionary keys.""" - super().__init__() - self['material'] = [] - self['homogenization'] = {} - self['phase'] = {} + _defaults = {'material': [], + 'homogenization': {}, + 'phase': {}} + + def __init__(self,d={}): + """Initialize object with default dictionary keys.""" + super().__init__(d) + for k,v in self._defaults.items(): + if k not in self: self[k] = v def save(self,fname='material.yaml',**kwargs): """ diff --git a/python/tests/reference/ConfigMaterial/material.yaml b/python/tests/reference/ConfigMaterial/material.yaml index 933e295b3..fbba6a631 100644 --- a/python/tests/reference/ConfigMaterial/material.yaml +++ b/python/tests/reference/ConfigMaterial/material.yaml @@ -1,10 +1,10 @@ homogenization: SX: - N_constituents: 2 - mech: {type: none} + N_constituents: 1 + mechanics: {type: none} Taylor: N_constituents: 2 - mech: {type: isostrain} + mechanics: {type: isostrain} material: - constituents: @@ -34,11 +34,11 @@ material: phase: Aluminum: lattice: cF - mech: + mechanics: output: [F, P, F_e, F_p, L_p] elasticity: {C_11: 106.75e9, C_12: 60.41e9, C_44: 28.34e9, type: hooke} Steel: lattice: cI - mech: + mechanics: output: [F, P, F_e, F_p, L_p] elasticity: {C_11: 233.3e9, C_12: 135.5e9, C_44: 118.0e9, type: hooke} From 5fb0e4908b9b553b33a2e5858eb2fa4afcc2709e Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Fri, 18 Dec 2020 07:09:05 +0100 Subject: [PATCH 057/148] Examples reflect actual behavior --- python/damask/_configmaterial.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/python/damask/_configmaterial.py b/python/damask/_configmaterial.py index ed72aa27d..b94e9897a 100644 --- a/python/damask/_configmaterial.py +++ b/python/damask/_configmaterial.py @@ -85,6 +85,8 @@ class ConfigMaterial(Config): fraction: 1.0 phase: Steel homogenization: SX + homogenization: {} + phase: {} """ constituents_ = {k:table.get(v) for k,v in constituents.items()} @@ -271,6 +273,8 @@ class ConfigMaterial(Config): fraction: 1.0 phase: Aluminum homogenization: SX + homogenization: {} + phase: {} """ length = -1 From 3010d11c8e919ff4fa62cf277270d45e39f62732 Mon Sep 17 00:00:00 2001 From: Test User Date: Fri, 18 Dec 2020 10:51:46 +0100 Subject: [PATCH 058/148] [skip ci] updated version information after successful test of v3.0.0-alpha2-39-g5fb0e4908 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index b7128c9af..d50c5b204 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v3.0.0-alpha2-35-g1ebd10745 +v3.0.0-alpha2-39-g5fb0e4908 From afc53e5d9f817772dfc36989de39960dd2df066d Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Fri, 18 Dec 2020 12:17:26 +0100 Subject: [PATCH 059/148] one more test migrated to pytest --- PRIVATE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PRIVATE b/PRIVATE index 9a184b4a9..a6a4eba5b 160000 --- a/PRIVATE +++ b/PRIVATE @@ -1 +1 @@ -Subproject commit 9a184b4a906d0a239febd72e50b06fb9d31fb765 +Subproject commit a6a4eba5bd3dfb2600b6bb5bed70e3e2045705bc From 35f9861818bbb3b3e6fdfd1d6f520c5fddc531c6 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Fri, 18 Dec 2020 15:19:04 +0100 Subject: [PATCH 060/148] Fortran standard is 2018 will not work for older compilers --- CMakeLists.txt | 76 +++------ PRIVATE | 2 +- cmake/Compiler-Intel.cmake | 2 +- python/damask/_config.py | 3 + python/tests/test_Table.py | 2 +- src/DAMASK_interface.f90 | 8 +- src/grid/grid_damage_spectral.f90 | 3 +- src/grid/grid_mech_FEM.f90 | 9 +- src/grid/grid_mech_spectral_basic.f90 | 9 +- src/grid/grid_mech_spectral_polarisation.f90 | 9 +- src/grid/grid_thermal_spectral.f90 | 3 +- src/grid/spectral_utilities.f90 | 23 ++- src/material.f90 | 2 +- src/mesh/mesh_mech_FEM.f90 | 33 +--- src/results.f90 | 169 ++++++++++--------- 15 files changed, 147 insertions(+), 206 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index dd2348fd1..8db6dd0c0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,18 @@ -######################################################################################## -# Compiler options for building DAMASK -cmake_minimum_required (VERSION 3.10.0 FATAL_ERROR) +cmake_minimum_required (VERSION 3.10.0) +include (FindPkgConfig REQUIRED) + +# Dummy project to determine compiler names and version +project (Prerequisites LANGUAGES) +set(ENV{PKG_CONFIG_PATH} "$ENV{PETSC_DIR}/$ENV{PETSC_ARCH}/lib/pkgconfig") +pkg_search_module (PETSC REQUIRED PETSc>3.12.0) +pkg_get_variable (CMAKE_Fortran_COMPILER PETSc fcompiler) +pkg_get_variable (CMAKE_C_COMPILER PETSc ccompiler) + +find_program (CAT_EXECUTABLE NAMES cat) +execute_process (COMMAND ${CAT_EXECUTABLE} ${PROJECT_SOURCE_DIR}/VERSION + RESULT_VARIABLE DAMASK_VERSION_RETURN + OUTPUT_VARIABLE DAMASK_VERSION + OUTPUT_STRIP_TRAILING_WHITESPACE) #--------------------------------------------------------------------------------------- # Find PETSc from system environment @@ -28,19 +40,10 @@ include ${petsc_conf_rules} include ${petsc_conf_variables} INCLUDE_DIRS := \${PETSC_FC_INCLUDES} LIBRARIES := \${PETSC_WITH_EXTERNAL_LIB} -COMPILERF := \${FC} -COMPILERC := \${CC} -LINKERNAME := \${FLINKER} includes: \t@echo \${INCLUDE_DIRS} extlibs: \t@echo \${LIBRARIES} -compilerf: -\t@echo \${COMPILERF} -compilerc: -\t@echo \${COMPILERC} -linker: -\t@echo \${LINKERNAME} ") # CMake will execute each target in the ${petsc_config_makefile} @@ -52,26 +55,10 @@ execute_process (COMMAND ${MAKE_EXECUTABLE} --no-print-directory -f ${petsc_conf OUTPUT_VARIABLE petsc_includes OUTPUT_STRIP_TRAILING_WHITESPACE) # Find the PETSc external linking directory settings -# required for final linking, must be appended after the executable execute_process (COMMAND ${MAKE_EXECUTABLE} --no-print-directory -f ${petsc_config_makefile} "extlibs" RESULT_VARIABLE PETSC_EXTERNAL_LIB_RETURN OUTPUT_VARIABLE petsc_external_lib OUTPUT_STRIP_TRAILING_WHITESPACE) -# PETSc specified fortran compiler -execute_process (COMMAND ${MAKE_EXECUTABLE} --no-print-directory -f ${petsc_config_makefile} "compilerf" - RESULT_VARIABLE PETSC_MPIFC_RETURN - OUTPUT_VARIABLE PETSC_MPIFC - OUTPUT_STRIP_TRAILING_WHITESPACE) -# PETSc specified C compiler -execute_process (COMMAND ${MAKE_EXECUTABLE} --no-print-directory -f ${petsc_config_makefile} "compilerc" - RESULT_VARIABLE PETSC_MPICC_RETURN - OUTPUT_VARIABLE PETSC_MPICC - OUTPUT_STRIP_TRAILING_WHITESPACE) -# PETSc specified linker (Fortran compiler + PETSc linking flags) -execute_process (COMMAND ${MAKE_EXECUTABLE} --no-print-directory -f ${petsc_config_makefile} "linker" - RESULT_VARIABLE PETSC_LINKER_RETURN - OUTPUT_VARIABLE PETSC_LINKER - OUTPUT_STRIP_TRAILING_WHITESPACE) # Remove temporary makefile, no need to keep it anymore. file (REMOVE_RECURSE ${TEMPDIR}) @@ -90,14 +77,6 @@ endforeach (exlib) message ("Found PETSC_DIR:\n${PETSC_DIR}\n" ) message ("Found PETSC_INCLUDES:\n${PETSC_INCLUDES}\n" ) message ("Found PETSC_EXTERNAL_LIB:\n${PETSC_EXTERNAL_LIB}\n") -message ("Found PETSC_LINKER:\n${PETSC_LINKER}\n" ) -message ("Found MPI Fortran Compiler:\n${PETSC_MPIFC}\n" ) -message ("Found MPI C Compiler:\n${PETSC_MPICC}\n" ) - -# set compiler commands to match PETSc (needs to be done before defining the project) -# https://cmake.org/Wiki/CMake_FAQ#How_do_I_use_a_different_compiler.3F -set (CMAKE_Fortran_COMPILER "${PETSC_MPIFC}") -set (CMAKE_C_COMPILER "${PETSC_MPICC}") #--------------------------------------------------------------------------------------- # Now start to care about DAMASK @@ -105,17 +84,18 @@ set (CMAKE_C_COMPILER "${PETSC_MPICC}") # DAMASK solver defines project to build string(TOLOWER ${DAMASK_SOLVER} DAMASK_SOLVER) if (DAMASK_SOLVER STREQUAL "grid") - project (damask-grid Fortran C) + project (damask-grid HOMEPAGE_URL https://damask.mpie.de LANGUAGES Fortran C) add_definitions (-DGrid) - message ("Building Grid Solver\n") elseif (DAMASK_SOLVER STREQUAL "mesh") - project (damask-mesh Fortran C) + project (damask-mesh HOMEPAGE_URL https://damask.mpie.de LANGUAGES Fortran C) add_definitions (-DMesh) - message ("Building Mesh Solver\n") else () message (FATAL_ERROR "Build target (DAMASK_SOLVER) is not defined") endif () -list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake) +add_definitions (-DDAMASKVERSION="${DAMASK_VERSION}") +add_definitions (-DPETSc) + +message ("\nBuilding ${CMAKE_PROJECT_NAME}\n") if (CMAKE_BUILD_TYPE STREQUAL "") set (CMAKE_BUILD_TYPE "RELEASE") @@ -153,17 +133,8 @@ if (CMAKE_BUILD_TYPE STREQUAL "SYNTAXONLY") set (BUILDCMD_POST "${BUILDCMD_POST} -fsyntax-only") endif () -# Parse DAMASK version from VERSION file -find_program (CAT_EXECUTABLE NAMES cat) -execute_process (COMMAND ${CAT_EXECUTABLE} ${PROJECT_SOURCE_DIR}/VERSION - RESULT_VARIABLE DAMASK_VERSION_RETURN - OUTPUT_VARIABLE DAMASK_V - OUTPUT_STRIP_TRAILING_WHITESPACE) -add_definitions (-DDAMASKVERSION="${DAMASK_V}") - -# definition of other macros -add_definitions (-DPETSc) +list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake) if (CMAKE_Fortran_COMPILER_ID STREQUAL "Intel") include (Compiler-Intel) elseif(CMAKE_Fortran_COMPILER_ID STREQUAL "GNU") @@ -174,9 +145,8 @@ else () message (FATAL_ERROR "Compiler type (CMAKE_Fortran_COMPILER_ID) not recognized") endif () - set (CMAKE_Fortran_FLAGS_${CMAKE_BUILD_TYPE} "${BUILDCMD_PRE} ${OPENMP_FLAGS} ${STANDARD_CHECK} ${OPTIMIZATION_FLAGS} ${COMPILE_FLAGS} ${PRECISION_FLAGS}") -set (CMAKE_Fortran_LINK_EXECUTABLE "${BUILDCMD_PRE} ${PETSC_LINKER} ${OPENMP_FLAGS} ${OPTIMIZATION_FLAGS} ${LINKER_FLAGS}") +set (CMAKE_Fortran_LINK_EXECUTABLE "${BUILDCMD_PRE} ${CMAKE_Fortran_COMPILER} ${OPENMP_FLAGS} ${OPTIMIZATION_FLAGS} ${LINKER_FLAGS}") if (CMAKE_BUILD_TYPE STREQUAL "DEBUG") set (CMAKE_Fortran_FLAGS_${CMAKE_BUILD_TYPE} "${CMAKE_Fortran_FLAGS_${CMAKE_BUILD_TYPE}} ${DEBUG_FLAGS}") diff --git a/PRIVATE b/PRIVATE index de65e1df5..e1a1048e1 160000 --- a/PRIVATE +++ b/PRIVATE @@ -1 +1 @@ -Subproject commit de65e1df5a76362de93667e9820dbf330b56f96d +Subproject commit e1a1048e1f593683b4b432d41455bd236008c3ad diff --git a/cmake/Compiler-Intel.cmake b/cmake/Compiler-Intel.cmake index 719ed885b..5b551069e 100644 --- a/cmake/Compiler-Intel.cmake +++ b/cmake/Compiler-Intel.cmake @@ -20,7 +20,7 @@ endif () # -assume std_mod_proc_name (included in -standard-semantics) causes problems if other modules # (PETSc, HDF5) are not compiled with this option (https://software.intel.com/en-us/forums/intel-fortran-compiler-for-linux-and-mac-os-x/topic/62172) -set (STANDARD_CHECK "-stand f15 -standard-semantics -assume nostd_mod_proc_name") +set (STANDARD_CHECK "-stand f18 -standard-semantics -assume nostd_mod_proc_name") set (LINKER_FLAGS "${LINKER_FLAGS} -shared-intel") # Link against shared Intel libraries instead of static ones diff --git a/python/damask/_config.py b/python/damask/_config.py index 24245f4bd..76955588f 100644 --- a/python/damask/_config.py +++ b/python/damask/_config.py @@ -21,6 +21,9 @@ class NiceDumper(yaml.SafeDumper): return self.represent_data(dict(data)) if isinstance(data, dict) and type(data) != dict else \ super().represent_data(data) + def ignore_aliases(self, data): + """No references.""" + return True class Config(dict): """YAML-based configuration.""" diff --git a/python/tests/test_Table.py b/python/tests/test_Table.py index ac5859ecb..8f617aff5 100644 --- a/python/tests/test_Table.py +++ b/python/tests/test_Table.py @@ -22,7 +22,7 @@ class TestTable: @pytest.mark.parametrize('N',[10,40]) def test_len(self,N): - len(Table(np.random.rand(N,3),{'X':3})) == N + assert len(Table(np.random.rand(N,3),{'X':3})) == N def test_get_scalar(self,default): d = default.get('s') diff --git a/src/DAMASK_interface.f90 b/src/DAMASK_interface.f90 index 41f421eb8..d38020225 100644 --- a/src/DAMASK_interface.f90 +++ b/src/DAMASK_interface.f90 @@ -10,7 +10,7 @@ !> and working directory. !-------------------------------------------------------------------------------------------------- #define PETSC_MAJOR 3 -#define PETSC_MINOR_MIN 10 +#define PETSC_MINOR_MIN 12 #define PETSC_MINOR_MAX 14 module DAMASK_interface @@ -392,7 +392,7 @@ end function makeRelativePath subroutine catchSIGTERM(signal) bind(C) integer(C_INT), value :: signal - interface_SIGTERM = .true. + call interface_setSIGTERM(.true.) print'(a,i0,a)', ' received signal ',signal, ', set SIGTERM=TRUE' @@ -417,7 +417,7 @@ end subroutine interface_setSIGTERM subroutine catchSIGUSR1(signal) bind(C) integer(C_INT), value :: signal - interface_SIGUSR1 = .true. + call interface_setSIGUSR1(.true.) print'(a,i0,a)', ' received signal ',signal, ', set SIGUSR1=TRUE' @@ -442,7 +442,7 @@ end subroutine interface_setSIGUSR1 subroutine catchSIGUSR2(signal) bind(C) integer(C_INT), value :: signal - interface_SIGUSR2 = .true. + call interface_setSIGUSR2(.true.) print'(a,i0,a)', ' received signal ',signal, ', set SIGUSR2=TRUE' diff --git a/src/grid/grid_damage_spectral.f90 b/src/grid/grid_damage_spectral.f90 index 4c014f3c0..79437945b 100644 --- a/src/grid/grid_damage_spectral.f90 +++ b/src/grid/grid_damage_spectral.f90 @@ -203,8 +203,7 @@ function grid_damage_spectral_solution(timeinc) result(solution) call VecMax(solution_vec,devNull,phi_max,ierr); CHKERRQ(ierr) if (solution%converged) & print'(/,a)', ' ... nonlocal damage converged .....................................' - write(IO_STDOUT,'(/,a,f8.6,2x,f8.6,2x,e11.4,/)',advance='no') ' Minimum|Maximum|Delta Damage = ',& - phi_min, phi_max, stagNorm + print'(/,a,f8.6,2x,f8.6,2x,e11.4)', ' Minimum|Maximum|Delta Damage = ', phi_min, phi_max, stagNorm print'(/,a)', ' ===========================================================================' flush(IO_STDOUT) diff --git a/src/grid/grid_mech_FEM.f90 b/src/grid/grid_mech_FEM.f90 index 146f28567..741ce404a 100644 --- a/src/grid/grid_mech_FEM.f90 +++ b/src/grid/grid_mech_FEM.f90 @@ -509,11 +509,10 @@ subroutine formResidual(da_local,x_local, & newIteration: if (totalIter <= PETScIter) then totalIter = totalIter + 1 print'(1x,a,3(a,i0))', trim(incInfo), ' @ Iteration ', num%itmin, '≤',totalIter+1, '≤', num%itmax - if (debugRotation) & - write(IO_STDOUT,'(/,a,/,3(3(f12.7,1x)/))',advance='no') & - ' deformation gradient aim (lab) =', transpose(params%rotation_BC%rotate(F_aim,active=.true.)) - write(IO_STDOUT,'(/,a,/,3(3(f12.7,1x)/))',advance='no') & - ' deformation gradient aim =', transpose(F_aim) + if (debugRotation) print'(/,a,/,2(3(f12.7,1x)/),3(f12.7,1x))', & + ' deformation gradient aim (lab) =', transpose(params%rotation_BC%rotate(F_aim,active=.true.)) + print'(/,a,/,2(3(f12.7,1x)/),3(f12.7,1x))', & + ' deformation gradient aim =', transpose(F_aim) flush(IO_STDOUT) endif newIteration diff --git a/src/grid/grid_mech_spectral_basic.f90 b/src/grid/grid_mech_spectral_basic.f90 index 4f5ceff61..d87a22fb7 100644 --- a/src/grid/grid_mech_spectral_basic.f90 +++ b/src/grid/grid_mech_spectral_basic.f90 @@ -471,11 +471,10 @@ subroutine formResidual(in, F, & newIteration: if (totalIter <= PETScIter) then totalIter = totalIter + 1 print'(1x,a,3(a,i0))', trim(incInfo), ' @ Iteration ', num%itmin, '≤',totalIter, '≤', num%itmax - if(debugRotation) & - write(IO_STDOUT,'(/,a,/,3(3(f12.7,1x)/))',advance='no') & - ' deformation gradient aim (lab) =', transpose(params%rotation_BC%rotate(F_aim,active=.true.)) - write(IO_STDOUT,'(/,a,/,3(3(f12.7,1x)/))',advance='no') & - ' deformation gradient aim =', transpose(F_aim) + if (debugRotation) print'(/,a,/,2(3(f12.7,1x)/),3(f12.7,1x))', & + ' deformation gradient aim (lab) =', transpose(params%rotation_BC%rotate(F_aim,active=.true.)) + print'(/,a,/,2(3(f12.7,1x)/),3(f12.7,1x))', & + ' deformation gradient aim =', transpose(F_aim) flush(IO_STDOUT) endif newIteration diff --git a/src/grid/grid_mech_spectral_polarisation.f90 b/src/grid/grid_mech_spectral_polarisation.f90 index d09b7fcb2..9bbb40a53 100644 --- a/src/grid/grid_mech_spectral_polarisation.f90 +++ b/src/grid/grid_mech_spectral_polarisation.f90 @@ -552,11 +552,10 @@ subroutine formResidual(in, FandF_tau, & newIteration: if (totalIter <= PETScIter) then totalIter = totalIter + 1 print'(1x,a,3(a,i0))', trim(incInfo), ' @ Iteration ', num%itmin, '≤',totalIter, '≤', num%itmax - if (debugRotation) & - write(IO_STDOUT,'(/,a,/,3(3(f12.7,1x)/))',advance='no') & - ' deformation gradient aim (lab) =', transpose(params%rotation_BC%rotate(F_aim,active=.true.)) - write(IO_STDOUT,'(/,a,/,3(3(f12.7,1x)/))',advance='no') & - ' deformation gradient aim =', transpose(F_aim) + if (debugRotation) print'(/,a,/,2(3(f12.7,1x)/),3(f12.7,1x))', & + ' deformation gradient aim (lab) =', transpose(params%rotation_BC%rotate(F_aim,active=.true.)) + print'(/,a,/,2(3(f12.7,1x)/),3(f12.7,1x))', & + ' deformation gradient aim =', transpose(F_aim) flush(IO_STDOUT) endif newIteration diff --git a/src/grid/grid_thermal_spectral.f90 b/src/grid/grid_thermal_spectral.f90 index 68a1c5ed1..f5d1a33bc 100644 --- a/src/grid/grid_thermal_spectral.f90 +++ b/src/grid/grid_thermal_spectral.f90 @@ -197,8 +197,7 @@ function grid_thermal_spectral_solution(timeinc) result(solution) call VecMax(solution_vec,devNull,T_max,ierr); CHKERRQ(ierr) if (solution%converged) & print'(/,a)', ' ... thermal conduction converged ..................................' - write(IO_STDOUT,'(/,a,f8.4,2x,f8.4,2x,f8.4,/)',advance='no') ' Minimum|Maximum|Delta Temperature / K = ',& - T_min, T_max, stagNorm + print'(/,a,f8.4,2x,f8.4,2x,f8.4)', ' Minimum|Maximum|Delta Temperature / K = ', T_min, T_max, stagNorm print'(/,a)', ' ===========================================================================' flush(IO_STDOUT) diff --git a/src/grid/spectral_utilities.f90 b/src/grid/spectral_utilities.f90 index 6d6e26cae..989448dc3 100644 --- a/src/grid/spectral_utilities.f90 +++ b/src/grid/spectral_utilities.f90 @@ -688,8 +688,8 @@ function utilities_maskedCompliance(rot_BC,mask_stress,C) if(debugGeneral) then print'(/,a)', ' ... updating masked compliance ............................................' - write(IO_STDOUT,'(/,a,/,9(9(2x,f12.7,1x)/))',advance='no') ' Stiffness C (load) / GPa =',& - transpose(temp99_Real)*1.0e-9_pReal + print'(/,a,/,8(9(2x,f12.7,1x)/),9(2x,f12.7,1x))', & + ' Stiffness C (load) / GPa =', transpose(temp99_Real)*1.0e-9_pReal flush(IO_STDOUT) endif @@ -709,9 +709,8 @@ function utilities_maskedCompliance(rot_BC,mask_stress,C) if (debugGeneral .or. errmatinv) then write(formatString, '(i2)') size_reduced formatString = '(/,a,/,'//trim(formatString)//'('//trim(formatString)//'(2x,es9.2,1x)/))' - write(IO_STDOUT,trim(formatString),advance='no') ' C * S (load) ', & - transpose(matmul(c_reduced,s_reduced)) - write(IO_STDOUT,trim(formatString),advance='no') ' S (load) ', transpose(s_reduced) + print trim(formatString), ' C * S (load) ', transpose(matmul(c_reduced,s_reduced)) + print trim(formatString), ' S (load) ', transpose(s_reduced) if(errmatinv) error stop 'matrix inversion error' endif temp99_real = reshape(unpack(reshape(s_reduced,[size_reduced**2]),reshape(mask,[81]),0.0_pReal),[9,9]) @@ -722,7 +721,7 @@ function utilities_maskedCompliance(rot_BC,mask_stress,C) utilities_maskedCompliance = math_99to3333(temp99_Real) if(debugGeneral) then - write(IO_STDOUT,'(/,a,/,9(9(2x,f10.5,1x)/),/)',advance='no') & + print'(/,a,/,9(9(2x,f10.5,1x)/),9(2x,f10.5,1x))', & ' Masked Compliance (load) * GPa =', transpose(temp99_Real)*1.0e9_pReal flush(IO_STDOUT) endif @@ -818,13 +817,11 @@ subroutine utilities_constitutiveResponse(P,P_av,C_volAvg,C_minmaxAvg,& P = reshape(homogenization_P, [3,3,grid(1),grid(2),grid3]) 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) - if (debugRotation) & - write(IO_STDOUT,'(/,a,/,3(3(2x,f12.4,1x)/))',advance='no') ' Piola--Kirchhoff stress (lab) / MPa =',& - transpose(P_av)*1.e-6_pReal - if(present(rotation_BC)) & - P_av = rotation_BC%rotate(P_av) - write(IO_STDOUT,'(/,a,/,3(3(2x,f12.4,1x)/))',advance='no') ' Piola--Kirchhoff stress / MPa =',& - transpose(P_av)*1.e-6_pReal + if (debugRotation) print'(/,a,/,2(3(2x,f12.4,1x)/),3(2x,f12.4,1x))', & + ' Piola--Kirchhoff stress (lab) / MPa =', transpose(P_av)*1.e-6_pReal + if(present(rotation_BC)) P_av = rotation_BC%rotate(P_av) + print'(/,a,/,2(3(2x,f12.4,1x)/),3(2x,f12.4,1x))', & + ' Piola--Kirchhoff stress / MPa =', transpose(P_av)*1.e-6_pReal flush(IO_STDOUT) dPdF_max = 0.0_pReal diff --git a/src/material.f90 b/src/material.f90 index 223ea6ed8..b05979298 100644 --- a/src/material.f90 +++ b/src/material.f90 @@ -176,7 +176,7 @@ subroutine material_init(restart) if (.not. restart) then call results_openJobFile - call results_mapping_constituent(material_phaseAt,material_phaseMemberAt,material_name_phase) + call results_mapping_phase(material_phaseAt,material_phaseMemberAt,material_name_phase) call results_mapping_homogenization(material_homogenizationAt,material_homogenizationMemberAt,material_name_homogenization) call results_closeJobFile endif diff --git a/src/mesh/mesh_mech_FEM.f90 b/src/mesh/mesh_mech_FEM.f90 index b6ce1e175..eb5f862c2 100644 --- a/src/mesh/mesh_mech_FEM.f90 +++ b/src/mesh/mesh_mech_FEM.f90 @@ -146,14 +146,9 @@ subroutine FEM_mech_init(fieldBC) call PetscFESetQuadrature(mechFE,mechQuad,ierr); CHKERRQ(ierr) call PetscFEGetDimension(mechFE,nBasis,ierr); CHKERRQ(ierr) nBasis = nBasis/nc -#if (PETSC_VERSION_MINOR > 10) call DMAddField(mech_mesh,PETSC_NULL_DMLABEL,mechFE,ierr); CHKERRQ(ierr) call DMCreateDS(mech_mesh,ierr); CHKERRQ(ierr) -#endif call DMGetDS(mech_mesh,mechDS,ierr); CHKERRQ(ierr) -#if (PETSC_VERSION_MINOR < 11) - call PetscDSAddDiscretization(mechDS,mechFE,ierr); CHKERRQ(ierr) -#endif call PetscDSGetTotalDimension(mechDS,cellDof,ierr); CHKERRQ(ierr) call PetscFEDestroy(mechFE,ierr); CHKERRQ(ierr) call PetscQuadratureDestroy(mechQuad,ierr); CHKERRQ(ierr) @@ -162,11 +157,7 @@ subroutine FEM_mech_init(fieldBC) ! Setup FEM mech boundary conditions call DMGetLabel(mech_mesh,'Face Sets',BCLabel,ierr); CHKERRQ(ierr) call DMPlexLabelComplete(mech_mesh,BCLabel,ierr); CHKERRQ(ierr) -#if (PETSC_VERSION_MINOR < 12) - call DMGetSection(mech_mesh,section,ierr); CHKERRQ(ierr) -#else call DMGetLocalSection(mech_mesh,section,ierr); CHKERRQ(ierr) -#endif allocate(pnumComp(1), source=dimPlex) allocate(pnumDof(0:dimPlex), source = 0) do topologDim = 0, dimPlex @@ -204,14 +195,8 @@ subroutine FEM_mech_init(fieldBC) endif endif enddo; enddo -#if (PETSC_VERSION_MINOR < 11) - call DMPlexCreateSection(mech_mesh,dimPlex,1,pNumComp,pNumDof, & - numBC,pBcField,pBcComps,pBcPoints,PETSC_NULL_IS,section,ierr) -#else call DMPlexCreateSection(mech_mesh,nolabel,pNumComp,pNumDof, & numBC,pBcField,pBcComps,pBcPoints,PETSC_NULL_IS,section,ierr) - -#endif CHKERRQ(ierr) call DMSetSection(mech_mesh,section,ierr); CHKERRQ(ierr) do faceSet = 1, numBC @@ -266,11 +251,7 @@ subroutine FEM_mech_init(fieldBC) x_scal(basis+1:basis+dimPlex) = pV0 + matmul(transpose(cellJMat),nodalPointsP + 1.0_pReal) enddo px_scal => x_scal -#if (PETSC_VERSION_MINOR < 11) - call DMPlexVecSetClosure(mech_mesh,section,solution_local,cell,px_scal,INSERT_ALL_VALUES,ierr) -#else - call DMPlexVecSetClosure(mech_mesh,section,solution_local,cell,px_scal,5,ierr) ! PETSc: cbee0a90b60958e5c50c89b1e41f4451dfa6008c -#endif + call DMPlexVecSetClosure(mech_mesh,section,solution_local,cell,px_scal,5,ierr) CHKERRQ(ierr) enddo @@ -353,11 +334,7 @@ subroutine FEM_mech_formResidual(dm_local,xx_local,f_local,dummy,ierr) allocate(pinvcellJ(dimPlex**2)) allocate(x_scal(cellDof)) -#if (PETSC_VERSION_MINOR < 12) - call DMGetSection(dm_local,section,ierr); CHKERRQ(ierr) -#else call DMGetLocalSection(dm_local,section,ierr); CHKERRQ(ierr) -#endif call DMGetDS(dm_local,prob,ierr); CHKERRQ(ierr) call PetscDSGetTabulation(prob,0,basisField,basisFieldDer,ierr) CHKERRQ(ierr) @@ -500,11 +477,7 @@ subroutine FEM_mech_formJacobian(dm_local,xx_local,Jac_pre,Jac,dummy,ierr) call MatZeroEntries(Jac,ierr); CHKERRQ(ierr) call DMGetDS(dm_local,prob,ierr); CHKERRQ(ierr) call PetscDSGetTabulation(prob,0,basisField,basisFieldDer,ierr) -#if (PETSC_VERSION_MINOR < 12) - call DMGetSection(dm_local,section,ierr); CHKERRQ(ierr) -#else call DMGetLocalSection(dm_local,section,ierr); CHKERRQ(ierr) -#endif call DMGetGlobalSection(dm_local,gSection,ierr); CHKERRQ(ierr) call DMGetLocalVector(dm_local,x_local,ierr); CHKERRQ(ierr) @@ -684,8 +657,8 @@ subroutine FEM_mech_converged(snes_local,PETScIter,xnorm,snorm,fnorm,reason,dumm print'(/,1x,a,a,i0,a,i0,f0.3)', trim(incInfo), & ' @ Iteration ',PETScIter,' mechanical residual norm = ', & int(fnorm/divTol),fnorm/divTol-int(fnorm/divTol) - write(IO_STDOUT,'(/,a,/,3(3(2x,f12.4,1x)/))',advance='no') ' Piola--Kirchhoff stress / MPa =',& - transpose(P_av)*1.e-6_pReal + print'(/,a,/,2(3(2x,f12.4,1x)/),3(2x,f12.4,1x))', & + ' Piola--Kirchhoff stress / MPa =',transpose(P_av)*1.e-6_pReal flush(IO_STDOUT) end subroutine FEM_mech_converged diff --git a/src/results.f90 b/src/results.f90 index f15ad4e4a..ea9fd62d4 100644 --- a/src/results.f90 +++ b/src/results.f90 @@ -49,7 +49,7 @@ module results results_setLink, & results_addAttribute, & results_removeLink, & - results_mapping_constituent, & + results_mapping_phase, & results_mapping_homogenization contains @@ -461,7 +461,7 @@ end subroutine results_writeTensorDataset_int !-------------------------------------------------------------------------------------------------- !> @brief adds the unique mapping from spatial position and constituent ID to results !-------------------------------------------------------------------------------------------------- -subroutine results_mapping_constituent(phaseAt,memberAtLocal,label) +subroutine results_mapping_phase(phaseAt,memberAtLocal,label) integer, dimension(:,:), intent(in) :: phaseAt !< phase section at (constituent,element) integer, dimension(:,:,:), intent(in) :: memberAtLocal !< phase member at (constituent,IP,element) @@ -491,6 +491,47 @@ subroutine results_mapping_constituent(phaseAt,memberAtLocal,label) integer(SIZE_T) :: type_size_string, type_size_int integer :: hdferr, ierr, i +!-------------------------------------------------------------------------------------------------- +! prepare MPI communication (transparent for non-MPI runs) + call h5pcreate_f(H5P_DATASET_XFER_F, plist_id, hdferr) + if(hdferr < 0) error stop 'HDF5 error' + memberOffset = 0 + do i=1, size(label) + memberOffset(i,worldrank) = count(phaseAt == i)*size(memberAtLocal,2) ! number of points/instance of this process + enddo + writeSize = 0 + writeSize(worldrank) = size(memberAtLocal(1,:,:)) ! total number of points by this process + +!-------------------------------------------------------------------------------------------------- +! MPI settings and communication +#ifdef PETSc + call h5pset_dxpl_mpio_f(plist_id, H5FD_MPIO_COLLECTIVE_F, hdferr) + if(hdferr < 0) error stop 'HDF5 error' + + call MPI_allreduce(MPI_IN_PLACE,writeSize,worldsize,MPI_INT,MPI_SUM,PETSC_COMM_WORLD,ierr) ! get output at each process + if(ierr /= 0) error stop 'MPI error' + + call MPI_allreduce(MPI_IN_PLACE,memberOffset,size(memberOffset),MPI_INT,MPI_SUM,PETSC_COMM_WORLD,ierr)! get offset at each process + if(ierr /= 0) error stop 'MPI error' +#endif + + myShape = int([size(phaseAt,1),writeSize(worldrank)], HSIZE_T) + myOffset = int([0,sum(writeSize(0:worldrank-1))], HSIZE_T) + totalShape = int([size(phaseAt,1),sum(writeSize)], HSIZE_T) + + +!--------------------------------------------------------------------------------------------------- +! expand phaseAt to consider IPs (is not stored per IP) + do i = 1, size(phaseAtMaterialpoint,2) + phaseAtMaterialpoint(:,i,:) = phaseAt + enddo + +!--------------------------------------------------------------------------------------------------- +! renumber member from my process to all processes + do i = 1, size(label) + where(phaseAtMaterialpoint == i) memberAtGlobal = memberAtLocal + sum(memberOffset(i,0:worldrank-1)) -1 ! convert to 0-based + enddo + !--------------------------------------------------------------------------------------------------- ! compound type: name of phase section + position/index within results array call h5tcopy_f(H5T_NATIVE_CHARACTER, dt_id, hdferr) @@ -525,34 +566,6 @@ subroutine results_mapping_constituent(phaseAt,memberAtLocal,label) call h5tclose_f(dt_id, hdferr) if(hdferr < 0) error stop 'HDF5 error' -!-------------------------------------------------------------------------------------------------- -! prepare MPI communication (transparent for non-MPI runs) - call h5pcreate_f(H5P_DATASET_XFER_F, plist_id, hdferr) - if(hdferr < 0) error stop 'HDF5 error' - memberOffset = 0 - do i=1, size(label) - memberOffset(i,worldrank) = count(phaseAt == i)*size(memberAtLocal,2) ! number of points/instance of this process - enddo - writeSize = 0 - writeSize(worldrank) = size(memberAtLocal(1,:,:)) ! total number of points by this process - -!-------------------------------------------------------------------------------------------------- -! MPI settings and communication -#ifdef PETSc - call h5pset_dxpl_mpio_f(plist_id, H5FD_MPIO_COLLECTIVE_F, hdferr) - if(hdferr < 0) error stop 'HDF5 error' - - call MPI_allreduce(MPI_IN_PLACE,writeSize,worldsize,MPI_INT,MPI_SUM,PETSC_COMM_WORLD,ierr) ! get output at each process - if(ierr /= 0) error stop 'MPI error' - - call MPI_allreduce(MPI_IN_PLACE,memberOffset,size(memberOffset),MPI_INT,MPI_SUM,PETSC_COMM_WORLD,ierr)! get offset at each process - if(ierr /= 0) error stop 'MPI error' -#endif - - myShape = int([size(phaseAt,1),writeSize(worldrank)], HSIZE_T) - myOffset = int([0,sum(writeSize(0:worldrank-1))], HSIZE_T) - totalShape = int([size(phaseAt,1),sum(writeSize)], HSIZE_T) - !-------------------------------------------------------------------------------------------------- ! create dataspace in memory (local shape = hyperslab) and in file (global shape) call h5screate_simple_f(2,myShape,memspace_id,hdferr,myShape) @@ -564,18 +577,6 @@ subroutine results_mapping_constituent(phaseAt,memberAtLocal,label) call h5sselect_hyperslab_f(filespace_id, H5S_SELECT_SET_F, myOffset, myShape, hdferr) if(hdferr < 0) error stop 'HDF5 error' -!--------------------------------------------------------------------------------------------------- -! expand phaseAt to consider IPs (is not stored per IP) - do i = 1, size(phaseAtMaterialpoint,2) - phaseAtMaterialpoint(:,i,:) = phaseAt - enddo - -!--------------------------------------------------------------------------------------------------- -! renumber member from my process to all processes - do i = 1, size(label) - where(phaseAtMaterialpoint == i) memberAtGlobal = memberAtLocal + sum(memberOffset(i,0:worldrank-1)) -1 ! convert to 0-based - enddo - !-------------------------------------------------------------------------------------------------- ! write the components of the compound type individually call h5pset_preserve_f(plist_id, .TRUE., hdferr) @@ -609,7 +610,7 @@ subroutine results_mapping_constituent(phaseAt,memberAtLocal,label) if(hdferr < 0) error stop 'HDF5 error' call h5tclose_f(position_id, hdferr) -end subroutine results_mapping_constituent +end subroutine results_mapping_phase !-------------------------------------------------------------------------------------------------- @@ -645,6 +646,48 @@ subroutine results_mapping_homogenization(homogenizationAt,memberAtLocal,label) integer(SIZE_T) :: type_size_string, type_size_int integer :: hdferr, ierr, i + +!-------------------------------------------------------------------------------------------------- +! prepare MPI communication (transparent for non-MPI runs) + call h5pcreate_f(H5P_DATASET_XFER_F, plist_id, hdferr) + if(hdferr < 0) error stop 'HDF5 error' + memberOffset = 0 + do i=1, size(label) + memberOffset(i,worldrank) = count(homogenizationAt == i)*size(memberAtLocal,1) ! number of points/instance of this process + enddo + writeSize = 0 + writeSize(worldrank) = size(memberAtLocal) ! total number of points by this process + +!-------------------------------------------------------------------------------------------------- +! MPI settings and communication +#ifdef PETSc + call h5pset_dxpl_mpio_f(plist_id, H5FD_MPIO_COLLECTIVE_F, hdferr) + if(hdferr < 0) error stop 'HDF5 error' + + call MPI_allreduce(MPI_IN_PLACE,writeSize,worldsize,MPI_INT,MPI_SUM,PETSC_COMM_WORLD,ierr) ! get output at each process + if(ierr /= 0) error stop 'MPI error' + + call MPI_allreduce(MPI_IN_PLACE,memberOffset,size(memberOffset),MPI_INT,MPI_SUM,PETSC_COMM_WORLD,ierr)! get offset at each process + if(ierr /= 0) error stop 'MPI error' +#endif + + myShape = int([writeSize(worldrank)], HSIZE_T) + myOffset = int([sum(writeSize(0:worldrank-1))], HSIZE_T) + totalShape = int([sum(writeSize)], HSIZE_T) + + +!--------------------------------------------------------------------------------------------------- +! expand phaseAt to consider IPs (is not stored per IP) + do i = 1, size(homogenizationAtMaterialpoint,1) + homogenizationAtMaterialpoint(i,:) = homogenizationAt + enddo + +!--------------------------------------------------------------------------------------------------- +! renumber member from my process to all processes + do i = 1, size(label) + where(homogenizationAtMaterialpoint == i) memberAtGlobal = memberAtLocal + sum(memberOffset(i,0:worldrank-1)) - 1 ! convert to 0-based + enddo + !--------------------------------------------------------------------------------------------------- ! compound type: name of phase section + position/index within results array call h5tcopy_f(H5T_NATIVE_CHARACTER, dt_id, hdferr) @@ -679,34 +722,6 @@ subroutine results_mapping_homogenization(homogenizationAt,memberAtLocal,label) call h5tclose_f(dt_id, hdferr) if(hdferr < 0) error stop 'HDF5 error' -!-------------------------------------------------------------------------------------------------- -! prepare MPI communication (transparent for non-MPI runs) - call h5pcreate_f(H5P_DATASET_XFER_F, plist_id, hdferr) - if(hdferr < 0) error stop 'HDF5 error' - memberOffset = 0 - do i=1, size(label) - memberOffset(i,worldrank) = count(homogenizationAt == i)*size(memberAtLocal,1) ! number of points/instance of this process - enddo - writeSize = 0 - writeSize(worldrank) = size(memberAtLocal) ! total number of points by this process - -!-------------------------------------------------------------------------------------------------- -! MPI settings and communication -#ifdef PETSc - call h5pset_dxpl_mpio_f(plist_id, H5FD_MPIO_COLLECTIVE_F, hdferr) - if(hdferr < 0) error stop 'HDF5 error' - - call MPI_allreduce(MPI_IN_PLACE,writeSize,worldsize,MPI_INT,MPI_SUM,PETSC_COMM_WORLD,ierr) ! get output at each process - if(ierr /= 0) error stop 'MPI error' - - call MPI_allreduce(MPI_IN_PLACE,memberOffset,size(memberOffset),MPI_INT,MPI_SUM,PETSC_COMM_WORLD,ierr)! get offset at each process - if(ierr /= 0) error stop 'MPI error' -#endif - - myShape = int([writeSize(worldrank)], HSIZE_T) - myOffset = int([sum(writeSize(0:worldrank-1))], HSIZE_T) - totalShape = int([sum(writeSize)], HSIZE_T) - !-------------------------------------------------------------------------------------------------- ! create dataspace in memory (local shape = hyperslab) and in file (global shape) call h5screate_simple_f(1,myShape,memspace_id,hdferr,myShape) @@ -718,18 +733,6 @@ subroutine results_mapping_homogenization(homogenizationAt,memberAtLocal,label) call h5sselect_hyperslab_f(filespace_id, H5S_SELECT_SET_F, myOffset, myShape, hdferr) if(hdferr < 0) error stop 'HDF5 error' -!--------------------------------------------------------------------------------------------------- -! expand phaseAt to consider IPs (is not stored per IP) - do i = 1, size(homogenizationAtMaterialpoint,1) - homogenizationAtMaterialpoint(i,:) = homogenizationAt - enddo - -!--------------------------------------------------------------------------------------------------- -! renumber member from my process to all processes - do i = 1, size(label) - where(homogenizationAtMaterialpoint == i) memberAtGlobal = memberAtLocal + sum(memberOffset(i,0:worldrank-1)) - 1 ! convert to 0-based - enddo - !-------------------------------------------------------------------------------------------------- ! write the components of the compound type individually call h5pset_preserve_f(plist_id, .TRUE., hdferr) From 35b833e2adddf19b96c616a54ae217e49b16f2cb Mon Sep 17 00:00:00 2001 From: Test User Date: Fri, 18 Dec 2020 20:08:35 +0100 Subject: [PATCH 061/148] [skip ci] updated version information after successful test of v3.0.0-alpha2-42-g6cc78cb41 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index d50c5b204..85027fcd3 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v3.0.0-alpha2-39-g5fb0e4908 +v3.0.0-alpha2-42-g6cc78cb41 From 877a489ea573d747f2126ba244ed5b49763b0c22 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Fri, 18 Dec 2020 17:41:00 +0100 Subject: [PATCH 062/148] improved tests --- PRIVATE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PRIVATE b/PRIVATE index a6a4eba5b..313dd5de6 160000 --- a/PRIVATE +++ b/PRIVATE @@ -1 +1 @@ -Subproject commit a6a4eba5bd3dfb2600b6bb5bed70e3e2045705bc +Subproject commit 313dd5de618c996cdf9ace95a096f25e757386d9 From 8dbc3d2d473816b0f7f7d1d293ecfc21fa5e7b08 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 19 Dec 2020 17:25:57 +0100 Subject: [PATCH 063/148] no special (untested) cases any more --- PRIVATE | 2 +- src/commercialFEM_fileList.f90 | 2 - src/crystallite.f90 | 1 - src/damage_local.f90 | 172 ------------------------- src/homogenization.f90 | 36 ------ src/material.f90 | 10 -- src/thermal_adiabatic.f90 | 226 --------------------------------- src/thermal_conduction.f90 | 4 - src/thermal_isothermal.f90 | 4 - 9 files changed, 1 insertion(+), 456 deletions(-) delete mode 100644 src/damage_local.f90 delete mode 100644 src/thermal_adiabatic.f90 diff --git a/PRIVATE b/PRIVATE index 313dd5de6..45ef93dbf 160000 --- a/PRIVATE +++ b/PRIVATE @@ -1 +1 @@ -Subproject commit 313dd5de618c996cdf9ace95a096f25e757386d9 +Subproject commit 45ef93dbfa3e0e6fa830914b3632e188c308a099 diff --git a/src/commercialFEM_fileList.f90 b/src/commercialFEM_fileList.f90 index beabfcae1..a5bbe69ca 100644 --- a/src/commercialFEM_fileList.f90 +++ b/src/commercialFEM_fileList.f90 @@ -46,10 +46,8 @@ #include "kinematics_slipplane_opening.f90" #include "crystallite.f90" #include "thermal_isothermal.f90" -#include "thermal_adiabatic.f90" #include "thermal_conduction.f90" #include "damage_none.f90" -#include "damage_local.f90" #include "damage_nonlocal.f90" #include "homogenization.f90" #include "homogenization_mech.f90" diff --git a/src/crystallite.f90 b/src/crystallite.f90 index 31a6bde2d..e594ef5a1 100644 --- a/src/crystallite.f90 +++ b/src/crystallite.f90 @@ -1629,7 +1629,6 @@ subroutine crystallite_forward enddo; enddo do i = 1,size(material_name_homogenization) homogState (i)%state0 = homogState (i)%state - thermalState(i)%state0 = thermalState(i)%state damageState (i)%state0 = damageState (i)%state enddo diff --git a/src/damage_local.f90 b/src/damage_local.f90 deleted file mode 100644 index 97eaf9a8c..000000000 --- a/src/damage_local.f90 +++ /dev/null @@ -1,172 +0,0 @@ -!-------------------------------------------------------------------------------------------------- -!> @author Pratheek Shanthraj, Max-Planck-Institut für Eisenforschung GmbH -!> @brief material subroutine for locally evolving damage field -!-------------------------------------------------------------------------------------------------- -module damage_local - use prec - use IO - use material - use config - use YAML_types - use constitutive - use results - - implicit none - private - - type :: tParameters - character(len=pStringLen), allocatable, dimension(:) :: & - output - end type tParameters - - type, private :: tNumerics - real(pReal) :: & - residualStiffness !< non-zero residual damage - end type tNumerics - - type(tparameters), dimension(:), allocatable :: & - param - - type(tNumerics), private :: num - - public :: & - damage_local_init, & - damage_local_updateState, & - damage_local_results - -contains - -!-------------------------------------------------------------------------------------------------- -!> @brief module initialization -!> @details reads in material parameters, allocates arrays, and does sanity checks -!-------------------------------------------------------------------------------------------------- -subroutine damage_local_init - - integer :: Ninstances,Nmaterialpoints,h - class(tNode), pointer :: & - num_generic, & - material_homogenization, & - homog, & - homogDamage - - print'(/,a)', ' <<<+- damage_local init -+>>>'; flush(IO_STDOUT) - -!---------------------------------------------------------------------------------------------- -! read numerics parameter and do sanity check - num_generic => config_numerics%get('generic',defaultVal=emptyDict) - num%residualStiffness = num_generic%get_asFloat('residualStiffness', defaultVal=1.0e-6_pReal) - if (num%residualStiffness < 0.0_pReal) call IO_error(301,ext_msg='residualStiffness') - - Ninstances = count(damage_type == DAMAGE_local_ID) - allocate(param(Ninstances)) - - material_homogenization => config_material%get('homogenization') - do h = 1, material_homogenization%length - if (damage_type(h) /= DAMAGE_LOCAL_ID) cycle - homog => material_homogenization%get(h) - homogDamage => homog%get('damage') - associate(prm => param(damage_typeInstance(h))) - -#if defined (__GFORTRAN__) - prm%output = output_asStrings(homogDamage) -#else - prm%output = homogDamage%get_asStrings('output',defaultVal=emptyStringArray) -#endif - - Nmaterialpoints = count(material_homogenizationAt == h) - damageState(h)%sizeState = 1 - allocate(damageState(h)%state0 (1,Nmaterialpoints), source=1.0_pReal) - allocate(damageState(h)%subState0(1,Nmaterialpoints), source=1.0_pReal) - allocate(damageState(h)%state (1,Nmaterialpoints), source=1.0_pReal) - - damage(h)%p => damageState(h)%state(1,:) - - end associate - enddo - -end subroutine damage_local_init - - -!-------------------------------------------------------------------------------------------------- -!> @brief calculates local change in damage field -!-------------------------------------------------------------------------------------------------- -function damage_local_updateState(subdt, ip, el) - - integer, intent(in) :: & - ip, & !< integration point number - el !< element number - real(pReal), intent(in) :: & - subdt - logical, dimension(2) :: & - damage_local_updateState - integer :: & - homog, & - offset - real(pReal) :: & - phi, phiDot, dPhiDot_dPhi - - homog = material_homogenizationAt(el) - offset = material_homogenizationMemberAt(ip,el) - phi = damageState(homog)%subState0(1,offset) - call damage_local_getSourceAndItsTangent(phiDot, dPhiDot_dPhi, phi, ip, el) - phi = max(num%residualStiffness,min(1.0_pReal,phi + subdt*phiDot)) - - damage_local_updateState = [ abs(phi - damageState(homog)%state(1,offset)) & - <= 1.0e-2_pReal & - .or. abs(phi - damageState(homog)%state(1,offset)) & - <= 1.0e-6_pReal*abs(damageState(homog)%state(1,offset)), & - .true.] - - damageState(homog)%state(1,offset) = phi - -end function damage_local_updateState - - -!-------------------------------------------------------------------------------------------------- -!> @brief calculates homogenized local damage driving forces -!-------------------------------------------------------------------------------------------------- -subroutine damage_local_getSourceAndItsTangent(phiDot, dPhiDot_dPhi, phi, ip, el) - - integer, intent(in) :: & - ip, & !< integration point number - el !< element number - real(pReal), intent(in) :: & - phi - real(pReal) :: & - phiDot, dPhiDot_dPhi - - phiDot = 0.0_pReal - dPhiDot_dPhi = 0.0_pReal - - call constitutive_damage_getRateAndItsTangents(phiDot, dPhiDot_dPhi, phi, ip, el) - - phiDot = phiDot/real(homogenization_Nconstituents(material_homogenizationAt(el)),pReal) - dPhiDot_dPhi = dPhiDot_dPhi/real(homogenization_Nconstituents(material_homogenizationAt(el)),pReal) - -end subroutine damage_local_getSourceAndItsTangent - - -!-------------------------------------------------------------------------------------------------- -!> @brief writes results to HDF5 output file -!-------------------------------------------------------------------------------------------------- -subroutine damage_local_results(homog,group) - - integer, intent(in) :: homog - character(len=*), intent(in) :: group - - integer :: o - - associate(prm => param(damage_typeInstance(homog))) - outputsLoop: do o = 1,size(prm%output) - select case(prm%output(o)) - case ('phi') - call results_writeDataset(group,damage(homog)%p,prm%output(o),& - 'damage indicator','-') - end select - enddo outputsLoop - end associate - -end subroutine damage_local_results - - -end module damage_local diff --git a/src/homogenization.f90 b/src/homogenization.f90 index 57478e039..30d9cfb90 100644 --- a/src/homogenization.f90 +++ b/src/homogenization.f90 @@ -15,10 +15,8 @@ module homogenization use FEsolving use discretization use thermal_isothermal - use thermal_adiabatic use thermal_conduction use damage_none - use damage_local use damage_nonlocal use results @@ -162,11 +160,9 @@ subroutine homogenization_init call mech_init(num_homog) if (any(thermal_type == THERMAL_isothermal_ID)) call thermal_isothermal_init - if (any(thermal_type == THERMAL_adiabatic_ID)) call thermal_adiabatic_init if (any(thermal_type == THERMAL_conduction_ID)) call thermal_conduction_init if (any(damage_type == DAMAGE_none_ID)) call damage_none_init - if (any(damage_type == DAMAGE_local_ID)) call damage_local_init if (any(damage_type == DAMAGE_nonlocal_ID)) call damage_nonlocal_init @@ -212,10 +208,6 @@ subroutine materialpoint_stressAndItsTangent(dt) homogState(material_homogenizationAt(e))%subState0(:,material_homogenizationMemberAt(i,e)) = & homogState(material_homogenizationAt(e))%State0( :,material_homogenizationMemberAt(i,e)) - if (thermalState(material_homogenizationAt(e))%sizeState > 0) & - thermalState(material_homogenizationAt(e))%subState0(:,material_homogenizationMemberAt(i,e)) = & - thermalState(material_homogenizationAt(e))%State0( :,material_homogenizationMemberAt(i,e)) - if (damageState(material_homogenizationAt(e))%sizeState > 0) & damageState(material_homogenizationAt(e))%subState0(:,material_homogenizationMemberAt(i,e)) = & damageState(material_homogenizationAt(e))%State0( :,material_homogenizationMemberAt(i,e)) @@ -245,9 +237,6 @@ subroutine materialpoint_stressAndItsTangent(dt) if(homogState(material_homogenizationAt(e))%sizeState > 0) & homogState(material_homogenizationAt(e))%subState0(:,material_homogenizationMemberAt(i,e)) = & homogState(material_homogenizationAt(e))%State (:,material_homogenizationMemberAt(i,e)) - if(thermalState(material_homogenizationAt(e))%sizeState > 0) & - thermalState(material_homogenizationAt(e))%subState0(:,material_homogenizationMemberAt(i,e)) = & - thermalState(material_homogenizationAt(e))%State (:,material_homogenizationMemberAt(i,e)) if(damageState(material_homogenizationAt(e))%sizeState > 0) & damageState(material_homogenizationAt(e))%subState0(:,material_homogenizationMemberAt(i,e)) = & damageState(material_homogenizationAt(e))%State (:,material_homogenizationMemberAt(i,e)) @@ -270,9 +259,6 @@ subroutine materialpoint_stressAndItsTangent(dt) if(homogState(material_homogenizationAt(e))%sizeState > 0) & homogState(material_homogenizationAt(e))%State( :,material_homogenizationMemberAt(i,e)) = & homogState(material_homogenizationAt(e))%subState0(:,material_homogenizationMemberAt(i,e)) - if(thermalState(material_homogenizationAt(e))%sizeState > 0) & - thermalState(material_homogenizationAt(e))%State( :,material_homogenizationMemberAt(i,e)) = & - thermalState(material_homogenizationAt(e))%subState0(:,material_homogenizationMemberAt(i,e)) if(damageState(material_homogenizationAt(e))%sizeState > 0) & damageState(material_homogenizationAt(e))%State( :,material_homogenizationMemberAt(i,e)) = & damageState(material_homogenizationAt(e))%subState0(:,material_homogenizationMemberAt(i,e)) @@ -400,24 +386,6 @@ function updateState(subdt,subF,ip,el) el) end select chosenHomogenization - chosenThermal: select case (thermal_type(material_homogenizationAt(el))) - case (THERMAL_adiabatic_ID) chosenThermal - updateState = & - updateState .and. & - thermal_adiabatic_updateState(subdt, & - ip, & - el) - end select chosenThermal - - chosenDamage: select case (damage_type(material_homogenizationAt(el))) - case (DAMAGE_local_ID) chosenDamage - updateState = & - updateState .and. & - damage_local_updateState(subdt, & - ip, & - el) - end select chosenDamage - end function updateState @@ -441,8 +409,6 @@ subroutine homogenization_results group = trim(group_base)//'/damage' call results_closeGroup(results_addGroup(group)) select case(damage_type(p)) - case(DAMAGE_LOCAL_ID) - call damage_local_results(p,group) case(DAMAGE_NONLOCAL_ID) call damage_nonlocal_results(p,group) end select @@ -450,8 +416,6 @@ subroutine homogenization_results group = trim(group_base)//'/thermal' call results_closeGroup(results_addGroup(group)) select case(thermal_type(p)) - case(THERMAL_ADIABATIC_ID) - call thermal_adiabatic_results(p,group) case(THERMAL_CONDUCTION_ID) call thermal_conduction_results(p,group) end select diff --git a/src/material.f90 b/src/material.f90 index bb5f484f6..1f2437ad3 100644 --- a/src/material.f90 +++ b/src/material.f90 @@ -41,10 +41,8 @@ module material STIFFNESS_DEGRADATION_UNDEFINED_ID, & STIFFNESS_DEGRADATION_DAMAGE_ID, & THERMAL_ISOTHERMAL_ID, & - THERMAL_ADIABATIC_ID, & THERMAL_CONDUCTION_ID, & DAMAGE_NONE_ID, & - DAMAGE_LOCAL_ID, & DAMAGE_NONLOCAL_ID, & HOMOGENIZATION_UNDEFINED_ID, & HOMOGENIZATION_NONE_ID, & @@ -86,7 +84,6 @@ module material type(tState), allocatable, dimension(:), public :: & homogState, & - thermalState, & damageState type(Rotation), dimension(:,:,:), allocatable, public, protected :: & @@ -123,10 +120,8 @@ module material STIFFNESS_DEGRADATION_UNDEFINED_ID, & STIFFNESS_DEGRADATION_DAMAGE_ID, & THERMAL_ISOTHERMAL_ID, & - THERMAL_ADIABATIC_ID, & THERMAL_CONDUCTION_ID, & DAMAGE_NONE_ID, & - DAMAGE_LOCAL_ID, & DAMAGE_NONLOCAL_ID, & HOMOGENIZATION_NONE_ID, & HOMOGENIZATION_ISOSTRAIN_ID, & @@ -152,7 +147,6 @@ subroutine material_init(restart) allocate(homogState (size(material_name_homogenization))) - allocate(thermalState (size(material_name_homogenization))) allocate(damageState (size(material_name_homogenization))) allocate(temperature (size(material_name_homogenization))) @@ -218,8 +212,6 @@ subroutine material_parseHomogenization select case (homogThermal%get_asString('type')) case('isothermal') thermal_type(h) = THERMAL_isothermal_ID - case('adiabatic') - thermal_type(h) = THERMAL_adiabatic_ID case('conduction') thermal_type(h) = THERMAL_conduction_ID case default @@ -232,8 +224,6 @@ subroutine material_parseHomogenization select case (homogDamage%get_asString('type')) case('none') damage_type(h) = DAMAGE_none_ID - case('local') - damage_type(h) = DAMAGE_local_ID case('nonlocal') damage_type(h) = DAMAGE_nonlocal_ID case default diff --git a/src/thermal_adiabatic.f90 b/src/thermal_adiabatic.f90 deleted file mode 100644 index c67d004bf..000000000 --- a/src/thermal_adiabatic.f90 +++ /dev/null @@ -1,226 +0,0 @@ -!-------------------------------------------------------------------------------------------------- -!> @author Pratheek Shanthraj, Max-Planck-Institut für Eisenforschung GmbH -!> @brief material subroutine for adiabatic temperature evolution -!-------------------------------------------------------------------------------------------------- -module thermal_adiabatic - use prec - use config - use material - use results - use constitutive - use YAML_types - use crystallite - use lattice - - implicit none - private - - type :: tParameters - character(len=pStringLen), allocatable, dimension(:) :: & - output - end type tParameters - - type(tparameters), dimension(:), allocatable :: & - param - - public :: & - thermal_adiabatic_init, & - thermal_adiabatic_updateState, & - thermal_adiabatic_getSourceAndItsTangent, & - thermal_adiabatic_getSpecificHeat, & - thermal_adiabatic_getMassDensity, & - thermal_adiabatic_results - -contains - - -!-------------------------------------------------------------------------------------------------- -!> @brief module initialization -!> @details reads in material parameters, allocates arrays, and does sanity checks -!-------------------------------------------------------------------------------------------------- -subroutine thermal_adiabatic_init - - integer :: maxNinstances,h,Nmaterialpoints - class(tNode), pointer :: & - material_homogenization, & - homog, & - homogThermal - - print'(/,a)', ' <<<+- thermal_adiabatic init -+>>>'; flush(6) - - maxNinstances = count(thermal_type == THERMAL_adiabatic_ID) - if (maxNinstances == 0) return - - allocate(param(maxNinstances)) - - material_homogenization => config_material%get('homogenization') - do h = 1, size(material_name_homogenization) - if (thermal_type(h) /= THERMAL_adiabatic_ID) cycle - homog => material_homogenization%get(h) - homogThermal => homog%get('thermal') - - associate(prm => param(thermal_typeInstance(h))) - -#if defined (__GFORTRAN__) - prm%output = output_asStrings(homogThermal) -#else - prm%output = homogThermal%get_asStrings('output',defaultVal=emptyStringArray) -#endif - - Nmaterialpoints=count(material_homogenizationAt==h) - thermalState(h)%sizeState = 1 - allocate(thermalState(h)%state0 (1,Nmaterialpoints), source=thermal_initialT(h)) - allocate(thermalState(h)%subState0(1,Nmaterialpoints), source=thermal_initialT(h)) - allocate(thermalState(h)%state (1,Nmaterialpoints), source=thermal_initialT(h)) - - temperature(h)%p => thermalState(h)%state(1,:) - allocate(temperatureRate(h)%p(Nmaterialpoints),source = 0.0_pReal) - - end associate - enddo - -end subroutine thermal_adiabatic_init - - -!-------------------------------------------------------------------------------------------------- -!> @brief calculates adiabatic change in temperature based on local heat generation model -!-------------------------------------------------------------------------------------------------- -function thermal_adiabatic_updateState(subdt, ip, el) - - integer, intent(in) :: & - ip, & !< integration point number - el !< element number - real(pReal), intent(in) :: & - subdt - - logical, dimension(2) :: & - thermal_adiabatic_updateState - integer :: & - homog, & - offset - real(pReal) :: & - T, Tdot, dTdot_dT - - homog = material_homogenizationAt(el) - offset = material_homogenizationMemberAt(ip,el) - - T = thermalState(homog)%subState0(1,offset) - call thermal_adiabatic_getSourceAndItsTangent(Tdot, dTdot_dT, T, ip, el) - T = T + subdt*Tdot/(thermal_adiabatic_getSpecificHeat(ip,el)*thermal_adiabatic_getMassDensity(ip,el)) - - thermal_adiabatic_updateState = [ abs(T - thermalState(homog)%state(1,offset)) & - <= 1.0e-2_pReal & - .or. abs(T - thermalState(homog)%state(1,offset)) & - <= 1.0e-6_pReal*abs(thermalState(homog)%state(1,offset)), & - .true.] - - temperature (homog)%p(material_homogenizationMemberAt(ip,el)) = T - temperatureRate(homog)%p(material_homogenizationMemberAt(ip,el)) = & - (thermalState(homog)%state(1,offset) - thermalState(homog)%subState0(1,offset))/(subdt+tiny(0.0_pReal)) - -end function thermal_adiabatic_updateState - - -!-------------------------------------------------------------------------------------------------- -!> @brief returns heat generation rate -!-------------------------------------------------------------------------------------------------- -subroutine thermal_adiabatic_getSourceAndItsTangent(Tdot, dTdot_dT, T, ip, el) - - integer, intent(in) :: & - ip, & !< integration point number - el !< element number - real(pReal), intent(in) :: & - T - real(pReal), intent(out) :: & - Tdot, dTdot_dT - integer :: & - homog - - Tdot = 0.0_pReal - dTdot_dT = 0.0_pReal - - homog = material_homogenizationAt(el) - call constitutive_thermal_getRateAndItsTangents(TDot, dTDot_dT, T, crystallite_S, crystallite_Lp, ip, el) - - Tdot = Tdot/real(homogenization_Nconstituents(homog),pReal) - dTdot_dT = dTdot_dT/real(homogenization_Nconstituents(homog),pReal) - -end subroutine thermal_adiabatic_getSourceAndItsTangent - - -!-------------------------------------------------------------------------------------------------- -!> @brief returns homogenized specific heat capacity -!-------------------------------------------------------------------------------------------------- -function thermal_adiabatic_getSpecificHeat(ip,el) - - integer, intent(in) :: & - ip, & !< integration point number - el !< element number - - real(pReal) :: & - thermal_adiabatic_getSpecificHeat - integer :: & - grain - - thermal_adiabatic_getSpecificHeat = 0.0_pReal - - do grain = 1, homogenization_Nconstituents(material_homogenizationAt(el)) - thermal_adiabatic_getSpecificHeat = thermal_adiabatic_getSpecificHeat & - + lattice_c_p(material_phaseAt(grain,el)) - enddo - - thermal_adiabatic_getSpecificHeat = thermal_adiabatic_getSpecificHeat & - / real(homogenization_Nconstituents(material_homogenizationAt(el)),pReal) - -end function thermal_adiabatic_getSpecificHeat - - -!-------------------------------------------------------------------------------------------------- -!> @brief returns homogenized mass density -!-------------------------------------------------------------------------------------------------- -function thermal_adiabatic_getMassDensity(ip,el) - - integer, intent(in) :: & - ip, & !< integration point number - el !< element number - real(pReal) :: & - thermal_adiabatic_getMassDensity - integer :: & - grain - - thermal_adiabatic_getMassDensity = 0.0_pReal - - do grain = 1, homogenization_Nconstituents(material_homogenizationAt(el)) - thermal_adiabatic_getMassDensity = thermal_adiabatic_getMassDensity & - + lattice_rho(material_phaseAt(grain,el)) - enddo - - thermal_adiabatic_getMassDensity = thermal_adiabatic_getMassDensity & - / real(homogenization_Nconstituents(material_homogenizationAt(el)),pReal) - -end function thermal_adiabatic_getMassDensity - - -!-------------------------------------------------------------------------------------------------- -!> @brief writes results to HDF5 output file -!-------------------------------------------------------------------------------------------------- -subroutine thermal_adiabatic_results(homog,group) - - integer, intent(in) :: homog - character(len=*), intent(in) :: group - - integer :: o - - associate(prm => param(damage_typeInstance(homog))) - outputsLoop: do o = 1,size(prm%output) - select case(trim(prm%output(o))) - case('T') - call results_writeDataset(group,temperature(homog)%p,'T',& - 'temperature','K') - end select - enddo outputsLoop - end associate - -end subroutine thermal_adiabatic_results - -end module thermal_adiabatic diff --git a/src/thermal_conduction.f90 b/src/thermal_conduction.f90 index 602bdab35..37a407101 100644 --- a/src/thermal_conduction.f90 +++ b/src/thermal_conduction.f90 @@ -66,10 +66,6 @@ subroutine thermal_conduction_init #endif Nmaterialpoints=count(material_homogenizationAt==h) - thermalState(h)%sizeState = 0 - allocate(thermalState(h)%state0 (0,Nmaterialpoints)) - allocate(thermalState(h)%subState0(0,Nmaterialpoints)) - allocate(thermalState(h)%state (0,Nmaterialpoints)) allocate (temperature (h)%p(Nmaterialpoints), source=thermal_initialT(h)) allocate (temperatureRate(h)%p(Nmaterialpoints), source=0.0_pReal) diff --git a/src/thermal_isothermal.f90 b/src/thermal_isothermal.f90 index adf2257de..2a41ada49 100644 --- a/src/thermal_isothermal.f90 +++ b/src/thermal_isothermal.f90 @@ -25,10 +25,6 @@ subroutine thermal_isothermal_init if (thermal_type(h) /= THERMAL_isothermal_ID) cycle Nmaterialpoints = count(material_homogenizationAt == h) - thermalState(h)%sizeState = 0 - allocate(thermalState(h)%state0 (0,Nmaterialpoints)) - allocate(thermalState(h)%subState0(0,Nmaterialpoints)) - allocate(thermalState(h)%state (0,Nmaterialpoints)) allocate(temperature (h)%p(Nmaterialpoints),source=thermal_initialT(h)) allocate(temperatureRate(h)%p(Nmaterialpoints),source = 0.0_pReal) From eca28556aee91a036620bda636e85501fc1ceb76 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 19 Dec 2020 17:43:37 +0100 Subject: [PATCH 064/148] not tested implement again in new structure if needed --- src/constitutive.f90 | 47 ++-------------------------- src/crystallite.f90 | 2 +- src/kinematics_thermal_expansion.f90 | 33 +++---------------- 3 files changed, 8 insertions(+), 74 deletions(-) diff --git a/src/constitutive.f90 b/src/constitutive.f90 index a60352f81..6dcd88f04 100644 --- a/src/constitutive.f90 +++ b/src/constitutive.f90 @@ -200,15 +200,6 @@ module constitutive el !< element end function plastic_dislotwin_homogenizedC - pure module function kinematics_thermal_expansion_initialStrain(homog,phase,offset) result(initialStrain) - integer, intent(in) :: & - phase, & - homog, & - offset - real(pReal), dimension(3,3) :: & - initialStrain - end function kinematics_thermal_expansion_initialStrain - module subroutine plastic_nonlocal_updateCompatibility(orientation,instance,i,e) integer, intent(in) :: & instance, & @@ -340,7 +331,7 @@ module constitutive end interface constitutive_dependentState interface constitutive_SandItsTangents - + module subroutine constitutive_hooke_SandItsTangents(S, dS_dFe, dS_dFi, Fe, Fi, ipc, ip, el) integer, intent(in) :: & ipc, & !< component-ID of integration point @@ -378,7 +369,6 @@ module constitutive constitutive_LpAndItsTangents, & constitutive_dependentState, & constitutive_LiAndItsTangents, & - constitutive_initialFi, & constitutive_SandItsTangents, & constitutive_collectDotState, & constitutive_deltaState, & @@ -421,7 +411,7 @@ subroutine constitutive_init print'(/,a)', ' <<<+- constitutive init -+>>>'; flush(IO_STDOUT) - phases => config_material%get('phase') + phases => config_material%get('phase') constitutive_source_maxSizeDotState = 0 PhaseLoop2:do p = 1,phases%length !-------------------------------------------------------------------------------------------------- @@ -607,39 +597,6 @@ subroutine constitutive_LiAndItsTangents(Li, dLi_dS, dLi_dFi, & end subroutine constitutive_LiAndItsTangents -!-------------------------------------------------------------------------------------------------- -!> @brief collects initial intermediate deformation gradient -!-------------------------------------------------------------------------------------------------- -pure function constitutive_initialFi(ipc, ip, el) - - integer, intent(in) :: & - ipc, & !< component-ID of integration point - ip, & !< integration point - el !< element - real(pReal), dimension(3,3) :: & - constitutive_initialFi !< composite initial intermediate deformation gradient - integer :: & - k !< counter in kinematics loop - integer :: & - phase, & - homog, offset - - constitutive_initialFi = math_I3 - phase = material_phaseAt(ipc,el) - - KinematicsLoop: do k = 1, phase_Nkinematics(phase) !< Warning: small initial strain assumption - kinematicsType: select case (phase_kinematics(k,phase)) - case (KINEMATICS_thermal_expansion_ID) kinematicsType - homog = material_homogenizationAt(el) - offset = material_homogenizationMemberAt(ip,el) - constitutive_initialFi = constitutive_initialFi & - + kinematics_thermal_expansion_initialStrain(homog,phase,offset) - end select kinematicsType - enddo KinematicsLoop - -end function constitutive_initialFi - - !-------------------------------------------------------------------------------------------------- !> @brief contains the constitutive equation for calculating the rate of change of microstructure !-------------------------------------------------------------------------------------------------- diff --git a/src/crystallite.f90 b/src/crystallite.f90 index e594ef5a1..f343d16b6 100644 --- a/src/crystallite.f90 +++ b/src/crystallite.f90 @@ -263,7 +263,7 @@ subroutine crystallite_init crystallite_Fp0(1:3,1:3,c,i,e) = material_orientation0(c,i,e)%asMatrix() ! Fp reflects initial orientation (see 10.1016/j.actamat.2006.01.005) crystallite_Fp0(1:3,1:3,c,i,e) = crystallite_Fp0(1:3,1:3,c,i,e) & / math_det33(crystallite_Fp0(1:3,1:3,c,i,e))**(1.0_pReal/3.0_pReal) - crystallite_Fi0(1:3,1:3,c,i,e) = constitutive_initialFi(c,i,e) + crystallite_Fi0(1:3,1:3,c,i,e) = math_I3 crystallite_F0(1:3,1:3,c,i,e) = math_I3 crystallite_Fe(1:3,1:3,c,i,e) = math_inv33(matmul(crystallite_Fi0(1:3,1:3,c,i,e), & crystallite_Fp0(1:3,1:3,c,i,e))) ! assuming that euler angles are given in internal strain free configuration diff --git a/src/kinematics_thermal_expansion.f90 b/src/kinematics_thermal_expansion.f90 index 36a882a48..5265d6172 100644 --- a/src/kinematics_thermal_expansion.f90 +++ b/src/kinematics_thermal_expansion.f90 @@ -26,7 +26,7 @@ contains !-------------------------------------------------------------------------------------------------- module function kinematics_thermal_expansion_init(kinematics_length) result(myKinematics) - integer, intent(in) :: kinematics_length + integer, intent(in) :: kinematics_length logical, dimension(:,:), allocatable :: myKinematics integer :: Ninstances,p,i,k @@ -35,8 +35,8 @@ module function kinematics_thermal_expansion_init(kinematics_length) result(myKi phases, & phase, & kinematics, & - kinematic_type - + kinematic_type + print'(/,a)', ' <<<+- kinematics_thermal_expansion init -+>>>' myKinematics = kinematics_active('thermal_expansion',kinematics_length) @@ -50,13 +50,13 @@ module function kinematics_thermal_expansion_init(kinematics_length) result(myKi do p = 1, phases%length if(any(myKinematics(:,p))) kinematics_thermal_expansion_instance(p) = count(myKinematics(:,1:p)) - phase => phases%get(p) + phase => phases%get(p) if(count(myKinematics(:,p)) == 0) cycle kinematics => phase%get('kinematics') do k = 1, kinematics%length if(myKinematics(k,p)) then associate(prm => param(kinematics_thermal_expansion_instance(p))) - kinematic_type => kinematics%get(k) + kinematic_type => kinematics%get(k) prm%T_ref = kinematic_type%get_asFloat('T_ref', defaultVal=0.0_pReal) @@ -81,29 +81,6 @@ module function kinematics_thermal_expansion_init(kinematics_length) result(myKi end function kinematics_thermal_expansion_init -!-------------------------------------------------------------------------------------------------- -!> @brief report initial thermal strain based on current temperature deviation from reference -!-------------------------------------------------------------------------------------------------- -pure module function kinematics_thermal_expansion_initialStrain(homog,phase,offset) result(initialStrain) - - integer, intent(in) :: & - phase, & - homog, & - offset - - real(pReal), dimension(3,3) :: & - initialStrain !< initial thermal strain (should be small strain, though) - - associate(prm => param(kinematics_thermal_expansion_instance(phase))) - initialStrain = & - (temperature(homog)%p(offset) - prm%T_ref)**1 / 1. * prm%A(1:3,1:3,1) + & ! constant coefficient - (temperature(homog)%p(offset) - prm%T_ref)**2 / 2. * prm%A(1:3,1:3,2) + & ! linear coefficient - (temperature(homog)%p(offset) - prm%T_ref)**3 / 3. * prm%A(1:3,1:3,3) ! quadratic coefficient - end associate - -end function kinematics_thermal_expansion_initialStrain - - !-------------------------------------------------------------------------------------------------- !> @brief constitutive equation for calculating the velocity gradient !-------------------------------------------------------------------------------------------------- From 0dc388ac5c8f8392d0ce3650e09ffbb1cd9a1e10 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 19 Dec 2020 17:54:54 +0100 Subject: [PATCH 065/148] limit multiphysics to FPI integration --- src/crystallite.f90 | 60 +-------------------------------------------- 1 file changed, 1 insertion(+), 59 deletions(-) diff --git a/src/crystallite.f90 b/src/crystallite.f90 index f343d16b6..c294acc31 100644 --- a/src/crystallite.f90 +++ b/src/crystallite.f90 @@ -1214,7 +1214,6 @@ subroutine integrateStateEuler(g,i,e) integer :: & p, & c, & - s, & sizeDotState logical :: & broken @@ -1233,16 +1232,10 @@ subroutine integrateStateEuler(g,i,e) plasticState(p)%state(1:sizeDotState,c) = plasticState(p)%subState0(1:sizeDotState,c) & + plasticState(p)%dotState (1:sizeDotState,c) & * crystallite_subdt(g,i,e) - do s = 1, phase_Nsources(p) - sizeDotState = sourceState(p)%p(s)%sizeDotState - sourceState(p)%p(s)%state(1:sizeDotState,c) = sourceState(p)%p(s)%subState0(1:sizeDotState,c) & - + sourceState(p)%p(s)%dotState (1:sizeDotState,c) & - * crystallite_subdt(g,i,e) - enddo broken = constitutive_deltaState(crystallite_S(1:3,1:3,g,i,e), & crystallite_Fe(1:3,1:3,g,i,e), & - crystallite_Fi(1:3,1:3,g,i,e),g,i,e,p,c) + crystallite_Fi(1:3,1:3,g,i,e),g,i,e,p,c) if(broken) return broken = integrateStress(g,i,e) @@ -1263,13 +1256,11 @@ subroutine integrateStateAdaptiveEuler(g,i,e) integer :: & p, & c, & - s, & sizeDotState logical :: & broken real(pReal), dimension(constitutive_plasticity_maxSizeDotState) :: residuum_plastic - real(pReal), dimension(constitutive_source_maxSizeDotState,maxval(phase_Nsources)) :: residuum_source p = material_phaseAt(g,e) @@ -1287,14 +1278,6 @@ subroutine integrateStateAdaptiveEuler(g,i,e) residuum_plastic(1:sizeDotState) = - plasticState(p)%dotstate(1:sizeDotState,c) * 0.5_pReal * crystallite_subdt(g,i,e) plasticState(p)%state(1:sizeDotState,c) = plasticState(p)%subState0(1:sizeDotState,c) & + plasticState(p)%dotstate(1:sizeDotState,c) * crystallite_subdt(g,i,e) - do s = 1, phase_Nsources(p) - sizeDotState = sourceState(p)%p(s)%sizeDotState - - residuum_source(1:sizeDotState,s) = - sourceState(p)%p(s)%dotstate(1:sizeDotState,c) & - * 0.5_pReal * crystallite_subdt(g,i,e) - sourceState(p)%p(s)%state(1:sizeDotState,c) = sourceState(p)%p(s)%subState0(1:sizeDotState,c) & - + sourceState(p)%p(s)%dotstate(1:sizeDotState,c) * crystallite_subdt(g,i,e) - enddo broken = constitutive_deltaState(crystallite_S(1:3,1:3,g,i,e), & crystallite_Fe(1:3,1:3,g,i,e), & @@ -1318,15 +1301,6 @@ subroutine integrateStateAdaptiveEuler(g,i,e) plasticState(p)%state(1:sizeDotState,c), & plasticState(p)%atol(1:sizeDotState)) - do s = 1, phase_Nsources(p) - sizeDotState = sourceState(p)%p(s)%sizeDotState - crystallite_converged(g,i,e) = & - crystallite_converged(g,i,e) .and. converged(residuum_source(1:sizeDotState,s) & - + 0.5_pReal*sourceState(p)%p(s)%dotState(:,c)*crystallite_subdt(g,i,e), & - sourceState(p)%p(s)%state(1:sizeDotState,c), & - sourceState(p)%p(s)%atol(1:sizeDotState)) - enddo - end subroutine integrateStateAdaptiveEuler @@ -1403,11 +1377,9 @@ subroutine integrateStateRK(g,i,e,A,B,CC,DB) n, & p, & c, & - s, & sizeDotState logical :: & broken - real(pReal), dimension(constitutive_source_maxSizeDotState,size(B),maxval(phase_Nsources)) :: source_RKdotState real(pReal), dimension(constitutive_plasticity_maxSizeDotState,size(B)) :: plastic_RKdotState p = material_phaseAt(g,e) @@ -1424,33 +1396,17 @@ subroutine integrateStateRK(g,i,e,A,B,CC,DB) sizeDotState = plasticState(p)%sizeDotState plastic_RKdotState(1:sizeDotState,stage) = plasticState(p)%dotState(:,c) plasticState(p)%dotState(:,c) = A(1,stage) * plastic_RKdotState(1:sizeDotState,1) - do s = 1, phase_Nsources(p) - sizeDotState = sourceState(p)%p(s)%sizeDotState - source_RKdotState(1:sizeDotState,stage,s) = sourceState(p)%p(s)%dotState(:,c) - sourceState(p)%p(s)%dotState(:,c) = A(1,stage) * source_RKdotState(1:sizeDotState,1,s) - enddo do n = 2, stage sizeDotState = plasticState(p)%sizeDotState plasticState(p)%dotState(:,c) = plasticState(p)%dotState(:,c) & + A(n,stage) * plastic_RKdotState(1:sizeDotState,n) - do s = 1, phase_Nsources(p) - sizeDotState = sourceState(p)%p(s)%sizeDotState - sourceState(p)%p(s)%dotState(:,c) = sourceState(p)%p(s)%dotState(:,c) & - + A(n,stage) * source_RKdotState(1:sizeDotState,n,s) - enddo enddo sizeDotState = plasticState(p)%sizeDotState plasticState(p)%state(1:sizeDotState,c) = plasticState(p)%subState0(1:sizeDotState,c) & + plasticState(p)%dotState (1:sizeDotState,c) & * crystallite_subdt(g,i,e) - do s = 1, phase_Nsources(p) - sizeDotState = sourceState(p)%p(s)%sizeDotState - sourceState(p)%p(s)%state(1:sizeDotState,c) = sourceState(p)%p(s)%subState0(1:sizeDotState,c) & - + sourceState(p)%p(s)%dotState (1:sizeDotState,c) & - * crystallite_subdt(g,i,e) - enddo broken = integrateStress(g,i,e,CC(stage)) if(broken) exit @@ -1478,20 +1434,6 @@ subroutine integrateStateRK(g,i,e,A,B,CC,DB) plasticState(p)%state(1:sizeDotState,c), & plasticState(p)%atol(1:sizeDotState)) - do s = 1, phase_Nsources(p) - sizeDotState = sourceState(p)%p(s)%sizeDotState - - source_RKdotState(1:sizeDotState,size(B),s) = sourceState(p)%p(s)%dotState(:,c) - sourceState(p)%p(s)%dotState(:,c) = matmul(source_RKdotState(1:sizeDotState,1:size(B),s),B) - sourceState(p)%p(s)%state(1:sizeDotState,c) = sourceState(p)%p(s)%subState0(1:sizeDotState,c) & - + sourceState(p)%p(s)%dotState (1:sizeDotState,c) & - * crystallite_subdt(g,i,e) - if(present(DB)) & - broken = broken .or. .not. converged(matmul(source_RKdotState(1:sizeDotState,1:size(DB),s),DB) & - * crystallite_subdt(g,i,e), & - sourceState(p)%p(s)%state(1:sizeDotState,c), & - sourceState(p)%p(s)%atol(1:sizeDotState)) - enddo if(broken) return broken = constitutive_deltaState(crystallite_S(1:3,1:3,g,i,e), & From d83f72dcb828e032b7e51d26627e65acbe31d43c Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 19 Dec 2020 18:22:40 +0100 Subject: [PATCH 066/148] separate collection of plastic and source state --- src/constitutive.f90 | 79 ++++++++++++++++++++++++++++++++++++++++++-- src/crystallite.f90 | 13 ++++++++ 2 files changed, 89 insertions(+), 3 deletions(-) diff --git a/src/constitutive.f90 b/src/constitutive.f90 index 6dcd88f04..003e5251b 100644 --- a/src/constitutive.f90 +++ b/src/constitutive.f90 @@ -371,7 +371,9 @@ module constitutive constitutive_LiAndItsTangents, & constitutive_SandItsTangents, & constitutive_collectDotState, & + constitutive_collectDotState_source, & constitutive_deltaState, & + constitutive_deltaState_source, & constitutive_damage_getRateAndItsTangents, & constitutive_thermal_getRateAndItsTangents, & constitutive_results, & @@ -655,6 +657,46 @@ function constitutive_collectDotState(S, FArray, Fi, FpArray, subdt, ipc, ip, el end select plasticityType broken = any(IEEE_is_NaN(plasticState(phase)%dotState(:,of))) + +end function constitutive_collectDotState + + +!-------------------------------------------------------------------------------------------------- +!> @brief contains the constitutive equation for calculating the rate of change of microstructure +!-------------------------------------------------------------------------------------------------- +function constitutive_collectDotState_source(S, FArray, Fi, FpArray, subdt, ipc, ip, el,phase,of) result(broken) + + integer, intent(in) :: & + ipc, & !< component-ID of integration point + ip, & !< integration point + el, & !< element + phase, & + of + real(pReal), intent(in) :: & + subdt !< timestep + real(pReal), intent(in), dimension(3,3,homogenization_maxNconstituents,discretization_nIPs,discretization_Nelems) :: & + FArray, & !< elastic deformation gradient + FpArray !< plastic deformation gradient + real(pReal), intent(in), dimension(3,3) :: & + Fi !< intermediate deformation gradient + real(pReal), intent(in), dimension(3,3) :: & + S !< 2nd Piola Kirchhoff stress (vector notation) + real(pReal), dimension(3,3) :: & + Mp + integer :: & + ho, & !< homogenization + tme, & !< thermal member position + i, & !< counter in source loop + instance + logical :: broken + + ho = material_homogenizationAt(el) + tme = material_homogenizationMemberAt(ip,el) + instance = phase_plasticityInstance(phase) + + + broken = .false. + SourceLoop: do i = 1, phase_Nsources(phase) sourceType: select case (phase_source(i,phase)) @@ -677,7 +719,7 @@ function constitutive_collectDotState(S, FArray, Fi, FpArray, subdt, ipc, ip, el enddo SourceLoop -end function constitutive_collectDotState +end function constitutive_collectDotState_source !-------------------------------------------------------------------------------------------------- @@ -735,6 +777,37 @@ function constitutive_deltaState(S, Fe, Fi, ipc, ip, el, phase, of) result(broke end select endif +end function constitutive_deltaState + + +!-------------------------------------------------------------------------------------------------- +!> @brief for constitutive models having an instantaneous change of state +!> will return false if delta state is not needed/supported by the constitutive model +!-------------------------------------------------------------------------------------------------- +function constitutive_deltaState_source(S, Fe, Fi, ipc, ip, el, phase, of) result(broken) + + integer, intent(in) :: & + ipc, & !< component-ID of integration point + ip, & !< integration point + el, & !< element + phase, & + of + real(pReal), intent(in), dimension(3,3) :: & + S, & !< 2nd Piola Kirchhoff stress + Fe, & !< elastic deformation gradient + Fi !< intermediate deformation gradient + real(pReal), dimension(3,3) :: & + Mp + integer :: & + i, & + instance, & + myOffset, & + mySize + logical :: & + broken + + + broken = .false. sourceLoop: do i = 1, phase_Nsources(phase) @@ -743,7 +816,7 @@ function constitutive_deltaState(S, Fe, Fi, ipc, ip, el, phase, of) result(broke case (SOURCE_damage_isoBrittle_ID) sourceType call source_damage_isoBrittle_deltaState (constitutive_homogenizedC(ipc,ip,el), Fe, & ipc, ip, el) - broken = broken .or. any(IEEE_is_NaN(sourceState(phase)%p(i)%deltaState(:,of))) + broken = any(IEEE_is_NaN(sourceState(phase)%p(i)%deltaState(:,of))) if(.not. broken) then myOffset = sourceState(phase)%p(i)%offsetDeltaState mySize = sourceState(phase)%p(i)%sizeDeltaState @@ -755,7 +828,7 @@ function constitutive_deltaState(S, Fe, Fi, ipc, ip, el, phase, of) result(broke enddo SourceLoop -end function constitutive_deltaState +end function constitutive_deltaState_source !-------------------------------------------------------------------------------------------------- diff --git a/src/crystallite.f90 b/src/crystallite.f90 index c294acc31..6ca3cc603 100644 --- a/src/crystallite.f90 +++ b/src/crystallite.f90 @@ -1104,6 +1104,11 @@ subroutine integrateStateFPI(g,i,e) crystallite_Fi(1:3,1:3,g,i,e), & crystallite_partitionedFp0, & crystallite_subdt(g,i,e), g,i,e,p,c) + broken = broken .or. constitutive_collectDotState_source(crystallite_S(1:3,1:3,g,i,e), & + crystallite_partitionedF0, & + crystallite_Fi(1:3,1:3,g,i,e), & + crystallite_partitionedFp0, & + crystallite_subdt(g,i,e), g,i,e,p,c) if(broken) return size_pl = plasticState(p)%sizeDotState @@ -1136,6 +1141,11 @@ subroutine integrateStateFPI(g,i,e) crystallite_Fi(1:3,1:3,g,i,e), & crystallite_partitionedFp0, & crystallite_subdt(g,i,e), g,i,e,p,c) + broken = broken .or. constitutive_collectDotState_source(crystallite_S(1:3,1:3,g,i,e), & + crystallite_partitionedF0, & + crystallite_Fi(1:3,1:3,g,i,e), & + crystallite_partitionedFp0, & + crystallite_subdt(g,i,e), g,i,e,p,c) if(broken) exit iteration zeta = damper(plasticState(p)%dotState(:,c),plastic_dotState(1:size_pl,1),& @@ -1171,6 +1181,9 @@ subroutine integrateStateFPI(g,i,e) broken = constitutive_deltaState(crystallite_S(1:3,1:3,g,i,e), & crystallite_Fe(1:3,1:3,g,i,e), & crystallite_Fi(1:3,1:3,g,i,e),g,i,e,p,c) + broken = broken .or. constitutive_deltaState_source(crystallite_S(1:3,1:3,g,i,e), & + crystallite_Fe(1:3,1:3,g,i,e), & + crystallite_Fi(1:3,1:3,g,i,e),g,i,e,p,c) exit iteration endif From 9f2c1509449a8dd4218309498340cfb2e41b7851 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 19 Dec 2020 20:31:15 +0100 Subject: [PATCH 067/148] separate integration for source and plastic state --- src/crystallite.f90 | 153 ++++++++++++++++++++++++++++++++------------ 1 file changed, 113 insertions(+), 40 deletions(-) diff --git a/src/crystallite.f90 b/src/crystallite.f90 index 6ca3cc603..3be9af9ee 100644 --- a/src/crystallite.f90 +++ b/src/crystallite.f90 @@ -417,6 +417,7 @@ function crystallite_stress() crystallite_subdt(c,i,e) = crystallite_subStep(c,i,e) * crystallite_dt(c,i,e) crystallite_converged(c,i,e) = .false. call integrateState(c,i,e) + call integrateSourceState(c,i,e) endif enddo @@ -1104,11 +1105,6 @@ subroutine integrateStateFPI(g,i,e) crystallite_Fi(1:3,1:3,g,i,e), & crystallite_partitionedFp0, & crystallite_subdt(g,i,e), g,i,e,p,c) - broken = broken .or. constitutive_collectDotState_source(crystallite_S(1:3,1:3,g,i,e), & - crystallite_partitionedF0, & - crystallite_Fi(1:3,1:3,g,i,e), & - crystallite_partitionedFp0, & - crystallite_subdt(g,i,e), g,i,e,p,c) if(broken) return size_pl = plasticState(p)%sizeDotState @@ -1116,22 +1112,11 @@ subroutine integrateStateFPI(g,i,e) + plasticState(p)%dotState (1:size_pl,c) & * crystallite_subdt(g,i,e) plastic_dotState(1:size_pl,2) = 0.0_pReal - do s = 1, phase_Nsources(p) - size_so(s) = sourceState(p)%p(s)%sizeDotState - sourceState(p)%p(s)%state(1:size_so(s),c) = sourceState(p)%p(s)%subState0(1:size_so(s),c) & - + sourceState(p)%p(s)%dotState (1:size_so(s),c) & - * crystallite_subdt(g,i,e) - source_dotState(1:size_so(s),2,s) = 0.0_pReal - enddo iteration: do NiterationState = 1, num%nState if(nIterationState > 1) plastic_dotState(1:size_pl,2) = plastic_dotState(1:size_pl,1) plastic_dotState(1:size_pl,1) = plasticState(p)%dotState(:,c) - do s = 1, phase_Nsources(p) - if(nIterationState > 1) source_dotState(1:size_so(s),2,s) = source_dotState(1:size_so(s),1,s) - source_dotState(1:size_so(s),1,s) = sourceState(p)%p(s)%dotState(:,c) - enddo broken = integrateStress(g,i,e) if(broken) exit iteration @@ -1141,11 +1126,6 @@ subroutine integrateStateFPI(g,i,e) crystallite_Fi(1:3,1:3,g,i,e), & crystallite_partitionedFp0, & crystallite_subdt(g,i,e), g,i,e,p,c) - broken = broken .or. constitutive_collectDotState_source(crystallite_S(1:3,1:3,g,i,e), & - crystallite_partitionedF0, & - crystallite_Fi(1:3,1:3,g,i,e), & - crystallite_partitionedFp0, & - crystallite_subdt(g,i,e), g,i,e,p,c) if(broken) exit iteration zeta = damper(plasticState(p)%dotState(:,c),plastic_dotState(1:size_pl,1),& @@ -1160,30 +1140,11 @@ subroutine integrateStateFPI(g,i,e) crystallite_converged(g,i,e) = converged(r(1:size_pl), & plasticState(p)%state(1:size_pl,c), & plasticState(p)%atol(1:size_pl)) - do s = 1, phase_Nsources(p) - zeta = damper(sourceState(p)%p(s)%dotState(:,c), & - source_dotState(1:size_so(s),1,s),& - source_dotState(1:size_so(s),2,s)) - sourceState(p)%p(s)%dotState(:,c) = sourceState(p)%p(s)%dotState(:,c) * zeta & - + source_dotState(1:size_so(s),1,s)* (1.0_pReal - zeta) - r(1:size_so(s)) = sourceState(p)%p(s)%state (1:size_so(s),c) & - - sourceState(p)%p(s)%subState0(1:size_so(s),c) & - - sourceState(p)%p(s)%dotState (1:size_so(s),c) * crystallite_subdt(g,i,e) - sourceState(p)%p(s)%state(1:size_so(s),c) = sourceState(p)%p(s)%state(1:size_so(s),c) & - - r(1:size_so(s)) - crystallite_converged(g,i,e) = & - crystallite_converged(g,i,e) .and. converged(r(1:size_so(s)), & - sourceState(p)%p(s)%state(1:size_so(s),c), & - sourceState(p)%p(s)%atol(1:size_so(s))) - enddo if(crystallite_converged(g,i,e)) then broken = constitutive_deltaState(crystallite_S(1:3,1:3,g,i,e), & crystallite_Fe(1:3,1:3,g,i,e), & crystallite_Fi(1:3,1:3,g,i,e),g,i,e,p,c) - broken = broken .or. constitutive_deltaState_source(crystallite_S(1:3,1:3,g,i,e), & - crystallite_Fe(1:3,1:3,g,i,e), & - crystallite_Fi(1:3,1:3,g,i,e),g,i,e,p,c) exit iteration endif @@ -1215,6 +1176,118 @@ subroutine integrateStateFPI(g,i,e) end subroutine integrateStateFPI +!-------------------------------------------------------------------------------------------------- +!> @brief integrate stress, state with adaptive 1st order explicit Euler method +!> using Fixed Point Iteration to adapt the stepsize +!-------------------------------------------------------------------------------------------------- +subroutine integrateSourceState(g,i,e) + + integer, intent(in) :: & + e, & !< element index in element loop + i, & !< integration point index in ip loop + g !< grain index in grain loop + integer :: & + NiterationState, & !< number of iterations in state loop + p, & + c, & + s, & + size_pl + integer, dimension(maxval(phase_Nsources)) :: & + size_so + real(pReal) :: & + zeta + real(pReal), dimension(max(constitutive_plasticity_maxSizeDotState,constitutive_source_maxSizeDotState)) :: & + r ! state residuum + real(pReal), dimension(constitutive_plasticity_maxSizeDotState,2) :: & + plastic_dotState + real(pReal), dimension(constitutive_source_maxSizeDotState,2,maxval(phase_Nsources)) :: source_dotState + logical :: & + broken + + p = material_phaseAt(g,e) + c = material_phaseMemberAt(g,i,e) + + broken = constitutive_collectDotState_source(crystallite_S(1:3,1:3,g,i,e), & + crystallite_partitionedF0, & + crystallite_Fi(1:3,1:3,g,i,e), & + crystallite_partitionedFp0, & + crystallite_subdt(g,i,e), g,i,e,p,c) + if(broken) return + + do s = 1, phase_Nsources(p) + size_so(s) = sourceState(p)%p(s)%sizeDotState + sourceState(p)%p(s)%state(1:size_so(s),c) = sourceState(p)%p(s)%subState0(1:size_so(s),c) & + + sourceState(p)%p(s)%dotState (1:size_so(s),c) & + * crystallite_subdt(g,i,e) + source_dotState(1:size_so(s),2,s) = 0.0_pReal + enddo + + iteration: do NiterationState = 1, num%nState + + if(nIterationState > 1) plastic_dotState(1:size_pl,2) = plastic_dotState(1:size_pl,1) + do s = 1, phase_Nsources(p) + if(nIterationState > 1) source_dotState(1:size_so(s),2,s) = source_dotState(1:size_so(s),1,s) + source_dotState(1:size_so(s),1,s) = sourceState(p)%p(s)%dotState(:,c) + enddo + + broken = constitutive_collectDotState_source(crystallite_S(1:3,1:3,g,i,e), & + crystallite_partitionedF0, & + crystallite_Fi(1:3,1:3,g,i,e), & + crystallite_partitionedFp0, & + crystallite_subdt(g,i,e), g,i,e,p,c) + if(broken) exit iteration + + do s = 1, phase_Nsources(p) + zeta = damper(sourceState(p)%p(s)%dotState(:,c), & + source_dotState(1:size_so(s),1,s),& + source_dotState(1:size_so(s),2,s)) + sourceState(p)%p(s)%dotState(:,c) = sourceState(p)%p(s)%dotState(:,c) * zeta & + + source_dotState(1:size_so(s),1,s)* (1.0_pReal - zeta) + r(1:size_so(s)) = sourceState(p)%p(s)%state (1:size_so(s),c) & + - sourceState(p)%p(s)%subState0(1:size_so(s),c) & + - sourceState(p)%p(s)%dotState (1:size_so(s),c) * crystallite_subdt(g,i,e) + sourceState(p)%p(s)%state(1:size_so(s),c) = sourceState(p)%p(s)%state(1:size_so(s),c) & + - r(1:size_so(s)) + crystallite_converged(g,i,e) = & + crystallite_converged(g,i,e) .and. converged(r(1:size_so(s)), & + sourceState(p)%p(s)%state(1:size_so(s),c), & + sourceState(p)%p(s)%atol(1:size_so(s))) + enddo + + if(crystallite_converged(g,i,e)) then + broken = constitutive_deltaState_source(crystallite_S(1:3,1:3,g,i,e), & + crystallite_Fe(1:3,1:3,g,i,e), & + crystallite_Fi(1:3,1:3,g,i,e),g,i,e,p,c) + exit iteration + endif + + enddo iteration + + + contains + + !-------------------------------------------------------------------------------------------------- + !> @brief calculate the damping for correction of state and dot state + !-------------------------------------------------------------------------------------------------- + real(pReal) pure function damper(current,previous,previous2) + + real(pReal), dimension(:), intent(in) ::& + current, previous, previous2 + + real(pReal) :: dot_prod12, dot_prod22 + + dot_prod12 = dot_product(current - previous, previous - previous2) + dot_prod22 = dot_product(previous - previous2, previous - previous2) + if ((dot_product(current,previous) < 0.0_pReal .or. dot_prod12 < 0.0_pReal) .and. dot_prod22 > 0.0_pReal) then + damper = 0.75_pReal + 0.25_pReal * tanh(2.0_pReal + 4.0_pReal * dot_prod12 / dot_prod22) + else + damper = 1.0_pReal + endif + + end function damper + +end subroutine integrateSourceState + !-------------------------------------------------------------------------------------------------- !> @brief integrate state with 1st order explicit Euler method !-------------------------------------------------------------------------------------------------- From 9425184b5281f9fcc09c01c683716355687eaec3 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 20 Dec 2020 09:27:37 +0100 Subject: [PATCH 068/148] using new functions --- src/CPFEM.f90 | 1 + src/CPFEM2.f90 | 1 + src/constitutive.f90 | 40 ++++++++++++++++++++++++++++++++++++++++ src/crystallite.f90 | 14 +------------- src/homogenization.f90 | 1 + 5 files changed, 44 insertions(+), 13 deletions(-) diff --git a/src/CPFEM.f90 b/src/CPFEM.f90 index a19a70432..6fc58ea0f 100644 --- a/src/CPFEM.f90 +++ b/src/CPFEM.f90 @@ -262,6 +262,7 @@ end subroutine CPFEM_general subroutine CPFEM_forward call crystallite_forward + call constitutive_forward end subroutine CPFEM_forward diff --git a/src/CPFEM2.f90 b/src/CPFEM2.f90 index 54e381d34..325a8791e 100644 --- a/src/CPFEM2.f90 +++ b/src/CPFEM2.f90 @@ -99,6 +99,7 @@ end subroutine CPFEM_restartWrite subroutine CPFEM_forward call crystallite_forward + call constitutive_forward end subroutine CPFEM_forward diff --git a/src/constitutive.f90 b/src/constitutive.f90 index 003e5251b..635f169cd 100644 --- a/src/constitutive.f90 +++ b/src/constitutive.f90 @@ -378,6 +378,8 @@ module constitutive constitutive_thermal_getRateAndItsTangents, & constitutive_results, & constitutive_allocateState, & + constitutive_forward, & + constitutive_restore, & plastic_nonlocal_updateCompatibility, & plastic_active, & source_active, & @@ -864,6 +866,44 @@ subroutine constitutive_allocateState(state, & end subroutine constitutive_allocateState +!-------------------------------------------------------------------------------------------------- +!> @brief Restore data after homog cutback. +!-------------------------------------------------------------------------------------------------- +subroutine constitutive_restore(i,e) + + integer, intent(in) :: & + i, & !< integration point number + e !< element number + integer :: & + c, & !< constituent number + s + + do c = 1,homogenization_Nconstituents(material_homogenizationAt(e)) + do s = 1, phase_Nsources(material_phaseAt(c,e)) + sourceState(material_phaseAt(c,e))%p(s)%state( :,material_phasememberAt(c,i,e)) = & + sourceState(material_phaseAt(c,e))%p(s)%partitionedState0(:,material_phasememberAt(c,i,e)) + enddo + enddo + +end subroutine constitutive_restore + + +!-------------------------------------------------------------------------------------------------- +!> @brief Forward data after successful increment. +! ToDo: Any guessing for the current states possible? +!-------------------------------------------------------------------------------------------------- +subroutine constitutive_forward + + integer :: i, j + + do i = 1, size(sourceState) + do j = 1,phase_Nsources(i) + sourceState(i)%p(j)%state0 = sourceState(i)%p(j)%state + enddo; enddo + +end subroutine constitutive_forward + + !-------------------------------------------------------------------------------------------------- !> @brief writes constitutive results to HDF5 output file !-------------------------------------------------------------------------------------------------- diff --git a/src/crystallite.f90 b/src/crystallite.f90 index 3be9af9ee..6abc31125 100644 --- a/src/crystallite.f90 +++ b/src/crystallite.f90 @@ -515,8 +515,7 @@ subroutine crystallite_restore(i,e,includeL) logical, intent(in) :: & includeL !< protect agains fake cutback integer :: & - c, & !< constituent number - s + c !< constituent number do c = 1,homogenization_Nconstituents(material_homogenizationAt(e)) if (includeL) then @@ -529,10 +528,6 @@ subroutine crystallite_restore(i,e,includeL) plasticState (material_phaseAt(c,e))%state( :,material_phasememberAt(c,i,e)) = & plasticState (material_phaseAt(c,e))%partitionedState0(:,material_phasememberAt(c,i,e)) - do s = 1, phase_Nsources(material_phaseAt(c,e)) - sourceState(material_phaseAt(c,e))%p(s)%state( :,material_phasememberAt(c,i,e)) = & - sourceState(material_phaseAt(c,e))%p(s)%partitionedState0(:,material_phasememberAt(c,i,e)) - enddo enddo end subroutine crystallite_restore @@ -1198,8 +1193,6 @@ subroutine integrateSourceState(g,i,e) zeta real(pReal), dimension(max(constitutive_plasticity_maxSizeDotState,constitutive_source_maxSizeDotState)) :: & r ! state residuum - real(pReal), dimension(constitutive_plasticity_maxSizeDotState,2) :: & - plastic_dotState real(pReal), dimension(constitutive_source_maxSizeDotState,2,maxval(phase_Nsources)) :: source_dotState logical :: & broken @@ -1224,7 +1217,6 @@ subroutine integrateSourceState(g,i,e) iteration: do NiterationState = 1, num%nState - if(nIterationState > 1) plastic_dotState(1:size_pl,2) = plastic_dotState(1:size_pl,1) do s = 1, phase_Nsources(p) if(nIterationState > 1) source_dotState(1:size_so(s),2,s) = source_dotState(1:size_so(s),1,s) source_dotState(1:size_so(s),1,s) = sourceState(p)%p(s)%dotState(:,c) @@ -1651,10 +1643,6 @@ subroutine crystallite_forward do i = 1, size(plasticState) plasticState(i)%state0 = plasticState(i)%state enddo - do i = 1, size(sourceState) - do j = 1,phase_Nsources(i) - sourceState(i)%p(j)%state0 = sourceState(i)%p(j)%state - enddo; enddo do i = 1,size(material_name_homogenization) homogState (i)%state0 = homogState (i)%state damageState (i)%state0 = damageState (i)%state diff --git a/src/homogenization.f90 b/src/homogenization.f90 index 30d9cfb90..4da567e4c 100644 --- a/src/homogenization.f90 +++ b/src/homogenization.f90 @@ -255,6 +255,7 @@ subroutine materialpoint_stressAndItsTangent(dt) subStep(i,e) = num%subStepSizeHomog * subStep(i,e) ! crystallite had severe trouble, so do a significant cutback call crystallite_restore(i,e,subStep(i,e) < 1.0_pReal) + call constitutive_restore(i,e) if(homogState(material_homogenizationAt(e))%sizeState > 0) & homogState(material_homogenizationAt(e))%State( :,material_homogenizationMemberAt(i,e)) = & From 613fa5f9b2047b34c647869a1838bf32f6ac22ac Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 20 Dec 2020 09:44:25 +0100 Subject: [PATCH 069/148] cleaning interface --- src/constitutive.f90 | 33 +++++---------------------------- src/crystallite.f90 | 20 +++----------------- 2 files changed, 8 insertions(+), 45 deletions(-) diff --git a/src/constitutive.f90 b/src/constitutive.f90 index 635f169cd..b2f68e5dd 100644 --- a/src/constitutive.f90 +++ b/src/constitutive.f90 @@ -666,7 +666,7 @@ end function constitutive_collectDotState !-------------------------------------------------------------------------------------------------- !> @brief contains the constitutive equation for calculating the rate of change of microstructure !-------------------------------------------------------------------------------------------------- -function constitutive_collectDotState_source(S, FArray, Fi, FpArray, subdt, ipc, ip, el,phase,of) result(broken) +function constitutive_collectDotState_source(S, ipc, ip, el,phase,of) result(broken) integer, intent(in) :: & ipc, & !< component-ID of integration point @@ -674,28 +674,12 @@ function constitutive_collectDotState_source(S, FArray, Fi, FpArray, subdt, ipc, el, & !< element phase, & of - real(pReal), intent(in) :: & - subdt !< timestep - real(pReal), intent(in), dimension(3,3,homogenization_maxNconstituents,discretization_nIPs,discretization_Nelems) :: & - FArray, & !< elastic deformation gradient - FpArray !< plastic deformation gradient - real(pReal), intent(in), dimension(3,3) :: & - Fi !< intermediate deformation gradient real(pReal), intent(in), dimension(3,3) :: & S !< 2nd Piola Kirchhoff stress (vector notation) - real(pReal), dimension(3,3) :: & - Mp integer :: & - ho, & !< homogenization - tme, & !< thermal member position - i, & !< counter in source loop - instance + i !< counter in source loop logical :: broken - ho = material_homogenizationAt(el) - tme = material_homogenizationMemberAt(ip,el) - instance = phase_plasticityInstance(phase) - broken = .false. @@ -728,7 +712,7 @@ end function constitutive_collectDotState_source !> @brief for constitutive models having an instantaneous change of state !> will return false if delta state is not needed/supported by the constitutive model !-------------------------------------------------------------------------------------------------- -function constitutive_deltaState(S, Fe, Fi, ipc, ip, el, phase, of) result(broken) +function constitutive_deltaState(S, Fi, ipc, ip, el, phase, of) result(broken) integer, intent(in) :: & ipc, & !< component-ID of integration point @@ -738,12 +722,10 @@ function constitutive_deltaState(S, Fe, Fi, ipc, ip, el, phase, of) result(broke of real(pReal), intent(in), dimension(3,3) :: & S, & !< 2nd Piola Kirchhoff stress - Fe, & !< elastic deformation gradient Fi !< intermediate deformation gradient real(pReal), dimension(3,3) :: & Mp integer :: & - i, & instance, & myOffset, & mySize @@ -786,7 +768,7 @@ end function constitutive_deltaState !> @brief for constitutive models having an instantaneous change of state !> will return false if delta state is not needed/supported by the constitutive model !-------------------------------------------------------------------------------------------------- -function constitutive_deltaState_source(S, Fe, Fi, ipc, ip, el, phase, of) result(broken) +function constitutive_deltaState_source(Fe, ipc, ip, el, phase, of) result(broken) integer, intent(in) :: & ipc, & !< component-ID of integration point @@ -795,14 +777,9 @@ function constitutive_deltaState_source(S, Fe, Fi, ipc, ip, el, phase, of) resul phase, & of real(pReal), intent(in), dimension(3,3) :: & - S, & !< 2nd Piola Kirchhoff stress - Fe, & !< elastic deformation gradient - Fi !< intermediate deformation gradient - real(pReal), dimension(3,3) :: & - Mp + Fe !< elastic deformation gradient integer :: & i, & - instance, & myOffset, & mySize logical :: & diff --git a/src/crystallite.f90 b/src/crystallite.f90 index 6abc31125..5378c4cbb 100644 --- a/src/crystallite.f90 +++ b/src/crystallite.f90 @@ -1138,7 +1138,6 @@ subroutine integrateStateFPI(g,i,e) if(crystallite_converged(g,i,e)) then broken = constitutive_deltaState(crystallite_S(1:3,1:3,g,i,e), & - crystallite_Fe(1:3,1:3,g,i,e), & crystallite_Fi(1:3,1:3,g,i,e),g,i,e,p,c) exit iteration endif @@ -1200,11 +1199,7 @@ subroutine integrateSourceState(g,i,e) p = material_phaseAt(g,e) c = material_phaseMemberAt(g,i,e) - broken = constitutive_collectDotState_source(crystallite_S(1:3,1:3,g,i,e), & - crystallite_partitionedF0, & - crystallite_Fi(1:3,1:3,g,i,e), & - crystallite_partitionedFp0, & - crystallite_subdt(g,i,e), g,i,e,p,c) + broken = constitutive_collectDotState_source(crystallite_S(1:3,1:3,g,i,e), g,i,e,p,c) if(broken) return do s = 1, phase_Nsources(p) @@ -1222,11 +1217,7 @@ subroutine integrateSourceState(g,i,e) source_dotState(1:size_so(s),1,s) = sourceState(p)%p(s)%dotState(:,c) enddo - broken = constitutive_collectDotState_source(crystallite_S(1:3,1:3,g,i,e), & - crystallite_partitionedF0, & - crystallite_Fi(1:3,1:3,g,i,e), & - crystallite_partitionedFp0, & - crystallite_subdt(g,i,e), g,i,e,p,c) + broken = constitutive_collectDotState_source(crystallite_S(1:3,1:3,g,i,e), g,i,e,p,c) if(broken) exit iteration do s = 1, phase_Nsources(p) @@ -1247,9 +1238,7 @@ subroutine integrateSourceState(g,i,e) enddo if(crystallite_converged(g,i,e)) then - broken = constitutive_deltaState_source(crystallite_S(1:3,1:3,g,i,e), & - crystallite_Fe(1:3,1:3,g,i,e), & - crystallite_Fi(1:3,1:3,g,i,e),g,i,e,p,c) + broken = constitutive_deltaState_source(crystallite_Fe(1:3,1:3,g,i,e),g,i,e,p,c) exit iteration endif @@ -1312,7 +1301,6 @@ subroutine integrateStateEuler(g,i,e) * crystallite_subdt(g,i,e) broken = constitutive_deltaState(crystallite_S(1:3,1:3,g,i,e), & - crystallite_Fe(1:3,1:3,g,i,e), & crystallite_Fi(1:3,1:3,g,i,e),g,i,e,p,c) if(broken) return @@ -1358,7 +1346,6 @@ subroutine integrateStateAdaptiveEuler(g,i,e) + plasticState(p)%dotstate(1:sizeDotState,c) * crystallite_subdt(g,i,e) broken = constitutive_deltaState(crystallite_S(1:3,1:3,g,i,e), & - crystallite_Fe(1:3,1:3,g,i,e), & crystallite_Fi(1:3,1:3,g,i,e),g,i,e,p,c) if(broken) return @@ -1515,7 +1502,6 @@ subroutine integrateStateRK(g,i,e,A,B,CC,DB) if(broken) return broken = constitutive_deltaState(crystallite_S(1:3,1:3,g,i,e), & - crystallite_Fe(1:3,1:3,g,i,e), & crystallite_Fi(1:3,1:3,g,i,e),g,i,e,p,c) if(broken) return From dac6540a466d605bb453e99368247713d2daf1e3 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 20 Dec 2020 10:48:13 +0100 Subject: [PATCH 070/148] crystallite should become part of constitutive_mech --- src/constitutive.f90 | 1621 +++++++++++++++++++++++++++++++++++++++++- src/crystallite.f90 | 1621 ------------------------------------------ 2 files changed, 1610 insertions(+), 1632 deletions(-) diff --git a/src/constitutive.f90 b/src/constitutive.f90 index b2f68e5dd..360fb09f1 100644 --- a/src/constitutive.f90 +++ b/src/constitutive.f90 @@ -15,9 +15,99 @@ module constitutive use discretization use geometry_plastic_nonlocal, only: & geometry_plastic_nonlocal_disable + use parallelization + use HDF5_utilities + use DAMASK_interface + use FEsolving + use results implicit none private + real(pReal), dimension(:,:,:), allocatable, public :: & + crystallite_dt !< requested time increment of each grain + real(pReal), dimension(:,:,:), allocatable :: & + crystallite_subdt, & !< substepped time increment of each grain + crystallite_subFrac, & !< already calculated fraction of increment + crystallite_subStep !< size of next integration step + type(rotation), dimension(:,:,:), allocatable :: & + crystallite_orientation !< current orientation + real(pReal), dimension(:,:,:,:,:), allocatable :: & + crystallite_F0, & !< def grad at start of FE inc + crystallite_subF, & !< def grad to be reached at end of crystallite inc + crystallite_subF0, & !< def grad at start of crystallite inc + ! + crystallite_Fe, & !< current "elastic" def grad (end of converged time step) + ! + crystallite_Fp, & !< current plastic def grad (end of converged time step) + crystallite_Fp0, & !< plastic def grad at start of FE inc + crystallite_partitionedFp0,& !< plastic def grad at start of homog inc + crystallite_subFp0,& !< plastic def grad at start of crystallite inc + ! + crystallite_Fi, & !< current intermediate def grad (end of converged time step) + crystallite_Fi0, & !< intermediate def grad at start of FE inc + crystallite_partitionedFi0,& !< intermediate def grad at start of homog inc + crystallite_subFi0,& !< intermediate def grad at start of crystallite inc + ! + crystallite_Lp0, & !< plastic velocitiy grad at start of FE inc + crystallite_partitionedLp0, & !< plastic velocity grad at start of homog inc + ! + crystallite_Li, & !< current intermediate velocitiy grad (end of converged time step) + crystallite_Li0, & !< intermediate velocitiy grad at start of FE inc + crystallite_partitionedLi0, & !< intermediate velocity grad at start of homog inc + ! + crystallite_S0, & !< 2nd Piola-Kirchhoff stress vector at start of FE inc + crystallite_partitionedS0 !< 2nd Piola-Kirchhoff stress vector at start of homog inc + real(pReal), dimension(:,:,:,:,:), allocatable, public, protected :: & + crystallite_P, & !< 1st Piola-Kirchhoff stress per grain + crystallite_Lp, & !< current plastic velocitiy grad (end of converged time step) + crystallite_S, & !< current 2nd Piola-Kirchhoff stress vector (end of converged time step) + crystallite_partitionedF0 !< def grad at start of homog inc + real(pReal), dimension(:,:,:,:,:), allocatable, public :: & + crystallite_partitionedF !< def grad to be reached at end of homog inc + + logical, dimension(:,:,:), allocatable, public :: & + crystallite_requested !< used by upper level (homogenization) to request crystallite calculation + logical, dimension(:,:,:), allocatable :: & + crystallite_converged !< convergence flag + + type :: tOutput !< new requested output (per phase) + character(len=pStringLen), allocatable, dimension(:) :: & + label + end type tOutput + type(tOutput), allocatable, dimension(:) :: output_constituent + + type :: tNumerics + integer :: & + iJacoLpresiduum, & !< frequency of Jacobian update of residuum in Lp + nState, & !< state loop limit + nStress !< stress loop limit + real(pReal) :: & + subStepMinCryst, & !< minimum (relative) size of sub-step allowed during cutback + subStepSizeCryst, & !< size of first substep when cutback + subStepSizeLp, & !< size of first substep when cutback in Lp calculation + subStepSizeLi, & !< size of first substep when cutback in Li calculation + stepIncreaseCryst, & !< increase of next substep size when previous substep converged + rtol_crystalliteState, & !< relative tolerance in state loop + rtol_crystalliteStress, & !< relative tolerance in stress loop + atol_crystalliteStress !< absolute tolerance in stress loop + end type tNumerics + + type(tNumerics) :: num ! numerics parameters. Better name? + + type :: tDebugOptions + logical :: & + basic, & + extensive, & + selective + integer :: & + element, & + ip, & + grain + end type tDebugOptions + + type(tDebugOptions) :: debugCrystallite + + procedure(integrateStateFPI), pointer :: integrateState integer(kind(PLASTICITY_undefined_ID)), dimension(:), allocatable :: & phase_plasticity !< plasticity of each phase @@ -350,17 +440,6 @@ module constitutive end interface constitutive_SandItsTangents - type :: tDebugOptions - logical :: & - basic, & - extensive, & - selective - integer :: & - element, & - ip, & - grain - end type tDebugOptions - type(tDebugOptions) :: debugConstitutive public :: & @@ -384,6 +463,20 @@ module constitutive plastic_active, & source_active, & kinematics_active + + public :: & + crystallite_init, & + crystallite_stress, & + crystallite_stressTangent, & + crystallite_orientations, & + crystallite_push33ToRef, & + crystallite_results, & + crystallite_restartWrite, & + crystallite_restartRead, & + crystallite_forward, & + crystallite_initializeRestorationPoints, & + crystallite_windForward, & + crystallite_restore contains @@ -892,4 +985,1510 @@ subroutine constitutive_results end subroutine constitutive_results +!-------------------------------------------------------------------------------------------------- +!> @brief allocates and initialize per grain variables +!-------------------------------------------------------------------------------------------------- +subroutine crystallite_init + + integer :: & + p, & + c, & !< counter in integration point component loop + i, & !< counter in integration point loop + e, & !< counter in element loop + cMax, & !< maximum number of integration point components + iMax, & !< maximum number of integration points + eMax !< maximum number of elements + + + class(tNode), pointer :: & + num_crystallite, & + debug_crystallite, & ! pointer to debug options for crystallite + phases, & + phase, & + mech + + print'(/,a)', ' <<<+- crystallite init -+>>>' + + debug_crystallite => config_debug%get('crystallite', defaultVal=emptyList) + debugCrystallite%basic = debug_crystallite%contains('basic') + debugCrystallite%extensive = debug_crystallite%contains('extensive') + debugCrystallite%selective = debug_crystallite%contains('selective') + debugCrystallite%element = config_debug%get_asInt('element', defaultVal=1) + debugCrystallite%ip = config_debug%get_asInt('integrationpoint', defaultVal=1) + debugCrystallite%grain = config_debug%get_asInt('grain', defaultVal=1) + + cMax = homogenization_maxNconstituents + iMax = discretization_nIPs + eMax = discretization_Nelems + + allocate(crystallite_partitionedF(3,3,cMax,iMax,eMax),source=0.0_pReal) + + allocate(crystallite_S0, & + crystallite_F0, crystallite_Fi0,crystallite_Fp0, & + crystallite_Li0,crystallite_Lp0, & + crystallite_partitionedS0, & + crystallite_partitionedF0,crystallite_partitionedFp0,crystallite_partitionedFi0, & + crystallite_partitionedLp0,crystallite_partitionedLi0, & + crystallite_S,crystallite_P, & + crystallite_Fe,crystallite_Fi,crystallite_Fp, & + crystallite_Li,crystallite_Lp, & + crystallite_subF,crystallite_subF0, & + crystallite_subFp0,crystallite_subFi0, & + source = crystallite_partitionedF) + + allocate(crystallite_dt(cMax,iMax,eMax),source=0.0_pReal) + allocate(crystallite_subdt,crystallite_subFrac,crystallite_subStep, & + source = crystallite_dt) + + allocate(crystallite_orientation(cMax,iMax,eMax)) + + allocate(crystallite_requested(cMax,iMax,eMax), source=.false.) + allocate(crystallite_converged(cMax,iMax,eMax), source=.true.) + + num_crystallite => config_numerics%get('crystallite',defaultVal=emptyDict) + + num%subStepMinCryst = num_crystallite%get_asFloat ('subStepMin', defaultVal=1.0e-3_pReal) + num%subStepSizeCryst = num_crystallite%get_asFloat ('subStepSize', defaultVal=0.25_pReal) + num%stepIncreaseCryst = num_crystallite%get_asFloat ('stepIncrease', defaultVal=1.5_pReal) + num%subStepSizeLp = num_crystallite%get_asFloat ('subStepSizeLp', defaultVal=0.5_pReal) + num%subStepSizeLi = num_crystallite%get_asFloat ('subStepSizeLi', defaultVal=0.5_pReal) + num%rtol_crystalliteState = num_crystallite%get_asFloat ('rtol_State', defaultVal=1.0e-6_pReal) + num%rtol_crystalliteStress = num_crystallite%get_asFloat ('rtol_Stress', defaultVal=1.0e-6_pReal) + num%atol_crystalliteStress = num_crystallite%get_asFloat ('atol_Stress', defaultVal=1.0e-8_pReal) + num%iJacoLpresiduum = num_crystallite%get_asInt ('iJacoLpresiduum', defaultVal=1) + num%nState = num_crystallite%get_asInt ('nState', defaultVal=20) + num%nStress = num_crystallite%get_asInt ('nStress', defaultVal=40) + + if(num%subStepMinCryst <= 0.0_pReal) call IO_error(301,ext_msg='subStepMinCryst') + if(num%subStepSizeCryst <= 0.0_pReal) call IO_error(301,ext_msg='subStepSizeCryst') + if(num%stepIncreaseCryst <= 0.0_pReal) call IO_error(301,ext_msg='stepIncreaseCryst') + + if(num%subStepSizeLp <= 0.0_pReal) call IO_error(301,ext_msg='subStepSizeLp') + if(num%subStepSizeLi <= 0.0_pReal) call IO_error(301,ext_msg='subStepSizeLi') + + if(num%rtol_crystalliteState <= 0.0_pReal) call IO_error(301,ext_msg='rtol_crystalliteState') + if(num%rtol_crystalliteStress <= 0.0_pReal) call IO_error(301,ext_msg='rtol_crystalliteStress') + if(num%atol_crystalliteStress <= 0.0_pReal) call IO_error(301,ext_msg='atol_crystalliteStress') + + if(num%iJacoLpresiduum < 1) call IO_error(301,ext_msg='iJacoLpresiduum') + + if(num%nState < 1) call IO_error(301,ext_msg='nState') + if(num%nStress< 1) call IO_error(301,ext_msg='nStress') + + select case(num_crystallite%get_asString('integrator',defaultVal='FPI')) + case('FPI') + integrateState => integrateStateFPI + case('Euler') + integrateState => integrateStateEuler + case('AdaptiveEuler') + integrateState => integrateStateAdaptiveEuler + case('RK4') + integrateState => integrateStateRK4 + case('RKCK45') + integrateState => integrateStateRKCK45 + case default + call IO_error(301,ext_msg='integrator') + end select + + phases => config_material%get('phase') + + allocate(output_constituent(phases%length)) + do p = 1, phases%length + phase => phases%get(p) + mech => phase%get('mechanics',defaultVal = emptyDict) +#if defined(__GFORTRAN__) + output_constituent(p)%label = output_asStrings(mech) +#else + output_constituent(p)%label = mech%get_asStrings('output',defaultVal=emptyStringArray) +#endif + enddo + +#ifdef DEBUG + if (debugCrystallite%basic) then + print'(a42,1x,i10)', ' # of elements: ', eMax + print'(a42,1x,i10)', ' # of integration points/element: ', iMax + print'(a42,1x,i10)', 'max # of constituents/integration point: ', cMax + flush(IO_STDOUT) + endif +#endif + + !$OMP PARALLEL DO PRIVATE(i,c) + do e = FEsolving_execElem(1),FEsolving_execElem(2) + do i = FEsolving_execIP(1), FEsolving_execIP(2); do c = 1, homogenization_Nconstituents(material_homogenizationAt(e)) + crystallite_Fp0(1:3,1:3,c,i,e) = material_orientation0(c,i,e)%asMatrix() ! Fp reflects initial orientation (see 10.1016/j.actamat.2006.01.005) + crystallite_Fp0(1:3,1:3,c,i,e) = crystallite_Fp0(1:3,1:3,c,i,e) & + / math_det33(crystallite_Fp0(1:3,1:3,c,i,e))**(1.0_pReal/3.0_pReal) + crystallite_Fi0(1:3,1:3,c,i,e) = math_I3 + crystallite_F0(1:3,1:3,c,i,e) = math_I3 + crystallite_Fe(1:3,1:3,c,i,e) = math_inv33(matmul(crystallite_Fi0(1:3,1:3,c,i,e), & + crystallite_Fp0(1:3,1:3,c,i,e))) ! assuming that euler angles are given in internal strain free configuration + crystallite_Fp(1:3,1:3,c,i,e) = crystallite_Fp0(1:3,1:3,c,i,e) + crystallite_Fi(1:3,1:3,c,i,e) = crystallite_Fi0(1:3,1:3,c,i,e) + crystallite_requested(c,i,e) = .true. + enddo; enddo + enddo + !$OMP END PARALLEL DO + + + crystallite_partitionedFp0 = crystallite_Fp0 + crystallite_partitionedFi0 = crystallite_Fi0 + crystallite_partitionedF0 = crystallite_F0 + crystallite_partitionedF = crystallite_F0 + + call crystallite_orientations() + + !$OMP PARALLEL DO + do e = FEsolving_execElem(1),FEsolving_execElem(2) + do i = FEsolving_execIP(1),FEsolving_execIP(2) + do c = 1,homogenization_Nconstituents(material_homogenizationAt(e)) + call constitutive_dependentState(crystallite_partitionedF0(1:3,1:3,c,i,e), & + crystallite_partitionedFp0(1:3,1:3,c,i,e), & + c,i,e) ! update dependent state variables to be consistent with basic states + enddo + enddo + enddo + !$OMP END PARALLEL DO + + +end subroutine crystallite_init + + +!-------------------------------------------------------------------------------------------------- +!> @brief calculate stress (P) +!-------------------------------------------------------------------------------------------------- +function crystallite_stress() + + logical, dimension(discretization_nIPs,discretization_Nelems) :: crystallite_stress + real(pReal) :: & + formerSubStep + integer :: & + NiterationCrystallite, & ! number of iterations in crystallite loop + c, & !< counter in integration point component loop + i, & !< counter in integration point loop + e, & !< counter in element loop + s + logical, dimension(homogenization_maxNconstituents,discretization_nIPs,discretization_Nelems) :: todo !ToDo: need to set some values to false for different Ngrains + real(pReal), dimension(:,:,:,:,:), allocatable :: & + subLp0,& !< plastic velocity grad at start of crystallite inc + subLi0 !< intermediate velocity grad at start of crystallite inc + + todo = .false. + + subLp0 = crystallite_partitionedLp0 + subLi0 = crystallite_partitionedLi0 + +!-------------------------------------------------------------------------------------------------- +! initialize to starting condition + crystallite_subStep = 0.0_pReal + !$OMP PARALLEL DO + elementLooping1: do e = FEsolving_execElem(1),FEsolving_execElem(2) + do i = FEsolving_execIP(1),FEsolving_execIP(2); do c = 1,homogenization_Nconstituents(material_homogenizationAt(e)) + homogenizationRequestsCalculation: if (crystallite_requested(c,i,e)) then + plasticState (material_phaseAt(c,e))%subState0( :,material_phaseMemberAt(c,i,e)) = & + plasticState (material_phaseAt(c,e))%partitionedState0(:,material_phaseMemberAt(c,i,e)) + + do s = 1, phase_Nsources(material_phaseAt(c,e)) + sourceState(material_phaseAt(c,e))%p(s)%subState0( :,material_phaseMemberAt(c,i,e)) = & + sourceState(material_phaseAt(c,e))%p(s)%partitionedState0(:,material_phaseMemberAt(c,i,e)) + enddo + crystallite_subFp0(1:3,1:3,c,i,e) = crystallite_partitionedFp0(1:3,1:3,c,i,e) + crystallite_subFi0(1:3,1:3,c,i,e) = crystallite_partitionedFi0(1:3,1:3,c,i,e) + crystallite_subF0(1:3,1:3,c,i,e) = crystallite_partitionedF0(1:3,1:3,c,i,e) + crystallite_subFrac(c,i,e) = 0.0_pReal + crystallite_subStep(c,i,e) = 1.0_pReal/num%subStepSizeCryst + todo(c,i,e) = .true. + crystallite_converged(c,i,e) = .false. ! pretend failed step of 1/subStepSizeCryst + endif homogenizationRequestsCalculation + enddo; enddo + enddo elementLooping1 + !$OMP END PARALLEL DO + + NiterationCrystallite = 0 + cutbackLooping: do while (any(todo(:,FEsolving_execIP(1):FEsolving_execIP(2),FEsolving_execELem(1):FEsolving_execElem(2)))) + NiterationCrystallite = NiterationCrystallite + 1 + +#ifdef DEBUG + if (debugCrystallite%extensive) & + print'(a,i6)', '<< CRYST stress >> crystallite iteration ',NiterationCrystallite +#endif + !$OMP PARALLEL DO PRIVATE(formerSubStep) + elementLooping3: do e = FEsolving_execElem(1),FEsolving_execElem(2) + do i = FEsolving_execIP(1),FEsolving_execIP(2) + do c = 1,homogenization_Nconstituents(material_homogenizationAt(e)) +!-------------------------------------------------------------------------------------------------- +! wind forward + if (crystallite_converged(c,i,e)) then + formerSubStep = crystallite_subStep(c,i,e) + crystallite_subFrac(c,i,e) = crystallite_subFrac(c,i,e) + crystallite_subStep(c,i,e) + crystallite_subStep(c,i,e) = min(1.0_pReal - crystallite_subFrac(c,i,e), & + num%stepIncreaseCryst * crystallite_subStep(c,i,e)) + + todo(c,i,e) = crystallite_subStep(c,i,e) > 0.0_pReal ! still time left to integrate on? + if (todo(c,i,e)) then + crystallite_subF0 (1:3,1:3,c,i,e) = crystallite_subF(1:3,1:3,c,i,e) + subLp0(1:3,1:3,c,i,e) = crystallite_Lp (1:3,1:3,c,i,e) + subLi0(1:3,1:3,c,i,e) = crystallite_Li (1:3,1:3,c,i,e) + crystallite_subFp0(1:3,1:3,c,i,e) = crystallite_Fp (1:3,1:3,c,i,e) + crystallite_subFi0(1:3,1:3,c,i,e) = crystallite_Fi (1:3,1:3,c,i,e) + plasticState( material_phaseAt(c,e))%subState0(:,material_phaseMemberAt(c,i,e)) & + = plasticState(material_phaseAt(c,e))%state( :,material_phaseMemberAt(c,i,e)) + do s = 1, phase_Nsources(material_phaseAt(c,e)) + sourceState( material_phaseAt(c,e))%p(s)%subState0(:,material_phaseMemberAt(c,i,e)) & + = sourceState(material_phaseAt(c,e))%p(s)%state( :,material_phaseMemberAt(c,i,e)) + enddo + endif + +!-------------------------------------------------------------------------------------------------- +! cut back (reduced time and restore) + else + 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_Fi (1:3,1:3,c,i,e) = crystallite_subFi0(1:3,1:3,c,i,e) + crystallite_S (1:3,1:3,c,i,e) = crystallite_S0 (1:3,1:3,c,i,e) + if (crystallite_subStep(c,i,e) < 1.0_pReal) then ! actual (not initial) cutback + crystallite_Lp (1:3,1:3,c,i,e) = subLp0(1:3,1:3,c,i,e) + crystallite_Li (1:3,1:3,c,i,e) = subLi0(1:3,1:3,c,i,e) + endif + plasticState (material_phaseAt(c,e))%state( :,material_phaseMemberAt(c,i,e)) & + = plasticState(material_phaseAt(c,e))%subState0(:,material_phaseMemberAt(c,i,e)) + do s = 1, phase_Nsources(material_phaseAt(c,e)) + sourceState( material_phaseAt(c,e))%p(s)%state( :,material_phaseMemberAt(c,i,e)) & + = sourceState(material_phaseAt(c,e))%p(s)%subState0(:,material_phaseMemberAt(c,i,e)) + enddo + + ! cant restore dotState here, since not yet calculated in first cutback after initialization + todo(c,i,e) = crystallite_subStep(c,i,e) > num%subStepMinCryst ! still on track or already done (beyond repair) + endif + +!-------------------------------------------------------------------------------------------------- +! prepare for integration + if (todo(c,i,e)) then + crystallite_subF(1:3,1:3,c,i,e) = crystallite_subF0(1:3,1:3,c,i,e) & + + crystallite_subStep(c,i,e) *( crystallite_partitionedF (1:3,1:3,c,i,e) & + -crystallite_partitionedF0(1:3,1:3,c,i,e)) + crystallite_Fe(1:3,1:3,c,i,e) = matmul(crystallite_subF(1:3,1:3,c,i,e), & + math_inv33(matmul(crystallite_Fi(1:3,1:3,c,i,e), & + crystallite_Fp(1:3,1:3,c,i,e)))) + crystallite_subdt(c,i,e) = crystallite_subStep(c,i,e) * crystallite_dt(c,i,e) + crystallite_converged(c,i,e) = .false. + call integrateState(c,i,e) + call integrateSourceState(c,i,e) + endif + + enddo + enddo + enddo elementLooping3 + !$OMP END PARALLEL DO + +!-------------------------------------------------------------------------------------------------- +! integrate --- requires fully defined state array (basic + dependent state) + where(.not. crystallite_converged .and. crystallite_subStep > num%subStepMinCryst) & ! do not try non-converged but fully cutbacked any further + todo = .true. ! TODO: again unroll this into proper elementloop to avoid N^2 for single point evaluation + enddo cutbackLooping + +! return whether converged or not + crystallite_stress = .false. + elementLooping5: do e = FEsolving_execElem(1),FEsolving_execElem(2) + do i = FEsolving_execIP(1),FEsolving_execIP(2) + crystallite_stress(i,e) = all(crystallite_converged(:,i,e)) + enddo + enddo elementLooping5 + +end function crystallite_stress + + +!-------------------------------------------------------------------------------------------------- +!> @brief Backup data for homog cutback. +!-------------------------------------------------------------------------------------------------- +subroutine crystallite_initializeRestorationPoints(i,e) + + integer, intent(in) :: & + i, & !< integration point number + e !< element number + integer :: & + c, & !< constituent number + s + + do c = 1,homogenization_Nconstituents(material_homogenizationAt(e)) + crystallite_partitionedFp0(1:3,1:3,c,i,e) = crystallite_Fp0(1:3,1:3,c,i,e) + crystallite_partitionedLp0(1:3,1:3,c,i,e) = crystallite_Lp0(1:3,1:3,c,i,e) + crystallite_partitionedFi0(1:3,1:3,c,i,e) = crystallite_Fi0(1:3,1:3,c,i,e) + crystallite_partitionedLi0(1:3,1:3,c,i,e) = crystallite_Li0(1:3,1:3,c,i,e) + crystallite_partitionedF0(1:3,1:3,c,i,e) = crystallite_F0(1:3,1:3,c,i,e) + crystallite_partitionedS0(1:3,1:3,c,i,e) = crystallite_S0(1:3,1:3,c,i,e) + + plasticState(material_phaseAt(c,e))%partitionedState0(:,material_phasememberAt(c,i,e)) = & + plasticState(material_phaseAt(c,e))%state0( :,material_phasememberAt(c,i,e)) + do s = 1, phase_Nsources(material_phaseAt(c,e)) + sourceState(material_phaseAt(c,e))%p(s)%partitionedState0(:,material_phasememberAt(c,i,e)) = & + sourceState(material_phaseAt(c,e))%p(s)%state0( :,material_phasememberAt(c,i,e)) + enddo + enddo + +end subroutine crystallite_initializeRestorationPoints + + +!-------------------------------------------------------------------------------------------------- +!> @brief Wind homog inc forward. +!-------------------------------------------------------------------------------------------------- +subroutine crystallite_windForward(i,e) + + integer, intent(in) :: & + i, & !< integration point number + e !< element number + integer :: & + c, & !< constituent number + s + + do c = 1,homogenization_Nconstituents(material_homogenizationAt(e)) + crystallite_partitionedF0 (1:3,1:3,c,i,e) = crystallite_partitionedF(1:3,1:3,c,i,e) + crystallite_partitionedFp0(1:3,1:3,c,i,e) = crystallite_Fp (1:3,1:3,c,i,e) + crystallite_partitionedLp0(1:3,1:3,c,i,e) = crystallite_Lp (1:3,1:3,c,i,e) + crystallite_partitionedFi0(1:3,1:3,c,i,e) = crystallite_Fi (1:3,1:3,c,i,e) + crystallite_partitionedLi0(1:3,1:3,c,i,e) = crystallite_Li (1:3,1:3,c,i,e) + crystallite_partitionedS0 (1:3,1:3,c,i,e) = crystallite_S (1:3,1:3,c,i,e) + + plasticState (material_phaseAt(c,e))%partitionedState0(:,material_phasememberAt(c,i,e)) = & + plasticState (material_phaseAt(c,e))%state (:,material_phasememberAt(c,i,e)) + do s = 1, phase_Nsources(material_phaseAt(c,e)) + sourceState(material_phaseAt(c,e))%p(s)%partitionedState0(:,material_phasememberAt(c,i,e)) = & + sourceState(material_phaseAt(c,e))%p(s)%state (:,material_phasememberAt(c,i,e)) + enddo + enddo + +end subroutine crystallite_windForward + + +!-------------------------------------------------------------------------------------------------- +!> @brief Restore data after homog cutback. +!-------------------------------------------------------------------------------------------------- +subroutine crystallite_restore(i,e,includeL) + + integer, intent(in) :: & + i, & !< integration point number + e !< element number + logical, intent(in) :: & + includeL !< protect agains fake cutback + integer :: & + c !< constituent number + + do c = 1,homogenization_Nconstituents(material_homogenizationAt(e)) + if (includeL) then + crystallite_Lp(1:3,1:3,c,i,e) = crystallite_partitionedLp0(1:3,1:3,c,i,e) + crystallite_Li(1:3,1:3,c,i,e) = crystallite_partitionedLi0(1:3,1:3,c,i,e) + endif ! maybe protecting everything from overwriting makes more sense + crystallite_Fp(1:3,1:3,c,i,e) = crystallite_partitionedFp0(1:3,1:3,c,i,e) + crystallite_Fi(1:3,1:3,c,i,e) = crystallite_partitionedFi0(1:3,1:3,c,i,e) + crystallite_S (1:3,1:3,c,i,e) = crystallite_partitionedS0 (1:3,1:3,c,i,e) + + plasticState (material_phaseAt(c,e))%state( :,material_phasememberAt(c,i,e)) = & + plasticState (material_phaseAt(c,e))%partitionedState0(:,material_phasememberAt(c,i,e)) + enddo + +end subroutine crystallite_restore + + +!-------------------------------------------------------------------------------------------------- +!> @brief Calculate tangent (dPdF). +!-------------------------------------------------------------------------------------------------- +function crystallite_stressTangent(c,i,e) result(dPdF) + + real(pReal), dimension(3,3,3,3) :: dPdF + integer, intent(in) :: & + c, & !< counter in constituent loop + i, & !< counter in integration point loop + e !< counter in element loop + integer :: & + o, & + p + + 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, & + dSdF, & + dSdFi, & + dLidS, & ! tangent in lattice configuration + dLidFi, & + dLpdS, & + dLpdFi, & + dFidS, & + dFpinvdF, & + rhs_3333, & + lhs_3333, & + temp_3333 + real(pReal), dimension(9,9):: temp_99 + logical :: error + + + call constitutive_SandItsTangents(devNull,dSdFe,dSdFi, & + crystallite_Fe(1:3,1:3,c,i,e), & + crystallite_Fi(1:3,1:3,c,i,e),c,i,e) + call constitutive_LiAndItsTangents(devNull,dLidS,dLidFi, & + crystallite_S (1:3,1:3,c,i,e), & + crystallite_Fi(1:3,1:3,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 + dFidS = 0.0_pReal + else + lhs_3333 = 0.0_pReal; rhs_3333 = 0.0_pReal + do o=1,3; do p=1,3 + 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)) + lhs_3333(1:3,o,1:3,p) = lhs_3333(1:3,o,1:3,p) & + + invFi*invFi(p,o) + 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)) + enddo; enddo + call math_invert(temp_99,error,math_3333to99(lhs_3333)) + if (error) then + call IO_warning(warning_ID=600,el=e,ip=i,g=c, & + ext_msg='inversion error in analytic tangent calculation') + dFidS = 0.0_pReal + else + dFidS = math_mul3333xx3333(math_99to3333(temp_99),rhs_3333) + endif + dLidS = math_mul3333xx3333(dLidFi,dFidS) + dLidS + endif + + call constitutive_LpAndItsTangents(devNull,dLpdS,dLpdFi, & + crystallite_S (1:3,1:3,c,i,e), & + crystallite_Fi(1:3,1:3,c,i,e),c,i,e) ! call constitutive law to calculate Lp tangent in lattice configuration + dLpdS = math_mul3333xx3333(dLpdFi,dFidS) + dLpdS + +!-------------------------------------------------------------------------------------------------- +! calculate dSdF + temp_33_1 = transpose(matmul(invFp,invFi)) + temp_33_2 = matmul(crystallite_subF(1:3,1:3,c,i,e),invSubFp0) + temp_33_3 = matmul(matmul(crystallite_subF(1:3,1:3,c,i,e),invFp), invSubFi0) + + 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) + temp_3333(1:3,1:3,p,o) = matmul(matmul(temp_33_2,dLpdS(1:3,1:3,p,o)), invFi) & + + matmul(temp_33_3,dLidS(1:3,1:3,p,o)) + enddo; enddo + lhs_3333 = crystallite_subdt(c,i,e)*math_mul3333xx3333(dSdFe,temp_3333) & + + math_mul3333xx3333(dSdFi,dFidS) + + call math_invert(temp_99,error,math_eye(9)+math_3333to99(lhs_3333)) + if (error) then + call IO_warning(warning_ID=600,el=e,ip=i,g=c, & + ext_msg='inversion error in analytic tangent calculation') + dSdF = rhs_3333 + else + dSdF = math_mul3333xx3333(math_99to3333(temp_99),rhs_3333) + endif + +!-------------------------------------------------------------------------------------------------- +! calculate dFpinvdF + temp_3333 = math_mul3333xx3333(dLpdS,dSdF) + do o=1,3; do p=1,3 + dFpinvdF(1:3,1:3,p,o) = -crystallite_subdt(c,i,e) & + * matmul(invSubFp0, matmul(temp_3333(1:3,1:3,p,o),invFi)) + enddo; enddo + +!-------------------------------------------------------------------------------------------------- +! assemble dPdF + temp_33_1 = matmul(crystallite_S(1:3,1:3,c,i,e),transpose(invFp)) + temp_33_2 = matmul(invFp,temp_33_1) + 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)) + + dPdF = 0.0_pReal + do p=1,3 + dPdF(p,1:3,p,1:3) = transpose(temp_33_2) + enddo + do o=1,3; do p=1,3 + dPdF(1:3,1:3,p,o) = dPdF(1:3,1:3,p,o) & + + matmul(matmul(crystallite_subF(1:3,1:3,c,i,e), & + dFpinvdF(1:3,1:3,p,o)),temp_33_1) & + + matmul(matmul(temp_33_3,dSdF(1:3,1:3,p,o)), & + transpose(invFp)) & + + matmul(temp_33_4,transpose(dFpinvdF(1:3,1:3,p,o))) + enddo; enddo + +end function crystallite_stressTangent + + +!-------------------------------------------------------------------------------------------------- +!> @brief calculates orientations +!-------------------------------------------------------------------------------------------------- +subroutine crystallite_orientations + + integer & + c, & !< counter in integration point component loop + i, & !< counter in integration point loop + e !< counter in element loop + + !$OMP PARALLEL DO + do e = FEsolving_execElem(1),FEsolving_execElem(2) + do i = FEsolving_execIP(1),FEsolving_execIP(2) + do c = 1,homogenization_Nconstituents(material_homogenizationAt(e)) + call crystallite_orientation(c,i,e)%fromMatrix(transpose(math_rotationalPart(crystallite_Fe(1:3,1:3,c,i,e)))) + enddo; enddo; enddo + !$OMP END PARALLEL DO + + nonlocalPresent: if (any(plasticState%nonlocal)) then + !$OMP PARALLEL DO + do e = FEsolving_execElem(1),FEsolving_execElem(2) + if (plasticState(material_phaseAt(1,e))%nonlocal) then + do i = FEsolving_execIP(1),FEsolving_execIP(2) + call plastic_nonlocal_updateCompatibility(crystallite_orientation, & + phase_plasticityInstance(material_phaseAt(1,e)),i,e) + enddo + endif + enddo + !$OMP END PARALLEL DO + endif nonlocalPresent + +end subroutine crystallite_orientations + + +!-------------------------------------------------------------------------------------------------- +!> @brief Map 2nd order tensor to reference config +!-------------------------------------------------------------------------------------------------- +function crystallite_push33ToRef(ipc,ip,el, tensor33) + + real(pReal), dimension(3,3) :: crystallite_push33ToRef + real(pReal), dimension(3,3), intent(in) :: tensor33 + real(pReal), dimension(3,3) :: T + integer, intent(in):: & + el, & + ip, & + ipc + + T = matmul(material_orientation0(ipc,ip,el)%asMatrix(), & ! ToDo: initial orientation correct? + transpose(math_inv33(crystallite_subF(1:3,1:3,ipc,ip,el)))) + crystallite_push33ToRef = matmul(transpose(T),matmul(tensor33,T)) + +end function crystallite_push33ToRef + + +!-------------------------------------------------------------------------------------------------- +!> @brief writes crystallite results to HDF5 output file +!-------------------------------------------------------------------------------------------------- +subroutine crystallite_results + + integer :: p,o + real(pReal), allocatable, dimension(:,:,:) :: selected_tensors + real(pReal), allocatable, dimension(:,:) :: selected_rotations + character(len=:), allocatable :: group,structureLabel + + do p=1,size(material_name_phase) + group = trim('current/phase')//'/'//trim(material_name_phase(p))//'/mechanics' + + call results_closeGroup(results_addGroup(group)) + + do o = 1, size(output_constituent(p)%label) + select case (output_constituent(p)%label(o)) + case('F') + selected_tensors = select_tensors(crystallite_partitionedF,p) + call results_writeDataset(group,selected_tensors,output_constituent(p)%label(o),& + 'deformation gradient','1') + case('F_e') + selected_tensors = select_tensors(crystallite_Fe,p) + call results_writeDataset(group,selected_tensors,output_constituent(p)%label(o),& + 'elastic deformation gradient','1') + case('F_p') + selected_tensors = select_tensors(crystallite_Fp,p) + call results_writeDataset(group,selected_tensors,output_constituent(p)%label(o),& + 'plastic deformation gradient','1') + case('F_i') + selected_tensors = select_tensors(crystallite_Fi,p) + call results_writeDataset(group,selected_tensors,output_constituent(p)%label(o),& + 'inelastic deformation gradient','1') + case('L_p') + selected_tensors = select_tensors(crystallite_Lp,p) + call results_writeDataset(group,selected_tensors,output_constituent(p)%label(o),& + 'plastic velocity gradient','1/s') + case('L_i') + selected_tensors = select_tensors(crystallite_Li,p) + call results_writeDataset(group,selected_tensors,output_constituent(p)%label(o),& + 'inelastic velocity gradient','1/s') + case('P') + selected_tensors = select_tensors(crystallite_P,p) + call results_writeDataset(group,selected_tensors,output_constituent(p)%label(o),& + 'First Piola-Kirchhoff stress','Pa') + case('S') + selected_tensors = select_tensors(crystallite_S,p) + call results_writeDataset(group,selected_tensors,output_constituent(p)%label(o),& + 'Second Piola-Kirchhoff stress','Pa') + case('O') + select case(lattice_structure(p)) + case(lattice_ISO_ID) + structureLabel = 'aP' + case(lattice_FCC_ID) + structureLabel = 'cF' + case(lattice_BCC_ID) + structureLabel = 'cI' + case(lattice_BCT_ID) + structureLabel = 'tI' + case(lattice_HEX_ID) + structureLabel = 'hP' + case(lattice_ORT_ID) + structureLabel = 'oP' + end select + selected_rotations = select_rotations(crystallite_orientation,p) + call results_writeDataset(group,selected_rotations,output_constituent(p)%label(o),& + 'crystal orientation as quaternion','q_0 ') + call results_addAttribute('Lattice',structureLabel,group//'/'//output_constituent(p)%label(o)) + end select + enddo + enddo + + contains + + !------------------------------------------------------------------------------------------------ + !> @brief select tensors for output + !------------------------------------------------------------------------------------------------ + function select_tensors(dataset,instance) + + integer, intent(in) :: instance + real(pReal), dimension(:,:,:,:,:), intent(in) :: dataset + real(pReal), allocatable, dimension(:,:,:) :: select_tensors + integer :: e,i,c,j + + allocate(select_tensors(3,3,count(material_phaseAt==instance)*discretization_nIPs)) + + j=0 + do e = 1, size(material_phaseAt,2) + do i = 1, discretization_nIPs + do c = 1, size(material_phaseAt,1) !ToDo: this needs to be changed for varying Ngrains + if (material_phaseAt(c,e) == instance) then + j = j + 1 + select_tensors(1:3,1:3,j) = dataset(1:3,1:3,c,i,e) + endif + enddo + enddo + enddo + + end function select_tensors + + +!-------------------------------------------------------------------------------------------------- +!> @brief select rotations for output +!-------------------------------------------------------------------------------------------------- + function select_rotations(dataset,instance) + + integer, intent(in) :: instance + type(rotation), dimension(:,:,:), intent(in) :: dataset + real(pReal), allocatable, dimension(:,:) :: select_rotations + integer :: e,i,c,j + + allocate(select_rotations(4,count(material_phaseAt==instance)*homogenization_maxNconstituents*discretization_nIPs)) + + j=0 + do e = 1, size(material_phaseAt,2) + do i = 1, discretization_nIPs + do c = 1, size(material_phaseAt,1) !ToDo: this needs to be changed for varying Ngrains + if (material_phaseAt(c,e) == instance) then + j = j + 1 + select_rotations(1:4,j) = dataset(c,i,e)%asQuaternion() + endif + enddo + enddo + enddo + + end function select_rotations + +end subroutine crystallite_results + + +!-------------------------------------------------------------------------------------------------- +!> @brief calculation of stress (P) with time integration based on a residuum in Lp and +!> intermediate acceleration of the Newton-Raphson correction +!-------------------------------------------------------------------------------------------------- +function integrateStress(ipc,ip,el,timeFraction) result(broken) + + integer, intent(in):: el, & ! element index + ip, & ! integration point index + ipc ! grain index + real(pReal), optional, intent(in) :: timeFraction ! fraction of timestep + + real(pReal), dimension(3,3):: F, & ! deformation gradient at end of timestep + Fp_new, & ! plastic deformation gradient at end of timestep + invFp_new, & ! inverse of Fp_new + invFp_current, & ! inverse of Fp_current + Lpguess, & ! current guess for plastic velocity gradient + Lpguess_old, & ! known last good guess for plastic velocity gradient + Lp_constitutive, & ! plastic velocity gradient resulting from constitutive law + residuumLp, & ! current residuum of plastic velocity gradient + residuumLp_old, & ! last residuum of plastic velocity gradient + 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_old, & ! known last good guess for intermediate velocity gradient + Li_constitutive, & ! intermediate velocity gradient resulting from constitutive law + residuumLi, & ! current residuum of intermediate velocity gradient + residuumLi_old, & ! last residuum of intermediate velocity gradient + deltaLi, & ! direction of next guess + Fe, & ! elastic deformation gradient + S, & ! 2nd Piola-Kirchhoff Stress in plastic (lattice) configuration + A, & + B, & + temp_33 + real(pReal), dimension(9) :: temp_9 ! needed for matrix inversion by LAPACK + integer, dimension(9) :: devNull_9 ! needed for matrix inversion by LAPACK + real(pReal), dimension(9,9) :: dRLp_dLp, & ! partial derivative of residuum (Jacobian for Newton-Raphson scheme) + dRLi_dLi ! partial derivative of residuumI (Jacobian for Newton-Raphson scheme) + real(pReal), dimension(3,3,3,3):: dS_dFe, & ! partial derivative of 2nd Piola-Kirchhoff stress + dS_dFi, & + dFe_dLp, & ! partial derivative of elastic deformation gradient + dFe_dLi, & + dFi_dLi, & + dLp_dFi, & + dLi_dFi, & + dLp_dS, & + dLi_dS + real(pReal) steplengthLp, & + steplengthLi, & + dt, & ! time increment + atol_Lp, & + atol_Li, & + devNull + integer NiterationStressLp, & ! number of stress integrations + NiterationStressLi, & ! number of inner stress integrations + ierr, & ! error indicator for LAPACK + o, & + p, & + jacoCounterLp, & + jacoCounterLi ! counters to check for Jacobian update + logical :: error,broken + + broken = .true. + + if (present(timeFraction)) then + dt = crystallite_subdt(ipc,ip,el) * timeFraction + F = crystallite_subF0(1:3,1:3,ipc,ip,el) & + + (crystallite_subF(1:3,1:3,ipc,ip,el) - crystallite_subF0(1:3,1:3,ipc,ip,el)) * timeFraction + else + dt = crystallite_subdt(ipc,ip,el) + F = crystallite_subF(1:3,1:3,ipc,ip,el) + endif + + call constitutive_dependentState(crystallite_partitionedF(1:3,1:3,ipc,ip,el), & + crystallite_Fp(1:3,1:3,ipc,ip,el),ipc,ip,el) + + Lpguess = crystallite_Lp(1:3,1:3,ipc,ip,el) ! take as first guess + Liguess = crystallite_Li(1:3,1:3,ipc,ip,el) ! take as first guess + + call math_invert33(invFp_current,devNull,error,crystallite_subFp0(1:3,1:3,ipc,ip,el)) + if (error) return ! error + call math_invert33(invFi_current,devNull,error,crystallite_subFi0(1:3,1:3,ipc,ip,el)) + if (error) return ! error + + A = matmul(F,invFp_current) ! intermediate tensor needed later to calculate dFe_dLp + + jacoCounterLi = 0 + steplengthLi = 1.0_pReal + residuumLi_old = 0.0_pReal + Liguess_old = Liguess + + NiterationStressLi = 0 + LiLoop: do + NiterationStressLi = NiterationStressLi + 1 + if (NiterationStressLi>num%nStress) return ! error + + invFi_new = matmul(invFi_current,math_I3 - dt*Liguess) + Fi_new = math_inv33(invFi_new) + + jacoCounterLp = 0 + steplengthLp = 1.0_pReal + residuumLp_old = 0.0_pReal + Lpguess_old = Lpguess + + NiterationStressLp = 0 + LpLoop: do + NiterationStressLp = NiterationStressLp + 1 + if (NiterationStressLp>num%nStress) return ! error + + B = math_I3 - dt*Lpguess + Fe = matmul(matmul(A,B), invFi_new) + call constitutive_SandItsTangents(S, dS_dFe, dS_dFi, & + Fe, Fi_new, ipc, ip, el) + + call constitutive_LpAndItsTangents(Lp_constitutive, dLp_dS, dLp_dFi, & + S, Fi_new, ipc, ip, el) + + !* update current residuum and check for convergence of loop + atol_Lp = max(num%rtol_crystalliteStress * max(norm2(Lpguess),norm2(Lp_constitutive)), & ! absolute tolerance from largest acceptable relative error + num%atol_crystalliteStress) ! minimum lower cutoff + residuumLp = Lpguess - Lp_constitutive + + if (any(IEEE_is_NaN(residuumLp))) then + return ! error + elseif (norm2(residuumLp) < atol_Lp) then ! converged if below absolute tolerance + exit LpLoop + elseif (NiterationStressLp == 1 .or. norm2(residuumLp) < norm2(residuumLp_old)) then ! not converged, but improved norm of residuum (always proceed in first iteration)... + residuumLp_old = residuumLp ! ...remember old values and... + Lpguess_old = Lpguess + steplengthLp = 1.0_pReal ! ...proceed with normal step length (calculate new search direction) + else ! not converged and residuum not improved... + steplengthLp = num%subStepSizeLp * steplengthLp ! ...try with smaller step length in same direction + Lpguess = Lpguess_old & + + deltaLp * stepLengthLp + cycle LpLoop + endif + + calculateJacobiLi: if (mod(jacoCounterLp, num%iJacoLpresiduum) == 0) then + jacoCounterLp = jacoCounterLp + 1 + + do o=1,3; do p=1,3 + dFe_dLp(o,1:3,p,1:3) = - dt * A(o,p)*transpose(invFi_new) ! dFe_dLp(i,j,k,l) = -dt * A(i,k) invFi(l,j) + enddo; enddo + dRLp_dLp = math_eye(9) & + - math_3333to99(math_mul3333xx3333(math_mul3333xx3333(dLp_dS,dS_dFe),dFe_dLp)) + temp_9 = math_33to9(residuumLp) + call dgesv(9,1,dRLp_dLp,9,devNull_9,temp_9,9,ierr) ! solve dRLp/dLp * delta Lp = -res for delta Lp + if (ierr /= 0) return ! error + deltaLp = - math_9to33(temp_9) + endif calculateJacobiLi + + Lpguess = Lpguess & + + deltaLp * steplengthLp + enddo LpLoop + + call constitutive_LiAndItsTangents(Li_constitutive, dLi_dS, dLi_dFi, & + S, Fi_new, ipc, ip, el) + + !* update current residuum and check for convergence of loop + atol_Li = max(num%rtol_crystalliteStress * max(norm2(Liguess),norm2(Li_constitutive)), & ! absolute tolerance from largest acceptable relative error + num%atol_crystalliteStress) ! minimum lower cutoff + residuumLi = Liguess - Li_constitutive + if (any(IEEE_is_NaN(residuumLi))) then + return ! error + elseif (norm2(residuumLi) < atol_Li) then ! converged if below absolute tolerance + exit LiLoop + elseif (NiterationStressLi == 1 .or. norm2(residuumLi) < norm2(residuumLi_old)) then ! not converged, but improved norm of residuum (always proceed in first iteration)... + residuumLi_old = residuumLi ! ...remember old values and... + Liguess_old = Liguess + steplengthLi = 1.0_pReal ! ...proceed with normal step length (calculate new search direction) + else ! not converged and residuum not improved... + steplengthLi = num%subStepSizeLi * steplengthLi ! ...try with smaller step length in same direction + Liguess = Liguess_old & + + deltaLi * steplengthLi + cycle LiLoop + endif + + calculateJacobiLp: if (mod(jacoCounterLi, num%iJacoLpresiduum) == 0) then + jacoCounterLi = jacoCounterLi + 1 + + temp_33 = matmul(matmul(A,B),invFi_current) + do o=1,3; do p=1,3 + dFe_dLi(1:3,o,1:3,p) = -dt*math_I3(o,p)*temp_33 ! dFe_dLp(i,j,k,l) = -dt * A(i,k) invFi(l,j) + dFi_dLi(1:3,o,1:3,p) = -dt*math_I3(o,p)*invFi_current + enddo; enddo + do o=1,3; do p=1,3 + dFi_dLi(1:3,1:3,o,p) = matmul(matmul(Fi_new,dFi_dLi(1:3,1:3,o,p)),Fi_new) + enddo; enddo + dRLi_dLi = math_eye(9) & + - math_3333to99(math_mul3333xx3333(dLi_dS, math_mul3333xx3333(dS_dFe, dFe_dLi) & + + math_mul3333xx3333(dS_dFi, dFi_dLi))) & + - math_3333to99(math_mul3333xx3333(dLi_dFi, dFi_dLi)) + temp_9 = math_33to9(residuumLi) + call dgesv(9,1,dRLi_dLi,9,devNull_9,temp_9,9,ierr) ! solve dRLi/dLp * delta Li = -res for delta Li + if (ierr /= 0) return ! error + deltaLi = - math_9to33(temp_9) + endif calculateJacobiLp + + Liguess = Liguess & + + deltaLi * steplengthLi + enddo LiLoop + + invFp_new = matmul(invFp_current,B) + call math_invert33(Fp_new,devNull,error,invFp_new) + if (error) return ! error + + 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_Lp (1:3,1:3,ipc,ip,el) = Lpguess + crystallite_Li (1:3,1:3,ipc,ip,el) = Liguess + crystallite_Fp (1:3,1:3,ipc,ip,el) = Fp_new / math_det33(Fp_new)**(1.0_pReal/3.0_pReal) ! regularize + crystallite_Fi (1:3,1:3,ipc,ip,el) = Fi_new + crystallite_Fe (1:3,1:3,ipc,ip,el) = matmul(matmul(F,invFp_new),invFi_new) + broken = .false. + +end function integrateStress + + +!-------------------------------------------------------------------------------------------------- +!> @brief integrate stress, state with adaptive 1st order explicit Euler method +!> using Fixed Point Iteration to adapt the stepsize +!-------------------------------------------------------------------------------------------------- +subroutine integrateStateFPI(g,i,e) + + integer, intent(in) :: & + e, & !< element index in element loop + i, & !< integration point index in ip loop + g !< grain index in grain loop + integer :: & + NiterationState, & !< number of iterations in state loop + p, & + c, & + s, & + size_pl + integer, dimension(maxval(phase_Nsources)) :: & + size_so + real(pReal) :: & + zeta + real(pReal), dimension(max(constitutive_plasticity_maxSizeDotState,constitutive_source_maxSizeDotState)) :: & + r ! state residuum + real(pReal), dimension(constitutive_plasticity_maxSizeDotState,2) :: & + plastic_dotState + real(pReal), dimension(constitutive_source_maxSizeDotState,2,maxval(phase_Nsources)) :: source_dotState + logical :: & + broken + + p = material_phaseAt(g,e) + c = material_phaseMemberAt(g,i,e) + + broken = constitutive_collectDotState(crystallite_S(1:3,1:3,g,i,e), & + crystallite_partitionedF0, & + crystallite_Fi(1:3,1:3,g,i,e), & + crystallite_partitionedFp0, & + crystallite_subdt(g,i,e), g,i,e,p,c) + if(broken) return + + size_pl = plasticState(p)%sizeDotState + plasticState(p)%state(1:size_pl,c) = plasticState(p)%subState0(1:size_pl,c) & + + plasticState(p)%dotState (1:size_pl,c) & + * crystallite_subdt(g,i,e) + plastic_dotState(1:size_pl,2) = 0.0_pReal + + iteration: do NiterationState = 1, num%nState + + if(nIterationState > 1) plastic_dotState(1:size_pl,2) = plastic_dotState(1:size_pl,1) + plastic_dotState(1:size_pl,1) = plasticState(p)%dotState(:,c) + + broken = integrateStress(g,i,e) + if(broken) exit iteration + + broken = constitutive_collectDotState(crystallite_S(1:3,1:3,g,i,e), & + crystallite_partitionedF0, & + crystallite_Fi(1:3,1:3,g,i,e), & + crystallite_partitionedFp0, & + crystallite_subdt(g,i,e), g,i,e,p,c) + if(broken) exit iteration + + zeta = damper(plasticState(p)%dotState(:,c),plastic_dotState(1:size_pl,1),& + plastic_dotState(1:size_pl,2)) + plasticState(p)%dotState(:,c) = plasticState(p)%dotState(:,c) * zeta & + + plastic_dotState(1:size_pl,1) * (1.0_pReal - zeta) + r(1:size_pl) = plasticState(p)%state (1:size_pl,c) & + - plasticState(p)%subState0(1:size_pl,c) & + - plasticState(p)%dotState (1:size_pl,c) * crystallite_subdt(g,i,e) + plasticState(p)%state(1:size_pl,c) = plasticState(p)%state(1:size_pl,c) & + - r(1:size_pl) + crystallite_converged(g,i,e) = converged(r(1:size_pl), & + plasticState(p)%state(1:size_pl,c), & + plasticState(p)%atol(1:size_pl)) + + if(crystallite_converged(g,i,e)) then + broken = constitutive_deltaState(crystallite_S(1:3,1:3,g,i,e), & + crystallite_Fi(1:3,1:3,g,i,e),g,i,e,p,c) + exit iteration + endif + + enddo iteration + + + contains + + !-------------------------------------------------------------------------------------------------- + !> @brief calculate the damping for correction of state and dot state + !-------------------------------------------------------------------------------------------------- + real(pReal) pure function damper(current,previous,previous2) + + real(pReal), dimension(:), intent(in) ::& + current, previous, previous2 + + real(pReal) :: dot_prod12, dot_prod22 + + dot_prod12 = dot_product(current - previous, previous - previous2) + dot_prod22 = dot_product(previous - previous2, previous - previous2) + if ((dot_product(current,previous) < 0.0_pReal .or. dot_prod12 < 0.0_pReal) .and. dot_prod22 > 0.0_pReal) then + damper = 0.75_pReal + 0.25_pReal * tanh(2.0_pReal + 4.0_pReal * dot_prod12 / dot_prod22) + else + damper = 1.0_pReal + endif + + end function damper + +end subroutine integrateStateFPI + + +!-------------------------------------------------------------------------------------------------- +!> @brief integrate stress, state with adaptive 1st order explicit Euler method +!> using Fixed Point Iteration to adapt the stepsize +!-------------------------------------------------------------------------------------------------- +subroutine integrateSourceState(g,i,e) + + integer, intent(in) :: & + e, & !< element index in element loop + i, & !< integration point index in ip loop + g !< grain index in grain loop + integer :: & + NiterationState, & !< number of iterations in state loop + p, & + c, & + s, & + size_pl + integer, dimension(maxval(phase_Nsources)) :: & + size_so + real(pReal) :: & + zeta + real(pReal), dimension(max(constitutive_plasticity_maxSizeDotState,constitutive_source_maxSizeDotState)) :: & + r ! state residuum + real(pReal), dimension(constitutive_source_maxSizeDotState,2,maxval(phase_Nsources)) :: source_dotState + logical :: & + broken + + p = material_phaseAt(g,e) + c = material_phaseMemberAt(g,i,e) + + broken = constitutive_collectDotState_source(crystallite_S(1:3,1:3,g,i,e), g,i,e,p,c) + if(broken) return + + do s = 1, phase_Nsources(p) + size_so(s) = sourceState(p)%p(s)%sizeDotState + sourceState(p)%p(s)%state(1:size_so(s),c) = sourceState(p)%p(s)%subState0(1:size_so(s),c) & + + sourceState(p)%p(s)%dotState (1:size_so(s),c) & + * crystallite_subdt(g,i,e) + source_dotState(1:size_so(s),2,s) = 0.0_pReal + enddo + + iteration: do NiterationState = 1, num%nState + + do s = 1, phase_Nsources(p) + if(nIterationState > 1) source_dotState(1:size_so(s),2,s) = source_dotState(1:size_so(s),1,s) + source_dotState(1:size_so(s),1,s) = sourceState(p)%p(s)%dotState(:,c) + enddo + + broken = constitutive_collectDotState_source(crystallite_S(1:3,1:3,g,i,e), g,i,e,p,c) + if(broken) exit iteration + + do s = 1, phase_Nsources(p) + zeta = damper(sourceState(p)%p(s)%dotState(:,c), & + source_dotState(1:size_so(s),1,s),& + source_dotState(1:size_so(s),2,s)) + sourceState(p)%p(s)%dotState(:,c) = sourceState(p)%p(s)%dotState(:,c) * zeta & + + source_dotState(1:size_so(s),1,s)* (1.0_pReal - zeta) + r(1:size_so(s)) = sourceState(p)%p(s)%state (1:size_so(s),c) & + - sourceState(p)%p(s)%subState0(1:size_so(s),c) & + - sourceState(p)%p(s)%dotState (1:size_so(s),c) * crystallite_subdt(g,i,e) + sourceState(p)%p(s)%state(1:size_so(s),c) = sourceState(p)%p(s)%state(1:size_so(s),c) & + - r(1:size_so(s)) + crystallite_converged(g,i,e) = & + crystallite_converged(g,i,e) .and. converged(r(1:size_so(s)), & + sourceState(p)%p(s)%state(1:size_so(s),c), & + sourceState(p)%p(s)%atol(1:size_so(s))) + enddo + + if(crystallite_converged(g,i,e)) then + broken = constitutive_deltaState_source(crystallite_Fe(1:3,1:3,g,i,e),g,i,e,p,c) + exit iteration + endif + + enddo iteration + + + contains + + !-------------------------------------------------------------------------------------------------- + !> @brief calculate the damping for correction of state and dot state + !-------------------------------------------------------------------------------------------------- + real(pReal) pure function damper(current,previous,previous2) + + real(pReal), dimension(:), intent(in) ::& + current, previous, previous2 + + real(pReal) :: dot_prod12, dot_prod22 + + dot_prod12 = dot_product(current - previous, previous - previous2) + dot_prod22 = dot_product(previous - previous2, previous - previous2) + if ((dot_product(current,previous) < 0.0_pReal .or. dot_prod12 < 0.0_pReal) .and. dot_prod22 > 0.0_pReal) then + damper = 0.75_pReal + 0.25_pReal * tanh(2.0_pReal + 4.0_pReal * dot_prod12 / dot_prod22) + else + damper = 1.0_pReal + endif + + end function damper + +end subroutine integrateSourceState + +!-------------------------------------------------------------------------------------------------- +!> @brief integrate state with 1st order explicit Euler method +!-------------------------------------------------------------------------------------------------- +subroutine integrateStateEuler(g,i,e) + + integer, intent(in) :: & + e, & !< element index in element loop + i, & !< integration point index in ip loop + g !< grain index in grain loop + integer :: & + p, & + c, & + sizeDotState + logical :: & + broken + + p = material_phaseAt(g,e) + c = material_phaseMemberAt(g,i,e) + + broken = constitutive_collectDotState(crystallite_S(1:3,1:3,g,i,e), & + crystallite_partitionedF0, & + crystallite_Fi(1:3,1:3,g,i,e), & + crystallite_partitionedFp0, & + crystallite_subdt(g,i,e), g,i,e,p,c) + if(broken) return + + sizeDotState = plasticState(p)%sizeDotState + plasticState(p)%state(1:sizeDotState,c) = plasticState(p)%subState0(1:sizeDotState,c) & + + plasticState(p)%dotState (1:sizeDotState,c) & + * crystallite_subdt(g,i,e) + + broken = constitutive_deltaState(crystallite_S(1:3,1:3,g,i,e), & + crystallite_Fi(1:3,1:3,g,i,e),g,i,e,p,c) + if(broken) return + + broken = integrateStress(g,i,e) + crystallite_converged(g,i,e) = .not. broken + +end subroutine integrateStateEuler + + +!-------------------------------------------------------------------------------------------------- +!> @brief integrate stress, state with 1st order Euler method with adaptive step size +!-------------------------------------------------------------------------------------------------- +subroutine integrateStateAdaptiveEuler(g,i,e) + + integer, intent(in) :: & + e, & !< element index in element loop + i, & !< integration point index in ip loop + g !< grain index in grain loop + integer :: & + p, & + c, & + sizeDotState + logical :: & + broken + + real(pReal), dimension(constitutive_plasticity_maxSizeDotState) :: residuum_plastic + + + p = material_phaseAt(g,e) + c = material_phaseMemberAt(g,i,e) + + broken = constitutive_collectDotState(crystallite_S(1:3,1:3,g,i,e), & + crystallite_partitionedF0, & + crystallite_Fi(1:3,1:3,g,i,e), & + crystallite_partitionedFp0, & + crystallite_subdt(g,i,e), g,i,e,p,c) + if(broken) return + + sizeDotState = plasticState(p)%sizeDotState + + residuum_plastic(1:sizeDotState) = - plasticState(p)%dotstate(1:sizeDotState,c) * 0.5_pReal * crystallite_subdt(g,i,e) + plasticState(p)%state(1:sizeDotState,c) = plasticState(p)%subState0(1:sizeDotState,c) & + + plasticState(p)%dotstate(1:sizeDotState,c) * crystallite_subdt(g,i,e) + + broken = constitutive_deltaState(crystallite_S(1:3,1:3,g,i,e), & + crystallite_Fi(1:3,1:3,g,i,e),g,i,e,p,c) + if(broken) return + + broken = integrateStress(g,i,e) + if(broken) return + + broken = constitutive_collectDotState(crystallite_S(1:3,1:3,g,i,e), & + crystallite_partitionedF0, & + crystallite_Fi(1:3,1:3,g,i,e), & + crystallite_partitionedFp0, & + crystallite_subdt(g,i,e), g,i,e,p,c) + if(broken) return + + + sizeDotState = plasticState(p)%sizeDotState + crystallite_converged(g,i,e) = converged(residuum_plastic(1:sizeDotState) & + + 0.5_pReal * plasticState(p)%dotState(:,c) * crystallite_subdt(g,i,e), & + plasticState(p)%state(1:sizeDotState,c), & + plasticState(p)%atol(1:sizeDotState)) + +end subroutine integrateStateAdaptiveEuler + + +!--------------------------------------------------------------------------------------------------- +!> @brief Integrate state (including stress integration) with the classic Runge Kutta method +!--------------------------------------------------------------------------------------------------- +subroutine integrateStateRK4(g,i,e) + + integer, intent(in) :: g,i,e + + real(pReal), dimension(3,3), parameter :: & + A = reshape([& + 0.5_pReal, 0.0_pReal, 0.0_pReal, & + 0.0_pReal, 0.5_pReal, 0.0_pReal, & + 0.0_pReal, 0.0_pReal, 1.0_pReal],& + shape(A)) + real(pReal), dimension(3), parameter :: & + C = [0.5_pReal, 0.5_pReal, 1.0_pReal] + real(pReal), dimension(4), parameter :: & + B = [1.0_pReal/6.0_pReal, 1.0_pReal/3.0_pReal, 1.0_pReal/3.0_pReal, 1.0_pReal/6.0_pReal] + + call integrateStateRK(g,i,e,A,B,C) + +end subroutine integrateStateRK4 + + +!--------------------------------------------------------------------------------------------------- +!> @brief Integrate state (including stress integration) with the Cash-Carp method +!--------------------------------------------------------------------------------------------------- +subroutine integrateStateRKCK45(g,i,e) + + integer, intent(in) :: g,i,e + + real(pReal), dimension(5,5), parameter :: & + A = reshape([& + 1._pReal/5._pReal, .0_pReal, .0_pReal, .0_pReal, .0_pReal, & + 3._pReal/40._pReal, 9._pReal/40._pReal, .0_pReal, .0_pReal, .0_pReal, & + 3_pReal/10._pReal, -9._pReal/10._pReal, 6._pReal/5._pReal, .0_pReal, .0_pReal, & + -11._pReal/54._pReal, 5._pReal/2._pReal, -70.0_pReal/27.0_pReal, 35.0_pReal/27.0_pReal, .0_pReal, & + 1631._pReal/55296._pReal,175._pReal/512._pReal,575._pReal/13824._pReal,44275._pReal/110592._pReal,253._pReal/4096._pReal],& + shape(A)) + real(pReal), dimension(5), parameter :: & + C = [0.2_pReal, 0.3_pReal, 0.6_pReal, 1.0_pReal, 0.875_pReal] + real(pReal), dimension(6), parameter :: & + B = & + [37.0_pReal/378.0_pReal, .0_pReal, 250.0_pReal/621.0_pReal, & + 125.0_pReal/594.0_pReal, .0_pReal, 512.0_pReal/1771.0_pReal], & + DB = B - & + [2825.0_pReal/27648.0_pReal, .0_pReal, 18575.0_pReal/48384.0_pReal,& + 13525.0_pReal/55296.0_pReal, 277.0_pReal/14336.0_pReal, 1._pReal/4._pReal] + + call integrateStateRK(g,i,e,A,B,C,DB) + +end subroutine integrateStateRKCK45 + + +!-------------------------------------------------------------------------------------------------- +!> @brief Integrate state (including stress integration) with an explicit Runge-Kutta method or an +!! embedded explicit Runge-Kutta method +!-------------------------------------------------------------------------------------------------- +subroutine integrateStateRK(g,i,e,A,B,CC,DB) + + + real(pReal), dimension(:,:), intent(in) :: A + real(pReal), dimension(:), intent(in) :: B, CC + real(pReal), dimension(:), intent(in), optional :: DB + + integer, intent(in) :: & + e, & !< element index in element loop + i, & !< integration point index in ip loop + g !< grain index in grain loop + integer :: & + stage, & ! stage index in integration stage loop + n, & + p, & + c, & + sizeDotState + logical :: & + broken + real(pReal), dimension(constitutive_plasticity_maxSizeDotState,size(B)) :: plastic_RKdotState + + p = material_phaseAt(g,e) + c = material_phaseMemberAt(g,i,e) + + broken = constitutive_collectDotState(crystallite_S(1:3,1:3,g,i,e), & + crystallite_partitionedF0, & + crystallite_Fi(1:3,1:3,g,i,e), & + crystallite_partitionedFp0, & + crystallite_subdt(g,i,e), g,i,e,p,c) + if(broken) return + + do stage = 1,size(A,1) + sizeDotState = plasticState(p)%sizeDotState + plastic_RKdotState(1:sizeDotState,stage) = plasticState(p)%dotState(:,c) + plasticState(p)%dotState(:,c) = A(1,stage) * plastic_RKdotState(1:sizeDotState,1) + + do n = 2, stage + sizeDotState = plasticState(p)%sizeDotState + plasticState(p)%dotState(:,c) = plasticState(p)%dotState(:,c) & + + A(n,stage) * plastic_RKdotState(1:sizeDotState,n) + enddo + + sizeDotState = plasticState(p)%sizeDotState + plasticState(p)%state(1:sizeDotState,c) = plasticState(p)%subState0(1:sizeDotState,c) & + + plasticState(p)%dotState (1:sizeDotState,c) & + * crystallite_subdt(g,i,e) + + broken = integrateStress(g,i,e,CC(stage)) + if(broken) exit + + broken = constitutive_collectDotState(crystallite_S(1:3,1:3,g,i,e), & + crystallite_partitionedF0, & + crystallite_Fi(1:3,1:3,g,i,e), & + crystallite_partitionedFp0, & + crystallite_subdt(g,i,e)*CC(stage), g,i,e,p,c) + if(broken) exit + + enddo + if(broken) return + + sizeDotState = plasticState(p)%sizeDotState + + plastic_RKdotState(1:sizeDotState,size(B)) = plasticState (p)%dotState(:,c) + plasticState(p)%dotState(:,c) = matmul(plastic_RKdotState(1:sizeDotState,1:size(B)),B) + plasticState(p)%state(1:sizeDotState,c) = plasticState(p)%subState0(1:sizeDotState,c) & + + plasticState(p)%dotState (1:sizeDotState,c) & + * crystallite_subdt(g,i,e) + if(present(DB)) & + broken = .not. converged( matmul(plastic_RKdotState(1:sizeDotState,1:size(DB)),DB) & + * crystallite_subdt(g,i,e), & + plasticState(p)%state(1:sizeDotState,c), & + plasticState(p)%atol(1:sizeDotState)) + + if(broken) return + + broken = constitutive_deltaState(crystallite_S(1:3,1:3,g,i,e), & + crystallite_Fi(1:3,1:3,g,i,e),g,i,e,p,c) + if(broken) return + + broken = integrateStress(g,i,e) + crystallite_converged(g,i,e) = .not. broken + + +end subroutine integrateStateRK + + +!-------------------------------------------------------------------------------------------------- +!> @brief determines whether a point is converged +!-------------------------------------------------------------------------------------------------- +logical pure function converged(residuum,state,atol) + + real(pReal), intent(in), dimension(:) ::& + residuum, state, atol + real(pReal) :: & + rTol + + rTol = num%rTol_crystalliteState + + converged = all(abs(residuum) <= max(atol, rtol*abs(state))) + +end function converged + + +!-------------------------------------------------------------------------------------------------- +!> @brief Write current restart information (Field and constitutive data) to file. +! ToDo: Merge data into one file for MPI, move state to constitutive and homogenization, respectively +!-------------------------------------------------------------------------------------------------- +subroutine crystallite_restartWrite + + integer :: i + integer(HID_T) :: fileHandle, groupHandle + character(len=pStringLen) :: fileName, datasetName + + print*, ' writing field and constitutive data required for restart to file';flush(IO_STDOUT) + + write(fileName,'(a,i0,a)') trim(getSolverJobName())//'_',worldrank,'.hdf5' + fileHandle = HDF5_openFile(fileName,'a') + + call HDF5_write(fileHandle,crystallite_partitionedF,'F') + call HDF5_write(fileHandle,crystallite_Fp, 'F_p') + call HDF5_write(fileHandle,crystallite_Fi, 'F_i') + call HDF5_write(fileHandle,crystallite_Lp, 'L_p') + call HDF5_write(fileHandle,crystallite_Li, 'L_i') + call HDF5_write(fileHandle,crystallite_S, 'S') + + groupHandle = HDF5_addGroup(fileHandle,'phase') + do i = 1,size(material_name_phase) + write(datasetName,'(i0,a)') i,'_omega' + call HDF5_write(groupHandle,plasticState(i)%state,datasetName) + enddo + call HDF5_closeGroup(groupHandle) + + groupHandle = HDF5_addGroup(fileHandle,'homogenization') + do i = 1, size(material_name_homogenization) + write(datasetName,'(i0,a)') i,'_omega' + call HDF5_write(groupHandle,homogState(i)%state,datasetName) + enddo + call HDF5_closeGroup(groupHandle) + + call HDF5_closeFile(fileHandle) + +end subroutine crystallite_restartWrite + + +!-------------------------------------------------------------------------------------------------- +!> @brief Read data for restart +! ToDo: Merge data into one file for MPI, move state to constitutive and homogenization, respectively +!-------------------------------------------------------------------------------------------------- +subroutine crystallite_restartRead + + integer :: i + integer(HID_T) :: fileHandle, groupHandle + character(len=pStringLen) :: fileName, datasetName + + print'(/,a,i0,a)', ' reading restart information of increment from file' + + write(fileName,'(a,i0,a)') trim(getSolverJobName())//'_',worldrank,'.hdf5' + fileHandle = HDF5_openFile(fileName) + + call HDF5_read(fileHandle,crystallite_F0, 'F') + call HDF5_read(fileHandle,crystallite_Fp0,'F_p') + call HDF5_read(fileHandle,crystallite_Fi0,'F_i') + call HDF5_read(fileHandle,crystallite_Lp0,'L_p') + call HDF5_read(fileHandle,crystallite_Li0,'L_i') + call HDF5_read(fileHandle,crystallite_S0, 'S') + + groupHandle = HDF5_openGroup(fileHandle,'phase') + do i = 1,size(material_name_phase) + write(datasetName,'(i0,a)') i,'_omega' + call HDF5_read(groupHandle,plasticState(i)%state0,datasetName) + enddo + call HDF5_closeGroup(groupHandle) + + groupHandle = HDF5_openGroup(fileHandle,'homogenization') + do i = 1,size(material_name_homogenization) + write(datasetName,'(i0,a)') i,'_omega' + call HDF5_read(groupHandle,homogState(i)%state0,datasetName) + enddo + call HDF5_closeGroup(groupHandle) + + call HDF5_closeFile(fileHandle) + +end subroutine crystallite_restartRead + + +!-------------------------------------------------------------------------------------------------- +!> @brief Forward data after successful increment. +! ToDo: Any guessing for the current states possible? +!-------------------------------------------------------------------------------------------------- +subroutine crystallite_forward + + integer :: i, j + + crystallite_F0 = crystallite_partitionedF + crystallite_Fp0 = crystallite_Fp + crystallite_Lp0 = crystallite_Lp + crystallite_Fi0 = crystallite_Fi + crystallite_Li0 = crystallite_Li + crystallite_S0 = crystallite_S + + do i = 1, size(plasticState) + plasticState(i)%state0 = plasticState(i)%state + enddo + do i = 1,size(material_name_homogenization) + homogState (i)%state0 = homogState (i)%state + damageState (i)%state0 = damageState (i)%state + enddo + +end subroutine crystallite_forward + end module constitutive diff --git a/src/crystallite.f90 b/src/crystallite.f90 index 5378c4cbb..662dfa316 100644 --- a/src/crystallite.f90 +++ b/src/crystallite.f90 @@ -9,1631 +9,10 @@ !-------------------------------------------------------------------------------------------------- module crystallite - use prec - use parallelization - use IO - use HDF5_utilities - use DAMASK_interface - use config - use rotations - use math - use FEsolving - use material - use constitutive - use discretization - use lattice - use results - implicit none - private - real(pReal), dimension(:,:,:), allocatable, public :: & - crystallite_dt !< requested time increment of each grain - real(pReal), dimension(:,:,:), allocatable :: & - crystallite_subdt, & !< substepped time increment of each grain - crystallite_subFrac, & !< already calculated fraction of increment - crystallite_subStep !< size of next integration step - type(rotation), dimension(:,:,:), allocatable :: & - crystallite_orientation !< current orientation - real(pReal), dimension(:,:,:,:,:), allocatable :: & - crystallite_F0, & !< def grad at start of FE inc - crystallite_subF, & !< def grad to be reached at end of crystallite inc - crystallite_subF0, & !< def grad at start of crystallite inc - ! - crystallite_Fe, & !< current "elastic" def grad (end of converged time step) - ! - crystallite_Fp, & !< current plastic def grad (end of converged time step) - crystallite_Fp0, & !< plastic def grad at start of FE inc - crystallite_partitionedFp0,& !< plastic def grad at start of homog inc - crystallite_subFp0,& !< plastic def grad at start of crystallite inc - ! - crystallite_Fi, & !< current intermediate def grad (end of converged time step) - crystallite_Fi0, & !< intermediate def grad at start of FE inc - crystallite_partitionedFi0,& !< intermediate def grad at start of homog inc - crystallite_subFi0,& !< intermediate def grad at start of crystallite inc - ! - crystallite_Lp0, & !< plastic velocitiy grad at start of FE inc - crystallite_partitionedLp0, & !< plastic velocity grad at start of homog inc - ! - crystallite_Li, & !< current intermediate velocitiy grad (end of converged time step) - crystallite_Li0, & !< intermediate velocitiy grad at start of FE inc - crystallite_partitionedLi0, & !< intermediate velocity grad at start of homog inc - ! - crystallite_S0, & !< 2nd Piola-Kirchhoff stress vector at start of FE inc - crystallite_partitionedS0 !< 2nd Piola-Kirchhoff stress vector at start of homog inc - real(pReal), dimension(:,:,:,:,:), allocatable, public, protected :: & - crystallite_P, & !< 1st Piola-Kirchhoff stress per grain - crystallite_Lp, & !< current plastic velocitiy grad (end of converged time step) - crystallite_S, & !< current 2nd Piola-Kirchhoff stress vector (end of converged time step) - crystallite_partitionedF0 !< def grad at start of homog inc - real(pReal), dimension(:,:,:,:,:), allocatable, public :: & - crystallite_partitionedF !< def grad to be reached at end of homog inc - logical, dimension(:,:,:), allocatable, public :: & - crystallite_requested !< used by upper level (homogenization) to request crystallite calculation - logical, dimension(:,:,:), allocatable :: & - crystallite_converged !< convergence flag - type :: tOutput !< new requested output (per phase) - character(len=pStringLen), allocatable, dimension(:) :: & - label - end type tOutput - type(tOutput), allocatable, dimension(:) :: output_constituent - type :: tNumerics - integer :: & - iJacoLpresiduum, & !< frequency of Jacobian update of residuum in Lp - nState, & !< state loop limit - nStress !< stress loop limit - real(pReal) :: & - subStepMinCryst, & !< minimum (relative) size of sub-step allowed during cutback - subStepSizeCryst, & !< size of first substep when cutback - subStepSizeLp, & !< size of first substep when cutback in Lp calculation - subStepSizeLi, & !< size of first substep when cutback in Li calculation - stepIncreaseCryst, & !< increase of next substep size when previous substep converged - rtol_crystalliteState, & !< relative tolerance in state loop - rtol_crystalliteStress, & !< relative tolerance in stress loop - atol_crystalliteStress !< absolute tolerance in stress loop - end type tNumerics - - type(tNumerics) :: num ! numerics parameters. Better name? - - type :: tDebugOptions - logical :: & - basic, & - extensive, & - selective - integer :: & - element, & - ip, & - grain - end type tDebugOptions - - type(tDebugOptions) :: debugCrystallite - - procedure(integrateStateFPI), pointer :: integrateState - - public :: & - crystallite_init, & - crystallite_stress, & - crystallite_stressTangent, & - crystallite_orientations, & - crystallite_push33ToRef, & - crystallite_results, & - crystallite_restartWrite, & - crystallite_restartRead, & - crystallite_forward, & - crystallite_initializeRestorationPoints, & - crystallite_windForward, & - crystallite_restore - -contains - - -!-------------------------------------------------------------------------------------------------- -!> @brief allocates and initialize per grain variables -!-------------------------------------------------------------------------------------------------- -subroutine crystallite_init - - integer :: & - p, & - c, & !< counter in integration point component loop - i, & !< counter in integration point loop - e, & !< counter in element loop - cMax, & !< maximum number of integration point components - iMax, & !< maximum number of integration points - eMax !< maximum number of elements - - - class(tNode), pointer :: & - num_crystallite, & - debug_crystallite, & ! pointer to debug options for crystallite - phases, & - phase, & - mech - - print'(/,a)', ' <<<+- crystallite init -+>>>' - - debug_crystallite => config_debug%get('crystallite', defaultVal=emptyList) - debugCrystallite%basic = debug_crystallite%contains('basic') - debugCrystallite%extensive = debug_crystallite%contains('extensive') - debugCrystallite%selective = debug_crystallite%contains('selective') - debugCrystallite%element = config_debug%get_asInt('element', defaultVal=1) - debugCrystallite%ip = config_debug%get_asInt('integrationpoint', defaultVal=1) - debugCrystallite%grain = config_debug%get_asInt('grain', defaultVal=1) - - cMax = homogenization_maxNconstituents - iMax = discretization_nIPs - eMax = discretization_Nelems - - allocate(crystallite_partitionedF(3,3,cMax,iMax,eMax),source=0.0_pReal) - - allocate(crystallite_S0, & - crystallite_F0, crystallite_Fi0,crystallite_Fp0, & - crystallite_Li0,crystallite_Lp0, & - crystallite_partitionedS0, & - crystallite_partitionedF0,crystallite_partitionedFp0,crystallite_partitionedFi0, & - crystallite_partitionedLp0,crystallite_partitionedLi0, & - crystallite_S,crystallite_P, & - crystallite_Fe,crystallite_Fi,crystallite_Fp, & - crystallite_Li,crystallite_Lp, & - crystallite_subF,crystallite_subF0, & - crystallite_subFp0,crystallite_subFi0, & - source = crystallite_partitionedF) - - allocate(crystallite_dt(cMax,iMax,eMax),source=0.0_pReal) - allocate(crystallite_subdt,crystallite_subFrac,crystallite_subStep, & - source = crystallite_dt) - - allocate(crystallite_orientation(cMax,iMax,eMax)) - - allocate(crystallite_requested(cMax,iMax,eMax), source=.false.) - allocate(crystallite_converged(cMax,iMax,eMax), source=.true.) - - num_crystallite => config_numerics%get('crystallite',defaultVal=emptyDict) - - num%subStepMinCryst = num_crystallite%get_asFloat ('subStepMin', defaultVal=1.0e-3_pReal) - num%subStepSizeCryst = num_crystallite%get_asFloat ('subStepSize', defaultVal=0.25_pReal) - num%stepIncreaseCryst = num_crystallite%get_asFloat ('stepIncrease', defaultVal=1.5_pReal) - num%subStepSizeLp = num_crystallite%get_asFloat ('subStepSizeLp', defaultVal=0.5_pReal) - num%subStepSizeLi = num_crystallite%get_asFloat ('subStepSizeLi', defaultVal=0.5_pReal) - num%rtol_crystalliteState = num_crystallite%get_asFloat ('rtol_State', defaultVal=1.0e-6_pReal) - num%rtol_crystalliteStress = num_crystallite%get_asFloat ('rtol_Stress', defaultVal=1.0e-6_pReal) - num%atol_crystalliteStress = num_crystallite%get_asFloat ('atol_Stress', defaultVal=1.0e-8_pReal) - num%iJacoLpresiduum = num_crystallite%get_asInt ('iJacoLpresiduum', defaultVal=1) - num%nState = num_crystallite%get_asInt ('nState', defaultVal=20) - num%nStress = num_crystallite%get_asInt ('nStress', defaultVal=40) - - if(num%subStepMinCryst <= 0.0_pReal) call IO_error(301,ext_msg='subStepMinCryst') - if(num%subStepSizeCryst <= 0.0_pReal) call IO_error(301,ext_msg='subStepSizeCryst') - if(num%stepIncreaseCryst <= 0.0_pReal) call IO_error(301,ext_msg='stepIncreaseCryst') - - if(num%subStepSizeLp <= 0.0_pReal) call IO_error(301,ext_msg='subStepSizeLp') - if(num%subStepSizeLi <= 0.0_pReal) call IO_error(301,ext_msg='subStepSizeLi') - - if(num%rtol_crystalliteState <= 0.0_pReal) call IO_error(301,ext_msg='rtol_crystalliteState') - if(num%rtol_crystalliteStress <= 0.0_pReal) call IO_error(301,ext_msg='rtol_crystalliteStress') - if(num%atol_crystalliteStress <= 0.0_pReal) call IO_error(301,ext_msg='atol_crystalliteStress') - - if(num%iJacoLpresiduum < 1) call IO_error(301,ext_msg='iJacoLpresiduum') - - if(num%nState < 1) call IO_error(301,ext_msg='nState') - if(num%nStress< 1) call IO_error(301,ext_msg='nStress') - - select case(num_crystallite%get_asString('integrator',defaultVal='FPI')) - case('FPI') - integrateState => integrateStateFPI - case('Euler') - integrateState => integrateStateEuler - case('AdaptiveEuler') - integrateState => integrateStateAdaptiveEuler - case('RK4') - integrateState => integrateStateRK4 - case('RKCK45') - integrateState => integrateStateRKCK45 - case default - call IO_error(301,ext_msg='integrator') - end select - - phases => config_material%get('phase') - - allocate(output_constituent(phases%length)) - do p = 1, phases%length - phase => phases%get(p) - mech => phase%get('mechanics',defaultVal = emptyDict) -#if defined(__GFORTRAN__) - output_constituent(p)%label = output_asStrings(mech) -#else - output_constituent(p)%label = mech%get_asStrings('output',defaultVal=emptyStringArray) -#endif - enddo - -#ifdef DEBUG - if (debugCrystallite%basic) then - print'(a42,1x,i10)', ' # of elements: ', eMax - print'(a42,1x,i10)', ' # of integration points/element: ', iMax - print'(a42,1x,i10)', 'max # of constituents/integration point: ', cMax - flush(IO_STDOUT) - endif -#endif - - !$OMP PARALLEL DO PRIVATE(i,c) - do e = FEsolving_execElem(1),FEsolving_execElem(2) - do i = FEsolving_execIP(1), FEsolving_execIP(2); do c = 1, homogenization_Nconstituents(material_homogenizationAt(e)) - crystallite_Fp0(1:3,1:3,c,i,e) = material_orientation0(c,i,e)%asMatrix() ! Fp reflects initial orientation (see 10.1016/j.actamat.2006.01.005) - crystallite_Fp0(1:3,1:3,c,i,e) = crystallite_Fp0(1:3,1:3,c,i,e) & - / math_det33(crystallite_Fp0(1:3,1:3,c,i,e))**(1.0_pReal/3.0_pReal) - crystallite_Fi0(1:3,1:3,c,i,e) = math_I3 - crystallite_F0(1:3,1:3,c,i,e) = math_I3 - crystallite_Fe(1:3,1:3,c,i,e) = math_inv33(matmul(crystallite_Fi0(1:3,1:3,c,i,e), & - crystallite_Fp0(1:3,1:3,c,i,e))) ! assuming that euler angles are given in internal strain free configuration - crystallite_Fp(1:3,1:3,c,i,e) = crystallite_Fp0(1:3,1:3,c,i,e) - crystallite_Fi(1:3,1:3,c,i,e) = crystallite_Fi0(1:3,1:3,c,i,e) - crystallite_requested(c,i,e) = .true. - enddo; enddo - enddo - !$OMP END PARALLEL DO - - - crystallite_partitionedFp0 = crystallite_Fp0 - crystallite_partitionedFi0 = crystallite_Fi0 - crystallite_partitionedF0 = crystallite_F0 - crystallite_partitionedF = crystallite_F0 - - call crystallite_orientations() - - !$OMP PARALLEL DO - do e = FEsolving_execElem(1),FEsolving_execElem(2) - do i = FEsolving_execIP(1),FEsolving_execIP(2) - do c = 1,homogenization_Nconstituents(material_homogenizationAt(e)) - call constitutive_dependentState(crystallite_partitionedF0(1:3,1:3,c,i,e), & - crystallite_partitionedFp0(1:3,1:3,c,i,e), & - c,i,e) ! update dependent state variables to be consistent with basic states - enddo - enddo - enddo - !$OMP END PARALLEL DO - - -end subroutine crystallite_init - - -!-------------------------------------------------------------------------------------------------- -!> @brief calculate stress (P) -!-------------------------------------------------------------------------------------------------- -function crystallite_stress() - - logical, dimension(discretization_nIPs,discretization_Nelems) :: crystallite_stress - real(pReal) :: & - formerSubStep - integer :: & - NiterationCrystallite, & ! number of iterations in crystallite loop - c, & !< counter in integration point component loop - i, & !< counter in integration point loop - e, & !< counter in element loop - s - logical, dimension(homogenization_maxNconstituents,discretization_nIPs,discretization_Nelems) :: todo !ToDo: need to set some values to false for different Ngrains - real(pReal), dimension(:,:,:,:,:), allocatable :: & - subLp0,& !< plastic velocity grad at start of crystallite inc - subLi0 !< intermediate velocity grad at start of crystallite inc - - todo = .false. - - subLp0 = crystallite_partitionedLp0 - subLi0 = crystallite_partitionedLi0 - -!-------------------------------------------------------------------------------------------------- -! initialize to starting condition - crystallite_subStep = 0.0_pReal - !$OMP PARALLEL DO - elementLooping1: do e = FEsolving_execElem(1),FEsolving_execElem(2) - do i = FEsolving_execIP(1),FEsolving_execIP(2); do c = 1,homogenization_Nconstituents(material_homogenizationAt(e)) - homogenizationRequestsCalculation: if (crystallite_requested(c,i,e)) then - plasticState (material_phaseAt(c,e))%subState0( :,material_phaseMemberAt(c,i,e)) = & - plasticState (material_phaseAt(c,e))%partitionedState0(:,material_phaseMemberAt(c,i,e)) - - do s = 1, phase_Nsources(material_phaseAt(c,e)) - sourceState(material_phaseAt(c,e))%p(s)%subState0( :,material_phaseMemberAt(c,i,e)) = & - sourceState(material_phaseAt(c,e))%p(s)%partitionedState0(:,material_phaseMemberAt(c,i,e)) - enddo - crystallite_subFp0(1:3,1:3,c,i,e) = crystallite_partitionedFp0(1:3,1:3,c,i,e) - crystallite_subFi0(1:3,1:3,c,i,e) = crystallite_partitionedFi0(1:3,1:3,c,i,e) - crystallite_subF0(1:3,1:3,c,i,e) = crystallite_partitionedF0(1:3,1:3,c,i,e) - crystallite_subFrac(c,i,e) = 0.0_pReal - crystallite_subStep(c,i,e) = 1.0_pReal/num%subStepSizeCryst - todo(c,i,e) = .true. - crystallite_converged(c,i,e) = .false. ! pretend failed step of 1/subStepSizeCryst - endif homogenizationRequestsCalculation - enddo; enddo - enddo elementLooping1 - !$OMP END PARALLEL DO - - NiterationCrystallite = 0 - cutbackLooping: do while (any(todo(:,FEsolving_execIP(1):FEsolving_execIP(2),FEsolving_execELem(1):FEsolving_execElem(2)))) - NiterationCrystallite = NiterationCrystallite + 1 - -#ifdef DEBUG - if (debugCrystallite%extensive) & - print'(a,i6)', '<< CRYST stress >> crystallite iteration ',NiterationCrystallite -#endif - !$OMP PARALLEL DO PRIVATE(formerSubStep) - elementLooping3: do e = FEsolving_execElem(1),FEsolving_execElem(2) - do i = FEsolving_execIP(1),FEsolving_execIP(2) - do c = 1,homogenization_Nconstituents(material_homogenizationAt(e)) -!-------------------------------------------------------------------------------------------------- -! wind forward - if (crystallite_converged(c,i,e)) then - formerSubStep = crystallite_subStep(c,i,e) - crystallite_subFrac(c,i,e) = crystallite_subFrac(c,i,e) + crystallite_subStep(c,i,e) - crystallite_subStep(c,i,e) = min(1.0_pReal - crystallite_subFrac(c,i,e), & - num%stepIncreaseCryst * crystallite_subStep(c,i,e)) - - todo(c,i,e) = crystallite_subStep(c,i,e) > 0.0_pReal ! still time left to integrate on? - if (todo(c,i,e)) then - crystallite_subF0 (1:3,1:3,c,i,e) = crystallite_subF(1:3,1:3,c,i,e) - subLp0(1:3,1:3,c,i,e) = crystallite_Lp (1:3,1:3,c,i,e) - subLi0(1:3,1:3,c,i,e) = crystallite_Li (1:3,1:3,c,i,e) - crystallite_subFp0(1:3,1:3,c,i,e) = crystallite_Fp (1:3,1:3,c,i,e) - crystallite_subFi0(1:3,1:3,c,i,e) = crystallite_Fi (1:3,1:3,c,i,e) - plasticState( material_phaseAt(c,e))%subState0(:,material_phaseMemberAt(c,i,e)) & - = plasticState(material_phaseAt(c,e))%state( :,material_phaseMemberAt(c,i,e)) - do s = 1, phase_Nsources(material_phaseAt(c,e)) - sourceState( material_phaseAt(c,e))%p(s)%subState0(:,material_phaseMemberAt(c,i,e)) & - = sourceState(material_phaseAt(c,e))%p(s)%state( :,material_phaseMemberAt(c,i,e)) - enddo - endif - -!-------------------------------------------------------------------------------------------------- -! cut back (reduced time and restore) - else - 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_Fi (1:3,1:3,c,i,e) = crystallite_subFi0(1:3,1:3,c,i,e) - crystallite_S (1:3,1:3,c,i,e) = crystallite_S0 (1:3,1:3,c,i,e) - if (crystallite_subStep(c,i,e) < 1.0_pReal) then ! actual (not initial) cutback - crystallite_Lp (1:3,1:3,c,i,e) = subLp0(1:3,1:3,c,i,e) - crystallite_Li (1:3,1:3,c,i,e) = subLi0(1:3,1:3,c,i,e) - endif - plasticState (material_phaseAt(c,e))%state( :,material_phaseMemberAt(c,i,e)) & - = plasticState(material_phaseAt(c,e))%subState0(:,material_phaseMemberAt(c,i,e)) - do s = 1, phase_Nsources(material_phaseAt(c,e)) - sourceState( material_phaseAt(c,e))%p(s)%state( :,material_phaseMemberAt(c,i,e)) & - = sourceState(material_phaseAt(c,e))%p(s)%subState0(:,material_phaseMemberAt(c,i,e)) - enddo - - ! cant restore dotState here, since not yet calculated in first cutback after initialization - todo(c,i,e) = crystallite_subStep(c,i,e) > num%subStepMinCryst ! still on track or already done (beyond repair) - endif - -!-------------------------------------------------------------------------------------------------- -! prepare for integration - if (todo(c,i,e)) then - crystallite_subF(1:3,1:3,c,i,e) = crystallite_subF0(1:3,1:3,c,i,e) & - + crystallite_subStep(c,i,e) *( crystallite_partitionedF (1:3,1:3,c,i,e) & - -crystallite_partitionedF0(1:3,1:3,c,i,e)) - crystallite_Fe(1:3,1:3,c,i,e) = matmul(crystallite_subF(1:3,1:3,c,i,e), & - math_inv33(matmul(crystallite_Fi(1:3,1:3,c,i,e), & - crystallite_Fp(1:3,1:3,c,i,e)))) - crystallite_subdt(c,i,e) = crystallite_subStep(c,i,e) * crystallite_dt(c,i,e) - crystallite_converged(c,i,e) = .false. - call integrateState(c,i,e) - call integrateSourceState(c,i,e) - endif - - enddo - enddo - enddo elementLooping3 - !$OMP END PARALLEL DO - -!-------------------------------------------------------------------------------------------------- -! integrate --- requires fully defined state array (basic + dependent state) - where(.not. crystallite_converged .and. crystallite_subStep > num%subStepMinCryst) & ! do not try non-converged but fully cutbacked any further - todo = .true. ! TODO: again unroll this into proper elementloop to avoid N^2 for single point evaluation - enddo cutbackLooping - -! return whether converged or not - crystallite_stress = .false. - elementLooping5: do e = FEsolving_execElem(1),FEsolving_execElem(2) - do i = FEsolving_execIP(1),FEsolving_execIP(2) - crystallite_stress(i,e) = all(crystallite_converged(:,i,e)) - enddo - enddo elementLooping5 - -end function crystallite_stress - - -!-------------------------------------------------------------------------------------------------- -!> @brief Backup data for homog cutback. -!-------------------------------------------------------------------------------------------------- -subroutine crystallite_initializeRestorationPoints(i,e) - - integer, intent(in) :: & - i, & !< integration point number - e !< element number - integer :: & - c, & !< constituent number - s - - do c = 1,homogenization_Nconstituents(material_homogenizationAt(e)) - crystallite_partitionedFp0(1:3,1:3,c,i,e) = crystallite_Fp0(1:3,1:3,c,i,e) - crystallite_partitionedLp0(1:3,1:3,c,i,e) = crystallite_Lp0(1:3,1:3,c,i,e) - crystallite_partitionedFi0(1:3,1:3,c,i,e) = crystallite_Fi0(1:3,1:3,c,i,e) - crystallite_partitionedLi0(1:3,1:3,c,i,e) = crystallite_Li0(1:3,1:3,c,i,e) - crystallite_partitionedF0(1:3,1:3,c,i,e) = crystallite_F0(1:3,1:3,c,i,e) - crystallite_partitionedS0(1:3,1:3,c,i,e) = crystallite_S0(1:3,1:3,c,i,e) - - plasticState(material_phaseAt(c,e))%partitionedState0(:,material_phasememberAt(c,i,e)) = & - plasticState(material_phaseAt(c,e))%state0( :,material_phasememberAt(c,i,e)) - do s = 1, phase_Nsources(material_phaseAt(c,e)) - sourceState(material_phaseAt(c,e))%p(s)%partitionedState0(:,material_phasememberAt(c,i,e)) = & - sourceState(material_phaseAt(c,e))%p(s)%state0( :,material_phasememberAt(c,i,e)) - enddo - enddo - -end subroutine crystallite_initializeRestorationPoints - - -!-------------------------------------------------------------------------------------------------- -!> @brief Wind homog inc forward. -!-------------------------------------------------------------------------------------------------- -subroutine crystallite_windForward(i,e) - - integer, intent(in) :: & - i, & !< integration point number - e !< element number - integer :: & - c, & !< constituent number - s - - do c = 1,homogenization_Nconstituents(material_homogenizationAt(e)) - crystallite_partitionedF0 (1:3,1:3,c,i,e) = crystallite_partitionedF(1:3,1:3,c,i,e) - crystallite_partitionedFp0(1:3,1:3,c,i,e) = crystallite_Fp (1:3,1:3,c,i,e) - crystallite_partitionedLp0(1:3,1:3,c,i,e) = crystallite_Lp (1:3,1:3,c,i,e) - crystallite_partitionedFi0(1:3,1:3,c,i,e) = crystallite_Fi (1:3,1:3,c,i,e) - crystallite_partitionedLi0(1:3,1:3,c,i,e) = crystallite_Li (1:3,1:3,c,i,e) - crystallite_partitionedS0 (1:3,1:3,c,i,e) = crystallite_S (1:3,1:3,c,i,e) - - plasticState (material_phaseAt(c,e))%partitionedState0(:,material_phasememberAt(c,i,e)) = & - plasticState (material_phaseAt(c,e))%state (:,material_phasememberAt(c,i,e)) - do s = 1, phase_Nsources(material_phaseAt(c,e)) - sourceState(material_phaseAt(c,e))%p(s)%partitionedState0(:,material_phasememberAt(c,i,e)) = & - sourceState(material_phaseAt(c,e))%p(s)%state (:,material_phasememberAt(c,i,e)) - enddo - enddo - -end subroutine crystallite_windForward - - -!-------------------------------------------------------------------------------------------------- -!> @brief Restore data after homog cutback. -!-------------------------------------------------------------------------------------------------- -subroutine crystallite_restore(i,e,includeL) - - integer, intent(in) :: & - i, & !< integration point number - e !< element number - logical, intent(in) :: & - includeL !< protect agains fake cutback - integer :: & - c !< constituent number - - do c = 1,homogenization_Nconstituents(material_homogenizationAt(e)) - if (includeL) then - crystallite_Lp(1:3,1:3,c,i,e) = crystallite_partitionedLp0(1:3,1:3,c,i,e) - crystallite_Li(1:3,1:3,c,i,e) = crystallite_partitionedLi0(1:3,1:3,c,i,e) - endif ! maybe protecting everything from overwriting makes more sense - crystallite_Fp(1:3,1:3,c,i,e) = crystallite_partitionedFp0(1:3,1:3,c,i,e) - crystallite_Fi(1:3,1:3,c,i,e) = crystallite_partitionedFi0(1:3,1:3,c,i,e) - crystallite_S (1:3,1:3,c,i,e) = crystallite_partitionedS0 (1:3,1:3,c,i,e) - - plasticState (material_phaseAt(c,e))%state( :,material_phasememberAt(c,i,e)) = & - plasticState (material_phaseAt(c,e))%partitionedState0(:,material_phasememberAt(c,i,e)) - enddo - -end subroutine crystallite_restore - - -!-------------------------------------------------------------------------------------------------- -!> @brief Calculate tangent (dPdF). -!-------------------------------------------------------------------------------------------------- -function crystallite_stressTangent(c,i,e) result(dPdF) - - real(pReal), dimension(3,3,3,3) :: dPdF - integer, intent(in) :: & - c, & !< counter in constituent loop - i, & !< counter in integration point loop - e !< counter in element loop - integer :: & - o, & - p - - 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, & - dSdF, & - dSdFi, & - dLidS, & ! tangent in lattice configuration - dLidFi, & - dLpdS, & - dLpdFi, & - dFidS, & - dFpinvdF, & - rhs_3333, & - lhs_3333, & - temp_3333 - real(pReal), dimension(9,9):: temp_99 - logical :: error - - - call constitutive_SandItsTangents(devNull,dSdFe,dSdFi, & - crystallite_Fe(1:3,1:3,c,i,e), & - crystallite_Fi(1:3,1:3,c,i,e),c,i,e) - call constitutive_LiAndItsTangents(devNull,dLidS,dLidFi, & - crystallite_S (1:3,1:3,c,i,e), & - crystallite_Fi(1:3,1:3,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 - dFidS = 0.0_pReal - else - lhs_3333 = 0.0_pReal; rhs_3333 = 0.0_pReal - do o=1,3; do p=1,3 - 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)) - lhs_3333(1:3,o,1:3,p) = lhs_3333(1:3,o,1:3,p) & - + invFi*invFi(p,o) - 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)) - enddo; enddo - call math_invert(temp_99,error,math_3333to99(lhs_3333)) - if (error) then - call IO_warning(warning_ID=600,el=e,ip=i,g=c, & - ext_msg='inversion error in analytic tangent calculation') - dFidS = 0.0_pReal - else - dFidS = math_mul3333xx3333(math_99to3333(temp_99),rhs_3333) - endif - dLidS = math_mul3333xx3333(dLidFi,dFidS) + dLidS - endif - - call constitutive_LpAndItsTangents(devNull,dLpdS,dLpdFi, & - crystallite_S (1:3,1:3,c,i,e), & - crystallite_Fi(1:3,1:3,c,i,e),c,i,e) ! call constitutive law to calculate Lp tangent in lattice configuration - dLpdS = math_mul3333xx3333(dLpdFi,dFidS) + dLpdS - -!-------------------------------------------------------------------------------------------------- -! calculate dSdF - temp_33_1 = transpose(matmul(invFp,invFi)) - temp_33_2 = matmul(crystallite_subF(1:3,1:3,c,i,e),invSubFp0) - temp_33_3 = matmul(matmul(crystallite_subF(1:3,1:3,c,i,e),invFp), invSubFi0) - - 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) - temp_3333(1:3,1:3,p,o) = matmul(matmul(temp_33_2,dLpdS(1:3,1:3,p,o)), invFi) & - + matmul(temp_33_3,dLidS(1:3,1:3,p,o)) - enddo; enddo - lhs_3333 = crystallite_subdt(c,i,e)*math_mul3333xx3333(dSdFe,temp_3333) & - + math_mul3333xx3333(dSdFi,dFidS) - - call math_invert(temp_99,error,math_eye(9)+math_3333to99(lhs_3333)) - if (error) then - call IO_warning(warning_ID=600,el=e,ip=i,g=c, & - ext_msg='inversion error in analytic tangent calculation') - dSdF = rhs_3333 - else - dSdF = math_mul3333xx3333(math_99to3333(temp_99),rhs_3333) - endif - -!-------------------------------------------------------------------------------------------------- -! calculate dFpinvdF - temp_3333 = math_mul3333xx3333(dLpdS,dSdF) - do o=1,3; do p=1,3 - dFpinvdF(1:3,1:3,p,o) = -crystallite_subdt(c,i,e) & - * matmul(invSubFp0, matmul(temp_3333(1:3,1:3,p,o),invFi)) - enddo; enddo - -!-------------------------------------------------------------------------------------------------- -! assemble dPdF - temp_33_1 = matmul(crystallite_S(1:3,1:3,c,i,e),transpose(invFp)) - temp_33_2 = matmul(invFp,temp_33_1) - 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)) - - dPdF = 0.0_pReal - do p=1,3 - dPdF(p,1:3,p,1:3) = transpose(temp_33_2) - enddo - do o=1,3; do p=1,3 - dPdF(1:3,1:3,p,o) = dPdF(1:3,1:3,p,o) & - + matmul(matmul(crystallite_subF(1:3,1:3,c,i,e), & - dFpinvdF(1:3,1:3,p,o)),temp_33_1) & - + matmul(matmul(temp_33_3,dSdF(1:3,1:3,p,o)), & - transpose(invFp)) & - + matmul(temp_33_4,transpose(dFpinvdF(1:3,1:3,p,o))) - enddo; enddo - -end function crystallite_stressTangent - - -!-------------------------------------------------------------------------------------------------- -!> @brief calculates orientations -!-------------------------------------------------------------------------------------------------- -subroutine crystallite_orientations - - integer & - c, & !< counter in integration point component loop - i, & !< counter in integration point loop - e !< counter in element loop - - !$OMP PARALLEL DO - do e = FEsolving_execElem(1),FEsolving_execElem(2) - do i = FEsolving_execIP(1),FEsolving_execIP(2) - do c = 1,homogenization_Nconstituents(material_homogenizationAt(e)) - call crystallite_orientation(c,i,e)%fromMatrix(transpose(math_rotationalPart(crystallite_Fe(1:3,1:3,c,i,e)))) - enddo; enddo; enddo - !$OMP END PARALLEL DO - - nonlocalPresent: if (any(plasticState%nonlocal)) then - !$OMP PARALLEL DO - do e = FEsolving_execElem(1),FEsolving_execElem(2) - if (plasticState(material_phaseAt(1,e))%nonlocal) then - do i = FEsolving_execIP(1),FEsolving_execIP(2) - call plastic_nonlocal_updateCompatibility(crystallite_orientation, & - phase_plasticityInstance(material_phaseAt(1,e)),i,e) - enddo - endif - enddo - !$OMP END PARALLEL DO - endif nonlocalPresent - -end subroutine crystallite_orientations - - -!-------------------------------------------------------------------------------------------------- -!> @brief Map 2nd order tensor to reference config -!-------------------------------------------------------------------------------------------------- -function crystallite_push33ToRef(ipc,ip,el, tensor33) - - real(pReal), dimension(3,3) :: crystallite_push33ToRef - real(pReal), dimension(3,3), intent(in) :: tensor33 - real(pReal), dimension(3,3) :: T - integer, intent(in):: & - el, & - ip, & - ipc - - T = matmul(material_orientation0(ipc,ip,el)%asMatrix(), & ! ToDo: initial orientation correct? - transpose(math_inv33(crystallite_subF(1:3,1:3,ipc,ip,el)))) - crystallite_push33ToRef = matmul(transpose(T),matmul(tensor33,T)) - -end function crystallite_push33ToRef - - -!-------------------------------------------------------------------------------------------------- -!> @brief writes crystallite results to HDF5 output file -!-------------------------------------------------------------------------------------------------- -subroutine crystallite_results - - integer :: p,o - real(pReal), allocatable, dimension(:,:,:) :: selected_tensors - real(pReal), allocatable, dimension(:,:) :: selected_rotations - character(len=:), allocatable :: group,structureLabel - - do p=1,size(material_name_phase) - group = trim('current/phase')//'/'//trim(material_name_phase(p))//'/mechanics' - - call results_closeGroup(results_addGroup(group)) - - do o = 1, size(output_constituent(p)%label) - select case (output_constituent(p)%label(o)) - case('F') - selected_tensors = select_tensors(crystallite_partitionedF,p) - call results_writeDataset(group,selected_tensors,output_constituent(p)%label(o),& - 'deformation gradient','1') - case('F_e') - selected_tensors = select_tensors(crystallite_Fe,p) - call results_writeDataset(group,selected_tensors,output_constituent(p)%label(o),& - 'elastic deformation gradient','1') - case('F_p') - selected_tensors = select_tensors(crystallite_Fp,p) - call results_writeDataset(group,selected_tensors,output_constituent(p)%label(o),& - 'plastic deformation gradient','1') - case('F_i') - selected_tensors = select_tensors(crystallite_Fi,p) - call results_writeDataset(group,selected_tensors,output_constituent(p)%label(o),& - 'inelastic deformation gradient','1') - case('L_p') - selected_tensors = select_tensors(crystallite_Lp,p) - call results_writeDataset(group,selected_tensors,output_constituent(p)%label(o),& - 'plastic velocity gradient','1/s') - case('L_i') - selected_tensors = select_tensors(crystallite_Li,p) - call results_writeDataset(group,selected_tensors,output_constituent(p)%label(o),& - 'inelastic velocity gradient','1/s') - case('P') - selected_tensors = select_tensors(crystallite_P,p) - call results_writeDataset(group,selected_tensors,output_constituent(p)%label(o),& - 'First Piola-Kirchhoff stress','Pa') - case('S') - selected_tensors = select_tensors(crystallite_S,p) - call results_writeDataset(group,selected_tensors,output_constituent(p)%label(o),& - 'Second Piola-Kirchhoff stress','Pa') - case('O') - select case(lattice_structure(p)) - case(lattice_ISO_ID) - structureLabel = 'aP' - case(lattice_FCC_ID) - structureLabel = 'cF' - case(lattice_BCC_ID) - structureLabel = 'cI' - case(lattice_BCT_ID) - structureLabel = 'tI' - case(lattice_HEX_ID) - structureLabel = 'hP' - case(lattice_ORT_ID) - structureLabel = 'oP' - end select - selected_rotations = select_rotations(crystallite_orientation,p) - call results_writeDataset(group,selected_rotations,output_constituent(p)%label(o),& - 'crystal orientation as quaternion','q_0 ') - call results_addAttribute('Lattice',structureLabel,group//'/'//output_constituent(p)%label(o)) - end select - enddo - enddo - - contains - - !------------------------------------------------------------------------------------------------ - !> @brief select tensors for output - !------------------------------------------------------------------------------------------------ - function select_tensors(dataset,instance) - - integer, intent(in) :: instance - real(pReal), dimension(:,:,:,:,:), intent(in) :: dataset - real(pReal), allocatable, dimension(:,:,:) :: select_tensors - integer :: e,i,c,j - - allocate(select_tensors(3,3,count(material_phaseAt==instance)*discretization_nIPs)) - - j=0 - do e = 1, size(material_phaseAt,2) - do i = 1, discretization_nIPs - do c = 1, size(material_phaseAt,1) !ToDo: this needs to be changed for varying Ngrains - if (material_phaseAt(c,e) == instance) then - j = j + 1 - select_tensors(1:3,1:3,j) = dataset(1:3,1:3,c,i,e) - endif - enddo - enddo - enddo - - end function select_tensors - - -!-------------------------------------------------------------------------------------------------- -!> @brief select rotations for output -!-------------------------------------------------------------------------------------------------- - function select_rotations(dataset,instance) - - integer, intent(in) :: instance - type(rotation), dimension(:,:,:), intent(in) :: dataset - real(pReal), allocatable, dimension(:,:) :: select_rotations - integer :: e,i,c,j - - allocate(select_rotations(4,count(material_phaseAt==instance)*homogenization_maxNconstituents*discretization_nIPs)) - - j=0 - do e = 1, size(material_phaseAt,2) - do i = 1, discretization_nIPs - do c = 1, size(material_phaseAt,1) !ToDo: this needs to be changed for varying Ngrains - if (material_phaseAt(c,e) == instance) then - j = j + 1 - select_rotations(1:4,j) = dataset(c,i,e)%asQuaternion() - endif - enddo - enddo - enddo - - end function select_rotations - -end subroutine crystallite_results - - -!-------------------------------------------------------------------------------------------------- -!> @brief calculation of stress (P) with time integration based on a residuum in Lp and -!> intermediate acceleration of the Newton-Raphson correction -!-------------------------------------------------------------------------------------------------- -function integrateStress(ipc,ip,el,timeFraction) result(broken) - - integer, intent(in):: el, & ! element index - ip, & ! integration point index - ipc ! grain index - real(pReal), optional, intent(in) :: timeFraction ! fraction of timestep - - real(pReal), dimension(3,3):: F, & ! deformation gradient at end of timestep - Fp_new, & ! plastic deformation gradient at end of timestep - invFp_new, & ! inverse of Fp_new - invFp_current, & ! inverse of Fp_current - Lpguess, & ! current guess for plastic velocity gradient - Lpguess_old, & ! known last good guess for plastic velocity gradient - Lp_constitutive, & ! plastic velocity gradient resulting from constitutive law - residuumLp, & ! current residuum of plastic velocity gradient - residuumLp_old, & ! last residuum of plastic velocity gradient - 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_old, & ! known last good guess for intermediate velocity gradient - Li_constitutive, & ! intermediate velocity gradient resulting from constitutive law - residuumLi, & ! current residuum of intermediate velocity gradient - residuumLi_old, & ! last residuum of intermediate velocity gradient - deltaLi, & ! direction of next guess - Fe, & ! elastic deformation gradient - S, & ! 2nd Piola-Kirchhoff Stress in plastic (lattice) configuration - A, & - B, & - temp_33 - real(pReal), dimension(9) :: temp_9 ! needed for matrix inversion by LAPACK - integer, dimension(9) :: devNull_9 ! needed for matrix inversion by LAPACK - real(pReal), dimension(9,9) :: dRLp_dLp, & ! partial derivative of residuum (Jacobian for Newton-Raphson scheme) - dRLi_dLi ! partial derivative of residuumI (Jacobian for Newton-Raphson scheme) - real(pReal), dimension(3,3,3,3):: dS_dFe, & ! partial derivative of 2nd Piola-Kirchhoff stress - dS_dFi, & - dFe_dLp, & ! partial derivative of elastic deformation gradient - dFe_dLi, & - dFi_dLi, & - dLp_dFi, & - dLi_dFi, & - dLp_dS, & - dLi_dS - real(pReal) steplengthLp, & - steplengthLi, & - dt, & ! time increment - atol_Lp, & - atol_Li, & - devNull - integer NiterationStressLp, & ! number of stress integrations - NiterationStressLi, & ! number of inner stress integrations - ierr, & ! error indicator for LAPACK - o, & - p, & - jacoCounterLp, & - jacoCounterLi ! counters to check for Jacobian update - logical :: error,broken - - broken = .true. - - if (present(timeFraction)) then - dt = crystallite_subdt(ipc,ip,el) * timeFraction - F = crystallite_subF0(1:3,1:3,ipc,ip,el) & - + (crystallite_subF(1:3,1:3,ipc,ip,el) - crystallite_subF0(1:3,1:3,ipc,ip,el)) * timeFraction - else - dt = crystallite_subdt(ipc,ip,el) - F = crystallite_subF(1:3,1:3,ipc,ip,el) - endif - - call constitutive_dependentState(crystallite_partitionedF(1:3,1:3,ipc,ip,el), & - crystallite_Fp(1:3,1:3,ipc,ip,el),ipc,ip,el) - - Lpguess = crystallite_Lp(1:3,1:3,ipc,ip,el) ! take as first guess - Liguess = crystallite_Li(1:3,1:3,ipc,ip,el) ! take as first guess - - call math_invert33(invFp_current,devNull,error,crystallite_subFp0(1:3,1:3,ipc,ip,el)) - if (error) return ! error - call math_invert33(invFi_current,devNull,error,crystallite_subFi0(1:3,1:3,ipc,ip,el)) - if (error) return ! error - - A = matmul(F,invFp_current) ! intermediate tensor needed later to calculate dFe_dLp - - jacoCounterLi = 0 - steplengthLi = 1.0_pReal - residuumLi_old = 0.0_pReal - Liguess_old = Liguess - - NiterationStressLi = 0 - LiLoop: do - NiterationStressLi = NiterationStressLi + 1 - if (NiterationStressLi>num%nStress) return ! error - - invFi_new = matmul(invFi_current,math_I3 - dt*Liguess) - Fi_new = math_inv33(invFi_new) - - jacoCounterLp = 0 - steplengthLp = 1.0_pReal - residuumLp_old = 0.0_pReal - Lpguess_old = Lpguess - - NiterationStressLp = 0 - LpLoop: do - NiterationStressLp = NiterationStressLp + 1 - if (NiterationStressLp>num%nStress) return ! error - - B = math_I3 - dt*Lpguess - Fe = matmul(matmul(A,B), invFi_new) - call constitutive_SandItsTangents(S, dS_dFe, dS_dFi, & - Fe, Fi_new, ipc, ip, el) - - call constitutive_LpAndItsTangents(Lp_constitutive, dLp_dS, dLp_dFi, & - S, Fi_new, ipc, ip, el) - - !* update current residuum and check for convergence of loop - atol_Lp = max(num%rtol_crystalliteStress * max(norm2(Lpguess),norm2(Lp_constitutive)), & ! absolute tolerance from largest acceptable relative error - num%atol_crystalliteStress) ! minimum lower cutoff - residuumLp = Lpguess - Lp_constitutive - - if (any(IEEE_is_NaN(residuumLp))) then - return ! error - elseif (norm2(residuumLp) < atol_Lp) then ! converged if below absolute tolerance - exit LpLoop - elseif (NiterationStressLp == 1 .or. norm2(residuumLp) < norm2(residuumLp_old)) then ! not converged, but improved norm of residuum (always proceed in first iteration)... - residuumLp_old = residuumLp ! ...remember old values and... - Lpguess_old = Lpguess - steplengthLp = 1.0_pReal ! ...proceed with normal step length (calculate new search direction) - else ! not converged and residuum not improved... - steplengthLp = num%subStepSizeLp * steplengthLp ! ...try with smaller step length in same direction - Lpguess = Lpguess_old & - + deltaLp * stepLengthLp - cycle LpLoop - endif - - calculateJacobiLi: if (mod(jacoCounterLp, num%iJacoLpresiduum) == 0) then - jacoCounterLp = jacoCounterLp + 1 - - do o=1,3; do p=1,3 - dFe_dLp(o,1:3,p,1:3) = - dt * A(o,p)*transpose(invFi_new) ! dFe_dLp(i,j,k,l) = -dt * A(i,k) invFi(l,j) - enddo; enddo - dRLp_dLp = math_eye(9) & - - math_3333to99(math_mul3333xx3333(math_mul3333xx3333(dLp_dS,dS_dFe),dFe_dLp)) - temp_9 = math_33to9(residuumLp) - call dgesv(9,1,dRLp_dLp,9,devNull_9,temp_9,9,ierr) ! solve dRLp/dLp * delta Lp = -res for delta Lp - if (ierr /= 0) return ! error - deltaLp = - math_9to33(temp_9) - endif calculateJacobiLi - - Lpguess = Lpguess & - + deltaLp * steplengthLp - enddo LpLoop - - call constitutive_LiAndItsTangents(Li_constitutive, dLi_dS, dLi_dFi, & - S, Fi_new, ipc, ip, el) - - !* update current residuum and check for convergence of loop - atol_Li = max(num%rtol_crystalliteStress * max(norm2(Liguess),norm2(Li_constitutive)), & ! absolute tolerance from largest acceptable relative error - num%atol_crystalliteStress) ! minimum lower cutoff - residuumLi = Liguess - Li_constitutive - if (any(IEEE_is_NaN(residuumLi))) then - return ! error - elseif (norm2(residuumLi) < atol_Li) then ! converged if below absolute tolerance - exit LiLoop - elseif (NiterationStressLi == 1 .or. norm2(residuumLi) < norm2(residuumLi_old)) then ! not converged, but improved norm of residuum (always proceed in first iteration)... - residuumLi_old = residuumLi ! ...remember old values and... - Liguess_old = Liguess - steplengthLi = 1.0_pReal ! ...proceed with normal step length (calculate new search direction) - else ! not converged and residuum not improved... - steplengthLi = num%subStepSizeLi * steplengthLi ! ...try with smaller step length in same direction - Liguess = Liguess_old & - + deltaLi * steplengthLi - cycle LiLoop - endif - - calculateJacobiLp: if (mod(jacoCounterLi, num%iJacoLpresiduum) == 0) then - jacoCounterLi = jacoCounterLi + 1 - - temp_33 = matmul(matmul(A,B),invFi_current) - do o=1,3; do p=1,3 - dFe_dLi(1:3,o,1:3,p) = -dt*math_I3(o,p)*temp_33 ! dFe_dLp(i,j,k,l) = -dt * A(i,k) invFi(l,j) - dFi_dLi(1:3,o,1:3,p) = -dt*math_I3(o,p)*invFi_current - enddo; enddo - do o=1,3; do p=1,3 - dFi_dLi(1:3,1:3,o,p) = matmul(matmul(Fi_new,dFi_dLi(1:3,1:3,o,p)),Fi_new) - enddo; enddo - dRLi_dLi = math_eye(9) & - - math_3333to99(math_mul3333xx3333(dLi_dS, math_mul3333xx3333(dS_dFe, dFe_dLi) & - + math_mul3333xx3333(dS_dFi, dFi_dLi))) & - - math_3333to99(math_mul3333xx3333(dLi_dFi, dFi_dLi)) - temp_9 = math_33to9(residuumLi) - call dgesv(9,1,dRLi_dLi,9,devNull_9,temp_9,9,ierr) ! solve dRLi/dLp * delta Li = -res for delta Li - if (ierr /= 0) return ! error - deltaLi = - math_9to33(temp_9) - endif calculateJacobiLp - - Liguess = Liguess & - + deltaLi * steplengthLi - enddo LiLoop - - invFp_new = matmul(invFp_current,B) - call math_invert33(Fp_new,devNull,error,invFp_new) - if (error) return ! error - - 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_Lp (1:3,1:3,ipc,ip,el) = Lpguess - crystallite_Li (1:3,1:3,ipc,ip,el) = Liguess - crystallite_Fp (1:3,1:3,ipc,ip,el) = Fp_new / math_det33(Fp_new)**(1.0_pReal/3.0_pReal) ! regularize - crystallite_Fi (1:3,1:3,ipc,ip,el) = Fi_new - crystallite_Fe (1:3,1:3,ipc,ip,el) = matmul(matmul(F,invFp_new),invFi_new) - broken = .false. - -end function integrateStress - - -!-------------------------------------------------------------------------------------------------- -!> @brief integrate stress, state with adaptive 1st order explicit Euler method -!> using Fixed Point Iteration to adapt the stepsize -!-------------------------------------------------------------------------------------------------- -subroutine integrateStateFPI(g,i,e) - - integer, intent(in) :: & - e, & !< element index in element loop - i, & !< integration point index in ip loop - g !< grain index in grain loop - integer :: & - NiterationState, & !< number of iterations in state loop - p, & - c, & - s, & - size_pl - integer, dimension(maxval(phase_Nsources)) :: & - size_so - real(pReal) :: & - zeta - real(pReal), dimension(max(constitutive_plasticity_maxSizeDotState,constitutive_source_maxSizeDotState)) :: & - r ! state residuum - real(pReal), dimension(constitutive_plasticity_maxSizeDotState,2) :: & - plastic_dotState - real(pReal), dimension(constitutive_source_maxSizeDotState,2,maxval(phase_Nsources)) :: source_dotState - logical :: & - broken - - p = material_phaseAt(g,e) - c = material_phaseMemberAt(g,i,e) - - broken = constitutive_collectDotState(crystallite_S(1:3,1:3,g,i,e), & - crystallite_partitionedF0, & - crystallite_Fi(1:3,1:3,g,i,e), & - crystallite_partitionedFp0, & - crystallite_subdt(g,i,e), g,i,e,p,c) - if(broken) return - - size_pl = plasticState(p)%sizeDotState - plasticState(p)%state(1:size_pl,c) = plasticState(p)%subState0(1:size_pl,c) & - + plasticState(p)%dotState (1:size_pl,c) & - * crystallite_subdt(g,i,e) - plastic_dotState(1:size_pl,2) = 0.0_pReal - - iteration: do NiterationState = 1, num%nState - - if(nIterationState > 1) plastic_dotState(1:size_pl,2) = plastic_dotState(1:size_pl,1) - plastic_dotState(1:size_pl,1) = plasticState(p)%dotState(:,c) - - broken = integrateStress(g,i,e) - if(broken) exit iteration - - broken = constitutive_collectDotState(crystallite_S(1:3,1:3,g,i,e), & - crystallite_partitionedF0, & - crystallite_Fi(1:3,1:3,g,i,e), & - crystallite_partitionedFp0, & - crystallite_subdt(g,i,e), g,i,e,p,c) - if(broken) exit iteration - - zeta = damper(plasticState(p)%dotState(:,c),plastic_dotState(1:size_pl,1),& - plastic_dotState(1:size_pl,2)) - plasticState(p)%dotState(:,c) = plasticState(p)%dotState(:,c) * zeta & - + plastic_dotState(1:size_pl,1) * (1.0_pReal - zeta) - r(1:size_pl) = plasticState(p)%state (1:size_pl,c) & - - plasticState(p)%subState0(1:size_pl,c) & - - plasticState(p)%dotState (1:size_pl,c) * crystallite_subdt(g,i,e) - plasticState(p)%state(1:size_pl,c) = plasticState(p)%state(1:size_pl,c) & - - r(1:size_pl) - crystallite_converged(g,i,e) = converged(r(1:size_pl), & - plasticState(p)%state(1:size_pl,c), & - plasticState(p)%atol(1:size_pl)) - - if(crystallite_converged(g,i,e)) then - broken = constitutive_deltaState(crystallite_S(1:3,1:3,g,i,e), & - crystallite_Fi(1:3,1:3,g,i,e),g,i,e,p,c) - exit iteration - endif - - enddo iteration - - - contains - - !-------------------------------------------------------------------------------------------------- - !> @brief calculate the damping for correction of state and dot state - !-------------------------------------------------------------------------------------------------- - real(pReal) pure function damper(current,previous,previous2) - - real(pReal), dimension(:), intent(in) ::& - current, previous, previous2 - - real(pReal) :: dot_prod12, dot_prod22 - - dot_prod12 = dot_product(current - previous, previous - previous2) - dot_prod22 = dot_product(previous - previous2, previous - previous2) - if ((dot_product(current,previous) < 0.0_pReal .or. dot_prod12 < 0.0_pReal) .and. dot_prod22 > 0.0_pReal) then - damper = 0.75_pReal + 0.25_pReal * tanh(2.0_pReal + 4.0_pReal * dot_prod12 / dot_prod22) - else - damper = 1.0_pReal - endif - - end function damper - -end subroutine integrateStateFPI - - -!-------------------------------------------------------------------------------------------------- -!> @brief integrate stress, state with adaptive 1st order explicit Euler method -!> using Fixed Point Iteration to adapt the stepsize -!-------------------------------------------------------------------------------------------------- -subroutine integrateSourceState(g,i,e) - - integer, intent(in) :: & - e, & !< element index in element loop - i, & !< integration point index in ip loop - g !< grain index in grain loop - integer :: & - NiterationState, & !< number of iterations in state loop - p, & - c, & - s, & - size_pl - integer, dimension(maxval(phase_Nsources)) :: & - size_so - real(pReal) :: & - zeta - real(pReal), dimension(max(constitutive_plasticity_maxSizeDotState,constitutive_source_maxSizeDotState)) :: & - r ! state residuum - real(pReal), dimension(constitutive_source_maxSizeDotState,2,maxval(phase_Nsources)) :: source_dotState - logical :: & - broken - - p = material_phaseAt(g,e) - c = material_phaseMemberAt(g,i,e) - - broken = constitutive_collectDotState_source(crystallite_S(1:3,1:3,g,i,e), g,i,e,p,c) - if(broken) return - - do s = 1, phase_Nsources(p) - size_so(s) = sourceState(p)%p(s)%sizeDotState - sourceState(p)%p(s)%state(1:size_so(s),c) = sourceState(p)%p(s)%subState0(1:size_so(s),c) & - + sourceState(p)%p(s)%dotState (1:size_so(s),c) & - * crystallite_subdt(g,i,e) - source_dotState(1:size_so(s),2,s) = 0.0_pReal - enddo - - iteration: do NiterationState = 1, num%nState - - do s = 1, phase_Nsources(p) - if(nIterationState > 1) source_dotState(1:size_so(s),2,s) = source_dotState(1:size_so(s),1,s) - source_dotState(1:size_so(s),1,s) = sourceState(p)%p(s)%dotState(:,c) - enddo - - broken = constitutive_collectDotState_source(crystallite_S(1:3,1:3,g,i,e), g,i,e,p,c) - if(broken) exit iteration - - do s = 1, phase_Nsources(p) - zeta = damper(sourceState(p)%p(s)%dotState(:,c), & - source_dotState(1:size_so(s),1,s),& - source_dotState(1:size_so(s),2,s)) - sourceState(p)%p(s)%dotState(:,c) = sourceState(p)%p(s)%dotState(:,c) * zeta & - + source_dotState(1:size_so(s),1,s)* (1.0_pReal - zeta) - r(1:size_so(s)) = sourceState(p)%p(s)%state (1:size_so(s),c) & - - sourceState(p)%p(s)%subState0(1:size_so(s),c) & - - sourceState(p)%p(s)%dotState (1:size_so(s),c) * crystallite_subdt(g,i,e) - sourceState(p)%p(s)%state(1:size_so(s),c) = sourceState(p)%p(s)%state(1:size_so(s),c) & - - r(1:size_so(s)) - crystallite_converged(g,i,e) = & - crystallite_converged(g,i,e) .and. converged(r(1:size_so(s)), & - sourceState(p)%p(s)%state(1:size_so(s),c), & - sourceState(p)%p(s)%atol(1:size_so(s))) - enddo - - if(crystallite_converged(g,i,e)) then - broken = constitutive_deltaState_source(crystallite_Fe(1:3,1:3,g,i,e),g,i,e,p,c) - exit iteration - endif - - enddo iteration - - - contains - - !-------------------------------------------------------------------------------------------------- - !> @brief calculate the damping for correction of state and dot state - !-------------------------------------------------------------------------------------------------- - real(pReal) pure function damper(current,previous,previous2) - - real(pReal), dimension(:), intent(in) ::& - current, previous, previous2 - - real(pReal) :: dot_prod12, dot_prod22 - - dot_prod12 = dot_product(current - previous, previous - previous2) - dot_prod22 = dot_product(previous - previous2, previous - previous2) - if ((dot_product(current,previous) < 0.0_pReal .or. dot_prod12 < 0.0_pReal) .and. dot_prod22 > 0.0_pReal) then - damper = 0.75_pReal + 0.25_pReal * tanh(2.0_pReal + 4.0_pReal * dot_prod12 / dot_prod22) - else - damper = 1.0_pReal - endif - - end function damper - -end subroutine integrateSourceState - -!-------------------------------------------------------------------------------------------------- -!> @brief integrate state with 1st order explicit Euler method -!-------------------------------------------------------------------------------------------------- -subroutine integrateStateEuler(g,i,e) - - integer, intent(in) :: & - e, & !< element index in element loop - i, & !< integration point index in ip loop - g !< grain index in grain loop - integer :: & - p, & - c, & - sizeDotState - logical :: & - broken - - p = material_phaseAt(g,e) - c = material_phaseMemberAt(g,i,e) - - broken = constitutive_collectDotState(crystallite_S(1:3,1:3,g,i,e), & - crystallite_partitionedF0, & - crystallite_Fi(1:3,1:3,g,i,e), & - crystallite_partitionedFp0, & - crystallite_subdt(g,i,e), g,i,e,p,c) - if(broken) return - - sizeDotState = plasticState(p)%sizeDotState - plasticState(p)%state(1:sizeDotState,c) = plasticState(p)%subState0(1:sizeDotState,c) & - + plasticState(p)%dotState (1:sizeDotState,c) & - * crystallite_subdt(g,i,e) - - broken = constitutive_deltaState(crystallite_S(1:3,1:3,g,i,e), & - crystallite_Fi(1:3,1:3,g,i,e),g,i,e,p,c) - if(broken) return - - broken = integrateStress(g,i,e) - crystallite_converged(g,i,e) = .not. broken - -end subroutine integrateStateEuler - - -!-------------------------------------------------------------------------------------------------- -!> @brief integrate stress, state with 1st order Euler method with adaptive step size -!-------------------------------------------------------------------------------------------------- -subroutine integrateStateAdaptiveEuler(g,i,e) - - integer, intent(in) :: & - e, & !< element index in element loop - i, & !< integration point index in ip loop - g !< grain index in grain loop - integer :: & - p, & - c, & - sizeDotState - logical :: & - broken - - real(pReal), dimension(constitutive_plasticity_maxSizeDotState) :: residuum_plastic - - - p = material_phaseAt(g,e) - c = material_phaseMemberAt(g,i,e) - - broken = constitutive_collectDotState(crystallite_S(1:3,1:3,g,i,e), & - crystallite_partitionedF0, & - crystallite_Fi(1:3,1:3,g,i,e), & - crystallite_partitionedFp0, & - crystallite_subdt(g,i,e), g,i,e,p,c) - if(broken) return - - sizeDotState = plasticState(p)%sizeDotState - - residuum_plastic(1:sizeDotState) = - plasticState(p)%dotstate(1:sizeDotState,c) * 0.5_pReal * crystallite_subdt(g,i,e) - plasticState(p)%state(1:sizeDotState,c) = plasticState(p)%subState0(1:sizeDotState,c) & - + plasticState(p)%dotstate(1:sizeDotState,c) * crystallite_subdt(g,i,e) - - broken = constitutive_deltaState(crystallite_S(1:3,1:3,g,i,e), & - crystallite_Fi(1:3,1:3,g,i,e),g,i,e,p,c) - if(broken) return - - broken = integrateStress(g,i,e) - if(broken) return - - broken = constitutive_collectDotState(crystallite_S(1:3,1:3,g,i,e), & - crystallite_partitionedF0, & - crystallite_Fi(1:3,1:3,g,i,e), & - crystallite_partitionedFp0, & - crystallite_subdt(g,i,e), g,i,e,p,c) - if(broken) return - - - sizeDotState = plasticState(p)%sizeDotState - crystallite_converged(g,i,e) = converged(residuum_plastic(1:sizeDotState) & - + 0.5_pReal * plasticState(p)%dotState(:,c) * crystallite_subdt(g,i,e), & - plasticState(p)%state(1:sizeDotState,c), & - plasticState(p)%atol(1:sizeDotState)) - -end subroutine integrateStateAdaptiveEuler - - -!--------------------------------------------------------------------------------------------------- -!> @brief Integrate state (including stress integration) with the classic Runge Kutta method -!--------------------------------------------------------------------------------------------------- -subroutine integrateStateRK4(g,i,e) - - integer, intent(in) :: g,i,e - - real(pReal), dimension(3,3), parameter :: & - A = reshape([& - 0.5_pReal, 0.0_pReal, 0.0_pReal, & - 0.0_pReal, 0.5_pReal, 0.0_pReal, & - 0.0_pReal, 0.0_pReal, 1.0_pReal],& - shape(A)) - real(pReal), dimension(3), parameter :: & - C = [0.5_pReal, 0.5_pReal, 1.0_pReal] - real(pReal), dimension(4), parameter :: & - B = [1.0_pReal/6.0_pReal, 1.0_pReal/3.0_pReal, 1.0_pReal/3.0_pReal, 1.0_pReal/6.0_pReal] - - call integrateStateRK(g,i,e,A,B,C) - -end subroutine integrateStateRK4 - - -!--------------------------------------------------------------------------------------------------- -!> @brief Integrate state (including stress integration) with the Cash-Carp method -!--------------------------------------------------------------------------------------------------- -subroutine integrateStateRKCK45(g,i,e) - - integer, intent(in) :: g,i,e - - real(pReal), dimension(5,5), parameter :: & - A = reshape([& - 1._pReal/5._pReal, .0_pReal, .0_pReal, .0_pReal, .0_pReal, & - 3._pReal/40._pReal, 9._pReal/40._pReal, .0_pReal, .0_pReal, .0_pReal, & - 3_pReal/10._pReal, -9._pReal/10._pReal, 6._pReal/5._pReal, .0_pReal, .0_pReal, & - -11._pReal/54._pReal, 5._pReal/2._pReal, -70.0_pReal/27.0_pReal, 35.0_pReal/27.0_pReal, .0_pReal, & - 1631._pReal/55296._pReal,175._pReal/512._pReal,575._pReal/13824._pReal,44275._pReal/110592._pReal,253._pReal/4096._pReal],& - shape(A)) - real(pReal), dimension(5), parameter :: & - C = [0.2_pReal, 0.3_pReal, 0.6_pReal, 1.0_pReal, 0.875_pReal] - real(pReal), dimension(6), parameter :: & - B = & - [37.0_pReal/378.0_pReal, .0_pReal, 250.0_pReal/621.0_pReal, & - 125.0_pReal/594.0_pReal, .0_pReal, 512.0_pReal/1771.0_pReal], & - DB = B - & - [2825.0_pReal/27648.0_pReal, .0_pReal, 18575.0_pReal/48384.0_pReal,& - 13525.0_pReal/55296.0_pReal, 277.0_pReal/14336.0_pReal, 1._pReal/4._pReal] - - call integrateStateRK(g,i,e,A,B,C,DB) - -end subroutine integrateStateRKCK45 - - -!-------------------------------------------------------------------------------------------------- -!> @brief Integrate state (including stress integration) with an explicit Runge-Kutta method or an -!! embedded explicit Runge-Kutta method -!-------------------------------------------------------------------------------------------------- -subroutine integrateStateRK(g,i,e,A,B,CC,DB) - - - real(pReal), dimension(:,:), intent(in) :: A - real(pReal), dimension(:), intent(in) :: B, CC - real(pReal), dimension(:), intent(in), optional :: DB - - integer, intent(in) :: & - e, & !< element index in element loop - i, & !< integration point index in ip loop - g !< grain index in grain loop - integer :: & - stage, & ! stage index in integration stage loop - n, & - p, & - c, & - sizeDotState - logical :: & - broken - real(pReal), dimension(constitutive_plasticity_maxSizeDotState,size(B)) :: plastic_RKdotState - - p = material_phaseAt(g,e) - c = material_phaseMemberAt(g,i,e) - - broken = constitutive_collectDotState(crystallite_S(1:3,1:3,g,i,e), & - crystallite_partitionedF0, & - crystallite_Fi(1:3,1:3,g,i,e), & - crystallite_partitionedFp0, & - crystallite_subdt(g,i,e), g,i,e,p,c) - if(broken) return - - do stage = 1,size(A,1) - sizeDotState = plasticState(p)%sizeDotState - plastic_RKdotState(1:sizeDotState,stage) = plasticState(p)%dotState(:,c) - plasticState(p)%dotState(:,c) = A(1,stage) * plastic_RKdotState(1:sizeDotState,1) - - do n = 2, stage - sizeDotState = plasticState(p)%sizeDotState - plasticState(p)%dotState(:,c) = plasticState(p)%dotState(:,c) & - + A(n,stage) * plastic_RKdotState(1:sizeDotState,n) - enddo - - sizeDotState = plasticState(p)%sizeDotState - plasticState(p)%state(1:sizeDotState,c) = plasticState(p)%subState0(1:sizeDotState,c) & - + plasticState(p)%dotState (1:sizeDotState,c) & - * crystallite_subdt(g,i,e) - - broken = integrateStress(g,i,e,CC(stage)) - if(broken) exit - - broken = constitutive_collectDotState(crystallite_S(1:3,1:3,g,i,e), & - crystallite_partitionedF0, & - crystallite_Fi(1:3,1:3,g,i,e), & - crystallite_partitionedFp0, & - crystallite_subdt(g,i,e)*CC(stage), g,i,e,p,c) - if(broken) exit - - enddo - if(broken) return - - sizeDotState = plasticState(p)%sizeDotState - - plastic_RKdotState(1:sizeDotState,size(B)) = plasticState (p)%dotState(:,c) - plasticState(p)%dotState(:,c) = matmul(plastic_RKdotState(1:sizeDotState,1:size(B)),B) - plasticState(p)%state(1:sizeDotState,c) = plasticState(p)%subState0(1:sizeDotState,c) & - + plasticState(p)%dotState (1:sizeDotState,c) & - * crystallite_subdt(g,i,e) - if(present(DB)) & - broken = .not. converged( matmul(plastic_RKdotState(1:sizeDotState,1:size(DB)),DB) & - * crystallite_subdt(g,i,e), & - plasticState(p)%state(1:sizeDotState,c), & - plasticState(p)%atol(1:sizeDotState)) - - if(broken) return - - broken = constitutive_deltaState(crystallite_S(1:3,1:3,g,i,e), & - crystallite_Fi(1:3,1:3,g,i,e),g,i,e,p,c) - if(broken) return - - broken = integrateStress(g,i,e) - crystallite_converged(g,i,e) = .not. broken - - -end subroutine integrateStateRK - - -!-------------------------------------------------------------------------------------------------- -!> @brief determines whether a point is converged -!-------------------------------------------------------------------------------------------------- -logical pure function converged(residuum,state,atol) - - real(pReal), intent(in), dimension(:) ::& - residuum, state, atol - real(pReal) :: & - rTol - - rTol = num%rTol_crystalliteState - - converged = all(abs(residuum) <= max(atol, rtol*abs(state))) - -end function converged - - -!-------------------------------------------------------------------------------------------------- -!> @brief Write current restart information (Field and constitutive data) to file. -! ToDo: Merge data into one file for MPI, move state to constitutive and homogenization, respectively -!-------------------------------------------------------------------------------------------------- -subroutine crystallite_restartWrite - - integer :: i - integer(HID_T) :: fileHandle, groupHandle - character(len=pStringLen) :: fileName, datasetName - - print*, ' writing field and constitutive data required for restart to file';flush(IO_STDOUT) - - write(fileName,'(a,i0,a)') trim(getSolverJobName())//'_',worldrank,'.hdf5' - fileHandle = HDF5_openFile(fileName,'a') - - call HDF5_write(fileHandle,crystallite_partitionedF,'F') - call HDF5_write(fileHandle,crystallite_Fp, 'F_p') - call HDF5_write(fileHandle,crystallite_Fi, 'F_i') - call HDF5_write(fileHandle,crystallite_Lp, 'L_p') - call HDF5_write(fileHandle,crystallite_Li, 'L_i') - call HDF5_write(fileHandle,crystallite_S, 'S') - - groupHandle = HDF5_addGroup(fileHandle,'phase') - do i = 1,size(material_name_phase) - write(datasetName,'(i0,a)') i,'_omega' - call HDF5_write(groupHandle,plasticState(i)%state,datasetName) - enddo - call HDF5_closeGroup(groupHandle) - - groupHandle = HDF5_addGroup(fileHandle,'homogenization') - do i = 1, size(material_name_homogenization) - write(datasetName,'(i0,a)') i,'_omega' - call HDF5_write(groupHandle,homogState(i)%state,datasetName) - enddo - call HDF5_closeGroup(groupHandle) - - call HDF5_closeFile(fileHandle) - -end subroutine crystallite_restartWrite - - -!-------------------------------------------------------------------------------------------------- -!> @brief Read data for restart -! ToDo: Merge data into one file for MPI, move state to constitutive and homogenization, respectively -!-------------------------------------------------------------------------------------------------- -subroutine crystallite_restartRead - - integer :: i - integer(HID_T) :: fileHandle, groupHandle - character(len=pStringLen) :: fileName, datasetName - - print'(/,a,i0,a)', ' reading restart information of increment from file' - - write(fileName,'(a,i0,a)') trim(getSolverJobName())//'_',worldrank,'.hdf5' - fileHandle = HDF5_openFile(fileName) - - call HDF5_read(fileHandle,crystallite_F0, 'F') - call HDF5_read(fileHandle,crystallite_Fp0,'F_p') - call HDF5_read(fileHandle,crystallite_Fi0,'F_i') - call HDF5_read(fileHandle,crystallite_Lp0,'L_p') - call HDF5_read(fileHandle,crystallite_Li0,'L_i') - call HDF5_read(fileHandle,crystallite_S0, 'S') - - groupHandle = HDF5_openGroup(fileHandle,'phase') - do i = 1,size(material_name_phase) - write(datasetName,'(i0,a)') i,'_omega' - call HDF5_read(groupHandle,plasticState(i)%state0,datasetName) - enddo - call HDF5_closeGroup(groupHandle) - - groupHandle = HDF5_openGroup(fileHandle,'homogenization') - do i = 1,size(material_name_homogenization) - write(datasetName,'(i0,a)') i,'_omega' - call HDF5_read(groupHandle,homogState(i)%state0,datasetName) - enddo - call HDF5_closeGroup(groupHandle) - - call HDF5_closeFile(fileHandle) - -end subroutine crystallite_restartRead - - -!-------------------------------------------------------------------------------------------------- -!> @brief Forward data after successful increment. -! ToDo: Any guessing for the current states possible? -!-------------------------------------------------------------------------------------------------- -subroutine crystallite_forward - - integer :: i, j - - crystallite_F0 = crystallite_partitionedF - crystallite_Fp0 = crystallite_Fp - crystallite_Lp0 = crystallite_Lp - crystallite_Fi0 = crystallite_Fi - crystallite_Li0 = crystallite_Li - crystallite_S0 = crystallite_S - - do i = 1, size(plasticState) - plasticState(i)%state0 = plasticState(i)%state - enddo - do i = 1,size(material_name_homogenization) - homogState (i)%state0 = homogState (i)%state - damageState (i)%state0 = damageState (i)%state - enddo - -end subroutine crystallite_forward end module crystallite From 93b9677ec82cef8a3a069733df186d71f139776d Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 20 Dec 2020 11:24:29 +0100 Subject: [PATCH 071/148] not needed anymore --- src/CPFEM.f90 | 1 - src/CPFEM2.f90 | 1 - src/commercialFEM_fileList.f90 | 1 - src/crystallite.f90 | 18 ------------------ src/damage_nonlocal.f90 | 1 - src/homogenization.f90 | 1 - src/thermal_conduction.f90 | 1 - 7 files changed, 24 deletions(-) delete mode 100644 src/crystallite.f90 diff --git a/src/CPFEM.f90 b/src/CPFEM.f90 index 6fc58ea0f..fe8c7d1b3 100644 --- a/src/CPFEM.f90 +++ b/src/CPFEM.f90 @@ -13,7 +13,6 @@ module CPFEM use discretization_marc use material use config - use crystallite use homogenization use IO use discretization diff --git a/src/CPFEM2.f90 b/src/CPFEM2.f90 index 325a8791e..636962948 100644 --- a/src/CPFEM2.f90 +++ b/src/CPFEM2.f90 @@ -21,7 +21,6 @@ module CPFEM2 use HDF5_utilities use homogenization use constitutive - use crystallite #if defined(Mesh) use FEM_quadrature use discretization_mesh diff --git a/src/commercialFEM_fileList.f90 b/src/commercialFEM_fileList.f90 index a5bbe69ca..08e7b9c1c 100644 --- a/src/commercialFEM_fileList.f90 +++ b/src/commercialFEM_fileList.f90 @@ -44,7 +44,6 @@ #include "source_damage_anisoDuctile.f90" #include "kinematics_cleavage_opening.f90" #include "kinematics_slipplane_opening.f90" -#include "crystallite.f90" #include "thermal_isothermal.f90" #include "thermal_conduction.f90" #include "damage_none.f90" diff --git a/src/crystallite.f90 b/src/crystallite.f90 deleted file mode 100644 index 662dfa316..000000000 --- a/src/crystallite.f90 +++ /dev/null @@ -1,18 +0,0 @@ -!-------------------------------------------------------------------------------------------------- -!> @author Martin Diehl, Max-Planck-Institut für Eisenforschung GmbH -!> @author Pratheek Shanthraj, Max-Planck-Institut für Eisenforschung GmbH -!> @author Franz Roters, Max-Planck-Institut für Eisenforschung GmbH -!> @author Philip Eisenlohr, Max-Planck-Institut für Eisenforschung GmbH -!> @author Christoph Kords, Max-Planck-Institut für Eisenforschung GmbH -!> @author Chen Zhang, Michigan State University -!> @brief crystallite state integration functions and reporting of results -!-------------------------------------------------------------------------------------------------- - -module crystallite - - - - - - -end module crystallite diff --git a/src/damage_nonlocal.f90 b/src/damage_nonlocal.f90 index c4426f185..ac4d8636a 100644 --- a/src/damage_nonlocal.f90 +++ b/src/damage_nonlocal.f90 @@ -7,7 +7,6 @@ module damage_nonlocal use material use config use YAML_types - use crystallite use lattice use constitutive use results diff --git a/src/homogenization.f90 b/src/homogenization.f90 index 4da567e4c..cbab8e468 100644 --- a/src/homogenization.f90 +++ b/src/homogenization.f90 @@ -11,7 +11,6 @@ module homogenization use math use material use constitutive - use crystallite use FEsolving use discretization use thermal_isothermal diff --git a/src/thermal_conduction.f90 b/src/thermal_conduction.f90 index 37a407101..d30e50677 100644 --- a/src/thermal_conduction.f90 +++ b/src/thermal_conduction.f90 @@ -8,7 +8,6 @@ module thermal_conduction use config use lattice use results - use crystallite use constitutive use YAML_types From 55d14fbfa8439f227c97deb589e03e0e0eca4fad Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 20 Dec 2020 16:32:33 +0100 Subject: [PATCH 072/148] separating --- src/constitutive.f90 | 141 ++++++-------------------------------- src/constitutive_mech.f90 | 123 +++++++++++++++++++++++++++++++++ 2 files changed, 144 insertions(+), 120 deletions(-) diff --git a/src/constitutive.f90 b/src/constitutive.f90 index 360fb09f1..2845e45b7 100644 --- a/src/constitutive.f90 +++ b/src/constitutive.f90 @@ -147,6 +147,27 @@ module constitutive module subroutine thermal_init end subroutine thermal_init + module function constitutive_collectDotState(S, FArray, Fi, FpArray, subdt, ipc, ip, el,phase,of) result(broken) + + integer, intent(in) :: & + ipc, & !< component-ID of integration point + ip, & !< integration point + el, & !< element + phase, & + of + real(pReal), intent(in) :: & + subdt !< timestep + real(pReal), intent(in), dimension(3,3,homogenization_maxNconstituents,discretization_nIPs,discretization_Nelems) :: & + FArray, & !< elastic deformation gradient + FpArray !< plastic deformation gradient + real(pReal), intent(in), dimension(3,3) :: & + Fi !< intermediate deformation gradient + real(pReal), intent(in), dimension(3,3) :: & + S !< 2nd Piola Kirchhoff stress (vector notation) + + logical :: broken +end function constitutive_collectDotState + module function plastic_active(plastic_label) result(active_plastic) character(len=*), intent(in) :: plastic_label @@ -165,67 +186,6 @@ module constitutive logical, dimension(:,:), allocatable :: active_kinematics end function kinematics_active - module subroutine plastic_isotropic_dotState(Mp,instance,of) - real(pReal), dimension(3,3), intent(in) :: & - Mp !< Mandel stress - integer, intent(in) :: & - instance, & - of - end subroutine plastic_isotropic_dotState - - module subroutine plastic_phenopowerlaw_dotState(Mp,instance,of) - real(pReal), dimension(3,3), intent(in) :: & - Mp !< Mandel stress - integer, intent(in) :: & - instance, & - of - end subroutine plastic_phenopowerlaw_dotState - - module subroutine plastic_kinehardening_dotState(Mp,instance,of) - real(pReal), dimension(3,3), intent(in) :: & - Mp !< Mandel stress - integer, intent(in) :: & - instance, & - of - end subroutine plastic_kinehardening_dotState - - module subroutine plastic_dislotwin_dotState(Mp,T,instance,of) - real(pReal), dimension(3,3), intent(in) :: & - Mp !< Mandel stress - real(pReal), intent(in) :: & - T - integer, intent(in) :: & - instance, & - of - end subroutine plastic_dislotwin_dotState - - module subroutine plastic_disloTungsten_dotState(Mp,T,instance,of) - real(pReal), dimension(3,3), intent(in) :: & - Mp !< Mandel stress - real(pReal), intent(in) :: & - T - integer, intent(in) :: & - instance, & - of - end subroutine plastic_disloTungsten_dotState - - module subroutine plastic_nonlocal_dotState(Mp, F, Fp, Temperature,timestep, & - instance,of,ip,el) - real(pReal), dimension(3,3), intent(in) :: & - Mp !< MandelStress - real(pReal), dimension(3,3,homogenization_maxNconstituents,discretization_nIPs,discretization_Nelems), intent(in) :: & - F, & !< deformation gradient - Fp !< plastic deformation gradient - real(pReal), intent(in) :: & - Temperature, & !< temperature - timestep !< substepped crystallite time increment - integer, intent(in) :: & - instance, & - of, & - ip, & !< current integration point - el !< current element number - end subroutine plastic_nonlocal_dotState - module subroutine source_damage_anisoBrittle_dotState(S, ipc, ip, el) integer, intent(in) :: & @@ -694,66 +654,7 @@ subroutine constitutive_LiAndItsTangents(Li, dLi_dS, dLi_dFi, & end subroutine constitutive_LiAndItsTangents -!-------------------------------------------------------------------------------------------------- -!> @brief contains the constitutive equation for calculating the rate of change of microstructure -!-------------------------------------------------------------------------------------------------- -function constitutive_collectDotState(S, FArray, Fi, FpArray, subdt, ipc, ip, el,phase,of) result(broken) - integer, intent(in) :: & - ipc, & !< component-ID of integration point - ip, & !< integration point - el, & !< element - phase, & - of - real(pReal), intent(in) :: & - subdt !< timestep - real(pReal), intent(in), dimension(3,3,homogenization_maxNconstituents,discretization_nIPs,discretization_Nelems) :: & - FArray, & !< elastic deformation gradient - FpArray !< plastic deformation gradient - real(pReal), intent(in), dimension(3,3) :: & - Fi !< intermediate deformation gradient - real(pReal), intent(in), dimension(3,3) :: & - S !< 2nd Piola Kirchhoff stress (vector notation) - real(pReal), dimension(3,3) :: & - Mp - integer :: & - ho, & !< homogenization - tme, & !< thermal member position - i, & !< counter in source loop - instance - logical :: broken - - ho = material_homogenizationAt(el) - tme = material_homogenizationMemberAt(ip,el) - instance = phase_plasticityInstance(phase) - - Mp = matmul(matmul(transpose(Fi),Fi),S) - - plasticityType: select case (phase_plasticity(phase)) - - case (PLASTICITY_ISOTROPIC_ID) plasticityType - call plastic_isotropic_dotState(Mp,instance,of) - - case (PLASTICITY_PHENOPOWERLAW_ID) plasticityType - call plastic_phenopowerlaw_dotState(Mp,instance,of) - - case (PLASTICITY_KINEHARDENING_ID) plasticityType - call plastic_kinehardening_dotState(Mp,instance,of) - - case (PLASTICITY_DISLOTWIN_ID) plasticityType - call plastic_dislotwin_dotState(Mp,temperature(ho)%p(tme),instance,of) - - case (PLASTICITY_DISLOTUNGSTEN_ID) plasticityType - call plastic_disloTungsten_dotState(Mp,temperature(ho)%p(tme),instance,of) - - case (PLASTICITY_NONLOCAL_ID) plasticityType - call plastic_nonlocal_dotState(Mp,FArray,FpArray,temperature(ho)%p(tme),subdt, & - instance,of,ip,el) - end select plasticityType - broken = any(IEEE_is_NaN(plasticState(phase)%dotState(:,of))) - - -end function constitutive_collectDotState !-------------------------------------------------------------------------------------------------- diff --git a/src/constitutive_mech.f90 b/src/constitutive_mech.f90 index 6b3c6fce6..b7c14e68d 100644 --- a/src/constitutive_mech.f90 +++ b/src/constitutive_mech.f90 @@ -133,6 +133,67 @@ submodule(constitutive) constitutive_mech el !< current element number end subroutine plastic_nonlocal_LpAndItsTangent + module subroutine plastic_isotropic_dotState(Mp,instance,of) + real(pReal), dimension(3,3), intent(in) :: & + Mp !< Mandel stress + integer, intent(in) :: & + instance, & + of + end subroutine plastic_isotropic_dotState + + module subroutine plastic_phenopowerlaw_dotState(Mp,instance,of) + real(pReal), dimension(3,3), intent(in) :: & + Mp !< Mandel stress + integer, intent(in) :: & + instance, & + of + end subroutine plastic_phenopowerlaw_dotState + + module subroutine plastic_kinehardening_dotState(Mp,instance,of) + real(pReal), dimension(3,3), intent(in) :: & + Mp !< Mandel stress + integer, intent(in) :: & + instance, & + of + end subroutine plastic_kinehardening_dotState + + module subroutine plastic_dislotwin_dotState(Mp,T,instance,of) + real(pReal), dimension(3,3), intent(in) :: & + Mp !< Mandel stress + real(pReal), intent(in) :: & + T + integer, intent(in) :: & + instance, & + of + end subroutine plastic_dislotwin_dotState + + module subroutine plastic_disloTungsten_dotState(Mp,T,instance,of) + real(pReal), dimension(3,3), intent(in) :: & + Mp !< Mandel stress + real(pReal), intent(in) :: & + T + integer, intent(in) :: & + instance, & + of + end subroutine plastic_disloTungsten_dotState + + module subroutine plastic_nonlocal_dotState(Mp, F, Fp, Temperature,timestep, & + instance,of,ip,el) + real(pReal), dimension(3,3), intent(in) :: & + Mp !< MandelStress + real(pReal), dimension(3,3,homogenization_maxNconstituents,discretization_nIPs,discretization_Nelems), intent(in) :: & + F, & !< deformation gradient + Fp !< plastic deformation gradient + real(pReal), intent(in) :: & + Temperature, & !< temperature + timestep !< substepped crystallite time increment + integer, intent(in) :: & + instance, & + of, & + ip, & !< current integration point + el !< current element number + end subroutine plastic_nonlocal_dotState + module subroutine plastic_dislotwin_dependentState(T,instance,of) integer, intent(in) :: & @@ -454,6 +515,68 @@ module subroutine constitutive_plastic_LpAndItsTangents(Lp, dLp_dS, dLp_dFi, & end subroutine constitutive_plastic_LpAndItsTangents +!-------------------------------------------------------------------------------------------------- +!> @brief contains the constitutive equation for calculating the rate of change of microstructure +!-------------------------------------------------------------------------------------------------- +function constitutive_collectDotState(S, FArray, Fi, FpArray, subdt, ipc, ip, el,phase,of) result(broken) + + integer, intent(in) :: & + ipc, & !< component-ID of integration point + ip, & !< integration point + el, & !< element + phase, & + of + real(pReal), intent(in) :: & + subdt !< timestep + real(pReal), intent(in), dimension(3,3,homogenization_maxNconstituents,discretization_nIPs,discretization_Nelems) :: & + FArray, & !< elastic deformation gradient + FpArray !< plastic deformation gradient + real(pReal), intent(in), dimension(3,3) :: & + Fi !< intermediate deformation gradient + real(pReal), intent(in), dimension(3,3) :: & + S !< 2nd Piola Kirchhoff stress (vector notation) + real(pReal), dimension(3,3) :: & + Mp + integer :: & + ho, & !< homogenization + tme, & !< thermal member position + i, & !< counter in source loop + instance + logical :: broken + + ho = material_homogenizationAt(el) + tme = material_homogenizationMemberAt(ip,el) + instance = phase_plasticityInstance(phase) + + Mp = matmul(matmul(transpose(Fi),Fi),S) + + plasticityType: select case (phase_plasticity(phase)) + + case (PLASTICITY_ISOTROPIC_ID) plasticityType + call plastic_isotropic_dotState(Mp,instance,of) + + case (PLASTICITY_PHENOPOWERLAW_ID) plasticityType + call plastic_phenopowerlaw_dotState(Mp,instance,of) + + case (PLASTICITY_KINEHARDENING_ID) plasticityType + call plastic_kinehardening_dotState(Mp,instance,of) + + case (PLASTICITY_DISLOTWIN_ID) plasticityType + call plastic_dislotwin_dotState(Mp,temperature(ho)%p(tme),instance,of) + + case (PLASTICITY_DISLOTUNGSTEN_ID) plasticityType + call plastic_disloTungsten_dotState(Mp,temperature(ho)%p(tme),instance,of) + + case (PLASTICITY_NONLOCAL_ID) plasticityType + call plastic_nonlocal_dotState(Mp,FArray,FpArray,temperature(ho)%p(tme),subdt, & + instance,of,ip,el) + end select plasticityType + broken = any(IEEE_is_NaN(plasticState(phase)%dotState(:,of))) + + +end function constitutive_collectDotState + + !-------------------------------------------------------------------------------------------- !> @brief writes plasticity constitutive results to HDF5 output file !-------------------------------------------------------------------------------------------- From d92a732dcc9f12073f8227a365ff378245902b80 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 20 Dec 2020 17:11:43 +0100 Subject: [PATCH 073/148] mech/plastic only --- src/constitutive.f90 | 94 +++++---------------------- src/constitutive_mech.f90 | 74 +++++++++++++++++++++ src/constitutive_plastic_nonlocal.f90 | 5 +- 3 files changed, 95 insertions(+), 78 deletions(-) diff --git a/src/constitutive.f90 b/src/constitutive.f90 index 2845e45b7..b7c2e08eb 100644 --- a/src/constitutive.f90 +++ b/src/constitutive.f90 @@ -13,8 +13,6 @@ module constitutive use results use lattice use discretization - use geometry_plastic_nonlocal, only: & - geometry_plastic_nonlocal_disable use parallelization use HDF5_utilities use DAMASK_interface @@ -169,6 +167,24 @@ module constitutive end function constitutive_collectDotState +module function constitutive_deltaState(S, Fi, ipc, ip, el, phase, of) result(broken) + + integer, intent(in) :: & + ipc, & !< component-ID of integration point + ip, & !< integration point + el, & !< element + phase, & + of + real(pReal), intent(in), dimension(3,3) :: & + S, & !< 2nd Piola Kirchhoff stress + Fi !< intermediate deformation gradient + logical :: & + broken + + +end function constitutive_deltaState + + module function plastic_active(plastic_label) result(active_plastic) character(len=*), intent(in) :: plastic_label logical, dimension(:), allocatable :: active_plastic @@ -309,24 +325,6 @@ end function constitutive_collectDotState end subroutine kinematics_thermal_expansion_LiAndItsTangent - module subroutine plastic_kinehardening_deltaState(Mp,instance,of) - real(pReal), dimension(3,3), intent(in) :: & - Mp !< Mandel stress - integer, intent(in) :: & - instance, & - of - end subroutine plastic_kinehardening_deltaState - - module subroutine plastic_nonlocal_deltaState(Mp,instance,of,ip,el) - real(pReal), dimension(3,3), intent(in) :: & - Mp - integer, intent(in) :: & - instance, & - of, & - ip, & - el - end subroutine plastic_nonlocal_deltaState - module subroutine source_damage_isoBrittle_deltaState(C, Fe, ipc, ip, el) integer, intent(in) :: & ipc, & !< component-ID of integration point @@ -702,62 +700,6 @@ function constitutive_collectDotState_source(S, ipc, ip, el,phase,of) result(bro end function constitutive_collectDotState_source -!-------------------------------------------------------------------------------------------------- -!> @brief for constitutive models having an instantaneous change of state -!> will return false if delta state is not needed/supported by the constitutive model -!-------------------------------------------------------------------------------------------------- -function constitutive_deltaState(S, Fi, ipc, ip, el, phase, of) result(broken) - - integer, intent(in) :: & - ipc, & !< component-ID of integration point - ip, & !< integration point - el, & !< element - phase, & - of - real(pReal), intent(in), dimension(3,3) :: & - S, & !< 2nd Piola Kirchhoff stress - Fi !< intermediate deformation gradient - real(pReal), dimension(3,3) :: & - Mp - integer :: & - instance, & - myOffset, & - mySize - logical :: & - broken - - Mp = matmul(matmul(transpose(Fi),Fi),S) - instance = phase_plasticityInstance(phase) - - plasticityType: select case (phase_plasticity(phase)) - - case (PLASTICITY_KINEHARDENING_ID) plasticityType - call plastic_kinehardening_deltaState(Mp,instance,of) - broken = any(IEEE_is_NaN(plasticState(phase)%deltaState(:,of))) - - case (PLASTICITY_NONLOCAL_ID) plasticityType - call plastic_nonlocal_deltaState(Mp,instance,of,ip,el) - broken = any(IEEE_is_NaN(plasticState(phase)%deltaState(:,of))) - - case default - broken = .false. - - end select plasticityType - - if(.not. broken) then - select case(phase_plasticity(phase)) - case (PLASTICITY_NONLOCAL_ID,PLASTICITY_KINEHARDENING_ID) - - myOffset = plasticState(phase)%offsetDeltaState - mySize = plasticState(phase)%sizeDeltaState - plasticState(phase)%state(myOffset + 1:myOffset + mySize,of) = & - plasticState(phase)%state(myOffset + 1:myOffset + mySize,of) + plasticState(phase)%deltaState(1:mySize,of) - end select - endif - -end function constitutive_deltaState - - !-------------------------------------------------------------------------------------------------- !> @brief for constitutive models having an instantaneous change of state !> will return false if delta state is not needed/supported by the constitutive model diff --git a/src/constitutive_mech.f90 b/src/constitutive_mech.f90 index b7c14e68d..cab4a17d8 100644 --- a/src/constitutive_mech.f90 +++ b/src/constitutive_mech.f90 @@ -220,6 +220,24 @@ submodule(constitutive) constitutive_mech el !< current element number end subroutine plastic_nonlocal_dependentState + module subroutine plastic_kinehardening_deltaState(Mp,instance,of) + real(pReal), dimension(3,3), intent(in) :: & + Mp !< Mandel stress + integer, intent(in) :: & + instance, & + of + end subroutine plastic_kinehardening_deltaState + + module subroutine plastic_nonlocal_deltaState(Mp,instance,of,ip,el) + real(pReal), dimension(3,3), intent(in) :: & + Mp + integer, intent(in) :: & + instance, & + of, & + ip, & + el + end subroutine plastic_nonlocal_deltaState + module subroutine plastic_isotropic_results(instance,group) integer, intent(in) :: instance character(len=*), intent(in) :: group @@ -577,6 +595,62 @@ function constitutive_collectDotState(S, FArray, Fi, FpArray, subdt, ipc, ip, el end function constitutive_collectDotState +!-------------------------------------------------------------------------------------------------- +!> @brief for constitutive models having an instantaneous change of state +!> will return false if delta state is not needed/supported by the constitutive model +!-------------------------------------------------------------------------------------------------- +function constitutive_deltaState(S, Fi, ipc, ip, el, phase, of) result(broken) + + integer, intent(in) :: & + ipc, & !< component-ID of integration point + ip, & !< integration point + el, & !< element + phase, & + of + real(pReal), intent(in), dimension(3,3) :: & + S, & !< 2nd Piola Kirchhoff stress + Fi !< intermediate deformation gradient + real(pReal), dimension(3,3) :: & + Mp + integer :: & + instance, & + myOffset, & + mySize + logical :: & + broken + + Mp = matmul(matmul(transpose(Fi),Fi),S) + instance = phase_plasticityInstance(phase) + + plasticityType: select case (phase_plasticity(phase)) + + case (PLASTICITY_KINEHARDENING_ID) plasticityType + call plastic_kinehardening_deltaState(Mp,instance,of) + broken = any(IEEE_is_NaN(plasticState(phase)%deltaState(:,of))) + + case (PLASTICITY_NONLOCAL_ID) plasticityType + call plastic_nonlocal_deltaState(Mp,instance,of,ip,el) + broken = any(IEEE_is_NaN(plasticState(phase)%deltaState(:,of))) + + case default + broken = .false. + + end select plasticityType + + if(.not. broken) then + select case(phase_plasticity(phase)) + case (PLASTICITY_NONLOCAL_ID,PLASTICITY_KINEHARDENING_ID) + + myOffset = plasticState(phase)%offsetDeltaState + mySize = plasticState(phase)%sizeDeltaState + plasticState(phase)%state(myOffset + 1:myOffset + mySize,of) = & + plasticState(phase)%state(myOffset + 1:myOffset + mySize,of) + plasticState(phase)%deltaState(1:mySize,of) + end select + endif + +end function constitutive_deltaState + + !-------------------------------------------------------------------------------------------- !> @brief writes plasticity constitutive results to HDF5 output file !-------------------------------------------------------------------------------------------- diff --git a/src/constitutive_plastic_nonlocal.f90 b/src/constitutive_plastic_nonlocal.f90 index ce9e4e391..65f74b6cc 100644 --- a/src/constitutive_plastic_nonlocal.f90 +++ b/src/constitutive_plastic_nonlocal.f90 @@ -10,7 +10,8 @@ submodule(constitutive:constitutive_mech) plastic_nonlocal IPneighborhood => geometry_plastic_nonlocal_IPneighborhood, & IPvolume => geometry_plastic_nonlocal_IPvolume0, & IParea => geometry_plastic_nonlocal_IParea0, & - IPareaNormal => geometry_plastic_nonlocal_IPareaNormal0 + IPareaNormal => geometry_plastic_nonlocal_IPareaNormal0, & + geometry_plastic_nonlocal_disable real(pReal), parameter :: & kB = 1.38e-23_pReal !< Boltzmann constant in J/Kelvin @@ -195,7 +196,7 @@ module function plastic_nonlocal_init() result(myPlasticity) call geometry_plastic_nonlocal_disable return endif - + print*, 'Reuber et al., Acta Materialia 71:333–348, 2014' print*, 'https://doi.org/10.1016/j.actamat.2014.03.012'//IO_EOL From 0f8396c9d350577a9ecf2a056eb79269882970b8 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 20 Dec 2020 18:22:04 +0100 Subject: [PATCH 074/148] cleaning --- src/constitutive.f90 | 27 +++++++++------------------ 1 file changed, 9 insertions(+), 18 deletions(-) diff --git a/src/constitutive.f90 b/src/constitutive.f90 index b7c2e08eb..d95eb5c0a 100644 --- a/src/constitutive.f90 +++ b/src/constitutive.f90 @@ -25,7 +25,6 @@ module constitutive crystallite_dt !< requested time increment of each grain real(pReal), dimension(:,:,:), allocatable :: & crystallite_subdt, & !< substepped time increment of each grain - crystallite_subFrac, & !< already calculated fraction of increment crystallite_subStep !< size of next integration step type(rotation), dimension(:,:,:), allocatable :: & crystallite_orientation !< current orientation @@ -853,12 +852,7 @@ subroutine crystallite_init print'(/,a)', ' <<<+- crystallite init -+>>>' debug_crystallite => config_debug%get('crystallite', defaultVal=emptyList) - debugCrystallite%basic = debug_crystallite%contains('basic') debugCrystallite%extensive = debug_crystallite%contains('extensive') - debugCrystallite%selective = debug_crystallite%contains('selective') - debugCrystallite%element = config_debug%get_asInt('element', defaultVal=1) - debugCrystallite%ip = config_debug%get_asInt('integrationpoint', defaultVal=1) - debugCrystallite%grain = config_debug%get_asInt('grain', defaultVal=1) cMax = homogenization_maxNconstituents iMax = discretization_nIPs @@ -880,7 +874,7 @@ subroutine crystallite_init source = crystallite_partitionedF) allocate(crystallite_dt(cMax,iMax,eMax),source=0.0_pReal) - allocate(crystallite_subdt,crystallite_subFrac,crystallite_subStep, & + allocate(crystallite_subdt,crystallite_subStep, & source = crystallite_dt) allocate(crystallite_orientation(cMax,iMax,eMax)) @@ -946,14 +940,10 @@ subroutine crystallite_init #endif enddo -#ifdef DEBUG - if (debugCrystallite%basic) then - print'(a42,1x,i10)', ' # of elements: ', eMax - print'(a42,1x,i10)', ' # of integration points/element: ', iMax - print'(a42,1x,i10)', 'max # of constituents/integration point: ', cMax - flush(IO_STDOUT) - endif -#endif + print'(a42,1x,i10)', ' # of elements: ', eMax + print'(a42,1x,i10)', ' # of integration points/element: ', iMax + print'(a42,1x,i10)', 'max # of constituents/integration point: ', cMax + flush(IO_STDOUT) !$OMP PARALLEL DO PRIVATE(i,c) do e = FEsolving_execElem(1),FEsolving_execElem(2) @@ -1011,6 +1001,7 @@ function crystallite_stress() e, & !< counter in element loop s logical, dimension(homogenization_maxNconstituents,discretization_nIPs,discretization_Nelems) :: todo !ToDo: need to set some values to false for different Ngrains + real(pReal), dimension(homogenization_maxNconstituents,discretization_nIPs,discretization_Nelems) :: subFrac !ToDo: need to set some values to false for different Ngrains real(pReal), dimension(:,:,:,:,:), allocatable :: & subLp0,& !< plastic velocity grad at start of crystallite inc subLi0 !< intermediate velocity grad at start of crystallite inc @@ -1037,7 +1028,7 @@ function crystallite_stress() crystallite_subFp0(1:3,1:3,c,i,e) = crystallite_partitionedFp0(1:3,1:3,c,i,e) crystallite_subFi0(1:3,1:3,c,i,e) = crystallite_partitionedFi0(1:3,1:3,c,i,e) crystallite_subF0(1:3,1:3,c,i,e) = crystallite_partitionedF0(1:3,1:3,c,i,e) - crystallite_subFrac(c,i,e) = 0.0_pReal + subFrac(c,i,e) = 0.0_pReal crystallite_subStep(c,i,e) = 1.0_pReal/num%subStepSizeCryst todo(c,i,e) = .true. crystallite_converged(c,i,e) = .false. ! pretend failed step of 1/subStepSizeCryst @@ -1062,8 +1053,8 @@ function crystallite_stress() ! wind forward if (crystallite_converged(c,i,e)) then formerSubStep = crystallite_subStep(c,i,e) - crystallite_subFrac(c,i,e) = crystallite_subFrac(c,i,e) + crystallite_subStep(c,i,e) - crystallite_subStep(c,i,e) = min(1.0_pReal - crystallite_subFrac(c,i,e), & + subFrac(c,i,e) = subFrac(c,i,e) + crystallite_subStep(c,i,e) + crystallite_subStep(c,i,e) = min(1.0_pReal - subFrac(c,i,e), & num%stepIncreaseCryst * crystallite_subStep(c,i,e)) todo(c,i,e) = crystallite_subStep(c,i,e) > 0.0_pReal ! still time left to integrate on? From d0b267b240cd619db243777682242174fdc57beb Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 20 Dec 2020 18:24:35 +0100 Subject: [PATCH 075/148] there are module functions --- src/constitutive_mech.f90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/constitutive_mech.f90 b/src/constitutive_mech.f90 index cab4a17d8..8f08aa08e 100644 --- a/src/constitutive_mech.f90 +++ b/src/constitutive_mech.f90 @@ -536,7 +536,7 @@ end subroutine constitutive_plastic_LpAndItsTangents !-------------------------------------------------------------------------------------------------- !> @brief contains the constitutive equation for calculating the rate of change of microstructure !-------------------------------------------------------------------------------------------------- -function constitutive_collectDotState(S, FArray, Fi, FpArray, subdt, ipc, ip, el,phase,of) result(broken) +module function constitutive_collectDotState(S, FArray, Fi, FpArray, subdt, ipc, ip, el,phase,of) result(broken) integer, intent(in) :: & ipc, & !< component-ID of integration point @@ -599,7 +599,7 @@ end function constitutive_collectDotState !> @brief for constitutive models having an instantaneous change of state !> will return false if delta state is not needed/supported by the constitutive model !-------------------------------------------------------------------------------------------------- -function constitutive_deltaState(S, Fi, ipc, ip, el, phase, of) result(broken) +module function constitutive_deltaState(S, Fi, ipc, ip, el, phase, of) result(broken) integer, intent(in) :: & ipc, & !< component-ID of integration point From 58f800cf3083be700b4eec0baf5a1dddeb6a2b25 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 20 Dec 2020 20:20:39 +0100 Subject: [PATCH 076/148] introduce new structure --- src/constitutive.f90 | 136 ++++++++++++++++++++++++++++--------------- 1 file changed, 88 insertions(+), 48 deletions(-) diff --git a/src/constitutive.f90 b/src/constitutive.f90 index d95eb5c0a..14dde1c9f 100644 --- a/src/constitutive.f90 +++ b/src/constitutive.f90 @@ -21,7 +21,7 @@ module constitutive implicit none private - real(pReal), dimension(:,:,:), allocatable, public :: & + real(pReal), dimension(:,:,:), allocatable, public :: & crystallite_dt !< requested time increment of each grain real(pReal), dimension(:,:,:), allocatable :: & crystallite_subdt, & !< substepped time increment of each grain @@ -40,9 +40,6 @@ module constitutive crystallite_partitionedFp0,& !< plastic def grad at start of homog inc crystallite_subFp0,& !< plastic def grad at start of crystallite inc ! - crystallite_Fi, & !< current intermediate def grad (end of converged time step) - crystallite_Fi0, & !< intermediate def grad at start of FE inc - crystallite_partitionedFi0,& !< intermediate def grad at start of homog inc crystallite_subFi0,& !< intermediate def grad at start of crystallite inc ! crystallite_Lp0, & !< plastic velocitiy grad at start of FE inc @@ -73,6 +70,15 @@ module constitutive end type tOutput type(tOutput), allocatable, dimension(:) :: output_constituent + type :: tTensorContainer + real(pReal), dimension(:,:,:), allocatable :: data + end type + + type(tTensorContainer), dimension(:), allocatable :: & + constitutive_mech_Fi, & + constitutive_mech_Fi0, & + constitutive_mech_partionedFi0 + type :: tNumerics integer :: & iJacoLpresiduum, & !< frequency of Jacobian update of residuum in Lp @@ -833,7 +839,9 @@ end subroutine constitutive_results subroutine crystallite_init integer :: & + Nconstituents, & p, & + m, & c, & !< counter in integration point component loop i, & !< counter in integration point loop e, & !< counter in element loop @@ -861,13 +869,13 @@ subroutine crystallite_init allocate(crystallite_partitionedF(3,3,cMax,iMax,eMax),source=0.0_pReal) allocate(crystallite_S0, & - crystallite_F0, crystallite_Fi0,crystallite_Fp0, & + crystallite_F0,crystallite_Fp0, & crystallite_Li0,crystallite_Lp0, & crystallite_partitionedS0, & - crystallite_partitionedF0,crystallite_partitionedFp0,crystallite_partitionedFi0, & + crystallite_partitionedF0,crystallite_partitionedFp0,& crystallite_partitionedLp0,crystallite_partitionedLi0, & crystallite_S,crystallite_P, & - crystallite_Fe,crystallite_Fi,crystallite_Fp, & + crystallite_Fe,crystallite_Fp, & crystallite_Li,crystallite_Lp, & crystallite_subF,crystallite_subF0, & crystallite_subFp0,crystallite_subFi0, & @@ -930,7 +938,11 @@ subroutine crystallite_init phases => config_material%get('phase') allocate(output_constituent(phases%length)) + allocate(constitutive_mech_Fi(phases%length)) + allocate(constitutive_mech_Fi0(phases%length)) + allocate(constitutive_mech_partionedFi0(phases%length)) do p = 1, phases%length + Nconstituents = count(material_phaseAt == p) * discretization_nIPs phase => phases%get(p) mech => phase%get('mechanics',defaultVal = emptyDict) #if defined(__GFORTRAN__) @@ -938,6 +950,9 @@ subroutine crystallite_init #else output_constituent(p)%label = mech%get_asStrings('output',defaultVal=emptyStringArray) #endif + allocate(constitutive_mech_Fi(p)%data(3,3,Nconstituents)) + allocate(constitutive_mech_Fi0(p)%data(3,3,Nconstituents)) + allocate(constitutive_mech_partionedFi0(p)%data(3,3,Nconstituents)) enddo print'(a42,1x,i10)', ' # of elements: ', eMax @@ -945,18 +960,27 @@ subroutine crystallite_init print'(a42,1x,i10)', 'max # of constituents/integration point: ', cMax flush(IO_STDOUT) - !$OMP PARALLEL DO PRIVATE(i,c) + !$OMP PARALLEL DO PRIVATE(p,m) do e = FEsolving_execElem(1),FEsolving_execElem(2) do i = FEsolving_execIP(1), FEsolving_execIP(2); do c = 1, homogenization_Nconstituents(material_homogenizationAt(e)) + + p = material_phaseAt(i,e) + m = material_phaseMemberAt(c,i,e) crystallite_Fp0(1:3,1:3,c,i,e) = material_orientation0(c,i,e)%asMatrix() ! Fp reflects initial orientation (see 10.1016/j.actamat.2006.01.005) crystallite_Fp0(1:3,1:3,c,i,e) = crystallite_Fp0(1:3,1:3,c,i,e) & / math_det33(crystallite_Fp0(1:3,1:3,c,i,e))**(1.0_pReal/3.0_pReal) - crystallite_Fi0(1:3,1:3,c,i,e) = math_I3 + constitutive_mech_Fi0(p)%data(1:3,1:3,m) = math_I3 + crystallite_F0(1:3,1:3,c,i,e) = math_I3 - crystallite_Fe(1:3,1:3,c,i,e) = math_inv33(matmul(crystallite_Fi0(1:3,1:3,c,i,e), & + + crystallite_Fe(1:3,1:3,c,i,e) = math_inv33(matmul(constitutive_mech_Fi0(p)%data(1:3,1:3,m), & crystallite_Fp0(1:3,1:3,c,i,e))) ! assuming that euler angles are given in internal strain free configuration crystallite_Fp(1:3,1:3,c,i,e) = crystallite_Fp0(1:3,1:3,c,i,e) - crystallite_Fi(1:3,1:3,c,i,e) = crystallite_Fi0(1:3,1:3,c,i,e) + constitutive_mech_Fi(p)%data(1:3,1:3,m) = constitutive_mech_Fi0(p)%data(1:3,1:3,m) + + constitutive_mech_partionedFi0(p)%data(1:3,1:3,m) = constitutive_mech_Fi0(p)%data(1:3,1:3,m) + + crystallite_requested(c,i,e) = .true. enddo; enddo enddo @@ -964,7 +988,6 @@ subroutine crystallite_init crystallite_partitionedFp0 = crystallite_Fp0 - crystallite_partitionedFi0 = crystallite_Fi0 crystallite_partitionedF0 = crystallite_F0 crystallite_partitionedF = crystallite_F0 @@ -999,7 +1022,7 @@ function crystallite_stress() c, & !< counter in integration point component loop i, & !< counter in integration point loop e, & !< counter in element loop - s + s, p, m logical, dimension(homogenization_maxNconstituents,discretization_nIPs,discretization_Nelems) :: todo !ToDo: need to set some values to false for different Ngrains real(pReal), dimension(homogenization_maxNconstituents,discretization_nIPs,discretization_Nelems) :: subFrac !ToDo: need to set some values to false for different Ngrains real(pReal), dimension(:,:,:,:,:), allocatable :: & @@ -1014,10 +1037,12 @@ function crystallite_stress() !-------------------------------------------------------------------------------------------------- ! initialize to starting condition crystallite_subStep = 0.0_pReal - !$OMP PARALLEL DO + !$OMP PARALLEL DO PRIVATE(p,m) elementLooping1: do e = FEsolving_execElem(1),FEsolving_execElem(2) do i = FEsolving_execIP(1),FEsolving_execIP(2); do c = 1,homogenization_Nconstituents(material_homogenizationAt(e)) homogenizationRequestsCalculation: if (crystallite_requested(c,i,e)) then + p = material_phaseAt(i,e) + m = material_phaseMemberAt(c,i,e) plasticState (material_phaseAt(c,e))%subState0( :,material_phaseMemberAt(c,i,e)) = & plasticState (material_phaseAt(c,e))%partitionedState0(:,material_phaseMemberAt(c,i,e)) @@ -1026,7 +1051,7 @@ function crystallite_stress() sourceState(material_phaseAt(c,e))%p(s)%partitionedState0(:,material_phaseMemberAt(c,i,e)) enddo crystallite_subFp0(1:3,1:3,c,i,e) = crystallite_partitionedFp0(1:3,1:3,c,i,e) - crystallite_subFi0(1:3,1:3,c,i,e) = crystallite_partitionedFi0(1:3,1:3,c,i,e) + crystallite_subFi0(1:3,1:3,c,i,e) = constitutive_mech_partionedFi0(p)%data(1:3,1:3,m) crystallite_subF0(1:3,1:3,c,i,e) = crystallite_partitionedF0(1:3,1:3,c,i,e) subFrac(c,i,e) = 0.0_pReal crystallite_subStep(c,i,e) = 1.0_pReal/num%subStepSizeCryst @@ -1045,10 +1070,12 @@ function crystallite_stress() if (debugCrystallite%extensive) & print'(a,i6)', '<< CRYST stress >> crystallite iteration ',NiterationCrystallite #endif - !$OMP PARALLEL DO PRIVATE(formerSubStep) + !$OMP PARALLEL DO PRIVATE(formerSubStep,p,m) elementLooping3: do e = FEsolving_execElem(1),FEsolving_execElem(2) do i = FEsolving_execIP(1),FEsolving_execIP(2) do c = 1,homogenization_Nconstituents(material_homogenizationAt(e)) + p = material_phaseAt(i,e) + m = material_phaseMemberAt(c,i,e) !-------------------------------------------------------------------------------------------------- ! wind forward if (crystallite_converged(c,i,e)) then @@ -1058,12 +1085,13 @@ function crystallite_stress() num%stepIncreaseCryst * crystallite_subStep(c,i,e)) todo(c,i,e) = crystallite_subStep(c,i,e) > 0.0_pReal ! still time left to integrate on? + if (todo(c,i,e)) then crystallite_subF0 (1:3,1:3,c,i,e) = crystallite_subF(1:3,1:3,c,i,e) subLp0(1:3,1:3,c,i,e) = crystallite_Lp (1:3,1:3,c,i,e) subLi0(1:3,1:3,c,i,e) = crystallite_Li (1:3,1:3,c,i,e) crystallite_subFp0(1:3,1:3,c,i,e) = crystallite_Fp (1:3,1:3,c,i,e) - crystallite_subFi0(1:3,1:3,c,i,e) = crystallite_Fi (1:3,1:3,c,i,e) + crystallite_subFi0(1:3,1:3,c,i,e) = constitutive_mech_Fi(p)%data(1:3,1:3,m) plasticState( material_phaseAt(c,e))%subState0(:,material_phaseMemberAt(c,i,e)) & = plasticState(material_phaseAt(c,e))%state( :,material_phaseMemberAt(c,i,e)) do s = 1, phase_Nsources(material_phaseAt(c,e)) @@ -1077,7 +1105,7 @@ function crystallite_stress() else 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_Fi (1:3,1:3,c,i,e) = crystallite_subFi0(1:3,1:3,c,i,e) + constitutive_mech_Fi(p)%data(1:3,1:3,m) = crystallite_subFi0(1:3,1:3,c,i,e) crystallite_S (1:3,1:3,c,i,e) = crystallite_S0 (1:3,1:3,c,i,e) if (crystallite_subStep(c,i,e) < 1.0_pReal) then ! actual (not initial) cutback crystallite_Lp (1:3,1:3,c,i,e) = subLp0(1:3,1:3,c,i,e) @@ -1101,7 +1129,7 @@ function crystallite_stress() + crystallite_subStep(c,i,e) *( crystallite_partitionedF (1:3,1:3,c,i,e) & -crystallite_partitionedF0(1:3,1:3,c,i,e)) crystallite_Fe(1:3,1:3,c,i,e) = matmul(crystallite_subF(1:3,1:3,c,i,e), & - math_inv33(matmul(crystallite_Fi(1:3,1:3,c,i,e), & + math_inv33(matmul(constitutive_mech_Fi(p)%data(1:3,1:3,m), & crystallite_Fp(1:3,1:3,c,i,e)))) crystallite_subdt(c,i,e) = crystallite_subStep(c,i,e) * crystallite_dt(c,i,e) crystallite_converged(c,i,e) = .false. @@ -1141,12 +1169,14 @@ subroutine crystallite_initializeRestorationPoints(i,e) e !< element number integer :: & c, & !< constituent number - s + s,p, m + p = material_phaseAt(i,e) do c = 1,homogenization_Nconstituents(material_homogenizationAt(e)) + m = material_phaseMemberAt(c,i,e) crystallite_partitionedFp0(1:3,1:3,c,i,e) = crystallite_Fp0(1:3,1:3,c,i,e) crystallite_partitionedLp0(1:3,1:3,c,i,e) = crystallite_Lp0(1:3,1:3,c,i,e) - crystallite_partitionedFi0(1:3,1:3,c,i,e) = crystallite_Fi0(1:3,1:3,c,i,e) + constitutive_mech_partionedFi0(p)%data(1:3,1:3,m) = constitutive_mech_Fi0(p)%data(1:3,1:3,m) crystallite_partitionedLi0(1:3,1:3,c,i,e) = crystallite_Li0(1:3,1:3,c,i,e) crystallite_partitionedF0(1:3,1:3,c,i,e) = crystallite_F0(1:3,1:3,c,i,e) crystallite_partitionedS0(1:3,1:3,c,i,e) = crystallite_S0(1:3,1:3,c,i,e) @@ -1172,13 +1202,14 @@ subroutine crystallite_windForward(i,e) e !< element number integer :: & c, & !< constituent number - s - + s, p, m + p = material_phaseAt(i,e) do c = 1,homogenization_Nconstituents(material_homogenizationAt(e)) + m = material_phaseMemberAt(c,i,e) crystallite_partitionedF0 (1:3,1:3,c,i,e) = crystallite_partitionedF(1:3,1:3,c,i,e) crystallite_partitionedFp0(1:3,1:3,c,i,e) = crystallite_Fp (1:3,1:3,c,i,e) crystallite_partitionedLp0(1:3,1:3,c,i,e) = crystallite_Lp (1:3,1:3,c,i,e) - crystallite_partitionedFi0(1:3,1:3,c,i,e) = crystallite_Fi (1:3,1:3,c,i,e) + constitutive_mech_partionedFi0(p)%data(1:3,1:3,m) = constitutive_mech_Fi(p)%data(1:3,1:3,m) crystallite_partitionedLi0(1:3,1:3,c,i,e) = crystallite_Li (1:3,1:3,c,i,e) crystallite_partitionedS0 (1:3,1:3,c,i,e) = crystallite_S (1:3,1:3,c,i,e) @@ -1204,15 +1235,17 @@ subroutine crystallite_restore(i,e,includeL) logical, intent(in) :: & includeL !< protect agains fake cutback integer :: & - c !< constituent number + c, p, m !< constituent number + p = material_phaseAt(i,e) do c = 1,homogenization_Nconstituents(material_homogenizationAt(e)) if (includeL) then crystallite_Lp(1:3,1:3,c,i,e) = crystallite_partitionedLp0(1:3,1:3,c,i,e) crystallite_Li(1:3,1:3,c,i,e) = crystallite_partitionedLi0(1:3,1:3,c,i,e) endif ! maybe protecting everything from overwriting makes more sense + m = material_phaseMemberAt(c,i,e) crystallite_Fp(1:3,1:3,c,i,e) = crystallite_partitionedFp0(1:3,1:3,c,i,e) - crystallite_Fi(1:3,1:3,c,i,e) = crystallite_partitionedFi0(1:3,1:3,c,i,e) + constitutive_mech_Fi(p)%data(1:3,1:3,m) = constitutive_mech_partionedFi0(p)%data(1:3,1:3,m) crystallite_S (1:3,1:3,c,i,e) = crystallite_partitionedS0 (1:3,1:3,c,i,e) plasticState (material_phaseAt(c,e))%state( :,material_phasememberAt(c,i,e)) = & @@ -1234,7 +1267,7 @@ function crystallite_stressTangent(c,i,e) result(dPdF) e !< counter in element loop integer :: & o, & - p + p, pp, m real(pReal), dimension(3,3) :: devNull, & invSubFp0,invSubFi0,invFp,invFi, & @@ -1254,17 +1287,19 @@ function crystallite_stressTangent(c,i,e) result(dPdF) real(pReal), dimension(9,9):: temp_99 logical :: error + pp = material_phaseAt(i,e) + m = material_phaseMemberAt(c,i,e) call constitutive_SandItsTangents(devNull,dSdFe,dSdFi, & crystallite_Fe(1:3,1:3,c,i,e), & - crystallite_Fi(1:3,1:3,c,i,e),c,i,e) + constitutive_mech_Fi(pp)%data(1:3,1:3,m),c,i,e) call constitutive_LiAndItsTangents(devNull,dLidS,dLidFi, & crystallite_S (1:3,1:3,c,i,e), & - crystallite_Fi(1:3,1:3,c,i,e), & + constitutive_mech_Fi(pp)%data(1:3,1:3,m), & 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)) + invFi = math_inv33(constitutive_mech_Fi(pp)%data(1:3,1:3,m)) invSubFp0 = math_inv33(crystallite_subFp0(1:3,1:3,c,i,e)) invSubFi0 = math_inv33(crystallite_subFi0(1:3,1:3,c,i,e)) @@ -1293,7 +1328,7 @@ function crystallite_stressTangent(c,i,e) result(dPdF) call constitutive_LpAndItsTangents(devNull,dLpdS,dLpdFi, & crystallite_S (1:3,1:3,c,i,e), & - crystallite_Fi(1:3,1:3,c,i,e),c,i,e) ! call constitutive law to calculate Lp tangent in lattice configuration + constitutive_mech_Fi(pp)%data(1:3,1:3,m),c,i,e) dLpdS = math_mul3333xx3333(dLpdFi,dFidS) + dLpdS !-------------------------------------------------------------------------------------------------- @@ -1434,8 +1469,7 @@ subroutine crystallite_results call results_writeDataset(group,selected_tensors,output_constituent(p)%label(o),& 'plastic deformation gradient','1') case('F_i') - selected_tensors = select_tensors(crystallite_Fi,p) - call results_writeDataset(group,selected_tensors,output_constituent(p)%label(o),& + call results_writeDataset(group,constitutive_mech_Fi(p)%data,output_constituent(p)%label(o),& 'inelastic deformation gradient','1') case('L_p') selected_tensors = select_tensors(crystallite_Lp,p) @@ -1593,6 +1627,7 @@ function integrateStress(ipc,ip,el,timeFraction) result(broken) ierr, & ! error indicator for LAPACK o, & p, & + m, & jacoCounterLp, & jacoCounterLi ! counters to check for Jacobian update logical :: error,broken @@ -1741,12 +1776,15 @@ function integrateStress(ipc,ip,el,timeFraction) result(broken) call math_invert33(Fp_new,devNull,error,invFp_new) if (error) return ! error + p = material_phaseAt(ipc,el) + m = material_phaseMemberAt(ipc,ip,el) + 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_Lp (1:3,1:3,ipc,ip,el) = Lpguess crystallite_Li (1:3,1:3,ipc,ip,el) = Liguess crystallite_Fp (1:3,1:3,ipc,ip,el) = Fp_new / math_det33(Fp_new)**(1.0_pReal/3.0_pReal) ! regularize - crystallite_Fi (1:3,1:3,ipc,ip,el) = Fi_new + constitutive_mech_Fi(p)%data(1:3,1:3,m) = Fi_new crystallite_Fe (1:3,1:3,ipc,ip,el) = matmul(matmul(F,invFp_new),invFi_new) broken = .false. @@ -1786,7 +1824,7 @@ subroutine integrateStateFPI(g,i,e) broken = constitutive_collectDotState(crystallite_S(1:3,1:3,g,i,e), & crystallite_partitionedF0, & - crystallite_Fi(1:3,1:3,g,i,e), & + constitutive_mech_Fi(p)%data(1:3,1:3,c), & crystallite_partitionedFp0, & crystallite_subdt(g,i,e), g,i,e,p,c) if(broken) return @@ -1807,7 +1845,7 @@ subroutine integrateStateFPI(g,i,e) broken = constitutive_collectDotState(crystallite_S(1:3,1:3,g,i,e), & crystallite_partitionedF0, & - crystallite_Fi(1:3,1:3,g,i,e), & + constitutive_mech_Fi(p)%data(1:3,1:3,c), & crystallite_partitionedFp0, & crystallite_subdt(g,i,e), g,i,e,p,c) if(broken) exit iteration @@ -1827,7 +1865,7 @@ subroutine integrateStateFPI(g,i,e) if(crystallite_converged(g,i,e)) then broken = constitutive_deltaState(crystallite_S(1:3,1:3,g,i,e), & - crystallite_Fi(1:3,1:3,g,i,e),g,i,e,p,c) + constitutive_mech_Fi(p)%data(1:3,1:3,c),g,i,e,p,c) exit iteration endif @@ -1979,7 +2017,7 @@ subroutine integrateStateEuler(g,i,e) broken = constitutive_collectDotState(crystallite_S(1:3,1:3,g,i,e), & crystallite_partitionedF0, & - crystallite_Fi(1:3,1:3,g,i,e), & + constitutive_mech_Fi(p)%data(1:3,1:3,c), & crystallite_partitionedFp0, & crystallite_subdt(g,i,e), g,i,e,p,c) if(broken) return @@ -1990,7 +2028,7 @@ subroutine integrateStateEuler(g,i,e) * crystallite_subdt(g,i,e) broken = constitutive_deltaState(crystallite_S(1:3,1:3,g,i,e), & - crystallite_Fi(1:3,1:3,g,i,e),g,i,e,p,c) + constitutive_mech_Fi(p)%data(1:3,1:3,c),g,i,e,p,c) if(broken) return broken = integrateStress(g,i,e) @@ -2023,7 +2061,7 @@ subroutine integrateStateAdaptiveEuler(g,i,e) broken = constitutive_collectDotState(crystallite_S(1:3,1:3,g,i,e), & crystallite_partitionedF0, & - crystallite_Fi(1:3,1:3,g,i,e), & + constitutive_mech_Fi(p)%data(1:3,1:3,c), & crystallite_partitionedFp0, & crystallite_subdt(g,i,e), g,i,e,p,c) if(broken) return @@ -2035,7 +2073,7 @@ subroutine integrateStateAdaptiveEuler(g,i,e) + plasticState(p)%dotstate(1:sizeDotState,c) * crystallite_subdt(g,i,e) broken = constitutive_deltaState(crystallite_S(1:3,1:3,g,i,e), & - crystallite_Fi(1:3,1:3,g,i,e),g,i,e,p,c) + constitutive_mech_Fi(p)%data(1:3,1:3,c),g,i,e,p,c) if(broken) return broken = integrateStress(g,i,e) @@ -2043,7 +2081,7 @@ subroutine integrateStateAdaptiveEuler(g,i,e) broken = constitutive_collectDotState(crystallite_S(1:3,1:3,g,i,e), & crystallite_partitionedF0, & - crystallite_Fi(1:3,1:3,g,i,e), & + constitutive_mech_Fi(p)%data(1:3,1:3,c), & crystallite_partitionedFp0, & crystallite_subdt(g,i,e), g,i,e,p,c) if(broken) return @@ -2141,7 +2179,7 @@ subroutine integrateStateRK(g,i,e,A,B,CC,DB) broken = constitutive_collectDotState(crystallite_S(1:3,1:3,g,i,e), & crystallite_partitionedF0, & - crystallite_Fi(1:3,1:3,g,i,e), & + constitutive_mech_Fi(p)%data(1:3,1:3,c), & crystallite_partitionedFp0, & crystallite_subdt(g,i,e), g,i,e,p,c) if(broken) return @@ -2167,7 +2205,7 @@ subroutine integrateStateRK(g,i,e,A,B,CC,DB) broken = constitutive_collectDotState(crystallite_S(1:3,1:3,g,i,e), & crystallite_partitionedF0, & - crystallite_Fi(1:3,1:3,g,i,e), & + constitutive_mech_Fi(p)%data(1:3,1:3,c), & crystallite_partitionedFp0, & crystallite_subdt(g,i,e)*CC(stage), g,i,e,p,c) if(broken) exit @@ -2191,7 +2229,7 @@ subroutine integrateStateRK(g,i,e,A,B,CC,DB) if(broken) return broken = constitutive_deltaState(crystallite_S(1:3,1:3,g,i,e), & - crystallite_Fi(1:3,1:3,g,i,e),g,i,e,p,c) + constitutive_mech_Fi(p)%data(1:3,1:3,c),g,i,e,p,c) if(broken) return broken = integrateStress(g,i,e) @@ -2235,7 +2273,6 @@ subroutine crystallite_restartWrite call HDF5_write(fileHandle,crystallite_partitionedF,'F') call HDF5_write(fileHandle,crystallite_Fp, 'F_p') - call HDF5_write(fileHandle,crystallite_Fi, 'F_i') call HDF5_write(fileHandle,crystallite_Lp, 'L_p') call HDF5_write(fileHandle,crystallite_Li, 'L_i') call HDF5_write(fileHandle,crystallite_S, 'S') @@ -2244,6 +2281,8 @@ subroutine crystallite_restartWrite do i = 1,size(material_name_phase) write(datasetName,'(i0,a)') i,'_omega' call HDF5_write(groupHandle,plasticState(i)%state,datasetName) + write(datasetName,'(i0,a)') i,'_F_i' + call HDF5_write(groupHandle,constitutive_mech_Fi(i)%data,datasetName) enddo call HDF5_closeGroup(groupHandle) @@ -2276,7 +2315,6 @@ subroutine crystallite_restartRead call HDF5_read(fileHandle,crystallite_F0, 'F') call HDF5_read(fileHandle,crystallite_Fp0,'F_p') - call HDF5_read(fileHandle,crystallite_Fi0,'F_i') call HDF5_read(fileHandle,crystallite_Lp0,'L_p') call HDF5_read(fileHandle,crystallite_Li0,'L_i') call HDF5_read(fileHandle,crystallite_S0, 'S') @@ -2285,6 +2323,8 @@ subroutine crystallite_restartRead do i = 1,size(material_name_phase) write(datasetName,'(i0,a)') i,'_omega' call HDF5_read(groupHandle,plasticState(i)%state0,datasetName) + write(datasetName,'(i0,a)') i,'_F_i' + call HDF5_read(groupHandle,constitutive_mech_Fi0(i)%data,datasetName) enddo call HDF5_closeGroup(groupHandle) @@ -2311,12 +2351,12 @@ subroutine crystallite_forward crystallite_F0 = crystallite_partitionedF crystallite_Fp0 = crystallite_Fp crystallite_Lp0 = crystallite_Lp - crystallite_Fi0 = crystallite_Fi crystallite_Li0 = crystallite_Li crystallite_S0 = crystallite_S do i = 1, size(plasticState) plasticState(i)%state0 = plasticState(i)%state + constitutive_mech_Fi0(i) = constitutive_mech_Fi(i) enddo do i = 1,size(material_name_homogenization) homogState (i)%state0 = homogState (i)%state From 07873b24092ffc65ae4dc1c798e8680f7e5cb180 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Mon, 21 Dec 2020 08:05:38 +0100 Subject: [PATCH 077/148] cleaning --- src/constitutive.f90 | 24 +++++++----------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/src/constitutive.f90 b/src/constitutive.f90 index 14dde1c9f..a9e8dc0b1 100644 --- a/src/constitutive.f90 +++ b/src/constitutive.f90 @@ -347,9 +347,7 @@ end function constitutive_deltaState module subroutine damage_results end subroutine damage_results - end interface - interface constitutive_LpAndItsTangents module subroutine constitutive_plastic_LpAndItsTangents(Lp, dLp_dS, dLp_dFi, & S, Fi, ipc, ip, el) @@ -367,9 +365,6 @@ end function constitutive_deltaState dLp_dFi !< derivative of Lp with respect to Fi end subroutine constitutive_plastic_LpAndItsTangents - end interface constitutive_LpAndItsTangents - - interface constitutive_dependentState module subroutine constitutive_plastic_dependentState(F, Fp, ipc, ip, el) integer, intent(in) :: & @@ -381,9 +376,7 @@ end function constitutive_deltaState Fp !< plastic deformation gradient end subroutine constitutive_plastic_dependentState - end interface constitutive_dependentState - interface constitutive_SandItsTangents module subroutine constitutive_hooke_SandItsTangents(S, dS_dFe, dS_dFi, Fe, Fi, ipc, ip, el) integer, intent(in) :: & @@ -400,7 +393,7 @@ end function constitutive_deltaState dS_dFi !< derivative of 2nd P-K stress with respect to intermediate deformation gradient end subroutine constitutive_hooke_SandItsTangents - end interface constitutive_SandItsTangents + end interface type(tDebugOptions) :: debugConstitutive @@ -408,10 +401,7 @@ end function constitutive_deltaState public :: & constitutive_init, & constitutive_homogenizedC, & - constitutive_LpAndItsTangents, & - constitutive_dependentState, & constitutive_LiAndItsTangents, & - constitutive_SandItsTangents, & constitutive_collectDotState, & constitutive_collectDotState_source, & constitutive_deltaState, & @@ -997,7 +987,7 @@ subroutine crystallite_init do e = FEsolving_execElem(1),FEsolving_execElem(2) do i = FEsolving_execIP(1),FEsolving_execIP(2) do c = 1,homogenization_Nconstituents(material_homogenizationAt(e)) - call constitutive_dependentState(crystallite_partitionedF0(1:3,1:3,c,i,e), & + call constitutive_plastic_dependentState(crystallite_partitionedF0(1:3,1:3,c,i,e), & crystallite_partitionedFp0(1:3,1:3,c,i,e), & c,i,e) ! update dependent state variables to be consistent with basic states enddo @@ -1290,7 +1280,7 @@ function crystallite_stressTangent(c,i,e) result(dPdF) pp = material_phaseAt(i,e) m = material_phaseMemberAt(c,i,e) - call constitutive_SandItsTangents(devNull,dSdFe,dSdFi, & + call constitutive_hooke_SandItsTangents(devNull,dSdFe,dSdFi, & crystallite_Fe(1:3,1:3,c,i,e), & constitutive_mech_Fi(pp)%data(1:3,1:3,m),c,i,e) call constitutive_LiAndItsTangents(devNull,dLidS,dLidFi, & @@ -1326,7 +1316,7 @@ function crystallite_stressTangent(c,i,e) result(dPdF) dLidS = math_mul3333xx3333(dLidFi,dFidS) + dLidS endif - call constitutive_LpAndItsTangents(devNull,dLpdS,dLpdFi, & + call constitutive_plastic_LpAndItsTangents(devNull,dLpdS,dLpdFi, & crystallite_S (1:3,1:3,c,i,e), & constitutive_mech_Fi(pp)%data(1:3,1:3,m),c,i,e) dLpdS = math_mul3333xx3333(dLpdFi,dFidS) + dLpdS @@ -1643,7 +1633,7 @@ function integrateStress(ipc,ip,el,timeFraction) result(broken) F = crystallite_subF(1:3,1:3,ipc,ip,el) endif - call constitutive_dependentState(crystallite_partitionedF(1:3,1:3,ipc,ip,el), & + call constitutive_plastic_dependentState(crystallite_partitionedF(1:3,1:3,ipc,ip,el), & crystallite_Fp(1:3,1:3,ipc,ip,el),ipc,ip,el) Lpguess = crystallite_Lp(1:3,1:3,ipc,ip,el) ! take as first guess @@ -1681,10 +1671,10 @@ function integrateStress(ipc,ip,el,timeFraction) result(broken) B = math_I3 - dt*Lpguess Fe = matmul(matmul(A,B), invFi_new) - call constitutive_SandItsTangents(S, dS_dFe, dS_dFi, & + call constitutive_hooke_SandItsTangents(S, dS_dFe, dS_dFi, & Fe, Fi_new, ipc, ip, el) - call constitutive_LpAndItsTangents(Lp_constitutive, dLp_dS, dLp_dFi, & + call constitutive_plastic_LpAndItsTangents(Lp_constitutive, dLp_dS, dLp_dFi, & S, Fi_new, ipc, ip, el) !* update current residuum and check for convergence of loop From 43cbe622d05c6f67bc30a4b226277e9f50b1875c Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Mon, 21 Dec 2020 09:48:20 +0100 Subject: [PATCH 078/148] phase depends on constituent, not integration point --- src/constitutive.f90 | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/constitutive.f90 b/src/constitutive.f90 index a9e8dc0b1..28c68b7b2 100644 --- a/src/constitutive.f90 +++ b/src/constitutive.f90 @@ -954,7 +954,7 @@ subroutine crystallite_init do e = FEsolving_execElem(1),FEsolving_execElem(2) do i = FEsolving_execIP(1), FEsolving_execIP(2); do c = 1, homogenization_Nconstituents(material_homogenizationAt(e)) - p = material_phaseAt(i,e) + p = material_phaseAt(c,e) m = material_phaseMemberAt(c,i,e) crystallite_Fp0(1:3,1:3,c,i,e) = material_orientation0(c,i,e)%asMatrix() ! Fp reflects initial orientation (see 10.1016/j.actamat.2006.01.005) crystallite_Fp0(1:3,1:3,c,i,e) = crystallite_Fp0(1:3,1:3,c,i,e) & @@ -1031,7 +1031,7 @@ function crystallite_stress() elementLooping1: do e = FEsolving_execElem(1),FEsolving_execElem(2) do i = FEsolving_execIP(1),FEsolving_execIP(2); do c = 1,homogenization_Nconstituents(material_homogenizationAt(e)) homogenizationRequestsCalculation: if (crystallite_requested(c,i,e)) then - p = material_phaseAt(i,e) + p = material_phaseAt(c,e) m = material_phaseMemberAt(c,i,e) plasticState (material_phaseAt(c,e))%subState0( :,material_phaseMemberAt(c,i,e)) = & plasticState (material_phaseAt(c,e))%partitionedState0(:,material_phaseMemberAt(c,i,e)) @@ -1064,7 +1064,7 @@ function crystallite_stress() elementLooping3: do e = FEsolving_execElem(1),FEsolving_execElem(2) do i = FEsolving_execIP(1),FEsolving_execIP(2) do c = 1,homogenization_Nconstituents(material_homogenizationAt(e)) - p = material_phaseAt(i,e) + p = material_phaseAt(c,e) m = material_phaseMemberAt(c,i,e) !-------------------------------------------------------------------------------------------------- ! wind forward @@ -1161,9 +1161,9 @@ subroutine crystallite_initializeRestorationPoints(i,e) c, & !< constituent number s,p, m - p = material_phaseAt(i,e) do c = 1,homogenization_Nconstituents(material_homogenizationAt(e)) - m = material_phaseMemberAt(c,i,e) + p = material_phaseAt(c,e) + m = material_phaseMemberAt(c,i,e) crystallite_partitionedFp0(1:3,1:3,c,i,e) = crystallite_Fp0(1:3,1:3,c,i,e) crystallite_partitionedLp0(1:3,1:3,c,i,e) = crystallite_Lp0(1:3,1:3,c,i,e) constitutive_mech_partionedFi0(p)%data(1:3,1:3,m) = constitutive_mech_Fi0(p)%data(1:3,1:3,m) @@ -1193,9 +1193,9 @@ subroutine crystallite_windForward(i,e) integer :: & c, & !< constituent number s, p, m - p = material_phaseAt(i,e) do c = 1,homogenization_Nconstituents(material_homogenizationAt(e)) - m = material_phaseMemberAt(c,i,e) + p = material_phaseAt(c,e) + m = material_phaseMemberAt(c,i,e) crystallite_partitionedF0 (1:3,1:3,c,i,e) = crystallite_partitionedF(1:3,1:3,c,i,e) crystallite_partitionedFp0(1:3,1:3,c,i,e) = crystallite_Fp (1:3,1:3,c,i,e) crystallite_partitionedLp0(1:3,1:3,c,i,e) = crystallite_Lp (1:3,1:3,c,i,e) @@ -1226,13 +1226,13 @@ subroutine crystallite_restore(i,e,includeL) includeL !< protect agains fake cutback integer :: & c, p, m !< constituent number - p = material_phaseAt(i,e) do c = 1,homogenization_Nconstituents(material_homogenizationAt(e)) if (includeL) then crystallite_Lp(1:3,1:3,c,i,e) = crystallite_partitionedLp0(1:3,1:3,c,i,e) crystallite_Li(1:3,1:3,c,i,e) = crystallite_partitionedLi0(1:3,1:3,c,i,e) endif ! maybe protecting everything from overwriting makes more sense + p = material_phaseAt(c,e) m = material_phaseMemberAt(c,i,e) crystallite_Fp(1:3,1:3,c,i,e) = crystallite_partitionedFp0(1:3,1:3,c,i,e) constitutive_mech_Fi(p)%data(1:3,1:3,m) = constitutive_mech_partionedFi0(p)%data(1:3,1:3,m) @@ -1277,7 +1277,7 @@ function crystallite_stressTangent(c,i,e) result(dPdF) real(pReal), dimension(9,9):: temp_99 logical :: error - pp = material_phaseAt(i,e) + pp = material_phaseAt(c,e) m = material_phaseMemberAt(c,i,e) call constitutive_hooke_SandItsTangents(devNull,dSdFe,dSdFi, & From 2ceb000002b80a28001999f08a30f5156b0cf573 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Mon, 21 Dec 2020 09:59:13 +0100 Subject: [PATCH 079/148] using new structure --- src/constitutive.f90 | 69 +++++++++++++++++++++++++------------------- 1 file changed, 39 insertions(+), 30 deletions(-) diff --git a/src/constitutive.f90 b/src/constitutive.f90 index 28c68b7b2..75d5e098f 100644 --- a/src/constitutive.f90 +++ b/src/constitutive.f90 @@ -45,10 +45,6 @@ module constitutive crystallite_Lp0, & !< plastic velocitiy grad at start of FE inc crystallite_partitionedLp0, & !< plastic velocity grad at start of homog inc ! - crystallite_Li, & !< current intermediate velocitiy grad (end of converged time step) - crystallite_Li0, & !< intermediate velocitiy grad at start of FE inc - crystallite_partitionedLi0, & !< intermediate velocity grad at start of homog inc - ! crystallite_S0, & !< 2nd Piola-Kirchhoff stress vector at start of FE inc crystallite_partitionedS0 !< 2nd Piola-Kirchhoff stress vector at start of homog inc real(pReal), dimension(:,:,:,:,:), allocatable, public, protected :: & @@ -77,7 +73,10 @@ module constitutive type(tTensorContainer), dimension(:), allocatable :: & constitutive_mech_Fi, & constitutive_mech_Fi0, & - constitutive_mech_partionedFi0 + constitutive_mech_partionedFi0, & + constitutive_mech_Li, & + constitutive_mech_Li0, & + constitutive_mech_partionedLi0 type :: tNumerics integer :: & @@ -859,14 +858,12 @@ subroutine crystallite_init allocate(crystallite_partitionedF(3,3,cMax,iMax,eMax),source=0.0_pReal) allocate(crystallite_S0, & - crystallite_F0,crystallite_Fp0, & - crystallite_Li0,crystallite_Lp0, & + crystallite_F0,crystallite_Fp0,crystallite_Lp0, & crystallite_partitionedS0, & crystallite_partitionedF0,crystallite_partitionedFp0,& - crystallite_partitionedLp0,crystallite_partitionedLi0, & + crystallite_partitionedLp0, & crystallite_S,crystallite_P, & - crystallite_Fe,crystallite_Fp, & - crystallite_Li,crystallite_Lp, & + crystallite_Fe,crystallite_Fp,crystallite_Lp, & crystallite_subF,crystallite_subF0, & crystallite_subFp0,crystallite_subFi0, & source = crystallite_partitionedF) @@ -931,6 +928,9 @@ subroutine crystallite_init allocate(constitutive_mech_Fi(phases%length)) allocate(constitutive_mech_Fi0(phases%length)) allocate(constitutive_mech_partionedFi0(phases%length)) + allocate(constitutive_mech_Li(phases%length)) + allocate(constitutive_mech_Li0(phases%length)) + allocate(constitutive_mech_partionedLi0(phases%length)) do p = 1, phases%length Nconstituents = count(material_phaseAt == p) * discretization_nIPs phase => phases%get(p) @@ -940,9 +940,12 @@ subroutine crystallite_init #else output_constituent(p)%label = mech%get_asStrings('output',defaultVal=emptyStringArray) #endif - allocate(constitutive_mech_Fi(p)%data(3,3,Nconstituents)) - allocate(constitutive_mech_Fi0(p)%data(3,3,Nconstituents)) - allocate(constitutive_mech_partionedFi0(p)%data(3,3,Nconstituents)) + allocate(constitutive_mech_Fi(p)%data(3,3,Nconstituents)) + allocate(constitutive_mech_Fi0(p)%data(3,3,Nconstituents)) + allocate(constitutive_mech_partionedFi0(p)%data(3,3,Nconstituents)) + allocate(constitutive_mech_Li(p)%data(3,3,Nconstituents)) + allocate(constitutive_mech_Li0(p)%data(3,3,Nconstituents)) + allocate(constitutive_mech_partionedLi0(p)%data(3,3,Nconstituents)) enddo print'(a42,1x,i10)', ' # of elements: ', eMax @@ -1021,8 +1024,8 @@ function crystallite_stress() todo = .false. + allocate(subLi0(3,3,homogenization_maxNconstituents,discretization_nIPs,discretization_Nelems)) subLp0 = crystallite_partitionedLp0 - subLi0 = crystallite_partitionedLi0 !-------------------------------------------------------------------------------------------------- ! initialize to starting condition @@ -1030,9 +1033,10 @@ function crystallite_stress() !$OMP PARALLEL DO PRIVATE(p,m) elementLooping1: do e = FEsolving_execElem(1),FEsolving_execElem(2) do i = FEsolving_execIP(1),FEsolving_execIP(2); do c = 1,homogenization_Nconstituents(material_homogenizationAt(e)) - homogenizationRequestsCalculation: if (crystallite_requested(c,i,e)) then p = material_phaseAt(c,e) m = material_phaseMemberAt(c,i,e) + subLi0(1:3,1:3,c,i,e) = constitutive_mech_partionedLi0(p)%data(1:3,1:3,m) + homogenizationRequestsCalculation: if (crystallite_requested(c,i,e)) then plasticState (material_phaseAt(c,e))%subState0( :,material_phaseMemberAt(c,i,e)) = & plasticState (material_phaseAt(c,e))%partitionedState0(:,material_phaseMemberAt(c,i,e)) @@ -1079,7 +1083,7 @@ function crystallite_stress() if (todo(c,i,e)) then crystallite_subF0 (1:3,1:3,c,i,e) = crystallite_subF(1:3,1:3,c,i,e) subLp0(1:3,1:3,c,i,e) = crystallite_Lp (1:3,1:3,c,i,e) - subLi0(1:3,1:3,c,i,e) = crystallite_Li (1:3,1:3,c,i,e) + subLi0(1:3,1:3,c,i,e) = constitutive_mech_Li(p)%data(1:3,1:3,m) crystallite_subFp0(1:3,1:3,c,i,e) = crystallite_Fp (1:3,1:3,c,i,e) crystallite_subFi0(1:3,1:3,c,i,e) = constitutive_mech_Fi(p)%data(1:3,1:3,m) plasticState( material_phaseAt(c,e))%subState0(:,material_phaseMemberAt(c,i,e)) & @@ -1099,7 +1103,7 @@ function crystallite_stress() crystallite_S (1:3,1:3,c,i,e) = crystallite_S0 (1:3,1:3,c,i,e) if (crystallite_subStep(c,i,e) < 1.0_pReal) then ! actual (not initial) cutback crystallite_Lp (1:3,1:3,c,i,e) = subLp0(1:3,1:3,c,i,e) - crystallite_Li (1:3,1:3,c,i,e) = subLi0(1:3,1:3,c,i,e) + constitutive_mech_Li(p)%data(1:3,1:3,m) = subLi0(1:3,1:3,c,i,e) endif plasticState (material_phaseAt(c,e))%state( :,material_phaseMemberAt(c,i,e)) & = plasticState(material_phaseAt(c,e))%subState0(:,material_phaseMemberAt(c,i,e)) @@ -1167,7 +1171,7 @@ subroutine crystallite_initializeRestorationPoints(i,e) crystallite_partitionedFp0(1:3,1:3,c,i,e) = crystallite_Fp0(1:3,1:3,c,i,e) crystallite_partitionedLp0(1:3,1:3,c,i,e) = crystallite_Lp0(1:3,1:3,c,i,e) constitutive_mech_partionedFi0(p)%data(1:3,1:3,m) = constitutive_mech_Fi0(p)%data(1:3,1:3,m) - crystallite_partitionedLi0(1:3,1:3,c,i,e) = crystallite_Li0(1:3,1:3,c,i,e) + constitutive_mech_partionedLi0(p)%data(1:3,1:3,m) = constitutive_mech_Li0(p)%data(1:3,1:3,m) crystallite_partitionedF0(1:3,1:3,c,i,e) = crystallite_F0(1:3,1:3,c,i,e) crystallite_partitionedS0(1:3,1:3,c,i,e) = crystallite_S0(1:3,1:3,c,i,e) @@ -1200,7 +1204,7 @@ subroutine crystallite_windForward(i,e) crystallite_partitionedFp0(1:3,1:3,c,i,e) = crystallite_Fp (1:3,1:3,c,i,e) crystallite_partitionedLp0(1:3,1:3,c,i,e) = crystallite_Lp (1:3,1:3,c,i,e) constitutive_mech_partionedFi0(p)%data(1:3,1:3,m) = constitutive_mech_Fi(p)%data(1:3,1:3,m) - crystallite_partitionedLi0(1:3,1:3,c,i,e) = crystallite_Li (1:3,1:3,c,i,e) + constitutive_mech_partionedLi0(p)%data(1:3,1:3,m) = constitutive_mech_Li(p)%data(1:3,1:3,m) crystallite_partitionedS0 (1:3,1:3,c,i,e) = crystallite_S (1:3,1:3,c,i,e) plasticState (material_phaseAt(c,e))%partitionedState0(:,material_phasememberAt(c,i,e)) = & @@ -1228,12 +1232,13 @@ subroutine crystallite_restore(i,e,includeL) c, p, m !< constituent number do c = 1,homogenization_Nconstituents(material_homogenizationAt(e)) - if (includeL) then - crystallite_Lp(1:3,1:3,c,i,e) = crystallite_partitionedLp0(1:3,1:3,c,i,e) - crystallite_Li(1:3,1:3,c,i,e) = crystallite_partitionedLi0(1:3,1:3,c,i,e) - endif ! maybe protecting everything from overwriting makes more sense p = material_phaseAt(c,e) m = material_phaseMemberAt(c,i,e) + if (includeL) then + crystallite_Lp(1:3,1:3,c,i,e) = crystallite_partitionedLp0(1:3,1:3,c,i,e) + constitutive_mech_Li(p)%data(1:3,1:3,m) = constitutive_mech_partionedLi0(p)%data(1:3,1:3,m) + endif ! maybe protecting everything from overwriting makes more sense + crystallite_Fp(1:3,1:3,c,i,e) = crystallite_partitionedFp0(1:3,1:3,c,i,e) constitutive_mech_Fi(p)%data(1:3,1:3,m) = constitutive_mech_partionedFi0(p)%data(1:3,1:3,m) crystallite_S (1:3,1:3,c,i,e) = crystallite_partitionedS0 (1:3,1:3,c,i,e) @@ -1466,8 +1471,7 @@ subroutine crystallite_results call results_writeDataset(group,selected_tensors,output_constituent(p)%label(o),& 'plastic velocity gradient','1/s') case('L_i') - selected_tensors = select_tensors(crystallite_Li,p) - call results_writeDataset(group,selected_tensors,output_constituent(p)%label(o),& + call results_writeDataset(group,constitutive_mech_Li(p)%data,output_constituent(p)%label(o),& 'inelastic velocity gradient','1/s') case('P') selected_tensors = select_tensors(crystallite_P,p) @@ -1636,8 +1640,11 @@ function integrateStress(ipc,ip,el,timeFraction) result(broken) call constitutive_plastic_dependentState(crystallite_partitionedF(1:3,1:3,ipc,ip,el), & crystallite_Fp(1:3,1:3,ipc,ip,el),ipc,ip,el) + p = material_phaseAt(ipc,el) + m = material_phaseMemberAt(ipc,ip,el) + Lpguess = crystallite_Lp(1:3,1:3,ipc,ip,el) ! take as first guess - Liguess = crystallite_Li(1:3,1:3,ipc,ip,el) ! take as first guess + Liguess = constitutive_mech_Li(p)%data(1:3,1:3,m) ! take as first guess call math_invert33(invFp_current,devNull,error,crystallite_subFp0(1:3,1:3,ipc,ip,el)) if (error) return ! error @@ -1772,7 +1779,7 @@ function integrateStress(ipc,ip,el,timeFraction) result(broken) 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_Lp (1:3,1:3,ipc,ip,el) = Lpguess - crystallite_Li (1:3,1:3,ipc,ip,el) = Liguess + constitutive_mech_Li(p)%data(1:3,1:3,m) = Liguess crystallite_Fp (1:3,1:3,ipc,ip,el) = Fp_new / math_det33(Fp_new)**(1.0_pReal/3.0_pReal) ! regularize constitutive_mech_Fi(p)%data(1:3,1:3,m) = Fi_new crystallite_Fe (1:3,1:3,ipc,ip,el) = matmul(matmul(F,invFp_new),invFi_new) @@ -2264,7 +2271,6 @@ subroutine crystallite_restartWrite call HDF5_write(fileHandle,crystallite_partitionedF,'F') call HDF5_write(fileHandle,crystallite_Fp, 'F_p') call HDF5_write(fileHandle,crystallite_Lp, 'L_p') - call HDF5_write(fileHandle,crystallite_Li, 'L_i') call HDF5_write(fileHandle,crystallite_S, 'S') groupHandle = HDF5_addGroup(fileHandle,'phase') @@ -2273,6 +2279,8 @@ subroutine crystallite_restartWrite call HDF5_write(groupHandle,plasticState(i)%state,datasetName) write(datasetName,'(i0,a)') i,'_F_i' call HDF5_write(groupHandle,constitutive_mech_Fi(i)%data,datasetName) + write(datasetName,'(i0,a)') i,'_L_i' + call HDF5_write(groupHandle,constitutive_mech_Li(i)%data,datasetName) enddo call HDF5_closeGroup(groupHandle) @@ -2306,7 +2314,6 @@ subroutine crystallite_restartRead call HDF5_read(fileHandle,crystallite_F0, 'F') call HDF5_read(fileHandle,crystallite_Fp0,'F_p') call HDF5_read(fileHandle,crystallite_Lp0,'L_p') - call HDF5_read(fileHandle,crystallite_Li0,'L_i') call HDF5_read(fileHandle,crystallite_S0, 'S') groupHandle = HDF5_openGroup(fileHandle,'phase') @@ -2315,6 +2322,8 @@ subroutine crystallite_restartRead call HDF5_read(groupHandle,plasticState(i)%state0,datasetName) write(datasetName,'(i0,a)') i,'_F_i' call HDF5_read(groupHandle,constitutive_mech_Fi0(i)%data,datasetName) + write(datasetName,'(i0,a)') i,'_L_i' + call HDF5_read(groupHandle,constitutive_mech_Li0(i)%data,datasetName) enddo call HDF5_closeGroup(groupHandle) @@ -2341,12 +2350,12 @@ subroutine crystallite_forward crystallite_F0 = crystallite_partitionedF crystallite_Fp0 = crystallite_Fp crystallite_Lp0 = crystallite_Lp - crystallite_Li0 = crystallite_Li crystallite_S0 = crystallite_S do i = 1, size(plasticState) plasticState(i)%state0 = plasticState(i)%state constitutive_mech_Fi0(i) = constitutive_mech_Fi(i) + constitutive_mech_Li0(i) = constitutive_mech_Li(i) enddo do i = 1,size(material_name_homogenization) homogState (i)%state0 = homogState (i)%state From 5fce37fb3e4effdc97cdac271add21896a912550 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Mon, 21 Dec 2020 10:57:18 +0100 Subject: [PATCH 080/148] only relevant for mechanics --- src/constitutive.f90 | 600 ++------------------------------------ src/constitutive_mech.f90 | 576 ++++++++++++++++++++++++++++++++++++ 2 files changed, 599 insertions(+), 577 deletions(-) diff --git a/src/constitutive.f90 b/src/constitutive.f90 index 75d5e098f..58442283a 100644 --- a/src/constitutive.f90 +++ b/src/constitutive.f90 @@ -392,6 +392,26 @@ end function constitutive_deltaState dS_dFi !< derivative of 2nd P-K stress with respect to intermediate deformation gradient end subroutine constitutive_hooke_SandItsTangents + module subroutine integrateStateFPI(g,i,e) + integer, intent(in) :: e, i, g + end subroutine integrateStateFPI + + module subroutine integrateStateEuler(g,i,e) + integer, intent(in) :: e, i, g + end subroutine integrateStateEuler + + module subroutine integrateStateAdaptiveEuler(g,i,e) + integer, intent(in) :: e, i, g + end subroutine integrateStateAdaptiveEuler + + module subroutine integrateStateRK4(g,i,e) + integer, intent(in) :: e, i, g + end subroutine integrateStateRK4 + + module subroutine integrateStateRKCK45(g,i,e) + integer, intent(in) :: e, i, g + end subroutine integrateStateRKCK45 + end interface @@ -414,9 +434,8 @@ end function constitutive_deltaState plastic_nonlocal_updateCompatibility, & plastic_active, & source_active, & - kinematics_active - - public :: & + kinematics_active, & + converged, & crystallite_init, & crystallite_stress, & crystallite_stressTangent, & @@ -429,6 +448,7 @@ end function constitutive_deltaState crystallite_initializeRestorationPoints, & crystallite_windForward, & crystallite_restore + contains @@ -1562,338 +1582,6 @@ subroutine crystallite_results end subroutine crystallite_results -!-------------------------------------------------------------------------------------------------- -!> @brief calculation of stress (P) with time integration based on a residuum in Lp and -!> intermediate acceleration of the Newton-Raphson correction -!-------------------------------------------------------------------------------------------------- -function integrateStress(ipc,ip,el,timeFraction) result(broken) - - integer, intent(in):: el, & ! element index - ip, & ! integration point index - ipc ! grain index - real(pReal), optional, intent(in) :: timeFraction ! fraction of timestep - - real(pReal), dimension(3,3):: F, & ! deformation gradient at end of timestep - Fp_new, & ! plastic deformation gradient at end of timestep - invFp_new, & ! inverse of Fp_new - invFp_current, & ! inverse of Fp_current - Lpguess, & ! current guess for plastic velocity gradient - Lpguess_old, & ! known last good guess for plastic velocity gradient - Lp_constitutive, & ! plastic velocity gradient resulting from constitutive law - residuumLp, & ! current residuum of plastic velocity gradient - residuumLp_old, & ! last residuum of plastic velocity gradient - 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_old, & ! known last good guess for intermediate velocity gradient - Li_constitutive, & ! intermediate velocity gradient resulting from constitutive law - residuumLi, & ! current residuum of intermediate velocity gradient - residuumLi_old, & ! last residuum of intermediate velocity gradient - deltaLi, & ! direction of next guess - Fe, & ! elastic deformation gradient - S, & ! 2nd Piola-Kirchhoff Stress in plastic (lattice) configuration - A, & - B, & - temp_33 - real(pReal), dimension(9) :: temp_9 ! needed for matrix inversion by LAPACK - integer, dimension(9) :: devNull_9 ! needed for matrix inversion by LAPACK - real(pReal), dimension(9,9) :: dRLp_dLp, & ! partial derivative of residuum (Jacobian for Newton-Raphson scheme) - dRLi_dLi ! partial derivative of residuumI (Jacobian for Newton-Raphson scheme) - real(pReal), dimension(3,3,3,3):: dS_dFe, & ! partial derivative of 2nd Piola-Kirchhoff stress - dS_dFi, & - dFe_dLp, & ! partial derivative of elastic deformation gradient - dFe_dLi, & - dFi_dLi, & - dLp_dFi, & - dLi_dFi, & - dLp_dS, & - dLi_dS - real(pReal) steplengthLp, & - steplengthLi, & - dt, & ! time increment - atol_Lp, & - atol_Li, & - devNull - integer NiterationStressLp, & ! number of stress integrations - NiterationStressLi, & ! number of inner stress integrations - ierr, & ! error indicator for LAPACK - o, & - p, & - m, & - jacoCounterLp, & - jacoCounterLi ! counters to check for Jacobian update - logical :: error,broken - - broken = .true. - - if (present(timeFraction)) then - dt = crystallite_subdt(ipc,ip,el) * timeFraction - F = crystallite_subF0(1:3,1:3,ipc,ip,el) & - + (crystallite_subF(1:3,1:3,ipc,ip,el) - crystallite_subF0(1:3,1:3,ipc,ip,el)) * timeFraction - else - dt = crystallite_subdt(ipc,ip,el) - F = crystallite_subF(1:3,1:3,ipc,ip,el) - endif - - call constitutive_plastic_dependentState(crystallite_partitionedF(1:3,1:3,ipc,ip,el), & - crystallite_Fp(1:3,1:3,ipc,ip,el),ipc,ip,el) - - p = material_phaseAt(ipc,el) - m = material_phaseMemberAt(ipc,ip,el) - - Lpguess = crystallite_Lp(1:3,1:3,ipc,ip,el) ! take as first guess - Liguess = constitutive_mech_Li(p)%data(1:3,1:3,m) ! take as first guess - - call math_invert33(invFp_current,devNull,error,crystallite_subFp0(1:3,1:3,ipc,ip,el)) - if (error) return ! error - call math_invert33(invFi_current,devNull,error,crystallite_subFi0(1:3,1:3,ipc,ip,el)) - if (error) return ! error - - A = matmul(F,invFp_current) ! intermediate tensor needed later to calculate dFe_dLp - - jacoCounterLi = 0 - steplengthLi = 1.0_pReal - residuumLi_old = 0.0_pReal - Liguess_old = Liguess - - NiterationStressLi = 0 - LiLoop: do - NiterationStressLi = NiterationStressLi + 1 - if (NiterationStressLi>num%nStress) return ! error - - invFi_new = matmul(invFi_current,math_I3 - dt*Liguess) - Fi_new = math_inv33(invFi_new) - - jacoCounterLp = 0 - steplengthLp = 1.0_pReal - residuumLp_old = 0.0_pReal - Lpguess_old = Lpguess - - NiterationStressLp = 0 - LpLoop: do - NiterationStressLp = NiterationStressLp + 1 - if (NiterationStressLp>num%nStress) return ! error - - B = math_I3 - dt*Lpguess - Fe = matmul(matmul(A,B), invFi_new) - call constitutive_hooke_SandItsTangents(S, dS_dFe, dS_dFi, & - Fe, Fi_new, ipc, ip, el) - - call constitutive_plastic_LpAndItsTangents(Lp_constitutive, dLp_dS, dLp_dFi, & - S, Fi_new, ipc, ip, el) - - !* update current residuum and check for convergence of loop - atol_Lp = max(num%rtol_crystalliteStress * max(norm2(Lpguess),norm2(Lp_constitutive)), & ! absolute tolerance from largest acceptable relative error - num%atol_crystalliteStress) ! minimum lower cutoff - residuumLp = Lpguess - Lp_constitutive - - if (any(IEEE_is_NaN(residuumLp))) then - return ! error - elseif (norm2(residuumLp) < atol_Lp) then ! converged if below absolute tolerance - exit LpLoop - elseif (NiterationStressLp == 1 .or. norm2(residuumLp) < norm2(residuumLp_old)) then ! not converged, but improved norm of residuum (always proceed in first iteration)... - residuumLp_old = residuumLp ! ...remember old values and... - Lpguess_old = Lpguess - steplengthLp = 1.0_pReal ! ...proceed with normal step length (calculate new search direction) - else ! not converged and residuum not improved... - steplengthLp = num%subStepSizeLp * steplengthLp ! ...try with smaller step length in same direction - Lpguess = Lpguess_old & - + deltaLp * stepLengthLp - cycle LpLoop - endif - - calculateJacobiLi: if (mod(jacoCounterLp, num%iJacoLpresiduum) == 0) then - jacoCounterLp = jacoCounterLp + 1 - - do o=1,3; do p=1,3 - dFe_dLp(o,1:3,p,1:3) = - dt * A(o,p)*transpose(invFi_new) ! dFe_dLp(i,j,k,l) = -dt * A(i,k) invFi(l,j) - enddo; enddo - dRLp_dLp = math_eye(9) & - - math_3333to99(math_mul3333xx3333(math_mul3333xx3333(dLp_dS,dS_dFe),dFe_dLp)) - temp_9 = math_33to9(residuumLp) - call dgesv(9,1,dRLp_dLp,9,devNull_9,temp_9,9,ierr) ! solve dRLp/dLp * delta Lp = -res for delta Lp - if (ierr /= 0) return ! error - deltaLp = - math_9to33(temp_9) - endif calculateJacobiLi - - Lpguess = Lpguess & - + deltaLp * steplengthLp - enddo LpLoop - - call constitutive_LiAndItsTangents(Li_constitutive, dLi_dS, dLi_dFi, & - S, Fi_new, ipc, ip, el) - - !* update current residuum and check for convergence of loop - atol_Li = max(num%rtol_crystalliteStress * max(norm2(Liguess),norm2(Li_constitutive)), & ! absolute tolerance from largest acceptable relative error - num%atol_crystalliteStress) ! minimum lower cutoff - residuumLi = Liguess - Li_constitutive - if (any(IEEE_is_NaN(residuumLi))) then - return ! error - elseif (norm2(residuumLi) < atol_Li) then ! converged if below absolute tolerance - exit LiLoop - elseif (NiterationStressLi == 1 .or. norm2(residuumLi) < norm2(residuumLi_old)) then ! not converged, but improved norm of residuum (always proceed in first iteration)... - residuumLi_old = residuumLi ! ...remember old values and... - Liguess_old = Liguess - steplengthLi = 1.0_pReal ! ...proceed with normal step length (calculate new search direction) - else ! not converged and residuum not improved... - steplengthLi = num%subStepSizeLi * steplengthLi ! ...try with smaller step length in same direction - Liguess = Liguess_old & - + deltaLi * steplengthLi - cycle LiLoop - endif - - calculateJacobiLp: if (mod(jacoCounterLi, num%iJacoLpresiduum) == 0) then - jacoCounterLi = jacoCounterLi + 1 - - temp_33 = matmul(matmul(A,B),invFi_current) - do o=1,3; do p=1,3 - dFe_dLi(1:3,o,1:3,p) = -dt*math_I3(o,p)*temp_33 ! dFe_dLp(i,j,k,l) = -dt * A(i,k) invFi(l,j) - dFi_dLi(1:3,o,1:3,p) = -dt*math_I3(o,p)*invFi_current - enddo; enddo - do o=1,3; do p=1,3 - dFi_dLi(1:3,1:3,o,p) = matmul(matmul(Fi_new,dFi_dLi(1:3,1:3,o,p)),Fi_new) - enddo; enddo - dRLi_dLi = math_eye(9) & - - math_3333to99(math_mul3333xx3333(dLi_dS, math_mul3333xx3333(dS_dFe, dFe_dLi) & - + math_mul3333xx3333(dS_dFi, dFi_dLi))) & - - math_3333to99(math_mul3333xx3333(dLi_dFi, dFi_dLi)) - temp_9 = math_33to9(residuumLi) - call dgesv(9,1,dRLi_dLi,9,devNull_9,temp_9,9,ierr) ! solve dRLi/dLp * delta Li = -res for delta Li - if (ierr /= 0) return ! error - deltaLi = - math_9to33(temp_9) - endif calculateJacobiLp - - Liguess = Liguess & - + deltaLi * steplengthLi - enddo LiLoop - - invFp_new = matmul(invFp_current,B) - call math_invert33(Fp_new,devNull,error,invFp_new) - if (error) return ! error - - p = material_phaseAt(ipc,el) - m = material_phaseMemberAt(ipc,ip,el) - - 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_Lp (1:3,1:3,ipc,ip,el) = Lpguess - constitutive_mech_Li(p)%data(1:3,1:3,m) = Liguess - crystallite_Fp (1:3,1:3,ipc,ip,el) = Fp_new / math_det33(Fp_new)**(1.0_pReal/3.0_pReal) ! regularize - constitutive_mech_Fi(p)%data(1:3,1:3,m) = Fi_new - crystallite_Fe (1:3,1:3,ipc,ip,el) = matmul(matmul(F,invFp_new),invFi_new) - broken = .false. - -end function integrateStress - - -!-------------------------------------------------------------------------------------------------- -!> @brief integrate stress, state with adaptive 1st order explicit Euler method -!> using Fixed Point Iteration to adapt the stepsize -!-------------------------------------------------------------------------------------------------- -subroutine integrateStateFPI(g,i,e) - - integer, intent(in) :: & - e, & !< element index in element loop - i, & !< integration point index in ip loop - g !< grain index in grain loop - integer :: & - NiterationState, & !< number of iterations in state loop - p, & - c, & - s, & - size_pl - integer, dimension(maxval(phase_Nsources)) :: & - size_so - real(pReal) :: & - zeta - real(pReal), dimension(max(constitutive_plasticity_maxSizeDotState,constitutive_source_maxSizeDotState)) :: & - r ! state residuum - real(pReal), dimension(constitutive_plasticity_maxSizeDotState,2) :: & - plastic_dotState - real(pReal), dimension(constitutive_source_maxSizeDotState,2,maxval(phase_Nsources)) :: source_dotState - logical :: & - broken - - p = material_phaseAt(g,e) - c = material_phaseMemberAt(g,i,e) - - broken = constitutive_collectDotState(crystallite_S(1:3,1:3,g,i,e), & - crystallite_partitionedF0, & - constitutive_mech_Fi(p)%data(1:3,1:3,c), & - crystallite_partitionedFp0, & - crystallite_subdt(g,i,e), g,i,e,p,c) - if(broken) return - - size_pl = plasticState(p)%sizeDotState - plasticState(p)%state(1:size_pl,c) = plasticState(p)%subState0(1:size_pl,c) & - + plasticState(p)%dotState (1:size_pl,c) & - * crystallite_subdt(g,i,e) - plastic_dotState(1:size_pl,2) = 0.0_pReal - - iteration: do NiterationState = 1, num%nState - - if(nIterationState > 1) plastic_dotState(1:size_pl,2) = plastic_dotState(1:size_pl,1) - plastic_dotState(1:size_pl,1) = plasticState(p)%dotState(:,c) - - broken = integrateStress(g,i,e) - if(broken) exit iteration - - broken = constitutive_collectDotState(crystallite_S(1:3,1:3,g,i,e), & - crystallite_partitionedF0, & - constitutive_mech_Fi(p)%data(1:3,1:3,c), & - crystallite_partitionedFp0, & - crystallite_subdt(g,i,e), g,i,e,p,c) - if(broken) exit iteration - - zeta = damper(plasticState(p)%dotState(:,c),plastic_dotState(1:size_pl,1),& - plastic_dotState(1:size_pl,2)) - plasticState(p)%dotState(:,c) = plasticState(p)%dotState(:,c) * zeta & - + plastic_dotState(1:size_pl,1) * (1.0_pReal - zeta) - r(1:size_pl) = plasticState(p)%state (1:size_pl,c) & - - plasticState(p)%subState0(1:size_pl,c) & - - plasticState(p)%dotState (1:size_pl,c) * crystallite_subdt(g,i,e) - plasticState(p)%state(1:size_pl,c) = plasticState(p)%state(1:size_pl,c) & - - r(1:size_pl) - crystallite_converged(g,i,e) = converged(r(1:size_pl), & - plasticState(p)%state(1:size_pl,c), & - plasticState(p)%atol(1:size_pl)) - - if(crystallite_converged(g,i,e)) then - broken = constitutive_deltaState(crystallite_S(1:3,1:3,g,i,e), & - constitutive_mech_Fi(p)%data(1:3,1:3,c),g,i,e,p,c) - exit iteration - endif - - enddo iteration - - - contains - - !-------------------------------------------------------------------------------------------------- - !> @brief calculate the damping for correction of state and dot state - !-------------------------------------------------------------------------------------------------- - real(pReal) pure function damper(current,previous,previous2) - - real(pReal), dimension(:), intent(in) ::& - current, previous, previous2 - - real(pReal) :: dot_prod12, dot_prod22 - - dot_prod12 = dot_product(current - previous, previous - previous2) - dot_prod22 = dot_product(previous - previous2, previous - previous2) - if ((dot_product(current,previous) < 0.0_pReal .or. dot_prod12 < 0.0_pReal) .and. dot_prod22 > 0.0_pReal) then - damper = 0.75_pReal + 0.25_pReal * tanh(2.0_pReal + 4.0_pReal * dot_prod12 / dot_prod22) - else - damper = 1.0_pReal - endif - - end function damper - -end subroutine integrateStateFPI - - !-------------------------------------------------------------------------------------------------- !> @brief integrate stress, state with adaptive 1st order explicit Euler method !> using Fixed Point Iteration to adapt the stepsize @@ -1993,248 +1681,6 @@ subroutine integrateSourceState(g,i,e) end subroutine integrateSourceState -!-------------------------------------------------------------------------------------------------- -!> @brief integrate state with 1st order explicit Euler method -!-------------------------------------------------------------------------------------------------- -subroutine integrateStateEuler(g,i,e) - - integer, intent(in) :: & - e, & !< element index in element loop - i, & !< integration point index in ip loop - g !< grain index in grain loop - integer :: & - p, & - c, & - sizeDotState - logical :: & - broken - - p = material_phaseAt(g,e) - c = material_phaseMemberAt(g,i,e) - - broken = constitutive_collectDotState(crystallite_S(1:3,1:3,g,i,e), & - crystallite_partitionedF0, & - constitutive_mech_Fi(p)%data(1:3,1:3,c), & - crystallite_partitionedFp0, & - crystallite_subdt(g,i,e), g,i,e,p,c) - if(broken) return - - sizeDotState = plasticState(p)%sizeDotState - plasticState(p)%state(1:sizeDotState,c) = plasticState(p)%subState0(1:sizeDotState,c) & - + plasticState(p)%dotState (1:sizeDotState,c) & - * crystallite_subdt(g,i,e) - - broken = constitutive_deltaState(crystallite_S(1:3,1:3,g,i,e), & - constitutive_mech_Fi(p)%data(1:3,1:3,c),g,i,e,p,c) - if(broken) return - - broken = integrateStress(g,i,e) - crystallite_converged(g,i,e) = .not. broken - -end subroutine integrateStateEuler - - -!-------------------------------------------------------------------------------------------------- -!> @brief integrate stress, state with 1st order Euler method with adaptive step size -!-------------------------------------------------------------------------------------------------- -subroutine integrateStateAdaptiveEuler(g,i,e) - - integer, intent(in) :: & - e, & !< element index in element loop - i, & !< integration point index in ip loop - g !< grain index in grain loop - integer :: & - p, & - c, & - sizeDotState - logical :: & - broken - - real(pReal), dimension(constitutive_plasticity_maxSizeDotState) :: residuum_plastic - - - p = material_phaseAt(g,e) - c = material_phaseMemberAt(g,i,e) - - broken = constitutive_collectDotState(crystallite_S(1:3,1:3,g,i,e), & - crystallite_partitionedF0, & - constitutive_mech_Fi(p)%data(1:3,1:3,c), & - crystallite_partitionedFp0, & - crystallite_subdt(g,i,e), g,i,e,p,c) - if(broken) return - - sizeDotState = plasticState(p)%sizeDotState - - residuum_plastic(1:sizeDotState) = - plasticState(p)%dotstate(1:sizeDotState,c) * 0.5_pReal * crystallite_subdt(g,i,e) - plasticState(p)%state(1:sizeDotState,c) = plasticState(p)%subState0(1:sizeDotState,c) & - + plasticState(p)%dotstate(1:sizeDotState,c) * crystallite_subdt(g,i,e) - - broken = constitutive_deltaState(crystallite_S(1:3,1:3,g,i,e), & - constitutive_mech_Fi(p)%data(1:3,1:3,c),g,i,e,p,c) - if(broken) return - - broken = integrateStress(g,i,e) - if(broken) return - - broken = constitutive_collectDotState(crystallite_S(1:3,1:3,g,i,e), & - crystallite_partitionedF0, & - constitutive_mech_Fi(p)%data(1:3,1:3,c), & - crystallite_partitionedFp0, & - crystallite_subdt(g,i,e), g,i,e,p,c) - if(broken) return - - - sizeDotState = plasticState(p)%sizeDotState - crystallite_converged(g,i,e) = converged(residuum_plastic(1:sizeDotState) & - + 0.5_pReal * plasticState(p)%dotState(:,c) * crystallite_subdt(g,i,e), & - plasticState(p)%state(1:sizeDotState,c), & - plasticState(p)%atol(1:sizeDotState)) - -end subroutine integrateStateAdaptiveEuler - - -!--------------------------------------------------------------------------------------------------- -!> @brief Integrate state (including stress integration) with the classic Runge Kutta method -!--------------------------------------------------------------------------------------------------- -subroutine integrateStateRK4(g,i,e) - - integer, intent(in) :: g,i,e - - real(pReal), dimension(3,3), parameter :: & - A = reshape([& - 0.5_pReal, 0.0_pReal, 0.0_pReal, & - 0.0_pReal, 0.5_pReal, 0.0_pReal, & - 0.0_pReal, 0.0_pReal, 1.0_pReal],& - shape(A)) - real(pReal), dimension(3), parameter :: & - C = [0.5_pReal, 0.5_pReal, 1.0_pReal] - real(pReal), dimension(4), parameter :: & - B = [1.0_pReal/6.0_pReal, 1.0_pReal/3.0_pReal, 1.0_pReal/3.0_pReal, 1.0_pReal/6.0_pReal] - - call integrateStateRK(g,i,e,A,B,C) - -end subroutine integrateStateRK4 - - -!--------------------------------------------------------------------------------------------------- -!> @brief Integrate state (including stress integration) with the Cash-Carp method -!--------------------------------------------------------------------------------------------------- -subroutine integrateStateRKCK45(g,i,e) - - integer, intent(in) :: g,i,e - - real(pReal), dimension(5,5), parameter :: & - A = reshape([& - 1._pReal/5._pReal, .0_pReal, .0_pReal, .0_pReal, .0_pReal, & - 3._pReal/40._pReal, 9._pReal/40._pReal, .0_pReal, .0_pReal, .0_pReal, & - 3_pReal/10._pReal, -9._pReal/10._pReal, 6._pReal/5._pReal, .0_pReal, .0_pReal, & - -11._pReal/54._pReal, 5._pReal/2._pReal, -70.0_pReal/27.0_pReal, 35.0_pReal/27.0_pReal, .0_pReal, & - 1631._pReal/55296._pReal,175._pReal/512._pReal,575._pReal/13824._pReal,44275._pReal/110592._pReal,253._pReal/4096._pReal],& - shape(A)) - real(pReal), dimension(5), parameter :: & - C = [0.2_pReal, 0.3_pReal, 0.6_pReal, 1.0_pReal, 0.875_pReal] - real(pReal), dimension(6), parameter :: & - B = & - [37.0_pReal/378.0_pReal, .0_pReal, 250.0_pReal/621.0_pReal, & - 125.0_pReal/594.0_pReal, .0_pReal, 512.0_pReal/1771.0_pReal], & - DB = B - & - [2825.0_pReal/27648.0_pReal, .0_pReal, 18575.0_pReal/48384.0_pReal,& - 13525.0_pReal/55296.0_pReal, 277.0_pReal/14336.0_pReal, 1._pReal/4._pReal] - - call integrateStateRK(g,i,e,A,B,C,DB) - -end subroutine integrateStateRKCK45 - - -!-------------------------------------------------------------------------------------------------- -!> @brief Integrate state (including stress integration) with an explicit Runge-Kutta method or an -!! embedded explicit Runge-Kutta method -!-------------------------------------------------------------------------------------------------- -subroutine integrateStateRK(g,i,e,A,B,CC,DB) - - - real(pReal), dimension(:,:), intent(in) :: A - real(pReal), dimension(:), intent(in) :: B, CC - real(pReal), dimension(:), intent(in), optional :: DB - - integer, intent(in) :: & - e, & !< element index in element loop - i, & !< integration point index in ip loop - g !< grain index in grain loop - integer :: & - stage, & ! stage index in integration stage loop - n, & - p, & - c, & - sizeDotState - logical :: & - broken - real(pReal), dimension(constitutive_plasticity_maxSizeDotState,size(B)) :: plastic_RKdotState - - p = material_phaseAt(g,e) - c = material_phaseMemberAt(g,i,e) - - broken = constitutive_collectDotState(crystallite_S(1:3,1:3,g,i,e), & - crystallite_partitionedF0, & - constitutive_mech_Fi(p)%data(1:3,1:3,c), & - crystallite_partitionedFp0, & - crystallite_subdt(g,i,e), g,i,e,p,c) - if(broken) return - - do stage = 1,size(A,1) - sizeDotState = plasticState(p)%sizeDotState - plastic_RKdotState(1:sizeDotState,stage) = plasticState(p)%dotState(:,c) - plasticState(p)%dotState(:,c) = A(1,stage) * plastic_RKdotState(1:sizeDotState,1) - - do n = 2, stage - sizeDotState = plasticState(p)%sizeDotState - plasticState(p)%dotState(:,c) = plasticState(p)%dotState(:,c) & - + A(n,stage) * plastic_RKdotState(1:sizeDotState,n) - enddo - - sizeDotState = plasticState(p)%sizeDotState - plasticState(p)%state(1:sizeDotState,c) = plasticState(p)%subState0(1:sizeDotState,c) & - + plasticState(p)%dotState (1:sizeDotState,c) & - * crystallite_subdt(g,i,e) - - broken = integrateStress(g,i,e,CC(stage)) - if(broken) exit - - broken = constitutive_collectDotState(crystallite_S(1:3,1:3,g,i,e), & - crystallite_partitionedF0, & - constitutive_mech_Fi(p)%data(1:3,1:3,c), & - crystallite_partitionedFp0, & - crystallite_subdt(g,i,e)*CC(stage), g,i,e,p,c) - if(broken) exit - - enddo - if(broken) return - - sizeDotState = plasticState(p)%sizeDotState - - plastic_RKdotState(1:sizeDotState,size(B)) = plasticState (p)%dotState(:,c) - plasticState(p)%dotState(:,c) = matmul(plastic_RKdotState(1:sizeDotState,1:size(B)),B) - plasticState(p)%state(1:sizeDotState,c) = plasticState(p)%subState0(1:sizeDotState,c) & - + plasticState(p)%dotState (1:sizeDotState,c) & - * crystallite_subdt(g,i,e) - if(present(DB)) & - broken = .not. converged( matmul(plastic_RKdotState(1:sizeDotState,1:size(DB)),DB) & - * crystallite_subdt(g,i,e), & - plasticState(p)%state(1:sizeDotState,c), & - plasticState(p)%atol(1:sizeDotState)) - - if(broken) return - - broken = constitutive_deltaState(crystallite_S(1:3,1:3,g,i,e), & - constitutive_mech_Fi(p)%data(1:3,1:3,c),g,i,e,p,c) - if(broken) return - - broken = integrateStress(g,i,e) - crystallite_converged(g,i,e) = .not. broken - - -end subroutine integrateStateRK - !-------------------------------------------------------------------------------------------------- !> @brief determines whether a point is converged diff --git a/src/constitutive_mech.f90 b/src/constitutive_mech.f90 index 8f08aa08e..dea5ed647 100644 --- a/src/constitutive_mech.f90 +++ b/src/constitutive_mech.f90 @@ -691,5 +691,581 @@ module subroutine plastic_results end subroutine plastic_results + +!-------------------------------------------------------------------------------------------------- +!> @brief calculation of stress (P) with time integration based on a residuum in Lp and +!> intermediate acceleration of the Newton-Raphson correction +!-------------------------------------------------------------------------------------------------- +function integrateStress(ipc,ip,el,timeFraction) result(broken) + + integer, intent(in):: el, & ! element index + ip, & ! integration point index + ipc ! grain index + real(pReal), optional, intent(in) :: timeFraction ! fraction of timestep + + real(pReal), dimension(3,3):: F, & ! deformation gradient at end of timestep + Fp_new, & ! plastic deformation gradient at end of timestep + invFp_new, & ! inverse of Fp_new + invFp_current, & ! inverse of Fp_current + Lpguess, & ! current guess for plastic velocity gradient + Lpguess_old, & ! known last good guess for plastic velocity gradient + Lp_constitutive, & ! plastic velocity gradient resulting from constitutive law + residuumLp, & ! current residuum of plastic velocity gradient + residuumLp_old, & ! last residuum of plastic velocity gradient + 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_old, & ! known last good guess for intermediate velocity gradient + Li_constitutive, & ! intermediate velocity gradient resulting from constitutive law + residuumLi, & ! current residuum of intermediate velocity gradient + residuumLi_old, & ! last residuum of intermediate velocity gradient + deltaLi, & ! direction of next guess + Fe, & ! elastic deformation gradient + S, & ! 2nd Piola-Kirchhoff Stress in plastic (lattice) configuration + A, & + B, & + temp_33 + real(pReal), dimension(9) :: temp_9 ! needed for matrix inversion by LAPACK + integer, dimension(9) :: devNull_9 ! needed for matrix inversion by LAPACK + real(pReal), dimension(9,9) :: dRLp_dLp, & ! partial derivative of residuum (Jacobian for Newton-Raphson scheme) + dRLi_dLi ! partial derivative of residuumI (Jacobian for Newton-Raphson scheme) + real(pReal), dimension(3,3,3,3):: dS_dFe, & ! partial derivative of 2nd Piola-Kirchhoff stress + dS_dFi, & + dFe_dLp, & ! partial derivative of elastic deformation gradient + dFe_dLi, & + dFi_dLi, & + dLp_dFi, & + dLi_dFi, & + dLp_dS, & + dLi_dS + real(pReal) steplengthLp, & + steplengthLi, & + dt, & ! time increment + atol_Lp, & + atol_Li, & + devNull + integer NiterationStressLp, & ! number of stress integrations + NiterationStressLi, & ! number of inner stress integrations + ierr, & ! error indicator for LAPACK + o, & + p, & + m, & + jacoCounterLp, & + jacoCounterLi ! counters to check for Jacobian update + logical :: error,broken + + broken = .true. + + if (present(timeFraction)) then + dt = crystallite_subdt(ipc,ip,el) * timeFraction + F = crystallite_subF0(1:3,1:3,ipc,ip,el) & + + (crystallite_subF(1:3,1:3,ipc,ip,el) - crystallite_subF0(1:3,1:3,ipc,ip,el)) * timeFraction + else + dt = crystallite_subdt(ipc,ip,el) + F = crystallite_subF(1:3,1:3,ipc,ip,el) + endif + + call constitutive_plastic_dependentState(crystallite_partitionedF(1:3,1:3,ipc,ip,el), & + crystallite_Fp(1:3,1:3,ipc,ip,el),ipc,ip,el) + + p = material_phaseAt(ipc,el) + m = material_phaseMemberAt(ipc,ip,el) + + Lpguess = crystallite_Lp(1:3,1:3,ipc,ip,el) ! take as first guess + Liguess = constitutive_mech_Li(p)%data(1:3,1:3,m) ! take as first guess + + call math_invert33(invFp_current,devNull,error,crystallite_subFp0(1:3,1:3,ipc,ip,el)) + if (error) return ! error + call math_invert33(invFi_current,devNull,error,crystallite_subFi0(1:3,1:3,ipc,ip,el)) + if (error) return ! error + + A = matmul(F,invFp_current) ! intermediate tensor needed later to calculate dFe_dLp + + jacoCounterLi = 0 + steplengthLi = 1.0_pReal + residuumLi_old = 0.0_pReal + Liguess_old = Liguess + + NiterationStressLi = 0 + LiLoop: do + NiterationStressLi = NiterationStressLi + 1 + if (NiterationStressLi>num%nStress) return ! error + + invFi_new = matmul(invFi_current,math_I3 - dt*Liguess) + Fi_new = math_inv33(invFi_new) + + jacoCounterLp = 0 + steplengthLp = 1.0_pReal + residuumLp_old = 0.0_pReal + Lpguess_old = Lpguess + + NiterationStressLp = 0 + LpLoop: do + NiterationStressLp = NiterationStressLp + 1 + if (NiterationStressLp>num%nStress) return ! error + + B = math_I3 - dt*Lpguess + Fe = matmul(matmul(A,B), invFi_new) + call constitutive_hooke_SandItsTangents(S, dS_dFe, dS_dFi, & + Fe, Fi_new, ipc, ip, el) + + call constitutive_plastic_LpAndItsTangents(Lp_constitutive, dLp_dS, dLp_dFi, & + S, Fi_new, ipc, ip, el) + + !* update current residuum and check for convergence of loop + atol_Lp = max(num%rtol_crystalliteStress * max(norm2(Lpguess),norm2(Lp_constitutive)), & ! absolute tolerance from largest acceptable relative error + num%atol_crystalliteStress) ! minimum lower cutoff + residuumLp = Lpguess - Lp_constitutive + + if (any(IEEE_is_NaN(residuumLp))) then + return ! error + elseif (norm2(residuumLp) < atol_Lp) then ! converged if below absolute tolerance + exit LpLoop + elseif (NiterationStressLp == 1 .or. norm2(residuumLp) < norm2(residuumLp_old)) then ! not converged, but improved norm of residuum (always proceed in first iteration)... + residuumLp_old = residuumLp ! ...remember old values and... + Lpguess_old = Lpguess + steplengthLp = 1.0_pReal ! ...proceed with normal step length (calculate new search direction) + else ! not converged and residuum not improved... + steplengthLp = num%subStepSizeLp * steplengthLp ! ...try with smaller step length in same direction + Lpguess = Lpguess_old & + + deltaLp * stepLengthLp + cycle LpLoop + endif + + calculateJacobiLi: if (mod(jacoCounterLp, num%iJacoLpresiduum) == 0) then + jacoCounterLp = jacoCounterLp + 1 + + do o=1,3; do p=1,3 + dFe_dLp(o,1:3,p,1:3) = - dt * A(o,p)*transpose(invFi_new) ! dFe_dLp(i,j,k,l) = -dt * A(i,k) invFi(l,j) + enddo; enddo + dRLp_dLp = math_eye(9) & + - math_3333to99(math_mul3333xx3333(math_mul3333xx3333(dLp_dS,dS_dFe),dFe_dLp)) + temp_9 = math_33to9(residuumLp) + call dgesv(9,1,dRLp_dLp,9,devNull_9,temp_9,9,ierr) ! solve dRLp/dLp * delta Lp = -res for delta Lp + if (ierr /= 0) return ! error + deltaLp = - math_9to33(temp_9) + endif calculateJacobiLi + + Lpguess = Lpguess & + + deltaLp * steplengthLp + enddo LpLoop + + call constitutive_LiAndItsTangents(Li_constitutive, dLi_dS, dLi_dFi, & + S, Fi_new, ipc, ip, el) + + !* update current residuum and check for convergence of loop + atol_Li = max(num%rtol_crystalliteStress * max(norm2(Liguess),norm2(Li_constitutive)), & ! absolute tolerance from largest acceptable relative error + num%atol_crystalliteStress) ! minimum lower cutoff + residuumLi = Liguess - Li_constitutive + if (any(IEEE_is_NaN(residuumLi))) then + return ! error + elseif (norm2(residuumLi) < atol_Li) then ! converged if below absolute tolerance + exit LiLoop + elseif (NiterationStressLi == 1 .or. norm2(residuumLi) < norm2(residuumLi_old)) then ! not converged, but improved norm of residuum (always proceed in first iteration)... + residuumLi_old = residuumLi ! ...remember old values and... + Liguess_old = Liguess + steplengthLi = 1.0_pReal ! ...proceed with normal step length (calculate new search direction) + else ! not converged and residuum not improved... + steplengthLi = num%subStepSizeLi * steplengthLi ! ...try with smaller step length in same direction + Liguess = Liguess_old & + + deltaLi * steplengthLi + cycle LiLoop + endif + + calculateJacobiLp: if (mod(jacoCounterLi, num%iJacoLpresiduum) == 0) then + jacoCounterLi = jacoCounterLi + 1 + + temp_33 = matmul(matmul(A,B),invFi_current) + do o=1,3; do p=1,3 + dFe_dLi(1:3,o,1:3,p) = -dt*math_I3(o,p)*temp_33 ! dFe_dLp(i,j,k,l) = -dt * A(i,k) invFi(l,j) + dFi_dLi(1:3,o,1:3,p) = -dt*math_I3(o,p)*invFi_current + enddo; enddo + do o=1,3; do p=1,3 + dFi_dLi(1:3,1:3,o,p) = matmul(matmul(Fi_new,dFi_dLi(1:3,1:3,o,p)),Fi_new) + enddo; enddo + dRLi_dLi = math_eye(9) & + - math_3333to99(math_mul3333xx3333(dLi_dS, math_mul3333xx3333(dS_dFe, dFe_dLi) & + + math_mul3333xx3333(dS_dFi, dFi_dLi))) & + - math_3333to99(math_mul3333xx3333(dLi_dFi, dFi_dLi)) + temp_9 = math_33to9(residuumLi) + call dgesv(9,1,dRLi_dLi,9,devNull_9,temp_9,9,ierr) ! solve dRLi/dLp * delta Li = -res for delta Li + if (ierr /= 0) return ! error + deltaLi = - math_9to33(temp_9) + endif calculateJacobiLp + + Liguess = Liguess & + + deltaLi * steplengthLi + enddo LiLoop + + invFp_new = matmul(invFp_current,B) + call math_invert33(Fp_new,devNull,error,invFp_new) + if (error) return ! error + + p = material_phaseAt(ipc,el) + m = material_phaseMemberAt(ipc,ip,el) + + 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_Lp (1:3,1:3,ipc,ip,el) = Lpguess + constitutive_mech_Li(p)%data(1:3,1:3,m) = Liguess + crystallite_Fp (1:3,1:3,ipc,ip,el) = Fp_new / math_det33(Fp_new)**(1.0_pReal/3.0_pReal) ! regularize + constitutive_mech_Fi(p)%data(1:3,1:3,m) = Fi_new + crystallite_Fe (1:3,1:3,ipc,ip,el) = matmul(matmul(F,invFp_new),invFi_new) + broken = .false. + +end function integrateStress + + +!-------------------------------------------------------------------------------------------------- +!> @brief integrate stress, state with adaptive 1st order explicit Euler method +!> using Fixed Point Iteration to adapt the stepsize +!-------------------------------------------------------------------------------------------------- +subroutine integrateStateFPI(g,i,e) + + integer, intent(in) :: & + e, & !< element index in element loop + i, & !< integration point index in ip loop + g !< grain index in grain loop + integer :: & + NiterationState, & !< number of iterations in state loop + p, & + c, & + s, & + size_pl + integer, dimension(maxval(phase_Nsources)) :: & + size_so + real(pReal) :: & + zeta + real(pReal), dimension(max(constitutive_plasticity_maxSizeDotState,constitutive_source_maxSizeDotState)) :: & + r ! state residuum + real(pReal), dimension(constitutive_plasticity_maxSizeDotState,2) :: & + plastic_dotState + real(pReal), dimension(constitutive_source_maxSizeDotState,2,maxval(phase_Nsources)) :: source_dotState + logical :: & + broken + + p = material_phaseAt(g,e) + c = material_phaseMemberAt(g,i,e) + + broken = constitutive_collectDotState(crystallite_S(1:3,1:3,g,i,e), & + crystallite_partitionedF0, & + constitutive_mech_Fi(p)%data(1:3,1:3,c), & + crystallite_partitionedFp0, & + crystallite_subdt(g,i,e), g,i,e,p,c) + if(broken) return + + size_pl = plasticState(p)%sizeDotState + plasticState(p)%state(1:size_pl,c) = plasticState(p)%subState0(1:size_pl,c) & + + plasticState(p)%dotState (1:size_pl,c) & + * crystallite_subdt(g,i,e) + plastic_dotState(1:size_pl,2) = 0.0_pReal + + iteration: do NiterationState = 1, num%nState + + if(nIterationState > 1) plastic_dotState(1:size_pl,2) = plastic_dotState(1:size_pl,1) + plastic_dotState(1:size_pl,1) = plasticState(p)%dotState(:,c) + + broken = integrateStress(g,i,e) + if(broken) exit iteration + + broken = constitutive_collectDotState(crystallite_S(1:3,1:3,g,i,e), & + crystallite_partitionedF0, & + constitutive_mech_Fi(p)%data(1:3,1:3,c), & + crystallite_partitionedFp0, & + crystallite_subdt(g,i,e), g,i,e,p,c) + if(broken) exit iteration + + zeta = damper(plasticState(p)%dotState(:,c),plastic_dotState(1:size_pl,1),& + plastic_dotState(1:size_pl,2)) + plasticState(p)%dotState(:,c) = plasticState(p)%dotState(:,c) * zeta & + + plastic_dotState(1:size_pl,1) * (1.0_pReal - zeta) + r(1:size_pl) = plasticState(p)%state (1:size_pl,c) & + - plasticState(p)%subState0(1:size_pl,c) & + - plasticState(p)%dotState (1:size_pl,c) * crystallite_subdt(g,i,e) + plasticState(p)%state(1:size_pl,c) = plasticState(p)%state(1:size_pl,c) & + - r(1:size_pl) + crystallite_converged(g,i,e) = converged(r(1:size_pl), & + plasticState(p)%state(1:size_pl,c), & + plasticState(p)%atol(1:size_pl)) + + if(crystallite_converged(g,i,e)) then + broken = constitutive_deltaState(crystallite_S(1:3,1:3,g,i,e), & + constitutive_mech_Fi(p)%data(1:3,1:3,c),g,i,e,p,c) + exit iteration + endif + + enddo iteration + + + contains + + !-------------------------------------------------------------------------------------------------- + !> @brief calculate the damping for correction of state and dot state + !-------------------------------------------------------------------------------------------------- + real(pReal) pure function damper(current,previous,previous2) + + real(pReal), dimension(:), intent(in) ::& + current, previous, previous2 + + real(pReal) :: dot_prod12, dot_prod22 + + dot_prod12 = dot_product(current - previous, previous - previous2) + dot_prod22 = dot_product(previous - previous2, previous - previous2) + if ((dot_product(current,previous) < 0.0_pReal .or. dot_prod12 < 0.0_pReal) .and. dot_prod22 > 0.0_pReal) then + damper = 0.75_pReal + 0.25_pReal * tanh(2.0_pReal + 4.0_pReal * dot_prod12 / dot_prod22) + else + damper = 1.0_pReal + endif + + end function damper + +end subroutine integrateStateFPI + + +!-------------------------------------------------------------------------------------------------- +!> @brief integrate state with 1st order explicit Euler method +!-------------------------------------------------------------------------------------------------- +subroutine integrateStateEuler(g,i,e) + + integer, intent(in) :: & + e, & !< element index in element loop + i, & !< integration point index in ip loop + g !< grain index in grain loop + integer :: & + p, & + c, & + sizeDotState + logical :: & + broken + + p = material_phaseAt(g,e) + c = material_phaseMemberAt(g,i,e) + + broken = constitutive_collectDotState(crystallite_S(1:3,1:3,g,i,e), & + crystallite_partitionedF0, & + constitutive_mech_Fi(p)%data(1:3,1:3,c), & + crystallite_partitionedFp0, & + crystallite_subdt(g,i,e), g,i,e,p,c) + if(broken) return + + sizeDotState = plasticState(p)%sizeDotState + plasticState(p)%state(1:sizeDotState,c) = plasticState(p)%subState0(1:sizeDotState,c) & + + plasticState(p)%dotState (1:sizeDotState,c) & + * crystallite_subdt(g,i,e) + + broken = constitutive_deltaState(crystallite_S(1:3,1:3,g,i,e), & + constitutive_mech_Fi(p)%data(1:3,1:3,c),g,i,e,p,c) + if(broken) return + + broken = integrateStress(g,i,e) + crystallite_converged(g,i,e) = .not. broken + +end subroutine integrateStateEuler + + +!-------------------------------------------------------------------------------------------------- +!> @brief integrate stress, state with 1st order Euler method with adaptive step size +!-------------------------------------------------------------------------------------------------- +subroutine integrateStateAdaptiveEuler(g,i,e) + + integer, intent(in) :: & + e, & !< element index in element loop + i, & !< integration point index in ip loop + g !< grain index in grain loop + integer :: & + p, & + c, & + sizeDotState + logical :: & + broken + + real(pReal), dimension(constitutive_plasticity_maxSizeDotState) :: residuum_plastic + + + p = material_phaseAt(g,e) + c = material_phaseMemberAt(g,i,e) + + broken = constitutive_collectDotState(crystallite_S(1:3,1:3,g,i,e), & + crystallite_partitionedF0, & + constitutive_mech_Fi(p)%data(1:3,1:3,c), & + crystallite_partitionedFp0, & + crystallite_subdt(g,i,e), g,i,e,p,c) + if(broken) return + + sizeDotState = plasticState(p)%sizeDotState + + residuum_plastic(1:sizeDotState) = - plasticState(p)%dotstate(1:sizeDotState,c) * 0.5_pReal * crystallite_subdt(g,i,e) + plasticState(p)%state(1:sizeDotState,c) = plasticState(p)%subState0(1:sizeDotState,c) & + + plasticState(p)%dotstate(1:sizeDotState,c) * crystallite_subdt(g,i,e) + + broken = constitutive_deltaState(crystallite_S(1:3,1:3,g,i,e), & + constitutive_mech_Fi(p)%data(1:3,1:3,c),g,i,e,p,c) + if(broken) return + + broken = integrateStress(g,i,e) + if(broken) return + + broken = constitutive_collectDotState(crystallite_S(1:3,1:3,g,i,e), & + crystallite_partitionedF0, & + constitutive_mech_Fi(p)%data(1:3,1:3,c), & + crystallite_partitionedFp0, & + crystallite_subdt(g,i,e), g,i,e,p,c) + if(broken) return + + + sizeDotState = plasticState(p)%sizeDotState + crystallite_converged(g,i,e) = converged(residuum_plastic(1:sizeDotState) & + + 0.5_pReal * plasticState(p)%dotState(:,c) * crystallite_subdt(g,i,e), & + plasticState(p)%state(1:sizeDotState,c), & + plasticState(p)%atol(1:sizeDotState)) + +end subroutine integrateStateAdaptiveEuler + + +!--------------------------------------------------------------------------------------------------- +!> @brief Integrate state (including stress integration) with the classic Runge Kutta method +!--------------------------------------------------------------------------------------------------- +subroutine integrateStateRK4(g,i,e) + + integer, intent(in) :: g,i,e + + real(pReal), dimension(3,3), parameter :: & + A = reshape([& + 0.5_pReal, 0.0_pReal, 0.0_pReal, & + 0.0_pReal, 0.5_pReal, 0.0_pReal, & + 0.0_pReal, 0.0_pReal, 1.0_pReal],& + shape(A)) + real(pReal), dimension(3), parameter :: & + C = [0.5_pReal, 0.5_pReal, 1.0_pReal] + real(pReal), dimension(4), parameter :: & + B = [1.0_pReal/6.0_pReal, 1.0_pReal/3.0_pReal, 1.0_pReal/3.0_pReal, 1.0_pReal/6.0_pReal] + + call integrateStateRK(g,i,e,A,B,C) + +end subroutine integrateStateRK4 + + +!--------------------------------------------------------------------------------------------------- +!> @brief Integrate state (including stress integration) with the Cash-Carp method +!--------------------------------------------------------------------------------------------------- +subroutine integrateStateRKCK45(g,i,e) + + integer, intent(in) :: g,i,e + + real(pReal), dimension(5,5), parameter :: & + A = reshape([& + 1._pReal/5._pReal, .0_pReal, .0_pReal, .0_pReal, .0_pReal, & + 3._pReal/40._pReal, 9._pReal/40._pReal, .0_pReal, .0_pReal, .0_pReal, & + 3_pReal/10._pReal, -9._pReal/10._pReal, 6._pReal/5._pReal, .0_pReal, .0_pReal, & + -11._pReal/54._pReal, 5._pReal/2._pReal, -70.0_pReal/27.0_pReal, 35.0_pReal/27.0_pReal, .0_pReal, & + 1631._pReal/55296._pReal,175._pReal/512._pReal,575._pReal/13824._pReal,44275._pReal/110592._pReal,253._pReal/4096._pReal],& + shape(A)) + real(pReal), dimension(5), parameter :: & + C = [0.2_pReal, 0.3_pReal, 0.6_pReal, 1.0_pReal, 0.875_pReal] + real(pReal), dimension(6), parameter :: & + B = & + [37.0_pReal/378.0_pReal, .0_pReal, 250.0_pReal/621.0_pReal, & + 125.0_pReal/594.0_pReal, .0_pReal, 512.0_pReal/1771.0_pReal], & + DB = B - & + [2825.0_pReal/27648.0_pReal, .0_pReal, 18575.0_pReal/48384.0_pReal,& + 13525.0_pReal/55296.0_pReal, 277.0_pReal/14336.0_pReal, 1._pReal/4._pReal] + + call integrateStateRK(g,i,e,A,B,C,DB) + +end subroutine integrateStateRKCK45 + + +!-------------------------------------------------------------------------------------------------- +!> @brief Integrate state (including stress integration) with an explicit Runge-Kutta method or an +!! embedded explicit Runge-Kutta method +!-------------------------------------------------------------------------------------------------- +subroutine integrateStateRK(g,i,e,A,B,CC,DB) + + + real(pReal), dimension(:,:), intent(in) :: A + real(pReal), dimension(:), intent(in) :: B, CC + real(pReal), dimension(:), intent(in), optional :: DB + + integer, intent(in) :: & + e, & !< element index in element loop + i, & !< integration point index in ip loop + g !< grain index in grain loop + integer :: & + stage, & ! stage index in integration stage loop + n, & + p, & + c, & + sizeDotState + logical :: & + broken + real(pReal), dimension(constitutive_plasticity_maxSizeDotState,size(B)) :: plastic_RKdotState + + p = material_phaseAt(g,e) + c = material_phaseMemberAt(g,i,e) + + broken = constitutive_collectDotState(crystallite_S(1:3,1:3,g,i,e), & + crystallite_partitionedF0, & + constitutive_mech_Fi(p)%data(1:3,1:3,c), & + crystallite_partitionedFp0, & + crystallite_subdt(g,i,e), g,i,e,p,c) + if(broken) return + + do stage = 1,size(A,1) + sizeDotState = plasticState(p)%sizeDotState + plastic_RKdotState(1:sizeDotState,stage) = plasticState(p)%dotState(:,c) + plasticState(p)%dotState(:,c) = A(1,stage) * plastic_RKdotState(1:sizeDotState,1) + + do n = 2, stage + sizeDotState = plasticState(p)%sizeDotState + plasticState(p)%dotState(:,c) = plasticState(p)%dotState(:,c) & + + A(n,stage) * plastic_RKdotState(1:sizeDotState,n) + enddo + + sizeDotState = plasticState(p)%sizeDotState + plasticState(p)%state(1:sizeDotState,c) = plasticState(p)%subState0(1:sizeDotState,c) & + + plasticState(p)%dotState (1:sizeDotState,c) & + * crystallite_subdt(g,i,e) + + broken = integrateStress(g,i,e,CC(stage)) + if(broken) exit + + broken = constitutive_collectDotState(crystallite_S(1:3,1:3,g,i,e), & + crystallite_partitionedF0, & + constitutive_mech_Fi(p)%data(1:3,1:3,c), & + crystallite_partitionedFp0, & + crystallite_subdt(g,i,e)*CC(stage), g,i,e,p,c) + if(broken) exit + + enddo + if(broken) return + + sizeDotState = plasticState(p)%sizeDotState + + plastic_RKdotState(1:sizeDotState,size(B)) = plasticState (p)%dotState(:,c) + plasticState(p)%dotState(:,c) = matmul(plastic_RKdotState(1:sizeDotState,1:size(B)),B) + plasticState(p)%state(1:sizeDotState,c) = plasticState(p)%subState0(1:sizeDotState,c) & + + plasticState(p)%dotState (1:sizeDotState,c) & + * crystallite_subdt(g,i,e) + if(present(DB)) & + broken = .not. converged( matmul(plastic_RKdotState(1:sizeDotState,1:size(DB)),DB) & + * crystallite_subdt(g,i,e), & + plasticState(p)%state(1:sizeDotState,c), & + plasticState(p)%atol(1:sizeDotState)) + + if(broken) return + + broken = constitutive_deltaState(crystallite_S(1:3,1:3,g,i,e), & + constitutive_mech_Fi(p)%data(1:3,1:3,c),g,i,e,p,c) + if(broken) return + + broken = integrateStress(g,i,e) + crystallite_converged(g,i,e) = .not. broken + + +end subroutine integrateStateRK + + end submodule constitutive_mech From 07ccaf5fe76e05ddcaea988a27cf410bf06974ac Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Mon, 21 Dec 2020 12:14:09 +0100 Subject: [PATCH 081/148] some ideas ... --- src/constitutive.f90 | 13 +++++++++++++ src/constitutive_mech.f90 | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/src/constitutive.f90 b/src/constitutive.f90 index 58442283a..b5158be4e 100644 --- a/src/constitutive.f90 +++ b/src/constitutive.f90 @@ -140,6 +140,7 @@ module constitutive interface +! == cleaned:begin ================================================================================= module subroutine mech_init end subroutine mech_init @@ -149,6 +150,18 @@ module constitutive module subroutine thermal_init end subroutine thermal_init + + module subroutine mech_results(group,ph) + character(len=*), intent(in) :: group + integer, intent(in) :: ph + end subroutine mech_results + + module subroutine mech_restart_read(fileHandle) + integer(HID_T), intent(in) :: fileHandle + end subroutine mech_restart_read + +! == cleaned:end =================================================================================== + module function constitutive_collectDotState(S, FArray, Fi, FpArray, subdt, ipc, ip, el,phase,of) result(broken) integer, intent(in) :: & diff --git a/src/constitutive_mech.f90 b/src/constitutive_mech.f90 index dea5ed647..acfe3a23b 100644 --- a/src/constitutive_mech.f90 +++ b/src/constitutive_mech.f90 @@ -651,6 +651,40 @@ module function constitutive_deltaState(S, Fi, ipc, ip, el, phase, of) result(br end function constitutive_deltaState +module subroutine mech_results(group,ph) + + character(len=*), intent(in) :: group + integer, intent(in) :: ph + + select case(phase_plasticity(ph)) + + case(PLASTICITY_ISOTROPIC_ID) + call plastic_isotropic_results(phase_plasticityInstance(ph),group//'plastic') + + case(PLASTICITY_PHENOPOWERLAW_ID) + call plastic_phenopowerlaw_results(phase_plasticityInstance(ph),group//'plastic') + + case(PLASTICITY_KINEHARDENING_ID) + call plastic_kinehardening_results(phase_plasticityInstance(ph),group//'plastic') + + case(PLASTICITY_DISLOTWIN_ID) + call plastic_dislotwin_results(phase_plasticityInstance(ph),group//'plastic') + + case(PLASTICITY_DISLOTUNGSTEN_ID) + call plastic_dislotungsten_results(phase_plasticityInstance(ph),group//'plastic') + + case(PLASTICITY_NONLOCAL_ID) + call plastic_nonlocal_results(phase_plasticityInstance(ph),group//'plastic') + end select + +end subroutine mech_results + + module subroutine mech_restart_read(fileHandle) + integer(HID_T), intent(in) :: fileHandle + end subroutine mech_restart_read + + + !-------------------------------------------------------------------------------------------- !> @brief writes plasticity constitutive results to HDF5 output file !-------------------------------------------------------------------------------------------- From b7445b007dc43329a7b3237ac13f24906d3ffb7a Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Mon, 21 Dec 2020 14:01:40 +0100 Subject: [PATCH 082/148] variables are now part of the same module --- src/constitutive.f90 | 7 +----- src/constitutive_mech.f90 | 50 ++++++++++----------------------------- 2 files changed, 13 insertions(+), 44 deletions(-) diff --git a/src/constitutive.f90 b/src/constitutive.f90 index b5158be4e..a7834852f 100644 --- a/src/constitutive.f90 +++ b/src/constitutive.f90 @@ -162,7 +162,7 @@ module constitutive ! == cleaned:end =================================================================================== - module function constitutive_collectDotState(S, FArray, Fi, FpArray, subdt, ipc, ip, el,phase,of) result(broken) + module function constitutive_collectDotState(FpArray, subdt, ipc, ip, el,phase,of) result(broken) integer, intent(in) :: & ipc, & !< component-ID of integration point @@ -173,12 +173,7 @@ module constitutive real(pReal), intent(in) :: & subdt !< timestep real(pReal), intent(in), dimension(3,3,homogenization_maxNconstituents,discretization_nIPs,discretization_Nelems) :: & - FArray, & !< elastic deformation gradient FpArray !< plastic deformation gradient - real(pReal), intent(in), dimension(3,3) :: & - Fi !< intermediate deformation gradient - real(pReal), intent(in), dimension(3,3) :: & - S !< 2nd Piola Kirchhoff stress (vector notation) logical :: broken end function constitutive_collectDotState diff --git a/src/constitutive_mech.f90 b/src/constitutive_mech.f90 index acfe3a23b..bc6a3ba1a 100644 --- a/src/constitutive_mech.f90 +++ b/src/constitutive_mech.f90 @@ -536,7 +536,7 @@ end subroutine constitutive_plastic_LpAndItsTangents !-------------------------------------------------------------------------------------------------- !> @brief contains the constitutive equation for calculating the rate of change of microstructure !-------------------------------------------------------------------------------------------------- -module function constitutive_collectDotState(S, FArray, Fi, FpArray, subdt, ipc, ip, el,phase,of) result(broken) +module function constitutive_collectDotState(FpArray, subdt, ipc, ip, el,phase,of) result(broken) integer, intent(in) :: & ipc, & !< component-ID of integration point @@ -547,12 +547,7 @@ module function constitutive_collectDotState(S, FArray, Fi, FpArray, subdt, ipc, real(pReal), intent(in) :: & subdt !< timestep real(pReal), intent(in), dimension(3,3,homogenization_maxNconstituents,discretization_nIPs,discretization_Nelems) :: & - FArray, & !< elastic deformation gradient FpArray !< plastic deformation gradient - real(pReal), intent(in), dimension(3,3) :: & - Fi !< intermediate deformation gradient - real(pReal), intent(in), dimension(3,3) :: & - S !< 2nd Piola Kirchhoff stress (vector notation) real(pReal), dimension(3,3) :: & Mp integer :: & @@ -561,12 +556,12 @@ module function constitutive_collectDotState(S, FArray, Fi, FpArray, subdt, ipc, i, & !< counter in source loop instance logical :: broken - ho = material_homogenizationAt(el) tme = material_homogenizationMemberAt(ip,el) instance = phase_plasticityInstance(phase) - Mp = matmul(matmul(transpose(Fi),Fi),S) + Mp = matmul(matmul(transpose(constitutive_mech_Fi(phase)%data(1:3,1:3,of)),& + constitutive_mech_Fi(phase)%data(1:3,1:3,of)),crystallite_S(1:3,1:3,ipc,ip,el)) plasticityType: select case (phase_plasticity(phase)) @@ -586,7 +581,7 @@ module function constitutive_collectDotState(S, FArray, Fi, FpArray, subdt, ipc, call plastic_disloTungsten_dotState(Mp,temperature(ho)%p(tme),instance,of) case (PLASTICITY_NONLOCAL_ID) plasticityType - call plastic_nonlocal_dotState(Mp,FArray,FpArray,temperature(ho)%p(tme),subdt, & + call plastic_nonlocal_dotState(Mp,crystallite_partitionedF0,FpArray,temperature(ho)%p(tme),subdt, & instance,of,ip,el) end select plasticityType broken = any(IEEE_is_NaN(plasticState(phase)%dotState(:,of))) @@ -983,11 +978,8 @@ subroutine integrateStateFPI(g,i,e) p = material_phaseAt(g,e) c = material_phaseMemberAt(g,i,e) - broken = constitutive_collectDotState(crystallite_S(1:3,1:3,g,i,e), & - crystallite_partitionedF0, & - constitutive_mech_Fi(p)%data(1:3,1:3,c), & - crystallite_partitionedFp0, & - crystallite_subdt(g,i,e), g,i,e,p,c) + broken = constitutive_collectDotState(crystallite_partitionedFp0, & + crystallite_subdt(g,i,e), g,i,e,p,c) if(broken) return size_pl = plasticState(p)%sizeDotState @@ -1004,10 +996,7 @@ subroutine integrateStateFPI(g,i,e) broken = integrateStress(g,i,e) if(broken) exit iteration - broken = constitutive_collectDotState(crystallite_S(1:3,1:3,g,i,e), & - crystallite_partitionedF0, & - constitutive_mech_Fi(p)%data(1:3,1:3,c), & - crystallite_partitionedFp0, & + broken = constitutive_collectDotState(crystallite_partitionedFp0, & crystallite_subdt(g,i,e), g,i,e,p,c) if(broken) exit iteration @@ -1077,10 +1066,7 @@ subroutine integrateStateEuler(g,i,e) p = material_phaseAt(g,e) c = material_phaseMemberAt(g,i,e) - broken = constitutive_collectDotState(crystallite_S(1:3,1:3,g,i,e), & - crystallite_partitionedF0, & - constitutive_mech_Fi(p)%data(1:3,1:3,c), & - crystallite_partitionedFp0, & + broken = constitutive_collectDotState(crystallite_partitionedFp0, & crystallite_subdt(g,i,e), g,i,e,p,c) if(broken) return @@ -1121,10 +1107,7 @@ subroutine integrateStateAdaptiveEuler(g,i,e) p = material_phaseAt(g,e) c = material_phaseMemberAt(g,i,e) - broken = constitutive_collectDotState(crystallite_S(1:3,1:3,g,i,e), & - crystallite_partitionedF0, & - constitutive_mech_Fi(p)%data(1:3,1:3,c), & - crystallite_partitionedFp0, & + broken = constitutive_collectDotState(crystallite_partitionedFp0, & crystallite_subdt(g,i,e), g,i,e,p,c) if(broken) return @@ -1141,10 +1124,7 @@ subroutine integrateStateAdaptiveEuler(g,i,e) broken = integrateStress(g,i,e) if(broken) return - broken = constitutive_collectDotState(crystallite_S(1:3,1:3,g,i,e), & - crystallite_partitionedF0, & - constitutive_mech_Fi(p)%data(1:3,1:3,c), & - crystallite_partitionedFp0, & + broken = constitutive_collectDotState(crystallite_partitionedFp0, & crystallite_subdt(g,i,e), g,i,e,p,c) if(broken) return @@ -1239,10 +1219,7 @@ subroutine integrateStateRK(g,i,e,A,B,CC,DB) p = material_phaseAt(g,e) c = material_phaseMemberAt(g,i,e) - broken = constitutive_collectDotState(crystallite_S(1:3,1:3,g,i,e), & - crystallite_partitionedF0, & - constitutive_mech_Fi(p)%data(1:3,1:3,c), & - crystallite_partitionedFp0, & + broken = constitutive_collectDotState(crystallite_partitionedFp0, & crystallite_subdt(g,i,e), g,i,e,p,c) if(broken) return @@ -1265,10 +1242,7 @@ subroutine integrateStateRK(g,i,e,A,B,CC,DB) broken = integrateStress(g,i,e,CC(stage)) if(broken) exit - broken = constitutive_collectDotState(crystallite_S(1:3,1:3,g,i,e), & - crystallite_partitionedF0, & - constitutive_mech_Fi(p)%data(1:3,1:3,c), & - crystallite_partitionedFp0, & + broken = constitutive_collectDotState(crystallite_partitionedFp0, & crystallite_subdt(g,i,e)*CC(stage), g,i,e,p,c) if(broken) exit From ceeb300061d85968ea1c233b0c89c93e2dab18e9 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Mon, 21 Dec 2020 14:51:55 +0100 Subject: [PATCH 083/148] fixes for ifort --- src/constitutive.f90 | 2 +- src/constitutive_mech.f90 | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/constitutive.f90 b/src/constitutive.f90 index 58442283a..f76b94579 100644 --- a/src/constitutive.f90 +++ b/src/constitutive.f90 @@ -47,7 +47,7 @@ module constitutive ! crystallite_S0, & !< 2nd Piola-Kirchhoff stress vector at start of FE inc crystallite_partitionedS0 !< 2nd Piola-Kirchhoff stress vector at start of homog inc - real(pReal), dimension(:,:,:,:,:), allocatable, public, protected :: & + real(pReal), dimension(:,:,:,:,:), allocatable, public :: & crystallite_P, & !< 1st Piola-Kirchhoff stress per grain crystallite_Lp, & !< current plastic velocitiy grad (end of converged time step) crystallite_S, & !< current 2nd Piola-Kirchhoff stress vector (end of converged time step) diff --git a/src/constitutive_mech.f90 b/src/constitutive_mech.f90 index dea5ed647..07e48b537 100644 --- a/src/constitutive_mech.f90 +++ b/src/constitutive_mech.f90 @@ -922,7 +922,7 @@ end function integrateStress !> @brief integrate stress, state with adaptive 1st order explicit Euler method !> using Fixed Point Iteration to adapt the stepsize !-------------------------------------------------------------------------------------------------- -subroutine integrateStateFPI(g,i,e) +module subroutine integrateStateFPI(g,i,e) integer, intent(in) :: & e, & !< element index in element loop @@ -1027,7 +1027,7 @@ end subroutine integrateStateFPI !-------------------------------------------------------------------------------------------------- !> @brief integrate state with 1st order explicit Euler method !-------------------------------------------------------------------------------------------------- -subroutine integrateStateEuler(g,i,e) +module subroutine integrateStateEuler(g,i,e) integer, intent(in) :: & e, & !< element index in element loop @@ -1068,7 +1068,7 @@ end subroutine integrateStateEuler !-------------------------------------------------------------------------------------------------- !> @brief integrate stress, state with 1st order Euler method with adaptive step size !-------------------------------------------------------------------------------------------------- -subroutine integrateStateAdaptiveEuler(g,i,e) +module subroutine integrateStateAdaptiveEuler(g,i,e) integer, intent(in) :: & e, & !< element index in element loop @@ -1127,7 +1127,7 @@ end subroutine integrateStateAdaptiveEuler !--------------------------------------------------------------------------------------------------- !> @brief Integrate state (including stress integration) with the classic Runge Kutta method !--------------------------------------------------------------------------------------------------- -subroutine integrateStateRK4(g,i,e) +module subroutine integrateStateRK4(g,i,e) integer, intent(in) :: g,i,e @@ -1150,7 +1150,7 @@ end subroutine integrateStateRK4 !--------------------------------------------------------------------------------------------------- !> @brief Integrate state (including stress integration) with the Cash-Carp method !--------------------------------------------------------------------------------------------------- -subroutine integrateStateRKCK45(g,i,e) +module subroutine integrateStateRKCK45(g,i,e) integer, intent(in) :: g,i,e From c913a577d01e0b2f5887a9748fc1cd459426f94c Mon Sep 17 00:00:00 2001 From: Test User Date: Mon, 21 Dec 2020 19:15:06 +0100 Subject: [PATCH 084/148] [skip ci] updated version information after successful test of v3.0.0-alpha2-62-gd1c7ec068 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 85027fcd3..5c2eab7c5 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v3.0.0-alpha2-42-g6cc78cb41 +v3.0.0-alpha2-62-gd1c7ec068 From 3ea05cabadb680c16e0dead27f5f30142bd58e24 Mon Sep 17 00:00:00 2001 From: Test User Date: Mon, 21 Dec 2020 21:32:13 +0100 Subject: [PATCH 085/148] [skip ci] updated version information after successful test of v3.0.0-alpha2-68-gbc32797fa --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 85027fcd3..72db22a20 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v3.0.0-alpha2-42-g6cc78cb41 +v3.0.0-alpha2-68-gbc32797fa From d8b57680ec0c43520f045954c7edc01c81fcb7df Mon Sep 17 00:00:00 2001 From: Philip Eisenlohr Date: Mon, 21 Dec 2020 15:46:07 -0500 Subject: [PATCH 086/148] raise NotImplemented when using R*b instead of R@b --- python/damask/_rotation.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/python/damask/_rotation.py b/python/damask/_rotation.py index f4d2cf248..780e81891 100644 --- a/python/damask/_rotation.py +++ b/python/damask/_rotation.py @@ -144,6 +144,11 @@ class Rotation: return self.copy(rotation=Rotation(np.block([np.cos(pwr*phi),np.sin(pwr*phi)*p]))._standardize()) + def __mul__(self,other): + """Standard multiplication is not implemented.""" + raise NotImplementedError('Use "R@b", i.e. matmul, to apply rotation "R" to object "b"') + + def __matmul__(self,other): """ Rotation of vector, second or fourth order tensor, or rotation object. From 2434712d7e0a556bc18721aefaba13569af5d95d Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Mon, 21 Dec 2020 23:33:32 +0100 Subject: [PATCH 087/148] better matching name --- src/constitutive.f90 | 6 +++--- src/homogenization.f90 | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/constitutive.f90 b/src/constitutive.f90 index 205df9d55..5e99abfd3 100644 --- a/src/constitutive.f90 +++ b/src/constitutive.f90 @@ -453,7 +453,7 @@ end function constitutive_deltaState crystallite_restartWrite, & crystallite_restartRead, & crystallite_forward, & - crystallite_initializeRestorationPoints, & + constitutive_initializeRestorationPoints, & crystallite_windForward, & crystallite_restore @@ -1184,7 +1184,7 @@ end function crystallite_stress !-------------------------------------------------------------------------------------------------- !> @brief Backup data for homog cutback. !-------------------------------------------------------------------------------------------------- -subroutine crystallite_initializeRestorationPoints(i,e) +subroutine constitutive_initializeRestorationPoints(i,e) integer, intent(in) :: & i, & !< integration point number @@ -1211,7 +1211,7 @@ subroutine crystallite_initializeRestorationPoints(i,e) enddo enddo -end subroutine crystallite_initializeRestorationPoints +end subroutine constitutive_initializeRestorationPoints !-------------------------------------------------------------------------------------------------- diff --git a/src/homogenization.f90 b/src/homogenization.f90 index cbab8e468..6ed53c13c 100644 --- a/src/homogenization.f90 +++ b/src/homogenization.f90 @@ -196,7 +196,7 @@ subroutine materialpoint_stressAndItsTangent(dt) do e = FEsolving_execElem(1),FEsolving_execElem(2) do i = FEsolving_execIP(1),FEsolving_execIP(2); - call crystallite_initializeRestorationPoints(i,e) + call constitutive_initializeRestorationPoints(i,e) subFrac(i,e) = 0.0_pReal converged(i,e) = .false. ! pretend failed step ... From da558b31c15470fd949b9dcf15863cfceaf6993c Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Tue, 22 Dec 2020 08:45:01 +0100 Subject: [PATCH 088/148] clear responsibilities --- src/constitutive.f90 | 20 +++++++++++++---- src/constitutive_mech.f90 | 46 ++++----------------------------------- src/homogenization.f90 | 1 + src/results.f90 | 2 -- 4 files changed, 21 insertions(+), 48 deletions(-) diff --git a/src/constitutive.f90 b/src/constitutive.f90 index 5e99abfd3..e49932cfe 100644 --- a/src/constitutive.f90 +++ b/src/constitutive.f90 @@ -348,9 +348,6 @@ end function constitutive_deltaState C end subroutine source_damage_isoBrittle_deltaState - module subroutine plastic_results - end subroutine plastic_results - module subroutine damage_results end subroutine damage_results @@ -844,7 +841,22 @@ end subroutine constitutive_forward !-------------------------------------------------------------------------------------------------- subroutine constitutive_results - call plastic_results + integer :: ph + character(len=:), allocatable :: group + + + group = '/current/phase/' + call results_closeGroup(results_addGroup(group)) + + do ph = 1, size(material_name_phase) + + group = group//trim(material_name_phase(ph))//'/' + call results_closeGroup(results_addGroup(group)) + + call mech_results(group,ph) + + enddo + call damage_results end subroutine constitutive_results diff --git a/src/constitutive_mech.f90 b/src/constitutive_mech.f90 index ba10ed39a..7d6ef2998 100644 --- a/src/constitutive_mech.f90 +++ b/src/constitutive_mech.f90 @@ -651,6 +651,9 @@ module subroutine mech_results(group,ph) character(len=*), intent(in) :: group integer, intent(in) :: ph + if (phase_plasticity(ph) /= PLASTICITY_NONE_ID) & + call results_closeGroup(results_addGroup(group//'plastic')) + select case(phase_plasticity(ph)) case(PLASTICITY_ISOTROPIC_ID) @@ -670,6 +673,7 @@ module subroutine mech_results(group,ph) case(PLASTICITY_NONLOCAL_ID) call plastic_nonlocal_results(phase_plasticityInstance(ph),group//'plastic') + end select end subroutine mech_results @@ -679,48 +683,6 @@ end subroutine mech_results end subroutine mech_restart_read - -!-------------------------------------------------------------------------------------------- -!> @brief writes plasticity constitutive results to HDF5 output file -!-------------------------------------------------------------------------------------------- -module subroutine plastic_results - - integer :: p - character(len=:), allocatable :: group - - plasticityLoop: do p=1,size(material_name_phase) - group = '/current/phase/'//trim(material_name_phase(p)) - call results_closeGroup(results_addGroup(group)) - - group = trim(group)//'/plastic' - - call results_closeGroup(results_addGroup(group)) - select case(phase_plasticity(p)) - - case(PLASTICITY_ISOTROPIC_ID) - call plastic_isotropic_results(phase_plasticityInstance(p),group) - - case(PLASTICITY_PHENOPOWERLAW_ID) - call plastic_phenopowerlaw_results(phase_plasticityInstance(p),group) - - case(PLASTICITY_KINEHARDENING_ID) - call plastic_kinehardening_results(phase_plasticityInstance(p),group) - - case(PLASTICITY_DISLOTWIN_ID) - call plastic_dislotwin_results(phase_plasticityInstance(p),group) - - case(PLASTICITY_DISLOTUNGSTEN_ID) - call plastic_dislotungsten_results(phase_plasticityInstance(p),group) - - case(PLASTICITY_NONLOCAL_ID) - call plastic_nonlocal_results(phase_plasticityInstance(p),group) - end select - - enddo plasticityLoop - -end subroutine plastic_results - - !-------------------------------------------------------------------------------------------------- !> @brief calculation of stress (P) with time integration based on a residuum in Lp and !> intermediate acceleration of the Newton-Raphson correction diff --git a/src/homogenization.f90 b/src/homogenization.f90 index 6ed53c13c..49cb0a9f7 100644 --- a/src/homogenization.f90 +++ b/src/homogenization.f90 @@ -399,6 +399,7 @@ subroutine homogenization_results integer :: p character(len=:), allocatable :: group_base,group + call results_closeGroup(results_addGroup('current/homogenization/')) do p=1,size(material_name_homogenization) group_base = 'current/homogenization/'//trim(material_name_homogenization(p)) diff --git a/src/results.f90 b/src/results.f90 index ea9fd62d4..6363e3efc 100644 --- a/src/results.f90 +++ b/src/results.f90 @@ -111,8 +111,6 @@ subroutine results_addIncrement(inc,time) call results_closeGroup(results_addGroup(trim('inc'//trim(adjustl(incChar))))) call results_setLink(trim('inc'//trim(adjustl(incChar))),'current') call results_addAttribute('time/s',time,trim('inc'//trim(adjustl(incChar)))) - call results_closeGroup(results_addGroup('current/phase')) - call results_closeGroup(results_addGroup('current/homogenization')) end subroutine results_addIncrement From 831e0ce1b95bcdf7392f0acdb2c81d4246b4d85c Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Tue, 22 Dec 2020 08:54:32 +0100 Subject: [PATCH 089/148] sorting responsibilities --- src/CPFEM.f90 | 1 - src/CPFEM2.f90 | 1 - src/constitutive.f90 | 138 +--------------------------------- src/constitutive_mech.f90 | 153 ++++++++++++++++++++++++++++++++++++-- 4 files changed, 147 insertions(+), 146 deletions(-) diff --git a/src/CPFEM.f90 b/src/CPFEM.f90 index fe8c7d1b3..0d8e31b46 100644 --- a/src/CPFEM.f90 +++ b/src/CPFEM.f90 @@ -277,7 +277,6 @@ subroutine CPFEM_results(inc,time) call results_openJobFile call results_addIncrement(inc,time) call constitutive_results - call crystallite_results call homogenization_results call discretization_results call results_finalizeIncrement diff --git a/src/CPFEM2.f90 b/src/CPFEM2.f90 index 636962948..dd4be8fc2 100644 --- a/src/CPFEM2.f90 +++ b/src/CPFEM2.f90 @@ -114,7 +114,6 @@ subroutine CPFEM_results(inc,time) call results_openJobFile call results_addIncrement(inc,time) call constitutive_results - call crystallite_results call homogenization_results call discretization_results call results_finalizeIncrement diff --git a/src/constitutive.f90 b/src/constitutive.f90 index e49932cfe..6d3fee622 100644 --- a/src/constitutive.f90 +++ b/src/constitutive.f90 @@ -446,7 +446,6 @@ end function constitutive_deltaState crystallite_stressTangent, & crystallite_orientations, & crystallite_push33ToRef, & - crystallite_results, & crystallite_restartWrite, & crystallite_restartRead, & crystallite_forward, & @@ -964,7 +963,6 @@ subroutine crystallite_init phases => config_material%get('phase') - allocate(output_constituent(phases%length)) allocate(constitutive_mech_Fi(phases%length)) allocate(constitutive_mech_Fi0(phases%length)) allocate(constitutive_mech_partionedFi0(phases%length)) @@ -973,13 +971,7 @@ subroutine crystallite_init allocate(constitutive_mech_partionedLi0(phases%length)) do p = 1, phases%length Nconstituents = count(material_phaseAt == p) * discretization_nIPs - phase => phases%get(p) - mech => phase%get('mechanics',defaultVal = emptyDict) -#if defined(__GFORTRAN__) - output_constituent(p)%label = output_asStrings(mech) -#else - output_constituent(p)%label = mech%get_asStrings('output',defaultVal=emptyStringArray) -#endif + allocate(constitutive_mech_Fi(p)%data(3,3,Nconstituents)) allocate(constitutive_mech_Fi0(p)%data(3,3,Nconstituents)) allocate(constitutive_mech_partionedFi0(p)%data(3,3,Nconstituents)) @@ -1474,134 +1466,6 @@ function crystallite_push33ToRef(ipc,ip,el, tensor33) end function crystallite_push33ToRef -!-------------------------------------------------------------------------------------------------- -!> @brief writes crystallite results to HDF5 output file -!-------------------------------------------------------------------------------------------------- -subroutine crystallite_results - - integer :: p,o - real(pReal), allocatable, dimension(:,:,:) :: selected_tensors - real(pReal), allocatable, dimension(:,:) :: selected_rotations - character(len=:), allocatable :: group,structureLabel - - do p=1,size(material_name_phase) - group = trim('current/phase')//'/'//trim(material_name_phase(p))//'/mechanics' - - call results_closeGroup(results_addGroup(group)) - - do o = 1, size(output_constituent(p)%label) - select case (output_constituent(p)%label(o)) - case('F') - selected_tensors = select_tensors(crystallite_partitionedF,p) - call results_writeDataset(group,selected_tensors,output_constituent(p)%label(o),& - 'deformation gradient','1') - case('F_e') - selected_tensors = select_tensors(crystallite_Fe,p) - call results_writeDataset(group,selected_tensors,output_constituent(p)%label(o),& - 'elastic deformation gradient','1') - case('F_p') - selected_tensors = select_tensors(crystallite_Fp,p) - call results_writeDataset(group,selected_tensors,output_constituent(p)%label(o),& - 'plastic deformation gradient','1') - case('F_i') - call results_writeDataset(group,constitutive_mech_Fi(p)%data,output_constituent(p)%label(o),& - 'inelastic deformation gradient','1') - case('L_p') - selected_tensors = select_tensors(crystallite_Lp,p) - call results_writeDataset(group,selected_tensors,output_constituent(p)%label(o),& - 'plastic velocity gradient','1/s') - case('L_i') - call results_writeDataset(group,constitutive_mech_Li(p)%data,output_constituent(p)%label(o),& - 'inelastic velocity gradient','1/s') - case('P') - selected_tensors = select_tensors(crystallite_P,p) - call results_writeDataset(group,selected_tensors,output_constituent(p)%label(o),& - 'First Piola-Kirchhoff stress','Pa') - case('S') - selected_tensors = select_tensors(crystallite_S,p) - call results_writeDataset(group,selected_tensors,output_constituent(p)%label(o),& - 'Second Piola-Kirchhoff stress','Pa') - case('O') - select case(lattice_structure(p)) - case(lattice_ISO_ID) - structureLabel = 'aP' - case(lattice_FCC_ID) - structureLabel = 'cF' - case(lattice_BCC_ID) - structureLabel = 'cI' - case(lattice_BCT_ID) - structureLabel = 'tI' - case(lattice_HEX_ID) - structureLabel = 'hP' - case(lattice_ORT_ID) - structureLabel = 'oP' - end select - selected_rotations = select_rotations(crystallite_orientation,p) - call results_writeDataset(group,selected_rotations,output_constituent(p)%label(o),& - 'crystal orientation as quaternion','q_0 ') - call results_addAttribute('Lattice',structureLabel,group//'/'//output_constituent(p)%label(o)) - end select - enddo - enddo - - contains - - !------------------------------------------------------------------------------------------------ - !> @brief select tensors for output - !------------------------------------------------------------------------------------------------ - function select_tensors(dataset,instance) - - integer, intent(in) :: instance - real(pReal), dimension(:,:,:,:,:), intent(in) :: dataset - real(pReal), allocatable, dimension(:,:,:) :: select_tensors - integer :: e,i,c,j - - allocate(select_tensors(3,3,count(material_phaseAt==instance)*discretization_nIPs)) - - j=0 - do e = 1, size(material_phaseAt,2) - do i = 1, discretization_nIPs - do c = 1, size(material_phaseAt,1) !ToDo: this needs to be changed for varying Ngrains - if (material_phaseAt(c,e) == instance) then - j = j + 1 - select_tensors(1:3,1:3,j) = dataset(1:3,1:3,c,i,e) - endif - enddo - enddo - enddo - - end function select_tensors - - -!-------------------------------------------------------------------------------------------------- -!> @brief select rotations for output -!-------------------------------------------------------------------------------------------------- - function select_rotations(dataset,instance) - - integer, intent(in) :: instance - type(rotation), dimension(:,:,:), intent(in) :: dataset - real(pReal), allocatable, dimension(:,:) :: select_rotations - integer :: e,i,c,j - - allocate(select_rotations(4,count(material_phaseAt==instance)*homogenization_maxNconstituents*discretization_nIPs)) - - j=0 - do e = 1, size(material_phaseAt,2) - do i = 1, discretization_nIPs - do c = 1, size(material_phaseAt,1) !ToDo: this needs to be changed for varying Ngrains - if (material_phaseAt(c,e) == instance) then - j = j + 1 - select_rotations(1:4,j) = dataset(c,i,e)%asQuaternion() - endif - enddo - enddo - enddo - - end function select_rotations - -end subroutine crystallite_results - - !-------------------------------------------------------------------------------------------------- !> @brief integrate stress, state with adaptive 1st order explicit Euler method !> using Fixed Point Iteration to adapt the stepsize diff --git a/src/constitutive_mech.f90 b/src/constitutive_mech.f90 index 7d6ef2998..10a86f9b4 100644 --- a/src/constitutive_mech.f90 +++ b/src/constitutive_mech.f90 @@ -299,10 +299,16 @@ module subroutine mech_init allocate(phase_elasticity(phases%length), source = ELASTICITY_undefined_ID) allocate(phase_elasticityInstance(phases%length), source = 0) allocate(phase_NstiffnessDegradations(phases%length),source=0) + allocate(output_constituent(phases%length)) do p = 1, phases%length phase => phases%get(p) mech => phase%get('mechanics') +#if defined(__GFORTRAN__) + output_constituent(p)%label = output_asStrings(mech) +#else + output_constituent(p)%label = mech%get_asStrings('output',defaultVal=emptyStringArray) +#endif elastic => mech%get('elasticity') if(elastic%get_asString('type') == 'hooke') then phase_elasticity(p) = ELASTICITY_HOOKE_ID @@ -652,30 +658,32 @@ module subroutine mech_results(group,ph) integer, intent(in) :: ph if (phase_plasticity(ph) /= PLASTICITY_NONE_ID) & - call results_closeGroup(results_addGroup(group//'plastic')) + call results_closeGroup(results_addGroup(group//'plastic/')) select case(phase_plasticity(ph)) case(PLASTICITY_ISOTROPIC_ID) - call plastic_isotropic_results(phase_plasticityInstance(ph),group//'plastic') + call plastic_isotropic_results(phase_plasticityInstance(ph),group//'plastic/') case(PLASTICITY_PHENOPOWERLAW_ID) - call plastic_phenopowerlaw_results(phase_plasticityInstance(ph),group//'plastic') + call plastic_phenopowerlaw_results(phase_plasticityInstance(ph),group//'plastic/') case(PLASTICITY_KINEHARDENING_ID) - call plastic_kinehardening_results(phase_plasticityInstance(ph),group//'plastic') + call plastic_kinehardening_results(phase_plasticityInstance(ph),group//'plastic/') case(PLASTICITY_DISLOTWIN_ID) - call plastic_dislotwin_results(phase_plasticityInstance(ph),group//'plastic') + call plastic_dislotwin_results(phase_plasticityInstance(ph),group//'plastic/') case(PLASTICITY_DISLOTUNGSTEN_ID) - call plastic_dislotungsten_results(phase_plasticityInstance(ph),group//'plastic') + call plastic_dislotungsten_results(phase_plasticityInstance(ph),group//'plastic/') case(PLASTICITY_NONLOCAL_ID) - call plastic_nonlocal_results(phase_plasticityInstance(ph),group//'plastic') + call plastic_nonlocal_results(phase_plasticityInstance(ph),group//'plastic/') end select + call crystallite_results(group,ph) + end subroutine mech_results module subroutine mech_restart_read(fileHandle) @@ -1237,5 +1245,136 @@ subroutine integrateStateRK(g,i,e,A,B,CC,DB) end subroutine integrateStateRK + +!-------------------------------------------------------------------------------------------------- +!> @brief writes crystallite results to HDF5 output file +!-------------------------------------------------------------------------------------------------- +subroutine crystallite_results(group,ph) + + character(len=*), intent(in) :: group + integer, intent(in) :: ph + + integer :: ou + real(pReal), allocatable, dimension(:,:,:) :: selected_tensors + real(pReal), allocatable, dimension(:,:) :: selected_rotations + character(len=:), allocatable :: structureLabel + + + call results_closeGroup(results_addGroup(group//'/mechanics/')) + + do ou = 1, size(output_constituent(ph)%label) + + select case (output_constituent(ph)%label(ou)) + case('F') + selected_tensors = select_tensors(crystallite_partitionedF,ph) + call results_writeDataset(group//'/mechanics/',selected_tensors,output_constituent(ph)%label(ou),& + 'deformation gradient','1') + case('F_e') + selected_tensors = select_tensors(crystallite_Fe,ph) + call results_writeDataset(group//'/mechanics/',selected_tensors,output_constituent(ph)%label(ou),& + 'elastic deformation gradient','1') + case('F_p') + selected_tensors = select_tensors(crystallite_Fp,ph) + call results_writeDataset(group//'/mechanics/',selected_tensors,output_constituent(ph)%label(ou),& + 'plastic deformation gradient','1') + case('F_i') + call results_writeDataset(group//'/mechanics/',constitutive_mech_Fi(ph)%data,output_constituent(ph)%label(ou),& + 'inelastic deformation gradient','1') + case('L_p') + selected_tensors = select_tensors(crystallite_Lp,ph) + call results_writeDataset(group//'/mechanics/',selected_tensors,output_constituent(ph)%label(ou),& + 'plastic velocity gradient','1/s') + case('L_i') + call results_writeDataset(group//'/mechanics/',constitutive_mech_Li(ph)%data,output_constituent(ph)%label(ou),& + 'inelastic velocity gradient','1/s') + case('P') + selected_tensors = select_tensors(crystallite_P,ph) + call results_writeDataset(group//'/mechanics/',selected_tensors,output_constituent(ph)%label(ou),& + 'First Piola-Kirchhoff stress','Pa') + case('S') + selected_tensors = select_tensors(crystallite_S,ph) + call results_writeDataset(group//'/mechanics/',selected_tensors,output_constituent(ph)%label(ou),& + 'Second Piola-Kirchhoff stress','Pa') + case('O') + select case(lattice_structure(ph)) + case(lattice_ISO_ID) + structureLabel = 'aP' + case(lattice_FCC_ID) + structureLabel = 'cF' + case(lattice_BCC_ID) + structureLabel = 'cI' + case(lattice_BCT_ID) + structureLabel = 'tI' + case(lattice_HEX_ID) + structureLabel = 'hP' + case(lattice_ORT_ID) + structureLabel = 'oP' + end select + selected_rotations = select_rotations(crystallite_orientation,ph) + call results_writeDataset(group//'/mechanics/',selected_rotations,output_constituent(ph)%label(ou),& + 'crystal orientation as quaternion','q_0 (q_1 q_2 q_3)') + call results_addAttribute('Lattice',structureLabel,group//'/mechanics/'//output_constituent(ph)%label(ou)) + end select + enddo + + + contains + + !------------------------------------------------------------------------------------------------ + !> @brief select tensors for output + !------------------------------------------------------------------------------------------------ + function select_tensors(dataset,instance) + + integer, intent(in) :: instance + real(pReal), dimension(:,:,:,:,:), intent(in) :: dataset + real(pReal), allocatable, dimension(:,:,:) :: select_tensors + integer :: e,i,c,j + + allocate(select_tensors(3,3,count(material_phaseAt==instance)*discretization_nIPs)) + + j=0 + do e = 1, size(material_phaseAt,2) + do i = 1, discretization_nIPs + do c = 1, size(material_phaseAt,1) !ToDo: this needs to be changed for varying Ngrains + if (material_phaseAt(c,e) == instance) then + j = j + 1 + select_tensors(1:3,1:3,j) = dataset(1:3,1:3,c,i,e) + endif + enddo + enddo + enddo + + end function select_tensors + + +!-------------------------------------------------------------------------------------------------- +!> @brief select rotations for output +!-------------------------------------------------------------------------------------------------- + function select_rotations(dataset,instance) + + integer, intent(in) :: instance + type(rotation), dimension(:,:,:), intent(in) :: dataset + real(pReal), allocatable, dimension(:,:) :: select_rotations + integer :: e,i,c,j + + allocate(select_rotations(4,count(material_phaseAt==instance)*homogenization_maxNconstituents*discretization_nIPs)) + + j=0 + do e = 1, size(material_phaseAt,2) + do i = 1, discretization_nIPs + do c = 1, size(material_phaseAt,1) !ToDo: this needs to be changed for varying Ngrains + if (material_phaseAt(c,e) == instance) then + j = j + 1 + select_rotations(1:4,j) = dataset(c,i,e)%asQuaternion() + endif + enddo + enddo + enddo + + end function select_rotations + +end subroutine crystallite_results + + end submodule constitutive_mech From 0e0814dbc396a248dc021a0dde71899168a8e2e8 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Tue, 22 Dec 2020 10:03:19 +0100 Subject: [PATCH 090/148] WIP: mechanics takes care of mechanics variables --- src/constitutive.f90 | 21 ++++++++------------- src/constitutive_mech.f90 | 18 +++++++++++++++++- 2 files changed, 25 insertions(+), 14 deletions(-) diff --git a/src/constitutive.f90 b/src/constitutive.f90 index 6d3fee622..de38e11cf 100644 --- a/src/constitutive.f90 +++ b/src/constitutive.f90 @@ -160,6 +160,10 @@ module constitutive integer(HID_T), intent(in) :: fileHandle end subroutine mech_restart_read + module subroutine mech_initializeRestorationPoints(ph,me) + integer, intent(in) :: ph, me + end subroutine mech_initializeRestorationPoints + ! == cleaned:end =================================================================================== module function constitutive_collectDotState(FpArray, subdt, ipc, ip, el,phase,of) result(broken) @@ -197,11 +201,6 @@ module function constitutive_deltaState(S, Fi, ipc, ip, el, phase, of) result(br end function constitutive_deltaState - module function plastic_active(plastic_label) result(active_plastic) - character(len=*), intent(in) :: plastic_label - logical, dimension(:), allocatable :: active_plastic - end function plastic_active - module function source_active(source_label,src_length) result(active_source) character(len=*), intent(in) :: source_label integer, intent(in) :: src_length @@ -437,7 +436,6 @@ end function constitutive_deltaState constitutive_forward, & constitutive_restore, & plastic_nonlocal_updateCompatibility, & - plastic_active, & source_active, & kinematics_active, & converged, & @@ -1195,20 +1193,17 @@ subroutine constitutive_initializeRestorationPoints(i,e) e !< element number integer :: & c, & !< constituent number - s,p, m + s,ph, me do c = 1,homogenization_Nconstituents(material_homogenizationAt(e)) - p = material_phaseAt(c,e) - m = material_phaseMemberAt(c,i,e) + ph = material_phaseAt(c,e) + me = material_phaseMemberAt(c,i,e) crystallite_partitionedFp0(1:3,1:3,c,i,e) = crystallite_Fp0(1:3,1:3,c,i,e) crystallite_partitionedLp0(1:3,1:3,c,i,e) = crystallite_Lp0(1:3,1:3,c,i,e) - constitutive_mech_partionedFi0(p)%data(1:3,1:3,m) = constitutive_mech_Fi0(p)%data(1:3,1:3,m) - constitutive_mech_partionedLi0(p)%data(1:3,1:3,m) = constitutive_mech_Li0(p)%data(1:3,1:3,m) crystallite_partitionedF0(1:3,1:3,c,i,e) = crystallite_F0(1:3,1:3,c,i,e) crystallite_partitionedS0(1:3,1:3,c,i,e) = crystallite_S0(1:3,1:3,c,i,e) - plasticState(material_phaseAt(c,e))%partitionedState0(:,material_phasememberAt(c,i,e)) = & - plasticState(material_phaseAt(c,e))%state0( :,material_phasememberAt(c,i,e)) + call mech_initializeRestorationPoints(ph,me) do s = 1, phase_Nsources(material_phaseAt(c,e)) sourceState(material_phaseAt(c,e))%p(s)%partitionedState0(:,material_phasememberAt(c,i,e)) = & sourceState(material_phaseAt(c,e))%p(s)%state0( :,material_phasememberAt(c,i,e)) diff --git a/src/constitutive_mech.f90 b/src/constitutive_mech.f90 index 10a86f9b4..7516e6ca5 100644 --- a/src/constitutive_mech.f90 +++ b/src/constitutive_mech.f90 @@ -360,7 +360,7 @@ end subroutine mech_init !-------------------------------------------------------------------------------------------------- !> @brief checks if a plastic module is active or not !-------------------------------------------------------------------------------------------------- -module function plastic_active(plastic_label) result(active_plastic) +function plastic_active(plastic_label) result(active_plastic) character(len=*), intent(in) :: plastic_label !< type of plasticity model logical, dimension(:), allocatable :: active_plastic @@ -1376,5 +1376,21 @@ subroutine crystallite_results(group,ph) end subroutine crystallite_results +!-------------------------------------------------------------------------------------------------- +!> @brief Backup data for homog cutback. +!-------------------------------------------------------------------------------------------------- +module subroutine mech_initializeRestorationPoints(ph,me) + + integer, intent(in) :: & + ph, & + me + + constitutive_mech_partionedFi0(ph)%data(1:3,1:3,me) = constitutive_mech_Fi0(ph)%data(1:3,1:3,me) + constitutive_mech_partionedLi0(ph)%data(1:3,1:3,me) = constitutive_mech_Li0(ph)%data(1:3,1:3,me) + plasticState(ph)%partitionedState0(:,me) = plasticState(ph)%state0(:,me) + +end subroutine mech_initializeRestorationPoints + + end submodule constitutive_mech From fa3d7b8dc7807672a250f9f09fcafd5aa9b99811 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Tue, 22 Dec 2020 10:23:46 +0100 Subject: [PATCH 091/148] new name --- src/constitutive.f90 | 6 +++--- src/homogenization.f90 | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/constitutive.f90 b/src/constitutive.f90 index de38e11cf..47a7dfc4b 100644 --- a/src/constitutive.f90 +++ b/src/constitutive.f90 @@ -448,7 +448,7 @@ end function constitutive_deltaState crystallite_restartRead, & crystallite_forward, & constitutive_initializeRestorationPoints, & - crystallite_windForward, & + constitutive_windForward, & crystallite_restore contains @@ -1216,7 +1216,7 @@ end subroutine constitutive_initializeRestorationPoints !-------------------------------------------------------------------------------------------------- !> @brief Wind homog inc forward. !-------------------------------------------------------------------------------------------------- -subroutine crystallite_windForward(i,e) +subroutine constitutive_windForward(i,e) integer, intent(in) :: & i, & !< integration point number @@ -1242,7 +1242,7 @@ subroutine crystallite_windForward(i,e) enddo enddo -end subroutine crystallite_windForward +end subroutine constitutive_windForward !-------------------------------------------------------------------------------------------------- diff --git a/src/homogenization.f90 b/src/homogenization.f90 index 49cb0a9f7..dcde08f32 100644 --- a/src/homogenization.f90 +++ b/src/homogenization.f90 @@ -231,7 +231,7 @@ subroutine materialpoint_stressAndItsTangent(dt) steppingNeeded: if (subStep(i,e) > num%subStepMinHomog) then ! wind forward grain starting point - call crystallite_windForward(i,e) + call constitutive_windForward(i,e) if(homogState(material_homogenizationAt(e))%sizeState > 0) & homogState(material_homogenizationAt(e))%subState0(:,material_homogenizationMemberAt(i,e)) = & From 2627ed1a829577a94018d2544f4b7539fcf0b789 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Tue, 22 Dec 2020 10:44:43 +0100 Subject: [PATCH 092/148] cleaning --- src/constitutive.f90 | 19 +------------------ src/constitutive_mech.f90 | 6 +++++- 2 files changed, 6 insertions(+), 19 deletions(-) diff --git a/src/constitutive.f90 b/src/constitutive.f90 index 47a7dfc4b..3c4e21989 100644 --- a/src/constitutive.f90 +++ b/src/constitutive.f90 @@ -60,11 +60,7 @@ module constitutive logical, dimension(:,:,:), allocatable :: & crystallite_converged !< convergence flag - type :: tOutput !< new requested output (per phase) - character(len=pStringLen), allocatable, dimension(:) :: & - label - end type tOutput - type(tOutput), allocatable, dimension(:) :: output_constituent + type :: tTensorContainer real(pReal), dimension(:,:,:), allocatable :: data @@ -201,19 +197,6 @@ module function constitutive_deltaState(S, Fi, ipc, ip, el, phase, of) result(br end function constitutive_deltaState - module function source_active(source_label,src_length) result(active_source) - character(len=*), intent(in) :: source_label - integer, intent(in) :: src_length - logical, dimension(:,:), allocatable :: active_source - end function source_active - - module function kinematics_active(kinematics_label,kinematics_length) result(active_kinematics) - character(len=*), intent(in) :: kinematics_label - integer, intent(in) :: kinematics_length - logical, dimension(:,:), allocatable :: active_kinematics - end function kinematics_active - - module subroutine source_damage_anisoBrittle_dotState(S, ipc, ip, el) integer, intent(in) :: & ipc, & !< component-ID of integration point diff --git a/src/constitutive_mech.f90 b/src/constitutive_mech.f90 index 7516e6ca5..c000e6c43 100644 --- a/src/constitutive_mech.f90 +++ b/src/constitutive_mech.f90 @@ -270,7 +270,11 @@ submodule(constitutive) constitutive_mech end interface - + type :: tOutput !< new requested output (per phase) + character(len=pStringLen), allocatable, dimension(:) :: & + label + end type tOutput + type(tOutput), allocatable, dimension(:) :: output_constituent contains From 81602dd0e0806492d6683f3ed7ec876e465386e7 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Tue, 22 Dec 2020 11:13:39 +0100 Subject: [PATCH 093/148] for internal use only --- src/constitutive.f90 | 20 -------------------- src/constitutive_mech.f90 | 2 +- 2 files changed, 1 insertion(+), 21 deletions(-) diff --git a/src/constitutive.f90 b/src/constitutive.f90 index 3c4e21989..21e2b82ee 100644 --- a/src/constitutive.f90 +++ b/src/constitutive.f90 @@ -162,22 +162,6 @@ module constitutive ! == cleaned:end =================================================================================== - module function constitutive_collectDotState(FpArray, subdt, ipc, ip, el,phase,of) result(broken) - - integer, intent(in) :: & - ipc, & !< component-ID of integration point - ip, & !< integration point - el, & !< element - phase, & - of - real(pReal), intent(in) :: & - subdt !< timestep - real(pReal), intent(in), dimension(3,3,homogenization_maxNconstituents,discretization_nIPs,discretization_Nelems) :: & - FpArray !< plastic deformation gradient - - logical :: broken -end function constitutive_collectDotState - module function constitutive_deltaState(S, Fi, ipc, ip, el, phase, of) result(broken) @@ -408,10 +392,6 @@ end function constitutive_deltaState constitutive_init, & constitutive_homogenizedC, & constitutive_LiAndItsTangents, & - constitutive_collectDotState, & - constitutive_collectDotState_source, & - constitutive_deltaState, & - constitutive_deltaState_source, & constitutive_damage_getRateAndItsTangents, & constitutive_thermal_getRateAndItsTangents, & constitutive_results, & diff --git a/src/constitutive_mech.f90 b/src/constitutive_mech.f90 index c000e6c43..e18b8401a 100644 --- a/src/constitutive_mech.f90 +++ b/src/constitutive_mech.f90 @@ -546,7 +546,7 @@ end subroutine constitutive_plastic_LpAndItsTangents !-------------------------------------------------------------------------------------------------- !> @brief contains the constitutive equation for calculating the rate of change of microstructure !-------------------------------------------------------------------------------------------------- -module function constitutive_collectDotState(FpArray, subdt, ipc, ip, el,phase,of) result(broken) +function constitutive_collectDotState(FpArray, subdt, ipc, ip, el,phase,of) result(broken) integer, intent(in) :: & ipc, & !< component-ID of integration point From 8b2f75b99b02a6f9844d4697890a9c2f59857da7 Mon Sep 17 00:00:00 2001 From: Test User Date: Tue, 22 Dec 2020 11:22:57 +0100 Subject: [PATCH 094/148] [skip ci] updated version information after successful test of v3.0.0-alpha2-75-gac45427e9 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 5c2eab7c5..3e5a7aa8c 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v3.0.0-alpha2-62-gd1c7ec068 +v3.0.0-alpha2-75-gac45427e9 From 830a61a9ffa89afa93fcc67999306ef043889979 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Tue, 22 Dec 2020 11:38:29 +0100 Subject: [PATCH 095/148] systematic names --- src/constitutive.f90 | 8 ++++---- src/constitutive_mech.f90 | 18 +++++++++--------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/constitutive.f90 b/src/constitutive.f90 index 21e2b82ee..fe978e2ef 100644 --- a/src/constitutive.f90 +++ b/src/constitutive.f90 @@ -637,7 +637,7 @@ end subroutine constitutive_LiAndItsTangents !-------------------------------------------------------------------------------------------------- !> @brief contains the constitutive equation for calculating the rate of change of microstructure !-------------------------------------------------------------------------------------------------- -function constitutive_collectDotState_source(S, ipc, ip, el,phase,of) result(broken) +function constitutive_source_collectDotState(S, ipc, ip, el,phase,of) result(broken) integer, intent(in) :: & ipc, & !< component-ID of integration point @@ -676,7 +676,7 @@ function constitutive_collectDotState_source(S, ipc, ip, el,phase,of) result(bro enddo SourceLoop -end function constitutive_collectDotState_source +end function constitutive_source_collectDotState !-------------------------------------------------------------------------------------------------- @@ -1453,7 +1453,7 @@ subroutine integrateSourceState(g,i,e) p = material_phaseAt(g,e) c = material_phaseMemberAt(g,i,e) - broken = constitutive_collectDotState_source(crystallite_S(1:3,1:3,g,i,e), g,i,e,p,c) + broken = constitutive_source_collectDotState(crystallite_S(1:3,1:3,g,i,e), g,i,e,p,c) if(broken) return do s = 1, phase_Nsources(p) @@ -1471,7 +1471,7 @@ subroutine integrateSourceState(g,i,e) source_dotState(1:size_so(s),1,s) = sourceState(p)%p(s)%dotState(:,c) enddo - broken = constitutive_collectDotState_source(crystallite_S(1:3,1:3,g,i,e), g,i,e,p,c) + broken = constitutive_source_collectDotState(crystallite_S(1:3,1:3,g,i,e), g,i,e,p,c) if(broken) exit iteration do s = 1, phase_Nsources(p) diff --git a/src/constitutive_mech.f90 b/src/constitutive_mech.f90 index e18b8401a..0cb4d97e6 100644 --- a/src/constitutive_mech.f90 +++ b/src/constitutive_mech.f90 @@ -546,7 +546,7 @@ end subroutine constitutive_plastic_LpAndItsTangents !-------------------------------------------------------------------------------------------------- !> @brief contains the constitutive equation for calculating the rate of change of microstructure !-------------------------------------------------------------------------------------------------- -function constitutive_collectDotState(FpArray, subdt, ipc, ip, el,phase,of) result(broken) +function mech_collectDotState(FpArray, subdt, ipc, ip, el,phase,of) result(broken) integer, intent(in) :: & ipc, & !< component-ID of integration point @@ -597,7 +597,7 @@ function constitutive_collectDotState(FpArray, subdt, ipc, ip, el,phase,of) resu broken = any(IEEE_is_NaN(plasticState(phase)%dotState(:,of))) -end function constitutive_collectDotState +end function mech_collectDotState !-------------------------------------------------------------------------------------------------- @@ -952,7 +952,7 @@ module subroutine integrateStateFPI(g,i,e) p = material_phaseAt(g,e) c = material_phaseMemberAt(g,i,e) - broken = constitutive_collectDotState(crystallite_partitionedFp0, & + broken = mech_collectDotState(crystallite_partitionedFp0, & crystallite_subdt(g,i,e), g,i,e,p,c) if(broken) return @@ -970,7 +970,7 @@ module subroutine integrateStateFPI(g,i,e) broken = integrateStress(g,i,e) if(broken) exit iteration - broken = constitutive_collectDotState(crystallite_partitionedFp0, & + broken = mech_collectDotState(crystallite_partitionedFp0, & crystallite_subdt(g,i,e), g,i,e,p,c) if(broken) exit iteration @@ -1040,7 +1040,7 @@ module subroutine integrateStateEuler(g,i,e) p = material_phaseAt(g,e) c = material_phaseMemberAt(g,i,e) - broken = constitutive_collectDotState(crystallite_partitionedFp0, & + broken = mech_collectDotState(crystallite_partitionedFp0, & crystallite_subdt(g,i,e), g,i,e,p,c) if(broken) return @@ -1081,7 +1081,7 @@ module subroutine integrateStateAdaptiveEuler(g,i,e) p = material_phaseAt(g,e) c = material_phaseMemberAt(g,i,e) - broken = constitutive_collectDotState(crystallite_partitionedFp0, & + broken = mech_collectDotState(crystallite_partitionedFp0, & crystallite_subdt(g,i,e), g,i,e,p,c) if(broken) return @@ -1098,7 +1098,7 @@ module subroutine integrateStateAdaptiveEuler(g,i,e) broken = integrateStress(g,i,e) if(broken) return - broken = constitutive_collectDotState(crystallite_partitionedFp0, & + broken = mech_collectDotState(crystallite_partitionedFp0, & crystallite_subdt(g,i,e), g,i,e,p,c) if(broken) return @@ -1193,7 +1193,7 @@ subroutine integrateStateRK(g,i,e,A,B,CC,DB) p = material_phaseAt(g,e) c = material_phaseMemberAt(g,i,e) - broken = constitutive_collectDotState(crystallite_partitionedFp0, & + broken = mech_collectDotState(crystallite_partitionedFp0, & crystallite_subdt(g,i,e), g,i,e,p,c) if(broken) return @@ -1216,7 +1216,7 @@ subroutine integrateStateRK(g,i,e,A,B,CC,DB) broken = integrateStress(g,i,e,CC(stage)) if(broken) exit - broken = constitutive_collectDotState(crystallite_partitionedFp0, & + broken = mech_collectDotState(crystallite_partitionedFp0, & crystallite_subdt(g,i,e)*CC(stage), g,i,e,p,c) if(broken) exit From 11d7f034e47d04a857aa1ef26f62aa6a9fafe461 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Tue, 22 Dec 2020 12:20:00 +0100 Subject: [PATCH 096/148] code follows modular structure --- src/constitutive.f90 | 69 +++++++++++++++++++++++++++---------- src/constitutive_damage.f90 | 69 +++++++++++++++++++------------------ 2 files changed, 86 insertions(+), 52 deletions(-) diff --git a/src/constitutive.f90 b/src/constitutive.f90 index fe978e2ef..e68ade06f 100644 --- a/src/constitutive.f90 +++ b/src/constitutive.f90 @@ -152,6 +152,12 @@ module constitutive integer, intent(in) :: ph end subroutine mech_results + module subroutine damage_results(group,ph) + character(len=*), intent(in) :: group + integer, intent(in) :: ph + end subroutine damage_results + + module subroutine mech_restart_read(fileHandle) integer(HID_T), intent(in) :: fileHandle end subroutine mech_restart_read @@ -314,10 +320,6 @@ end function constitutive_deltaState C end subroutine source_damage_isoBrittle_deltaState - module subroutine damage_results - end subroutine damage_results - - module subroutine constitutive_plastic_LpAndItsTangents(Lp, dLp_dS, dLp_dFi, & S, Fi, ipc, ip, el) @@ -468,7 +470,7 @@ end subroutine constitutive_init !-------------------------------------------------------------------------------------------------- !> @brief checks if a source mechanism is active or not !-------------------------------------------------------------------------------------------------- -module function source_active(source_label,src_length) result(active_source) +function source_active(source_label,src_length) result(active_source) character(len=*), intent(in) :: source_label !< name of source mechanism integer, intent(in) :: src_length !< max. number of sources in system @@ -499,8 +501,7 @@ end function source_active !-------------------------------------------------------------------------------------------------- !> @brief checks if a kinematic mechanism is active or not !-------------------------------------------------------------------------------------------------- - -module function kinematics_active(kinematics_label,kinematics_length) result(active_kinematics) +function kinematics_active(kinematics_label,kinematics_length) result(active_kinematics) character(len=*), intent(in) :: kinematics_label !< name of kinematic mechanism integer, intent(in) :: kinematics_length !< max. number of kinematics in system @@ -631,13 +632,10 @@ subroutine constitutive_LiAndItsTangents(Li, dLi_dS, dLi_dFi, & end subroutine constitutive_LiAndItsTangents - - - !-------------------------------------------------------------------------------------------------- !> @brief contains the constitutive equation for calculating the rate of change of microstructure !-------------------------------------------------------------------------------------------------- -function constitutive_source_collectDotState(S, ipc, ip, el,phase,of) result(broken) +function constitutive_damage_collectDotState(S, ipc, ip, el,phase,of) result(broken) integer, intent(in) :: & ipc, & !< component-ID of integration point @@ -667,6 +665,39 @@ function constitutive_source_collectDotState(S, ipc, ip, el,phase,of) result(bro case (SOURCE_damage_anisoDuctile_ID) sourceType call source_damage_anisoDuctile_dotState(ipc, ip, el) + end select sourceType + + broken = broken .or. any(IEEE_is_NaN(sourceState(phase)%p(i)%dotState(:,of))) + + enddo SourceLoop + +end function constitutive_damage_collectDotState + + +!-------------------------------------------------------------------------------------------------- +!> @brief contains the constitutive equation for calculating the rate of change of microstructure +!-------------------------------------------------------------------------------------------------- +function constitutive_thermal_collectDotState(S, ipc, ip, el,phase,of) result(broken) + + integer, intent(in) :: & + ipc, & !< component-ID of integration point + ip, & !< integration point + el, & !< element + phase, & + of + real(pReal), intent(in), dimension(3,3) :: & + S !< 2nd Piola Kirchhoff stress (vector notation) + integer :: & + i !< counter in source loop + logical :: broken + + + broken = .false. + + SourceLoop: do i = 1, phase_Nsources(phase) + + sourceType: select case (phase_source(i,phase)) + case (SOURCE_thermal_externalheat_ID) sourceType call source_thermal_externalheat_dotState(phase,of) @@ -676,7 +707,7 @@ function constitutive_source_collectDotState(S, ipc, ip, el,phase,of) result(bro enddo SourceLoop -end function constitutive_source_collectDotState +end function constitutive_thermal_collectDotState !-------------------------------------------------------------------------------------------------- @@ -805,20 +836,18 @@ subroutine constitutive_results character(len=:), allocatable :: group - group = '/current/phase/' - call results_closeGroup(results_addGroup(group)) + call results_closeGroup(results_addGroup('/current/phase/')) do ph = 1, size(material_name_phase) - group = group//trim(material_name_phase(ph))//'/' + group = '/current/phase/'//trim(material_name_phase(ph))//'/' call results_closeGroup(results_addGroup(group)) call mech_results(group,ph) + call damage_results(group,ph) enddo - call damage_results - end subroutine constitutive_results @@ -1453,7 +1482,8 @@ subroutine integrateSourceState(g,i,e) p = material_phaseAt(g,e) c = material_phaseMemberAt(g,i,e) - broken = constitutive_source_collectDotState(crystallite_S(1:3,1:3,g,i,e), g,i,e,p,c) + broken = constitutive_thermal_collectDotState(crystallite_S(1:3,1:3,g,i,e), g,i,e,p,c) + broken = broken .or. constitutive_damage_collectDotState(crystallite_S(1:3,1:3,g,i,e), g,i,e,p,c) if(broken) return do s = 1, phase_Nsources(p) @@ -1471,7 +1501,8 @@ subroutine integrateSourceState(g,i,e) source_dotState(1:size_so(s),1,s) = sourceState(p)%p(s)%dotState(:,c) enddo - broken = constitutive_source_collectDotState(crystallite_S(1:3,1:3,g,i,e), g,i,e,p,c) + broken = constitutive_thermal_collectDotState(crystallite_S(1:3,1:3,g,i,e), g,i,e,p,c) + broken = broken .or. constitutive_damage_collectDotState(crystallite_S(1:3,1:3,g,i,e), g,i,e,p,c) if(broken) exit iteration do s = 1, phase_Nsources(p) diff --git a/src/constitutive_damage.f90 b/src/constitutive_damage.f90 index a864ca1b8..4e23b78ea 100644 --- a/src/constitutive_damage.f90 +++ b/src/constitutive_damage.f90 @@ -1,5 +1,5 @@ !---------------------------------------------------------------------------------------------------- -!> @brief internal microstructure state for all damage sources and kinematics constitutive models +!> @brief internal microstructure state for all damage sources and kinematics constitutive models !---------------------------------------------------------------------------------------------------- submodule(constitutive) constitutive_damage @@ -8,7 +8,7 @@ submodule(constitutive) constitutive_damage module function source_damage_anisoBrittle_init(source_length) result(mySources) integer, intent(in) :: source_length logical, dimension(:,:), allocatable :: mySources - end function source_damage_anisoBrittle_init + end function source_damage_anisoBrittle_init module function source_damage_anisoDuctile_init(source_length) result(mySources) integer, intent(in) :: source_length @@ -23,7 +23,7 @@ submodule(constitutive) constitutive_damage module function source_damage_isoDuctile_init(source_length) result(mySources) integer, intent(in) :: source_length logical, dimension(:,:), allocatable :: mySources - end function source_damage_isoDuctile_init + end function source_damage_isoDuctile_init module function kinematics_cleavage_opening_init(kinematics_length) result(myKinematics) integer, intent(in) :: kinematics_length @@ -39,14 +39,14 @@ submodule(constitutive) constitutive_damage module subroutine source_damage_anisobrittle_getRateAndItsTangent(localphiDot, dLocalphiDot_dPhi, phi, phase, constituent) integer, intent(in) :: & phase, & !< phase ID of element - constituent !< position of element within its phase instance + constituent !< position of element within its phase instance real(pReal), intent(in) :: & - phi !< damage parameter + phi !< damage parameter real(pReal), intent(out) :: & localphiDot, & dLocalphiDot_dPhi end subroutine source_damage_anisoBrittle_getRateAndItsTangent - + module subroutine source_damage_anisoDuctile_getRateAndItsTangent(localphiDot, dLocalphiDot_dPhi, phi, phase, constituent) integer, intent(in) :: & phase, & !< phase ID of element @@ -129,7 +129,7 @@ module subroutine damage_init allocate(sourceState(ph)%p(phase_Nsources(ph))) enddo - allocate(phase_source(maxval(phase_Nsources),phases%length), source = SOURCE_undefined_ID) + allocate(phase_source(maxval(phase_Nsources),phases%length), source = SOURCE_undefined_ID) ! initialize source mechanisms if(maxval(phase_Nsources) /= 0) then @@ -141,19 +141,19 @@ module subroutine damage_init !-------------------------------------------------------------------------------------------------- ! initialize kinematic mechanisms - allocate(phase_Nkinematics(phases%length),source = 0) + allocate(phase_Nkinematics(phases%length),source = 0) do ph = 1,phases%length phase => phases%get(ph) kinematics => phase%get('kinematics',defaultVal=emptyList) phase_Nkinematics(ph) = kinematics%length enddo - - allocate(phase_kinematics(maxval(phase_Nkinematics),phases%length), source = KINEMATICS_undefined_ID) + + allocate(phase_kinematics(maxval(phase_Nkinematics),phases%length), source = KINEMATICS_undefined_ID) if(maxval(phase_Nkinematics) /= 0) then where(kinematics_cleavage_opening_init(maxval(phase_Nkinematics))) phase_kinematics = KINEMATICS_cleavage_opening_ID where(kinematics_slipplane_opening_init(maxval(phase_Nkinematics))) phase_kinematics = KINEMATICS_slipplane_opening_ID - endif + endif end subroutine damage_init @@ -167,7 +167,7 @@ module subroutine constitutive_damage_getRateAndItsTangents(phiDot, dPhiDot_dPhi ip, & !< integration point number el !< element number real(pReal), intent(in) :: & - phi !< damage parameter + phi !< damage parameter real(pReal), intent(inout) :: & phiDot, & dPhiDot_dPhi @@ -183,7 +183,7 @@ module subroutine constitutive_damage_getRateAndItsTangents(phiDot, dPhiDot_dPhi phiDot = 0.0_pReal dPhiDot_dPhi = 0.0_pReal - + do grain = 1, homogenization_Nconstituents(material_homogenizationAt(el)) phase = material_phaseAt(grain,el) constituent = material_phasememberAt(grain,ip,el) @@ -217,32 +217,35 @@ end subroutine constitutive_damage_getRateAndItsTangents !---------------------------------------------------------------------------------------------- !< @brief writes damage sources results to HDF5 output file !---------------------------------------------------------------------------------------------- -module subroutine damage_results +module subroutine damage_results(group,ph) - integer :: p,i - character(len=pStringLen) :: group + character(len=*), intent(in) :: group + integer, intent(in) :: ph - do p = 1, size(material_name_phase) + integer :: so - sourceLoop: do i = 1, phase_Nsources(p) - group = trim('current/phase')//'/'//trim(material_name_phase(p)) - group = trim(group)//'/sources' - call results_closeGroup(results_addGroup(group)) + sourceLoop: do so = 1, phase_Nsources(ph) - sourceType: select case (phase_source(i,p)) + if (phase_source(so,ph) /= SOURCE_UNDEFINED_ID) & + call results_closeGroup(results_addGroup(group//'damage/')) - case (SOURCE_damage_anisoBrittle_ID) sourceType - call source_damage_anisoBrittle_results(p,group) - case (SOURCE_damage_anisoDuctile_ID) sourceType - call source_damage_anisoDuctile_results(p,group) - case (SOURCE_damage_isoBrittle_ID) sourceType - call source_damage_isoBrittle_results(p,group) - case (SOURCE_damage_isoDuctile_ID) sourceType - call source_damage_isoDuctile_results(p,group) - end select sourceType + sourceType: select case (phase_source(so,ph)) - enddo SourceLoop - enddo + case (SOURCE_damage_anisoBrittle_ID) sourceType + call source_damage_anisoBrittle_results(ph,group//'damage/') + + case (SOURCE_damage_anisoDuctile_ID) sourceType + call source_damage_anisoDuctile_results(ph,group//'damage/') + + case (SOURCE_damage_isoBrittle_ID) sourceType + call source_damage_isoBrittle_results(ph,group//'damage/') + + case (SOURCE_damage_isoDuctile_ID) sourceType + call source_damage_isoDuctile_results(ph,group//'damage/') + + end select sourceType + + enddo SourceLoop end subroutine damage_results From b452cce2f6529f5997e0b95ed96f8af2f2161908 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Tue, 22 Dec 2020 19:13:30 +0100 Subject: [PATCH 097/148] only needed for mechanics --- src/constitutive.f90 | 18 ------------------ src/constitutive_mech.f90 | 3 ++- 2 files changed, 2 insertions(+), 19 deletions(-) diff --git a/src/constitutive.f90 b/src/constitutive.f90 index e68ade06f..b4a638575 100644 --- a/src/constitutive.f90 +++ b/src/constitutive.f90 @@ -61,7 +61,6 @@ module constitutive crystallite_converged !< convergence flag - type :: tTensorContainer real(pReal), dimension(:,:,:), allocatable :: data end type @@ -169,23 +168,6 @@ module constitutive ! == cleaned:end =================================================================================== -module function constitutive_deltaState(S, Fi, ipc, ip, el, phase, of) result(broken) - - integer, intent(in) :: & - ipc, & !< component-ID of integration point - ip, & !< integration point - el, & !< element - phase, & - of - real(pReal), intent(in), dimension(3,3) :: & - S, & !< 2nd Piola Kirchhoff stress - Fi !< intermediate deformation gradient - logical :: & - broken - - -end function constitutive_deltaState - module subroutine source_damage_anisoBrittle_dotState(S, ipc, ip, el) integer, intent(in) :: & diff --git a/src/constitutive_mech.f90 b/src/constitutive_mech.f90 index 0cb4d97e6..6da151c9d 100644 --- a/src/constitutive_mech.f90 +++ b/src/constitutive_mech.f90 @@ -604,7 +604,7 @@ end function mech_collectDotState !> @brief for constitutive models having an instantaneous change of state !> will return false if delta state is not needed/supported by the constitutive model !-------------------------------------------------------------------------------------------------- -module function constitutive_deltaState(S, Fi, ipc, ip, el, phase, of) result(broken) +function constitutive_deltaState(S, Fi, ipc, ip, el, phase, of) result(broken) integer, intent(in) :: & ipc, & !< component-ID of integration point @@ -1389,6 +1389,7 @@ module subroutine mech_initializeRestorationPoints(ph,me) ph, & me + constitutive_mech_partionedFi0(ph)%data(1:3,1:3,me) = constitutive_mech_Fi0(ph)%data(1:3,1:3,me) constitutive_mech_partionedLi0(ph)%data(1:3,1:3,me) = constitutive_mech_Li0(ph)%data(1:3,1:3,me) plasticState(ph)%partitionedState0(:,me) = plasticState(ph)%state0(:,me) From f28fe0812e6ea8501071a2dc4d4af4e1f388fa9b Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Tue, 22 Dec 2020 19:24:00 +0100 Subject: [PATCH 098/148] sorting --- src/constitutive.f90 | 36 +++--------------------------------- src/constitutive_mech.f90 | 37 +++++++++++++++++++++++++++++++------ 2 files changed, 34 insertions(+), 39 deletions(-) diff --git a/src/constitutive.f90 b/src/constitutive.f90 index b4a638575..2423b5af8 100644 --- a/src/constitutive.f90 +++ b/src/constitutive.f90 @@ -351,22 +351,6 @@ module constitutive integer, intent(in) :: e, i, g end subroutine integrateStateFPI - module subroutine integrateStateEuler(g,i,e) - integer, intent(in) :: e, i, g - end subroutine integrateStateEuler - - module subroutine integrateStateAdaptiveEuler(g,i,e) - integer, intent(in) :: e, i, g - end subroutine integrateStateAdaptiveEuler - - module subroutine integrateStateRK4(g,i,e) - integer, intent(in) :: e, i, g - end subroutine integrateStateRK4 - - module subroutine integrateStateRKCK45(g,i,e) - integer, intent(in) :: e, i, g - end subroutine integrateStateRKCK45 - end interface @@ -696,7 +680,7 @@ end function constitutive_thermal_collectDotState !> @brief for constitutive models having an instantaneous change of state !> will return false if delta state is not needed/supported by the constitutive model !-------------------------------------------------------------------------------------------------- -function constitutive_deltaState_source(Fe, ipc, ip, el, phase, of) result(broken) +function constitutive_damage_deltaState(Fe, ipc, ip, el, phase, of) result(broken) integer, intent(in) :: & ipc, & !< component-ID of integration point @@ -735,7 +719,7 @@ function constitutive_deltaState_source(Fe, ipc, ip, el, phase, of) result(broke enddo SourceLoop -end function constitutive_deltaState_source +end function constitutive_damage_deltaState !-------------------------------------------------------------------------------------------------- @@ -918,20 +902,6 @@ subroutine crystallite_init if(num%nState < 1) call IO_error(301,ext_msg='nState') if(num%nStress< 1) call IO_error(301,ext_msg='nStress') - select case(num_crystallite%get_asString('integrator',defaultVal='FPI')) - case('FPI') - integrateState => integrateStateFPI - case('Euler') - integrateState => integrateStateEuler - case('AdaptiveEuler') - integrateState => integrateStateAdaptiveEuler - case('RK4') - integrateState => integrateStateRK4 - case('RKCK45') - integrateState => integrateStateRKCK45 - case default - call IO_error(301,ext_msg='integrator') - end select phases => config_material%get('phase') @@ -1505,7 +1475,7 @@ subroutine integrateSourceState(g,i,e) enddo if(crystallite_converged(g,i,e)) then - broken = constitutive_deltaState_source(crystallite_Fe(1:3,1:3,g,i,e),g,i,e,p,c) + broken = constitutive_damage_deltaState(crystallite_Fe(1:3,1:3,g,i,e),g,i,e,p,c) exit iteration endif diff --git a/src/constitutive_mech.f90 b/src/constitutive_mech.f90 index 6da151c9d..0af2621c0 100644 --- a/src/constitutive_mech.f90 +++ b/src/constitutive_mech.f90 @@ -133,7 +133,7 @@ submodule(constitutive) constitutive_mech el !< current element number end subroutine plastic_nonlocal_LpAndItsTangent - module subroutine plastic_isotropic_dotState(Mp,instance,of) + module subroutine plastic_isotropic_dotState(Mp,instance,of) real(pReal), dimension(3,3), intent(in) :: & Mp !< Mandel stress integer, intent(in) :: & @@ -220,7 +220,7 @@ submodule(constitutive) constitutive_mech el !< current element number end subroutine plastic_nonlocal_dependentState - module subroutine plastic_kinehardening_deltaState(Mp,instance,of) + module subroutine plastic_kinehardening_deltaState(Mp,instance,of) real(pReal), dimension(3,3), intent(in) :: & Mp !< Mandel stress integer, intent(in) :: & @@ -289,6 +289,7 @@ module subroutine mech_init p, & stiffDegradationCtr class(tNode), pointer :: & + num_crystallite, & phases, & phase, & mech, & @@ -358,6 +359,30 @@ module subroutine mech_init phase_plasticityInstance(p) = count(phase_plasticity(1:p) == phase_plasticity(p)) enddo + num_crystallite => config_numerics%get('crystallite',defaultVal=emptyDict) + + select case(num_crystallite%get_asString('integrator',defaultVal='FPI')) + + case('FPI') + integrateState => integrateStateFPI + + case('Euler') + integrateState => integrateStateEuler + + case('AdaptiveEuler') + integrateState => integrateStateAdaptiveEuler + + case('RK4') + integrateState => integrateStateRK4 + + case('RKCK45') + integrateState => integrateStateRKCK45 + + case default + call IO_error(301,ext_msg='integrator') + + end select + end subroutine mech_init @@ -1024,7 +1049,7 @@ end subroutine integrateStateFPI !-------------------------------------------------------------------------------------------------- !> @brief integrate state with 1st order explicit Euler method !-------------------------------------------------------------------------------------------------- -module subroutine integrateStateEuler(g,i,e) +subroutine integrateStateEuler(g,i,e) integer, intent(in) :: & e, & !< element index in element loop @@ -1062,7 +1087,7 @@ end subroutine integrateStateEuler !-------------------------------------------------------------------------------------------------- !> @brief integrate stress, state with 1st order Euler method with adaptive step size !-------------------------------------------------------------------------------------------------- -module subroutine integrateStateAdaptiveEuler(g,i,e) +subroutine integrateStateAdaptiveEuler(g,i,e) integer, intent(in) :: & e, & !< element index in element loop @@ -1115,7 +1140,7 @@ end subroutine integrateStateAdaptiveEuler !--------------------------------------------------------------------------------------------------- !> @brief Integrate state (including stress integration) with the classic Runge Kutta method !--------------------------------------------------------------------------------------------------- -module subroutine integrateStateRK4(g,i,e) +subroutine integrateStateRK4(g,i,e) integer, intent(in) :: g,i,e @@ -1138,7 +1163,7 @@ end subroutine integrateStateRK4 !--------------------------------------------------------------------------------------------------- !> @brief Integrate state (including stress integration) with the Cash-Carp method !--------------------------------------------------------------------------------------------------- -module subroutine integrateStateRKCK45(g,i,e) +subroutine integrateStateRKCK45(g,i,e) integer, intent(in) :: g,i,e From 79a8a40e6d8205203d7fb1e350d861ca84251ee0 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Tue, 22 Dec 2020 20:45:27 +0100 Subject: [PATCH 099/148] Fp is directly accessible --- src/constitutive_mech.f90 | 14 ++++++-------- src/constitutive_plastic_nonlocal.f90 | 25 +++++++++++-------------- 2 files changed, 17 insertions(+), 22 deletions(-) diff --git a/src/constitutive_mech.f90 b/src/constitutive_mech.f90 index 0af2621c0..b879d0fe2 100644 --- a/src/constitutive_mech.f90 +++ b/src/constitutive_mech.f90 @@ -177,13 +177,12 @@ submodule(constitutive) constitutive_mech of end subroutine plastic_disloTungsten_dotState - module subroutine plastic_nonlocal_dotState(Mp, F, Fp, Temperature,timestep, & + module subroutine plastic_nonlocal_dotState(Mp, F, Temperature,timestep, & instance,of,ip,el) real(pReal), dimension(3,3), intent(in) :: & Mp !< MandelStress real(pReal), dimension(3,3,homogenization_maxNconstituents,discretization_nIPs,discretization_Nelems), intent(in) :: & - F, & !< deformation gradient - Fp !< plastic deformation gradient + F !< deformation gradient real(pReal), intent(in) :: & Temperature, & !< temperature timestep !< substepped crystallite time increment @@ -209,10 +208,9 @@ submodule(constitutive) constitutive_mech of end subroutine plastic_dislotungsten_dependentState - module subroutine plastic_nonlocal_dependentState(F, Fp, instance, of, ip, el) + module subroutine plastic_nonlocal_dependentState(F, instance, of, ip, el) real(pReal), dimension(3,3), intent(in) :: & - F, & !< deformation gradient - Fp !< plastic deformation gradient + F !< deformation gradient integer, intent(in) :: & instance, & of, & @@ -490,7 +488,7 @@ module subroutine constitutive_plastic_dependentState(F, Fp, ipc, ip, el) case (PLASTICITY_DISLOTUNGSTEN_ID) plasticityType call plastic_dislotungsten_dependentState(instance,of) case (PLASTICITY_NONLOCAL_ID) plasticityType - call plastic_nonlocal_dependentState (F,Fp,instance,of,ip,el) + call plastic_nonlocal_dependentState (F,instance,of,ip,el) end select plasticityType end subroutine constitutive_plastic_dependentState @@ -616,7 +614,7 @@ function mech_collectDotState(FpArray, subdt, ipc, ip, el,phase,of) result(broke call plastic_disloTungsten_dotState(Mp,temperature(ho)%p(tme),instance,of) case (PLASTICITY_NONLOCAL_ID) plasticityType - call plastic_nonlocal_dotState(Mp,crystallite_partitionedF0,FpArray,temperature(ho)%p(tme),subdt, & + call plastic_nonlocal_dotState(Mp,crystallite_partitionedF0,temperature(ho)%p(tme),subdt, & instance,of,ip,el) end select plasticityType broken = any(IEEE_is_NaN(plasticState(phase)%dotState(:,of))) diff --git a/src/constitutive_plastic_nonlocal.f90 b/src/constitutive_plastic_nonlocal.f90 index 65f74b6cc..d6209d3a0 100644 --- a/src/constitutive_plastic_nonlocal.f90 +++ b/src/constitutive_plastic_nonlocal.f90 @@ -552,11 +552,10 @@ end function plastic_nonlocal_init !-------------------------------------------------------------------------------------------------- !> @brief calculates quantities characterizing the microstructure !-------------------------------------------------------------------------------------------------- -module subroutine plastic_nonlocal_dependentState(F, Fp, instance, of, ip, el) +module subroutine plastic_nonlocal_dependentState(F, instance, of, ip, el) real(pReal), dimension(3,3), intent(in) :: & - F, & - Fp + F integer, intent(in) :: & instance, & of, & @@ -643,8 +642,8 @@ module subroutine plastic_nonlocal_dependentState(F, Fp, instance, of, ip, el) rho0 = getRho0(instance,of,ip,el) if (.not. phase_localPlasticity(material_phaseAt(1,el)) .and. prm%shortRangeStressCorrection) then - invFp = math_inv33(Fp) - invFe = matmul(Fp,math_inv33(F)) + invFp = math_inv33(crystallite_Fp(1:3,1:3,1,ip,el)) + invFe = matmul(crystallite_Fp(1:3,1:3,1,ip,el),math_inv33(F)) rho_edg_delta = rho0(:,mob_edg_pos) - rho0(:,mob_edg_neg) rho_scr_delta = rho0(:,mob_scr_pos) - rho0(:,mob_scr_neg) @@ -973,14 +972,13 @@ end subroutine plastic_nonlocal_deltaState !--------------------------------------------------------------------------------------------------- !> @brief calculates the rate of change of microstructure !--------------------------------------------------------------------------------------------------- -module subroutine plastic_nonlocal_dotState(Mp, F, Fp, Temperature,timestep, & +module subroutine plastic_nonlocal_dotState(Mp, F, Temperature,timestep, & instance,of,ip,el) real(pReal), dimension(3,3), intent(in) :: & Mp !< MandelStress real(pReal), dimension(3,3,homogenization_maxNconstituents,discretization_nIPs,discretization_Nelems), intent(in) :: & - F, & !< elastic deformation gradient - Fp !< plastic deformation gradient + F !< Deformation gradient real(pReal), intent(in) :: & Temperature, & !< temperature timestep !< substepped crystallite time increment @@ -1147,7 +1145,7 @@ module subroutine plastic_nonlocal_dotState(Mp, F, Fp, Temperature,timestep, & - rhoDip(s,1) / timestep - rhoDotAthermalAnnihilation(s,9) & - rhoDotSingle2DipoleGlide(s,9)) ! make sure that we do not annihilate more dipoles than we have - rhoDot = rhoDotFlux(F,Fp,timestep, instance,of,ip,el) & + rhoDot = rhoDotFlux(F,timestep, instance,of,ip,el) & + rhoDotMultiplication & + rhoDotSingle2DipoleGlide & + rhoDotAthermalAnnihilation & @@ -1176,11 +1174,10 @@ end subroutine plastic_nonlocal_dotState !--------------------------------------------------------------------------------------------------- !> @brief calculates the rate of change of microstructure !--------------------------------------------------------------------------------------------------- -function rhoDotFlux(F,Fp,timestep, instance,of,ip,el) +function rhoDotFlux(F,timestep, instance,of,ip,el) real(pReal), dimension(3,3,homogenization_maxNconstituents,discretization_nIPs,discretization_Nelems), intent(in) :: & - F, & !< elastic deformation gradient - Fp !< plastic deformation gradient + F !< Deformation gradient real(pReal), intent(in) :: & timestep !< substepped crystallite time increment integer, intent(in) :: & @@ -1293,7 +1290,7 @@ function rhoDotFlux(F,Fp,timestep, instance,of,ip,el) m(1:3,:,4) = prm%slip_transverse my_F = F(1:3,1:3,1,ip,el) - my_Fe = matmul(my_F, math_inv33(Fp(1:3,1:3,1,ip,el))) + my_Fe = matmul(my_F, math_inv33(crystallite_Fp(1:3,1:3,1,ip,el))) neighbors: do n = 1,nIPneighbors @@ -1311,7 +1308,7 @@ function rhoDotFlux(F,Fp,timestep, instance,of,ip,el) if (neighbor_n > 0) then ! if neighbor exists, average deformation gradient neighbor_instance = phase_plasticityInstance(material_phaseAt(1,neighbor_el)) neighbor_F = F(1:3,1:3,1,neighbor_ip,neighbor_el) - neighbor_Fe = matmul(neighbor_F, math_inv33(Fp(1:3,1:3,1,neighbor_ip,neighbor_el))) + neighbor_Fe = matmul(neighbor_F, math_inv33(crystallite_Fp(1:3,1:3,1,neighbor_ip,neighbor_el))) Favg = 0.5_pReal * (my_F + neighbor_F) else ! if no neighbor, take my value as average Favg = my_F From 3719b9a52ceb37b6534a683bfc503ec2fd79365b Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Tue, 22 Dec 2020 22:21:11 +0100 Subject: [PATCH 100/148] storing Lp and related fields in new structure --- src/constitutive.f90 | 99 +++++++++++++-------------- src/constitutive_mech.f90 | 39 ++++------- src/constitutive_plastic_nonlocal.f90 | 12 ++-- 3 files changed, 69 insertions(+), 81 deletions(-) diff --git a/src/constitutive.f90 b/src/constitutive.f90 index 2423b5af8..c71856d1a 100644 --- a/src/constitutive.f90 +++ b/src/constitutive.f90 @@ -35,9 +35,6 @@ module constitutive ! crystallite_Fe, & !< current "elastic" def grad (end of converged time step) ! - crystallite_Fp, & !< current plastic def grad (end of converged time step) - crystallite_Fp0, & !< plastic def grad at start of FE inc - crystallite_partitionedFp0,& !< plastic def grad at start of homog inc crystallite_subFp0,& !< plastic def grad at start of crystallite inc ! crystallite_subFi0,& !< intermediate def grad at start of crystallite inc @@ -71,7 +68,11 @@ module constitutive constitutive_mech_partionedFi0, & constitutive_mech_Li, & constitutive_mech_Li0, & - constitutive_mech_partionedLi0 + constitutive_mech_partionedLi0, & + constitutive_mech_Fp, & + constitutive_mech_Fp0, & + constitutive_mech_partionedFp0 + type :: tNumerics integer :: & @@ -320,14 +321,13 @@ module constitutive end subroutine constitutive_plastic_LpAndItsTangents - module subroutine constitutive_plastic_dependentState(F, Fp, ipc, ip, el) + module subroutine constitutive_plastic_dependentState(F, ipc, ip, el) integer, intent(in) :: & ipc, & !< component-ID of integration point ip, & !< integration point el !< element real(pReal), intent(in), dimension(3,3) :: & - F, & !< elastic deformation gradient - Fp !< plastic deformation gradient + F !< elastic deformation gradient end subroutine constitutive_plastic_dependentState @@ -643,33 +643,22 @@ end function constitutive_damage_collectDotState !-------------------------------------------------------------------------------------------------- !> @brief contains the constitutive equation for calculating the rate of change of microstructure !-------------------------------------------------------------------------------------------------- -function constitutive_thermal_collectDotState(S, ipc, ip, el,phase,of) result(broken) +function constitutive_thermal_collectDotState(ph,me) result(broken) - integer, intent(in) :: & - ipc, & !< component-ID of integration point - ip, & !< integration point - el, & !< element - phase, & - of - real(pReal), intent(in), dimension(3,3) :: & - S !< 2nd Piola Kirchhoff stress (vector notation) - integer :: & - i !< counter in source loop + integer, intent(in) :: ph, me logical :: broken + integer :: i + broken = .false. - SourceLoop: do i = 1, phase_Nsources(phase) + SourceLoop: do i = 1, phase_Nsources(ph) - sourceType: select case (phase_source(i,phase)) + if (phase_source(i,ph) == SOURCE_thermal_externalheat_ID) & + call source_thermal_externalheat_dotState(ph,me) - case (SOURCE_thermal_externalheat_ID) sourceType - call source_thermal_externalheat_dotState(phase,of) - - end select sourceType - - broken = broken .or. any(IEEE_is_NaN(sourceState(phase)%p(i)%dotState(:,of))) + broken = broken .or. any(IEEE_is_NaN(sourceState(ph)%p(i)%dotState(:,me))) enddo SourceLoop @@ -853,12 +842,12 @@ subroutine crystallite_init allocate(crystallite_partitionedF(3,3,cMax,iMax,eMax),source=0.0_pReal) allocate(crystallite_S0, & - crystallite_F0,crystallite_Fp0,crystallite_Lp0, & + crystallite_F0,crystallite_Lp0, & crystallite_partitionedS0, & - crystallite_partitionedF0,crystallite_partitionedFp0,& + crystallite_partitionedF0,& crystallite_partitionedLp0, & crystallite_S,crystallite_P, & - crystallite_Fe,crystallite_Fp,crystallite_Lp, & + crystallite_Fe,crystallite_Lp, & crystallite_subF,crystallite_subF0, & crystallite_subFp0,crystallite_subFi0, & source = crystallite_partitionedF) @@ -908,6 +897,9 @@ subroutine crystallite_init allocate(constitutive_mech_Fi(phases%length)) allocate(constitutive_mech_Fi0(phases%length)) allocate(constitutive_mech_partionedFi0(phases%length)) + allocate(constitutive_mech_Fp(phases%length)) + allocate(constitutive_mech_Fp0(phases%length)) + allocate(constitutive_mech_partionedFp0(phases%length)) allocate(constitutive_mech_Li(phases%length)) allocate(constitutive_mech_Li0(phases%length)) allocate(constitutive_mech_partionedLi0(phases%length)) @@ -917,6 +909,9 @@ subroutine crystallite_init allocate(constitutive_mech_Fi(p)%data(3,3,Nconstituents)) allocate(constitutive_mech_Fi0(p)%data(3,3,Nconstituents)) allocate(constitutive_mech_partionedFi0(p)%data(3,3,Nconstituents)) + allocate(constitutive_mech_Fp(p)%data(3,3,Nconstituents)) + allocate(constitutive_mech_Fp0(p)%data(3,3,Nconstituents)) + allocate(constitutive_mech_partionedFp0(p)%data(3,3,Nconstituents)) allocate(constitutive_mech_Li(p)%data(3,3,Nconstituents)) allocate(constitutive_mech_Li0(p)%data(3,3,Nconstituents)) allocate(constitutive_mech_partionedLi0(p)%data(3,3,Nconstituents)) @@ -933,39 +928,38 @@ subroutine crystallite_init p = material_phaseAt(c,e) m = material_phaseMemberAt(c,i,e) - crystallite_Fp0(1:3,1:3,c,i,e) = material_orientation0(c,i,e)%asMatrix() ! Fp reflects initial orientation (see 10.1016/j.actamat.2006.01.005) - crystallite_Fp0(1:3,1:3,c,i,e) = crystallite_Fp0(1:3,1:3,c,i,e) & - / math_det33(crystallite_Fp0(1:3,1:3,c,i,e))**(1.0_pReal/3.0_pReal) + constitutive_mech_Fp0(p)%data(1:3,1:3,m) = material_orientation0(c,i,e)%asMatrix() ! Fp reflects initial orientation (see 10.1016/j.actamat.2006.01.005) + constitutive_mech_Fp0(p)%data(1:3,1:3,m) = constitutive_mech_Fp0(p)%data(1:3,1:3,m) & + / math_det33(constitutive_mech_Fp0(p)%data(1:3,1:3,m))**(1.0_pReal/3.0_pReal) constitutive_mech_Fi0(p)%data(1:3,1:3,m) = math_I3 crystallite_F0(1:3,1:3,c,i,e) = math_I3 crystallite_Fe(1:3,1:3,c,i,e) = math_inv33(matmul(constitutive_mech_Fi0(p)%data(1:3,1:3,m), & - crystallite_Fp0(1:3,1:3,c,i,e))) ! assuming that euler angles are given in internal strain free configuration - crystallite_Fp(1:3,1:3,c,i,e) = crystallite_Fp0(1:3,1:3,c,i,e) + constitutive_mech_Fp0(p)%data(1:3,1:3,m))) ! assuming that euler angles are given in internal strain free configuration + constitutive_mech_Fp(p)%data(1:3,1:3,m) = constitutive_mech_Fp0(p)%data(1:3,1:3,m) constitutive_mech_Fi(p)%data(1:3,1:3,m) = constitutive_mech_Fi0(p)%data(1:3,1:3,m) constitutive_mech_partionedFi0(p)%data(1:3,1:3,m) = constitutive_mech_Fi0(p)%data(1:3,1:3,m) - + constitutive_mech_partionedFp0(p)%data(1:3,1:3,m) = constitutive_mech_Fp0(p)%data(1:3,1:3,m) crystallite_requested(c,i,e) = .true. enddo; enddo enddo !$OMP END PARALLEL DO - - crystallite_partitionedFp0 = crystallite_Fp0 crystallite_partitionedF0 = crystallite_F0 crystallite_partitionedF = crystallite_F0 call crystallite_orientations() - !$OMP PARALLEL DO + !$OMP PARALLEL DO PRIVATE(p,m) do e = FEsolving_execElem(1),FEsolving_execElem(2) do i = FEsolving_execIP(1),FEsolving_execIP(2) do c = 1,homogenization_Nconstituents(material_homogenizationAt(e)) + p = material_phaseAt(c,e) + m = material_phaseMemberAt(c,i,e) call constitutive_plastic_dependentState(crystallite_partitionedF0(1:3,1:3,c,i,e), & - crystallite_partitionedFp0(1:3,1:3,c,i,e), & c,i,e) ! update dependent state variables to be consistent with basic states enddo enddo @@ -1018,7 +1012,7 @@ function crystallite_stress() sourceState(material_phaseAt(c,e))%p(s)%subState0( :,material_phaseMemberAt(c,i,e)) = & sourceState(material_phaseAt(c,e))%p(s)%partitionedState0(:,material_phaseMemberAt(c,i,e)) enddo - crystallite_subFp0(1:3,1:3,c,i,e) = crystallite_partitionedFp0(1:3,1:3,c,i,e) + crystallite_subFp0(1:3,1:3,c,i,e) = constitutive_mech_partionedFp0(p)%data(1:3,1:3,m) crystallite_subFi0(1:3,1:3,c,i,e) = constitutive_mech_partionedFi0(p)%data(1:3,1:3,m) crystallite_subF0(1:3,1:3,c,i,e) = crystallite_partitionedF0(1:3,1:3,c,i,e) subFrac(c,i,e) = 0.0_pReal @@ -1058,7 +1052,7 @@ function crystallite_stress() crystallite_subF0 (1:3,1:3,c,i,e) = crystallite_subF(1:3,1:3,c,i,e) subLp0(1:3,1:3,c,i,e) = crystallite_Lp (1:3,1:3,c,i,e) subLi0(1:3,1:3,c,i,e) = constitutive_mech_Li(p)%data(1:3,1:3,m) - 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) = constitutive_mech_Fp(p)%data(1:3,1:3,m) crystallite_subFi0(1:3,1:3,c,i,e) = constitutive_mech_Fi(p)%data(1:3,1:3,m) plasticState( material_phaseAt(c,e))%subState0(:,material_phaseMemberAt(c,i,e)) & = plasticState(material_phaseAt(c,e))%state( :,material_phaseMemberAt(c,i,e)) @@ -1072,7 +1066,7 @@ function crystallite_stress() ! cut back (reduced time and restore) else 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) + constitutive_mech_Fp(p)%data(1:3,1:3,m) = crystallite_subFp0(1:3,1:3,c,i,e) constitutive_mech_Fi(p)%data(1:3,1:3,m) = crystallite_subFi0(1:3,1:3,c,i,e) crystallite_S (1:3,1:3,c,i,e) = crystallite_S0 (1:3,1:3,c,i,e) if (crystallite_subStep(c,i,e) < 1.0_pReal) then ! actual (not initial) cutback @@ -1098,7 +1092,7 @@ function crystallite_stress() -crystallite_partitionedF0(1:3,1:3,c,i,e)) crystallite_Fe(1:3,1:3,c,i,e) = matmul(crystallite_subF(1:3,1:3,c,i,e), & math_inv33(matmul(constitutive_mech_Fi(p)%data(1:3,1:3,m), & - crystallite_Fp(1:3,1:3,c,i,e)))) + constitutive_mech_Fp(p)%data(1:3,1:3,m)))) crystallite_subdt(c,i,e) = crystallite_subStep(c,i,e) * crystallite_dt(c,i,e) crystallite_converged(c,i,e) = .false. call integrateState(c,i,e) @@ -1142,7 +1136,6 @@ subroutine constitutive_initializeRestorationPoints(i,e) do c = 1,homogenization_Nconstituents(material_homogenizationAt(e)) ph = material_phaseAt(c,e) me = material_phaseMemberAt(c,i,e) - crystallite_partitionedFp0(1:3,1:3,c,i,e) = crystallite_Fp0(1:3,1:3,c,i,e) crystallite_partitionedLp0(1:3,1:3,c,i,e) = crystallite_Lp0(1:3,1:3,c,i,e) crystallite_partitionedF0(1:3,1:3,c,i,e) = crystallite_F0(1:3,1:3,c,i,e) crystallite_partitionedS0(1:3,1:3,c,i,e) = crystallite_S0(1:3,1:3,c,i,e) @@ -1172,7 +1165,7 @@ subroutine constitutive_windForward(i,e) p = material_phaseAt(c,e) m = material_phaseMemberAt(c,i,e) crystallite_partitionedF0 (1:3,1:3,c,i,e) = crystallite_partitionedF(1:3,1:3,c,i,e) - crystallite_partitionedFp0(1:3,1:3,c,i,e) = crystallite_Fp (1:3,1:3,c,i,e) + constitutive_mech_partionedFp0(p)%data(1:3,1:3,m) = constitutive_mech_Fp(p)%data(1:3,1:3,m) crystallite_partitionedLp0(1:3,1:3,c,i,e) = crystallite_Lp (1:3,1:3,c,i,e) constitutive_mech_partionedFi0(p)%data(1:3,1:3,m) = constitutive_mech_Fi(p)%data(1:3,1:3,m) constitutive_mech_partionedLi0(p)%data(1:3,1:3,m) = constitutive_mech_Li(p)%data(1:3,1:3,m) @@ -1210,7 +1203,7 @@ subroutine crystallite_restore(i,e,includeL) constitutive_mech_Li(p)%data(1:3,1:3,m) = constitutive_mech_partionedLi0(p)%data(1:3,1:3,m) endif ! maybe protecting everything from overwriting makes more sense - crystallite_Fp(1:3,1:3,c,i,e) = crystallite_partitionedFp0(1:3,1:3,c,i,e) + constitutive_mech_Fp(p)%data(1:3,1:3,m) = constitutive_mech_partionedFp0(p)%data(1:3,1:3,m) constitutive_mech_Fi(p)%data(1:3,1:3,m) = constitutive_mech_partionedFi0(p)%data(1:3,1:3,m) crystallite_S (1:3,1:3,c,i,e) = crystallite_partitionedS0 (1:3,1:3,c,i,e) @@ -1264,7 +1257,7 @@ function crystallite_stressTangent(c,i,e) result(dPdF) constitutive_mech_Fi(pp)%data(1:3,1:3,m), & c,i,e) - invFp = math_inv33(crystallite_Fp(1:3,1:3,c,i,e)) + invFp = math_inv33(constitutive_mech_Fp(pp)%data(1:3,1:3,m)) invFi = math_inv33(constitutive_mech_Fi(pp)%data(1:3,1:3,m)) invSubFp0 = math_inv33(crystallite_subFp0(1:3,1:3,c,i,e)) invSubFi0 = math_inv33(crystallite_subFi0(1:3,1:3,c,i,e)) @@ -1434,7 +1427,7 @@ subroutine integrateSourceState(g,i,e) p = material_phaseAt(g,e) c = material_phaseMemberAt(g,i,e) - broken = constitutive_thermal_collectDotState(crystallite_S(1:3,1:3,g,i,e), g,i,e,p,c) + broken = constitutive_thermal_collectDotState(p,c) broken = broken .or. constitutive_damage_collectDotState(crystallite_S(1:3,1:3,g,i,e), g,i,e,p,c) if(broken) return @@ -1453,7 +1446,7 @@ subroutine integrateSourceState(g,i,e) source_dotState(1:size_so(s),1,s) = sourceState(p)%p(s)%dotState(:,c) enddo - broken = constitutive_thermal_collectDotState(crystallite_S(1:3,1:3,g,i,e), g,i,e,p,c) + broken = constitutive_thermal_collectDotState(p,c) broken = broken .or. constitutive_damage_collectDotState(crystallite_S(1:3,1:3,g,i,e), g,i,e,p,c) if(broken) exit iteration @@ -1540,7 +1533,6 @@ subroutine crystallite_restartWrite fileHandle = HDF5_openFile(fileName,'a') call HDF5_write(fileHandle,crystallite_partitionedF,'F') - call HDF5_write(fileHandle,crystallite_Fp, 'F_p') call HDF5_write(fileHandle,crystallite_Lp, 'L_p') call HDF5_write(fileHandle,crystallite_S, 'S') @@ -1552,6 +1544,8 @@ subroutine crystallite_restartWrite call HDF5_write(groupHandle,constitutive_mech_Fi(i)%data,datasetName) write(datasetName,'(i0,a)') i,'_L_i' call HDF5_write(groupHandle,constitutive_mech_Li(i)%data,datasetName) + write(datasetName,'(i0,a)') i,'_F_p' + call HDF5_write(groupHandle,constitutive_mech_Fp(i)%data,datasetName) enddo call HDF5_closeGroup(groupHandle) @@ -1583,7 +1577,6 @@ subroutine crystallite_restartRead fileHandle = HDF5_openFile(fileName) call HDF5_read(fileHandle,crystallite_F0, 'F') - call HDF5_read(fileHandle,crystallite_Fp0,'F_p') call HDF5_read(fileHandle,crystallite_Lp0,'L_p') call HDF5_read(fileHandle,crystallite_S0, 'S') @@ -1595,6 +1588,8 @@ subroutine crystallite_restartRead call HDF5_read(groupHandle,constitutive_mech_Fi0(i)%data,datasetName) write(datasetName,'(i0,a)') i,'_L_i' call HDF5_read(groupHandle,constitutive_mech_Li0(i)%data,datasetName) + write(datasetName,'(i0,a)') i,'_F_p' + call HDF5_read(groupHandle,constitutive_mech_Fp0(i)%data,datasetName) enddo call HDF5_closeGroup(groupHandle) @@ -1619,13 +1614,13 @@ subroutine crystallite_forward integer :: i, j crystallite_F0 = crystallite_partitionedF - crystallite_Fp0 = crystallite_Fp crystallite_Lp0 = crystallite_Lp crystallite_S0 = crystallite_S do i = 1, size(plasticState) plasticState(i)%state0 = plasticState(i)%state constitutive_mech_Fi0(i) = constitutive_mech_Fi(i) + constitutive_mech_Fp0(i) = constitutive_mech_Fp(i) constitutive_mech_Li0(i) = constitutive_mech_Li(i) enddo do i = 1,size(material_name_homogenization) diff --git a/src/constitutive_mech.f90 b/src/constitutive_mech.f90 index b879d0fe2..2faa27a5c 100644 --- a/src/constitutive_mech.f90 +++ b/src/constitutive_mech.f90 @@ -462,15 +462,14 @@ end subroutine constitutive_hooke_SandItsTangents !-------------------------------------------------------------------------------------------------- !> @brief calls microstructure function of the different plasticity constitutive models !-------------------------------------------------------------------------------------------------- -module subroutine constitutive_plastic_dependentState(F, Fp, ipc, ip, el) +module subroutine constitutive_plastic_dependentState(F, ipc, ip, el) integer, intent(in) :: & ipc, & !< component-ID of integration point ip, & !< integration point el !< element real(pReal), intent(in), dimension(3,3) :: & - F, & !< elastic deformation gradient - Fp !< plastic deformation gradient + F !< elastic deformation gradient integer :: & ho, & !< homogenization @@ -569,7 +568,7 @@ end subroutine constitutive_plastic_LpAndItsTangents !-------------------------------------------------------------------------------------------------- !> @brief contains the constitutive equation for calculating the rate of change of microstructure !-------------------------------------------------------------------------------------------------- -function mech_collectDotState(FpArray, subdt, ipc, ip, el,phase,of) result(broken) +function mech_collectDotState(subdt, ipc, ip, el,phase,of) result(broken) integer, intent(in) :: & ipc, & !< component-ID of integration point @@ -579,8 +578,6 @@ function mech_collectDotState(FpArray, subdt, ipc, ip, el,phase,of) result(broke of real(pReal), intent(in) :: & subdt !< timestep - real(pReal), intent(in), dimension(3,3,homogenization_maxNconstituents,discretization_nIPs,discretization_Nelems) :: & - FpArray !< plastic deformation gradient real(pReal), dimension(3,3) :: & Mp integer :: & @@ -793,8 +790,7 @@ function integrateStress(ipc,ip,el,timeFraction) result(broken) F = crystallite_subF(1:3,1:3,ipc,ip,el) endif - call constitutive_plastic_dependentState(crystallite_partitionedF(1:3,1:3,ipc,ip,el), & - crystallite_Fp(1:3,1:3,ipc,ip,el),ipc,ip,el) + call constitutive_plastic_dependentState(crystallite_partitionedF(1:3,1:3,ipc,ip,el),ipc,ip,el) p = material_phaseAt(ipc,el) m = material_phaseMemberAt(ipc,ip,el) @@ -936,7 +932,7 @@ function integrateStress(ipc,ip,el,timeFraction) result(broken) crystallite_S (1:3,1:3,ipc,ip,el) = S crystallite_Lp (1:3,1:3,ipc,ip,el) = Lpguess constitutive_mech_Li(p)%data(1:3,1:3,m) = Liguess - crystallite_Fp (1:3,1:3,ipc,ip,el) = Fp_new / math_det33(Fp_new)**(1.0_pReal/3.0_pReal) ! regularize + constitutive_mech_Fp(p)%data(1:3,1:3,m) = Fp_new / math_det33(Fp_new)**(1.0_pReal/3.0_pReal) ! regularize constitutive_mech_Fi(p)%data(1:3,1:3,m) = Fi_new crystallite_Fe (1:3,1:3,ipc,ip,el) = matmul(matmul(F,invFp_new),invFi_new) broken = .false. @@ -975,8 +971,7 @@ module subroutine integrateStateFPI(g,i,e) p = material_phaseAt(g,e) c = material_phaseMemberAt(g,i,e) - broken = mech_collectDotState(crystallite_partitionedFp0, & - crystallite_subdt(g,i,e), g,i,e,p,c) + broken = mech_collectDotState(crystallite_subdt(g,i,e), g,i,e,p,c) if(broken) return size_pl = plasticState(p)%sizeDotState @@ -993,8 +988,7 @@ module subroutine integrateStateFPI(g,i,e) broken = integrateStress(g,i,e) if(broken) exit iteration - broken = mech_collectDotState(crystallite_partitionedFp0, & - crystallite_subdt(g,i,e), g,i,e,p,c) + broken = mech_collectDotState(crystallite_subdt(g,i,e), g,i,e,p,c) if(broken) exit iteration zeta = damper(plasticState(p)%dotState(:,c),plastic_dotState(1:size_pl,1),& @@ -1063,8 +1057,7 @@ subroutine integrateStateEuler(g,i,e) p = material_phaseAt(g,e) c = material_phaseMemberAt(g,i,e) - broken = mech_collectDotState(crystallite_partitionedFp0, & - crystallite_subdt(g,i,e), g,i,e,p,c) + broken = mech_collectDotState(crystallite_subdt(g,i,e), g,i,e,p,c) if(broken) return sizeDotState = plasticState(p)%sizeDotState @@ -1104,8 +1097,7 @@ subroutine integrateStateAdaptiveEuler(g,i,e) p = material_phaseAt(g,e) c = material_phaseMemberAt(g,i,e) - broken = mech_collectDotState(crystallite_partitionedFp0, & - crystallite_subdt(g,i,e), g,i,e,p,c) + broken = mech_collectDotState(crystallite_subdt(g,i,e), g,i,e,p,c) if(broken) return sizeDotState = plasticState(p)%sizeDotState @@ -1121,8 +1113,7 @@ subroutine integrateStateAdaptiveEuler(g,i,e) broken = integrateStress(g,i,e) if(broken) return - broken = mech_collectDotState(crystallite_partitionedFp0, & - crystallite_subdt(g,i,e), g,i,e,p,c) + broken = mech_collectDotState(crystallite_subdt(g,i,e), g,i,e,p,c) if(broken) return @@ -1216,8 +1207,7 @@ subroutine integrateStateRK(g,i,e,A,B,CC,DB) p = material_phaseAt(g,e) c = material_phaseMemberAt(g,i,e) - broken = mech_collectDotState(crystallite_partitionedFp0, & - crystallite_subdt(g,i,e), g,i,e,p,c) + broken = mech_collectDotState(crystallite_subdt(g,i,e), g,i,e,p,c) if(broken) return do stage = 1,size(A,1) @@ -1239,8 +1229,7 @@ subroutine integrateStateRK(g,i,e,A,B,CC,DB) broken = integrateStress(g,i,e,CC(stage)) if(broken) exit - broken = mech_collectDotState(crystallite_partitionedFp0, & - crystallite_subdt(g,i,e)*CC(stage), g,i,e,p,c) + broken = mech_collectDotState(crystallite_subdt(g,i,e)*CC(stage), g,i,e,p,c) if(broken) exit enddo @@ -1301,8 +1290,7 @@ subroutine crystallite_results(group,ph) call results_writeDataset(group//'/mechanics/',selected_tensors,output_constituent(ph)%label(ou),& 'elastic deformation gradient','1') case('F_p') - selected_tensors = select_tensors(crystallite_Fp,ph) - call results_writeDataset(group//'/mechanics/',selected_tensors,output_constituent(ph)%label(ou),& + call results_writeDataset(group//'/mechanics/',constitutive_mech_Fp(ph)%data,output_constituent(ph)%label(ou),& 'plastic deformation gradient','1') case('F_i') call results_writeDataset(group//'/mechanics/',constitutive_mech_Fi(ph)%data,output_constituent(ph)%label(ou),& @@ -1414,6 +1402,7 @@ module subroutine mech_initializeRestorationPoints(ph,me) constitutive_mech_partionedFi0(ph)%data(1:3,1:3,me) = constitutive_mech_Fi0(ph)%data(1:3,1:3,me) + constitutive_mech_partionedFp0(ph)%data(1:3,1:3,me) = constitutive_mech_Fp0(ph)%data(1:3,1:3,me) constitutive_mech_partionedLi0(ph)%data(1:3,1:3,me) = constitutive_mech_Li0(ph)%data(1:3,1:3,me) plasticState(ph)%partitionedState0(:,me) = plasticState(ph)%state0(:,me) diff --git a/src/constitutive_plastic_nonlocal.f90 b/src/constitutive_plastic_nonlocal.f90 index d6209d3a0..0d7875291 100644 --- a/src/constitutive_plastic_nonlocal.f90 +++ b/src/constitutive_plastic_nonlocal.f90 @@ -563,6 +563,8 @@ module subroutine plastic_nonlocal_dependentState(F, instance, of, ip, el) el integer :: & + ph, & + me, & no, & !< neighbor offset neighbor_el, & ! element number of neighboring material point neighbor_ip, & ! integration point of neighboring material point @@ -642,8 +644,10 @@ module subroutine plastic_nonlocal_dependentState(F, instance, of, ip, el) rho0 = getRho0(instance,of,ip,el) if (.not. phase_localPlasticity(material_phaseAt(1,el)) .and. prm%shortRangeStressCorrection) then - invFp = math_inv33(crystallite_Fp(1:3,1:3,1,ip,el)) - invFe = matmul(crystallite_Fp(1:3,1:3,1,ip,el),math_inv33(F)) + ph = material_phaseAt(1,el) + me = material_phaseMemberAt(1,ip,el) + invFp = math_inv33(constitutive_mech_Fp(ph)%data(1:3,1:3,me)) + invFe = matmul(constitutive_mech_Fp(ph)%data(1:3,1:3,me),math_inv33(F)) rho_edg_delta = rho0(:,mob_edg_pos) - rho0(:,mob_edg_neg) rho_scr_delta = rho0(:,mob_scr_pos) - rho0(:,mob_scr_neg) @@ -1290,7 +1294,7 @@ function rhoDotFlux(F,timestep, instance,of,ip,el) m(1:3,:,4) = prm%slip_transverse my_F = F(1:3,1:3,1,ip,el) - my_Fe = matmul(my_F, math_inv33(crystallite_Fp(1:3,1:3,1,ip,el))) + my_Fe = matmul(my_F, math_inv33(constitutive_mech_Fp(ph)%data(1:3,1:3,of))) neighbors: do n = 1,nIPneighbors @@ -1308,7 +1312,7 @@ function rhoDotFlux(F,timestep, instance,of,ip,el) if (neighbor_n > 0) then ! if neighbor exists, average deformation gradient neighbor_instance = phase_plasticityInstance(material_phaseAt(1,neighbor_el)) neighbor_F = F(1:3,1:3,1,neighbor_ip,neighbor_el) - neighbor_Fe = matmul(neighbor_F, math_inv33(crystallite_Fp(1:3,1:3,1,neighbor_ip,neighbor_el))) + neighbor_Fe = matmul(neighbor_F, math_inv33(constitutive_mech_Fp(np)%data(1:3,1:3,no))) Favg = 0.5_pReal * (my_F + neighbor_F) else ! if no neighbor, take my value as average Favg = my_F From 6bb8d894ca0463ed22dc7c0799fe5246b13d5ce0 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Tue, 22 Dec 2020 22:22:43 +0100 Subject: [PATCH 101/148] need to stay compatible with tests --- src/constitutive_damage.f90 | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/constitutive_damage.f90 b/src/constitutive_damage.f90 index 4e23b78ea..3ce614666 100644 --- a/src/constitutive_damage.f90 +++ b/src/constitutive_damage.f90 @@ -227,21 +227,21 @@ module subroutine damage_results(group,ph) sourceLoop: do so = 1, phase_Nsources(ph) if (phase_source(so,ph) /= SOURCE_UNDEFINED_ID) & - call results_closeGroup(results_addGroup(group//'damage/')) + call results_closeGroup(results_addGroup(group//'sources/')) ! should be 'damage' sourceType: select case (phase_source(so,ph)) case (SOURCE_damage_anisoBrittle_ID) sourceType - call source_damage_anisoBrittle_results(ph,group//'damage/') + call source_damage_anisoBrittle_results(ph,group//'sources/') case (SOURCE_damage_anisoDuctile_ID) sourceType - call source_damage_anisoDuctile_results(ph,group//'damage/') + call source_damage_anisoDuctile_results(ph,group//'sources/') case (SOURCE_damage_isoBrittle_ID) sourceType - call source_damage_isoBrittle_results(ph,group//'damage/') + call source_damage_isoBrittle_results(ph,group//'sources/') case (SOURCE_damage_isoDuctile_ID) sourceType - call source_damage_isoDuctile_results(ph,group//'damage/') + call source_damage_isoDuctile_results(ph,group//'sources/') end select sourceType From 916657e2f55486d16b34fedda7cb7b1fcf9b0adc Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Tue, 22 Dec 2020 23:27:56 +0100 Subject: [PATCH 102/148] separating --- src/constitutive.f90 | 20 ++++++++++---------- src/constitutive_mech.f90 | 16 ++++++++++++++++ 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/src/constitutive.f90 b/src/constitutive.f90 index c71856d1a..432f9d606 100644 --- a/src/constitutive.f90 +++ b/src/constitutive.f90 @@ -166,6 +166,10 @@ module constitutive integer, intent(in) :: ph, me end subroutine mech_initializeRestorationPoints + module subroutine constitutive_mech_windForward(ph,me) + integer, intent(in) :: ph, me + end subroutine constitutive_mech_windForward + ! == cleaned:end =================================================================================== @@ -1141,6 +1145,7 @@ subroutine constitutive_initializeRestorationPoints(i,e) crystallite_partitionedS0(1:3,1:3,c,i,e) = crystallite_S0(1:3,1:3,c,i,e) call mech_initializeRestorationPoints(ph,me) + do s = 1, phase_Nsources(material_phaseAt(c,e)) sourceState(material_phaseAt(c,e))%p(s)%partitionedState0(:,material_phasememberAt(c,i,e)) = & sourceState(material_phaseAt(c,e))%p(s)%state0( :,material_phasememberAt(c,i,e)) @@ -1160,22 +1165,17 @@ subroutine constitutive_windForward(i,e) e !< element number integer :: & c, & !< constituent number - s, p, m + s, ph, me do c = 1,homogenization_Nconstituents(material_homogenizationAt(e)) - p = material_phaseAt(c,e) - m = material_phaseMemberAt(c,i,e) + ph = material_phaseAt(c,e) + me = material_phaseMemberAt(c,i,e) crystallite_partitionedF0 (1:3,1:3,c,i,e) = crystallite_partitionedF(1:3,1:3,c,i,e) - constitutive_mech_partionedFp0(p)%data(1:3,1:3,m) = constitutive_mech_Fp(p)%data(1:3,1:3,m) crystallite_partitionedLp0(1:3,1:3,c,i,e) = crystallite_Lp (1:3,1:3,c,i,e) - constitutive_mech_partionedFi0(p)%data(1:3,1:3,m) = constitutive_mech_Fi(p)%data(1:3,1:3,m) - constitutive_mech_partionedLi0(p)%data(1:3,1:3,m) = constitutive_mech_Li(p)%data(1:3,1:3,m) crystallite_partitionedS0 (1:3,1:3,c,i,e) = crystallite_S (1:3,1:3,c,i,e) - plasticState (material_phaseAt(c,e))%partitionedState0(:,material_phasememberAt(c,i,e)) = & - plasticState (material_phaseAt(c,e))%state (:,material_phasememberAt(c,i,e)) + call constitutive_mech_windForward(ph,me) do s = 1, phase_Nsources(material_phaseAt(c,e)) - sourceState(material_phaseAt(c,e))%p(s)%partitionedState0(:,material_phasememberAt(c,i,e)) = & - sourceState(material_phaseAt(c,e))%p(s)%state (:,material_phasememberAt(c,i,e)) + sourceState(ph)%p(s)%partitionedState0(:,me) = sourceState(ph)%p(s)%state(:,me) enddo enddo diff --git a/src/constitutive_mech.f90 b/src/constitutive_mech.f90 index 2faa27a5c..76e7dd080 100644 --- a/src/constitutive_mech.f90 +++ b/src/constitutive_mech.f90 @@ -1409,5 +1409,21 @@ module subroutine mech_initializeRestorationPoints(ph,me) end subroutine mech_initializeRestorationPoints +!-------------------------------------------------------------------------------------------------- +!> @brief Wind homog inc forward. +!-------------------------------------------------------------------------------------------------- +module subroutine constitutive_mech_windForward(ph,me) + + integer, intent(in) :: ph, me + + constitutive_mech_partionedFp0(ph)%data(1:3,1:3,me) = constitutive_mech_Fp(ph)%data(1:3,1:3,me) + constitutive_mech_partionedFi0(ph)%data(1:3,1:3,me) = constitutive_mech_Fi(ph)%data(1:3,1:3,me) + constitutive_mech_partionedLi0(ph)%data(1:3,1:3,me) = constitutive_mech_Li(ph)%data(1:3,1:3,me) + + plasticState(ph)%partitionedState0(:,me) = plasticState(ph)%state(:,me) + + +end subroutine constitutive_mech_windForward + end submodule constitutive_mech From 82eb532193a0c1f36cd903323b43e35fc0ebf9c6 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Wed, 23 Dec 2020 06:58:54 +0100 Subject: [PATCH 103/148] separating functionality --- src/CPFEM.f90 | 2 +- src/CPFEM2.f90 | 2 +- src/constitutive.f90 | 42 +++++++++------------------------------ src/constitutive_mech.f90 | 19 ++++++++++++++++++ src/homogenization.f90 | 17 ++++++++++++++++ 5 files changed, 47 insertions(+), 35 deletions(-) diff --git a/src/CPFEM.f90 b/src/CPFEM.f90 index 0d8e31b46..abbcce04a 100644 --- a/src/CPFEM.f90 +++ b/src/CPFEM.f90 @@ -260,7 +260,7 @@ end subroutine CPFEM_general !-------------------------------------------------------------------------------------------------- subroutine CPFEM_forward - call crystallite_forward + call homogenization_forward call constitutive_forward end subroutine CPFEM_forward diff --git a/src/CPFEM2.f90 b/src/CPFEM2.f90 index dd4be8fc2..44b93d1cb 100644 --- a/src/CPFEM2.f90 +++ b/src/CPFEM2.f90 @@ -97,7 +97,7 @@ end subroutine CPFEM_restartWrite !-------------------------------------------------------------------------------------------------- subroutine CPFEM_forward - call crystallite_forward + call homogenization_forward call constitutive_forward end subroutine CPFEM_forward diff --git a/src/constitutive.f90 b/src/constitutive.f90 index 432f9d606..a84befcd3 100644 --- a/src/constitutive.f90 +++ b/src/constitutive.f90 @@ -32,16 +32,11 @@ module constitutive crystallite_F0, & !< def grad at start of FE inc crystallite_subF, & !< def grad to be reached at end of crystallite inc crystallite_subF0, & !< def grad at start of crystallite inc - ! crystallite_Fe, & !< current "elastic" def grad (end of converged time step) - ! crystallite_subFp0,& !< plastic def grad at start of crystallite inc - ! crystallite_subFi0,& !< intermediate def grad at start of crystallite inc - ! crystallite_Lp0, & !< plastic velocitiy grad at start of FE inc crystallite_partitionedLp0, & !< plastic velocity grad at start of homog inc - ! crystallite_S0, & !< 2nd Piola-Kirchhoff stress vector at start of FE inc crystallite_partitionedS0 !< 2nd Piola-Kirchhoff stress vector at start of homog inc real(pReal), dimension(:,:,:,:,:), allocatable, public :: & @@ -170,10 +165,11 @@ module constitutive integer, intent(in) :: ph, me end subroutine constitutive_mech_windForward + module subroutine constitutive_mech_forward + end subroutine constitutive_mech_forward + ! == cleaned:end =================================================================================== - - module subroutine source_damage_anisoBrittle_dotState(S, ipc, ip, el) integer, intent(in) :: & ipc, & !< component-ID of integration point @@ -381,7 +377,6 @@ module constitutive crystallite_push33ToRef, & crystallite_restartWrite, & crystallite_restartRead, & - crystallite_forward, & constitutive_initializeRestorationPoints, & constitutive_windForward, & crystallite_restore @@ -778,6 +773,12 @@ subroutine constitutive_forward integer :: i, j + crystallite_F0 = crystallite_partitionedF + crystallite_Lp0 = crystallite_Lp + crystallite_S0 = crystallite_S + + call constitutive_mech_forward() + do i = 1, size(sourceState) do j = 1,phase_Nsources(i) sourceState(i)%p(j)%state0 = sourceState(i)%p(j)%state @@ -1605,29 +1606,4 @@ subroutine crystallite_restartRead end subroutine crystallite_restartRead -!-------------------------------------------------------------------------------------------------- -!> @brief Forward data after successful increment. -! ToDo: Any guessing for the current states possible? -!-------------------------------------------------------------------------------------------------- -subroutine crystallite_forward - - integer :: i, j - - crystallite_F0 = crystallite_partitionedF - crystallite_Lp0 = crystallite_Lp - crystallite_S0 = crystallite_S - - do i = 1, size(plasticState) - plasticState(i)%state0 = plasticState(i)%state - constitutive_mech_Fi0(i) = constitutive_mech_Fi(i) - constitutive_mech_Fp0(i) = constitutive_mech_Fp(i) - constitutive_mech_Li0(i) = constitutive_mech_Li(i) - enddo - do i = 1,size(material_name_homogenization) - homogState (i)%state0 = homogState (i)%state - damageState (i)%state0 = damageState (i)%state - enddo - -end subroutine crystallite_forward - end module constitutive diff --git a/src/constitutive_mech.f90 b/src/constitutive_mech.f90 index 76e7dd080..ac3c50892 100644 --- a/src/constitutive_mech.f90 +++ b/src/constitutive_mech.f90 @@ -1425,5 +1425,24 @@ module subroutine constitutive_mech_windForward(ph,me) end subroutine constitutive_mech_windForward + +!-------------------------------------------------------------------------------------------------- +!> @brief Forward data after successful increment. +! ToDo: Any guessing for the current states possible? +!-------------------------------------------------------------------------------------------------- +module subroutine constitutive_mech_forward() + + integer :: ph + + + do ph = 1, size(plasticState) + plasticState(ph)%state0 = plasticState(ph)%state + constitutive_mech_Fi0(ph) = constitutive_mech_Fi(ph) + constitutive_mech_Fp0(ph) = constitutive_mech_Fp(ph) + constitutive_mech_Li0(ph) = constitutive_mech_Li(ph) + enddo + +end subroutine constitutive_mech_forward + end submodule constitutive_mech diff --git a/src/homogenization.f90 b/src/homogenization.f90 index dcde08f32..8ceac0eb8 100644 --- a/src/homogenization.f90 +++ b/src/homogenization.f90 @@ -112,6 +112,7 @@ module homogenization public :: & homogenization_init, & materialpoint_stressAndItsTangent, & + homogenization_forward, & homogenization_results contains @@ -425,4 +426,20 @@ subroutine homogenization_results end subroutine homogenization_results + +!-------------------------------------------------------------------------------------------------- +!> @brief Forward data after successful increment. +! ToDo: Any guessing for the current states possible? +!-------------------------------------------------------------------------------------------------- +subroutine homogenization_forward + + integer :: ho + + do ho = 1, size(material_name_homogenization) + homogState (ho)%state0 = homogState (ho)%state + damageState(ho)%state0 = damageState(ho)%state + enddo + +end subroutine homogenization_forward + end module homogenization From 8cf1035cf324d0105b4145d6995fc4d178221cb2 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Wed, 23 Dec 2020 07:07:18 +0100 Subject: [PATCH 104/148] unifying names --- src/constitutive.f90 | 100 ++++++++++++------------- src/constitutive_mech.f90 | 84 ++++++++++----------- src/constitutive_plastic_dislotwin.f90 | 10 +-- src/damage_nonlocal.f90 | 6 +- src/kinematics_cleavage_opening.f90 | 6 +- src/kinematics_slipplane_opening.f90 | 6 +- src/kinematics_thermal_expansion.f90 | 6 +- src/source_damage_anisoBrittle.f90 | 8 +- src/source_damage_anisoDuctile.f90 | 8 +- src/source_damage_isoBrittle.f90 | 8 +- src/source_damage_isoDuctile.f90 | 8 +- 11 files changed, 125 insertions(+), 125 deletions(-) diff --git a/src/constitutive.f90 b/src/constitutive.f90 index a84befcd3..80d5b4116 100644 --- a/src/constitutive.f90 +++ b/src/constitutive.f90 @@ -170,25 +170,25 @@ module constitutive ! == cleaned:end =================================================================================== - module subroutine source_damage_anisoBrittle_dotState(S, ipc, ip, el) + module subroutine source_damage_anisoBrittle_dotState(S, co, ip, el) integer, intent(in) :: & - ipc, & !< component-ID of integration point + co, & !< component-ID of integration point ip, & !< integration point el !< element real(pReal), intent(in), dimension(3,3) :: & S end subroutine source_damage_anisoBrittle_dotState - module subroutine source_damage_anisoDuctile_dotState(ipc, ip, el) + module subroutine source_damage_anisoDuctile_dotState(co, ip, el) integer, intent(in) :: & - ipc, & !< component-ID of integration point + co, & !< component-ID of integration point ip, & !< integration point el !< element end subroutine source_damage_anisoDuctile_dotState - module subroutine source_damage_isoDuctile_dotState(ipc, ip, el) + module subroutine source_damage_isoDuctile_dotState(co, ip, el) integer, intent(in) :: & - ipc, & !< component-ID of integration point + co, & !< component-ID of integration point ip, & !< integration point el !< element end subroutine source_damage_isoDuctile_dotState @@ -224,11 +224,11 @@ module constitutive dTDot_dT end subroutine constitutive_thermal_getRateAndItsTangents - module function plastic_dislotwin_homogenizedC(ipc,ip,el) result(homogenizedC) + module function plastic_dislotwin_homogenizedC(co,ip,el) result(homogenizedC) real(pReal), dimension(6,6) :: & homogenizedC integer, intent(in) :: & - ipc, & !< component-ID of integration point + co, & !< component-ID of integration point ip, & !< integration point el !< element end function plastic_dislotwin_homogenizedC @@ -254,9 +254,9 @@ module constitutive of end subroutine plastic_isotropic_LiAndItsTangent - module subroutine kinematics_cleavage_opening_LiAndItsTangent(Ld, dLd_dTstar, S, ipc, ip, el) + module subroutine kinematics_cleavage_opening_LiAndItsTangent(Ld, dLd_dTstar, S, co, ip, el) integer, intent(in) :: & - ipc, & !< grain number + co, & !< grain number ip, & !< integration point number el !< element number real(pReal), intent(in), dimension(3,3) :: & @@ -267,9 +267,9 @@ module constitutive dLd_dTstar !< derivative of Ld with respect to Tstar (4th-order tensor) end subroutine kinematics_cleavage_opening_LiAndItsTangent - module subroutine kinematics_slipplane_opening_LiAndItsTangent(Ld, dLd_dTstar, S, ipc, ip, el) + module subroutine kinematics_slipplane_opening_LiAndItsTangent(Ld, dLd_dTstar, S, co, ip, el) integer, intent(in) :: & - ipc, & !< grain number + co, & !< grain number ip, & !< integration point number el !< element number real(pReal), intent(in), dimension(3,3) :: & @@ -280,9 +280,9 @@ module constitutive dLd_dTstar !< derivative of Ld with respect to Tstar (4th-order tensor) end subroutine kinematics_slipplane_opening_LiAndItsTangent - module subroutine kinematics_thermal_expansion_LiAndItsTangent(Li, dLi_dTstar, ipc, ip, el) + module subroutine kinematics_thermal_expansion_LiAndItsTangent(Li, dLi_dTstar, co, ip, el) integer, intent(in) :: & - ipc, & !< grain number + co, & !< grain number ip, & !< integration point number el !< element number real(pReal), intent(out), dimension(3,3) :: & @@ -292,9 +292,9 @@ module constitutive end subroutine kinematics_thermal_expansion_LiAndItsTangent - module subroutine source_damage_isoBrittle_deltaState(C, Fe, ipc, ip, el) + module subroutine source_damage_isoBrittle_deltaState(C, Fe, co, ip, el) integer, intent(in) :: & - ipc, & !< component-ID of integration point + co, & !< component-ID of integration point ip, & !< integration point el !< element real(pReal), intent(in), dimension(3,3) :: & @@ -305,9 +305,9 @@ module constitutive module subroutine constitutive_plastic_LpAndItsTangents(Lp, dLp_dS, dLp_dFi, & - S, Fi, ipc, ip, el) + S, Fi, co, ip, el) integer, intent(in) :: & - ipc, & !< component-ID of integration point + co, & !< component-ID of integration point ip, & !< integration point el !< element real(pReal), intent(in), dimension(3,3) :: & @@ -321,9 +321,9 @@ module constitutive end subroutine constitutive_plastic_LpAndItsTangents - module subroutine constitutive_plastic_dependentState(F, ipc, ip, el) + module subroutine constitutive_plastic_dependentState(F, co, ip, el) integer, intent(in) :: & - ipc, & !< component-ID of integration point + co, & !< component-ID of integration point ip, & !< integration point el !< element real(pReal), intent(in), dimension(3,3) :: & @@ -332,9 +332,9 @@ module constitutive - module subroutine constitutive_hooke_SandItsTangents(S, dS_dFe, dS_dFi, Fe, Fi, ipc, ip, el) + module subroutine constitutive_hooke_SandItsTangents(S, dS_dFe, dS_dFi, Fe, Fi, co, ip, el) integer, intent(in) :: & - ipc, & !< component-ID of integration point + co, & !< component-ID of integration point ip, & !< integration point el !< element real(pReal), intent(in), dimension(3,3) :: & @@ -498,20 +498,20 @@ end function kinematics_active !> @brief returns the homogenize elasticity matrix !> ToDo: homogenizedC66 would be more consistent !-------------------------------------------------------------------------------------------------- -function constitutive_homogenizedC(ipc,ip,el) +function constitutive_homogenizedC(co,ip,el) real(pReal), dimension(6,6) :: & constitutive_homogenizedC integer, intent(in) :: & - ipc, & !< component-ID of integration point + co, & !< component-ID of integration point ip, & !< integration point el !< element - plasticityType: select case (phase_plasticity(material_phaseAt(ipc,el))) + plasticityType: select case (phase_plasticity(material_phaseAt(co,el))) case (PLASTICITY_DISLOTWIN_ID) plasticityType - constitutive_homogenizedC = plastic_dislotwin_homogenizedC(ipc,ip,el) + constitutive_homogenizedC = plastic_dislotwin_homogenizedC(co,ip,el) case default plasticityType - constitutive_homogenizedC = lattice_C66(1:6,1:6,material_phaseAt(ipc,el)) + constitutive_homogenizedC = lattice_C66(1:6,1:6,material_phaseAt(co,el)) end select plasticityType end function constitutive_homogenizedC @@ -522,10 +522,10 @@ end function constitutive_homogenizedC ! ToDo: MD: S is Mi? !-------------------------------------------------------------------------------------------------- subroutine constitutive_LiAndItsTangents(Li, dLi_dS, dLi_dFi, & - S, Fi, ipc, ip, el) + S, Fi, co, ip, el) integer, intent(in) :: & - ipc, & !< component-ID of integration point + co, & !< component-ID of integration point ip, & !< integration point el !< element real(pReal), intent(in), dimension(3,3) :: & @@ -554,10 +554,10 @@ subroutine constitutive_LiAndItsTangents(Li, dLi_dS, dLi_dFi, & dLi_dS = 0.0_pReal dLi_dFi = 0.0_pReal - plasticityType: select case (phase_plasticity(material_phaseAt(ipc,el))) + plasticityType: select case (phase_plasticity(material_phaseAt(co,el))) case (PLASTICITY_isotropic_ID) plasticityType - of = material_phasememberAt(ipc,ip,el) - instance = phase_plasticityInstance(material_phaseAt(ipc,el)) + of = material_phasememberAt(co,ip,el) + instance = phase_plasticityInstance(material_phaseAt(co,el)) call plastic_isotropic_LiAndItsTangent(my_Li, my_dLi_dS, S ,instance,of) case default plasticityType my_Li = 0.0_pReal @@ -567,14 +567,14 @@ subroutine constitutive_LiAndItsTangents(Li, dLi_dS, dLi_dFi, & Li = Li + my_Li dLi_dS = dLi_dS + my_dLi_dS - KinematicsLoop: do k = 1, phase_Nkinematics(material_phaseAt(ipc,el)) - kinematicsType: select case (phase_kinematics(k,material_phaseAt(ipc,el))) + KinematicsLoop: do k = 1, phase_Nkinematics(material_phaseAt(co,el)) + kinematicsType: select case (phase_kinematics(k,material_phaseAt(co,el))) case (KINEMATICS_cleavage_opening_ID) kinematicsType - call kinematics_cleavage_opening_LiAndItsTangent(my_Li, my_dLi_dS, S, ipc, ip, el) + call kinematics_cleavage_opening_LiAndItsTangent(my_Li, my_dLi_dS, S, co, ip, el) case (KINEMATICS_slipplane_opening_ID) kinematicsType - call kinematics_slipplane_opening_LiAndItsTangent(my_Li, my_dLi_dS, S, ipc, ip, el) + call kinematics_slipplane_opening_LiAndItsTangent(my_Li, my_dLi_dS, S, co, ip, el) case (KINEMATICS_thermal_expansion_ID) kinematicsType - call kinematics_thermal_expansion_LiAndItsTangent(my_Li, my_dLi_dS, ipc, ip, el) + call kinematics_thermal_expansion_LiAndItsTangent(my_Li, my_dLi_dS, co, ip, el) case default kinematicsType my_Li = 0.0_pReal my_dLi_dS = 0.0_pReal @@ -600,10 +600,10 @@ end subroutine constitutive_LiAndItsTangents !-------------------------------------------------------------------------------------------------- !> @brief contains the constitutive equation for calculating the rate of change of microstructure !-------------------------------------------------------------------------------------------------- -function constitutive_damage_collectDotState(S, ipc, ip, el,phase,of) result(broken) +function constitutive_damage_collectDotState(S, co, ip, el,phase,of) result(broken) integer, intent(in) :: & - ipc, & !< component-ID of integration point + co, & !< component-ID of integration point ip, & !< integration point el, & !< element phase, & @@ -622,13 +622,13 @@ function constitutive_damage_collectDotState(S, ipc, ip, el,phase,of) result(bro sourceType: select case (phase_source(i,phase)) case (SOURCE_damage_anisoBrittle_ID) sourceType - call source_damage_anisoBrittle_dotState(S, ipc, ip, el) ! correct stress? + call source_damage_anisoBrittle_dotState(S, co, ip, el) ! correct stress? case (SOURCE_damage_isoDuctile_ID) sourceType - call source_damage_isoDuctile_dotState(ipc, ip, el) + call source_damage_isoDuctile_dotState(co, ip, el) case (SOURCE_damage_anisoDuctile_ID) sourceType - call source_damage_anisoDuctile_dotState(ipc, ip, el) + call source_damage_anisoDuctile_dotState(co, ip, el) end select sourceType @@ -668,10 +668,10 @@ end function constitutive_thermal_collectDotState !> @brief for constitutive models having an instantaneous change of state !> will return false if delta state is not needed/supported by the constitutive model !-------------------------------------------------------------------------------------------------- -function constitutive_damage_deltaState(Fe, ipc, ip, el, phase, of) result(broken) +function constitutive_damage_deltaState(Fe, co, ip, el, phase, of) result(broken) integer, intent(in) :: & - ipc, & !< component-ID of integration point + co, & !< component-ID of integration point ip, & !< integration point el, & !< element phase, & @@ -693,8 +693,8 @@ function constitutive_damage_deltaState(Fe, ipc, ip, el, phase, of) result(broke sourceType: select case (phase_source(i,phase)) case (SOURCE_damage_isoBrittle_ID) sourceType - call source_damage_isoBrittle_deltaState (constitutive_homogenizedC(ipc,ip,el), Fe, & - ipc, ip, el) + call source_damage_isoBrittle_deltaState (constitutive_homogenizedC(co,ip,el), Fe, & + co, ip, el) broken = any(IEEE_is_NaN(sourceState(phase)%p(i)%deltaState(:,of))) if(.not. broken) then myOffset = sourceState(phase)%p(i)%offsetDeltaState @@ -1382,7 +1382,7 @@ end subroutine crystallite_orientations !-------------------------------------------------------------------------------------------------- !> @brief Map 2nd order tensor to reference config !-------------------------------------------------------------------------------------------------- -function crystallite_push33ToRef(ipc,ip,el, tensor33) +function crystallite_push33ToRef(co,ip,el, tensor33) real(pReal), dimension(3,3) :: crystallite_push33ToRef real(pReal), dimension(3,3), intent(in) :: tensor33 @@ -1390,10 +1390,10 @@ function crystallite_push33ToRef(ipc,ip,el, tensor33) integer, intent(in):: & el, & ip, & - ipc + co - T = matmul(material_orientation0(ipc,ip,el)%asMatrix(), & ! ToDo: initial orientation correct? - transpose(math_inv33(crystallite_subF(1:3,1:3,ipc,ip,el)))) + T = matmul(material_orientation0(co,ip,el)%asMatrix(), & ! ToDo: initial orientation correct? + transpose(math_inv33(crystallite_subF(1:3,1:3,co,ip,el)))) crystallite_push33ToRef = matmul(transpose(T),matmul(tensor33,T)) end function crystallite_push33ToRef diff --git a/src/constitutive_mech.f90 b/src/constitutive_mech.f90 index ac3c50892..124b4d608 100644 --- a/src/constitutive_mech.f90 +++ b/src/constitutive_mech.f90 @@ -416,10 +416,10 @@ end function plastic_active !> the elastic and intermediate deformation gradients using Hooke's law !-------------------------------------------------------------------------------------------------- module subroutine constitutive_hooke_SandItsTangents(S, dS_dFe, dS_dFi, & - Fe, Fi, ipc, ip, el) + Fe, Fi, co, ip, el) integer, intent(in) :: & - ipc, & !< component-ID of integration point + co, & !< component-ID of integration point ip, & !< integration point el !< element real(pReal), intent(in), dimension(3,3) :: & @@ -439,10 +439,10 @@ module subroutine constitutive_hooke_SandItsTangents(S, dS_dFe, dS_dFi, & i, j ho = material_homogenizationAt(el) - C = math_66toSym3333(constitutive_homogenizedC(ipc,ip,el)) + C = math_66toSym3333(constitutive_homogenizedC(co,ip,el)) - DegradationLoop: do d = 1, phase_NstiffnessDegradations(material_phaseAt(ipc,el)) - degradationType: select case(phase_stiffnessDegradation(d,material_phaseAt(ipc,el))) + DegradationLoop: do d = 1, phase_NstiffnessDegradations(material_phaseAt(co,el)) + degradationType: select case(phase_stiffnessDegradation(d,material_phaseAt(co,el))) case (STIFFNESS_DEGRADATION_damage_ID) degradationType C = C * damage(ho)%p(material_homogenizationMemberAt(ip,el))**2 end select degradationType @@ -462,10 +462,10 @@ end subroutine constitutive_hooke_SandItsTangents !-------------------------------------------------------------------------------------------------- !> @brief calls microstructure function of the different plasticity constitutive models !-------------------------------------------------------------------------------------------------- -module subroutine constitutive_plastic_dependentState(F, ipc, ip, el) +module subroutine constitutive_plastic_dependentState(F, co, ip, el) integer, intent(in) :: & - ipc, & !< component-ID of integration point + co, & !< component-ID of integration point ip, & !< integration point el !< element real(pReal), intent(in), dimension(3,3) :: & @@ -478,10 +478,10 @@ module subroutine constitutive_plastic_dependentState(F, ipc, ip, el) ho = material_homogenizationAt(el) tme = material_homogenizationMemberAt(ip,el) - of = material_phasememberAt(ipc,ip,el) - instance = phase_plasticityInstance(material_phaseAt(ipc,el)) + of = material_phasememberAt(co,ip,el) + instance = phase_plasticityInstance(material_phaseAt(co,el)) - plasticityType: select case (phase_plasticity(material_phaseAt(ipc,el))) + plasticityType: select case (phase_plasticity(material_phaseAt(co,el))) case (PLASTICITY_DISLOTWIN_ID) plasticityType call plastic_dislotwin_dependentState(temperature(ho)%p(tme),instance,of) case (PLASTICITY_DISLOTUNGSTEN_ID) plasticityType @@ -499,9 +499,9 @@ end subroutine constitutive_plastic_dependentState ! Mp in, dLp_dMp out !-------------------------------------------------------------------------------------------------- module subroutine constitutive_plastic_LpAndItsTangents(Lp, dLp_dS, dLp_dFi, & - S, Fi, ipc, ip, el) + S, Fi, co, ip, el) integer, intent(in) :: & - ipc, & !< component-ID of integration point + co, & !< component-ID of integration point ip, & !< integration point el !< element real(pReal), intent(in), dimension(3,3) :: & @@ -527,10 +527,10 @@ module subroutine constitutive_plastic_LpAndItsTangents(Lp, dLp_dS, dLp_dFi, & tme = material_homogenizationMemberAt(ip,el) Mp = matmul(matmul(transpose(Fi),Fi),S) - of = material_phasememberAt(ipc,ip,el) - instance = phase_plasticityInstance(material_phaseAt(ipc,el)) + of = material_phasememberAt(co,ip,el) + instance = phase_plasticityInstance(material_phaseAt(co,el)) - plasticityType: select case (phase_plasticity(material_phaseAt(ipc,el))) + plasticityType: select case (phase_plasticity(material_phaseAt(co,el))) case (PLASTICITY_NONE_ID) plasticityType Lp = 0.0_pReal @@ -568,10 +568,10 @@ end subroutine constitutive_plastic_LpAndItsTangents !-------------------------------------------------------------------------------------------------- !> @brief contains the constitutive equation for calculating the rate of change of microstructure !-------------------------------------------------------------------------------------------------- -function mech_collectDotState(subdt, ipc, ip, el,phase,of) result(broken) +function mech_collectDotState(subdt, co, ip, el,phase,of) result(broken) integer, intent(in) :: & - ipc, & !< component-ID of integration point + co, & !< component-ID of integration point ip, & !< integration point el, & !< element phase, & @@ -591,7 +591,7 @@ function mech_collectDotState(subdt, ipc, ip, el,phase,of) result(broken) instance = phase_plasticityInstance(phase) Mp = matmul(matmul(transpose(constitutive_mech_Fi(phase)%data(1:3,1:3,of)),& - constitutive_mech_Fi(phase)%data(1:3,1:3,of)),crystallite_S(1:3,1:3,ipc,ip,el)) + constitutive_mech_Fi(phase)%data(1:3,1:3,of)),crystallite_S(1:3,1:3,co,ip,el)) plasticityType: select case (phase_plasticity(phase)) @@ -624,10 +624,10 @@ end function mech_collectDotState !> @brief for constitutive models having an instantaneous change of state !> will return false if delta state is not needed/supported by the constitutive model !-------------------------------------------------------------------------------------------------- -function constitutive_deltaState(S, Fi, ipc, ip, el, phase, of) result(broken) +function constitutive_deltaState(S, Fi, co, ip, el, phase, of) result(broken) integer, intent(in) :: & - ipc, & !< component-ID of integration point + co, & !< component-ID of integration point ip, & !< integration point el, & !< element phase, & @@ -719,11 +719,11 @@ end subroutine mech_results !> @brief calculation of stress (P) with time integration based on a residuum in Lp and !> intermediate acceleration of the Newton-Raphson correction !-------------------------------------------------------------------------------------------------- -function integrateStress(ipc,ip,el,timeFraction) result(broken) +function integrateStress(co,ip,el,timeFraction) result(broken) integer, intent(in):: el, & ! element index ip, & ! integration point index - ipc ! grain index + co ! grain index real(pReal), optional, intent(in) :: timeFraction ! fraction of timestep real(pReal), dimension(3,3):: F, & ! deformation gradient at end of timestep @@ -782,25 +782,25 @@ function integrateStress(ipc,ip,el,timeFraction) result(broken) broken = .true. if (present(timeFraction)) then - dt = crystallite_subdt(ipc,ip,el) * timeFraction - F = crystallite_subF0(1:3,1:3,ipc,ip,el) & - + (crystallite_subF(1:3,1:3,ipc,ip,el) - crystallite_subF0(1:3,1:3,ipc,ip,el)) * timeFraction + dt = crystallite_subdt(co,ip,el) * timeFraction + F = crystallite_subF0(1:3,1:3,co,ip,el) & + + (crystallite_subF(1:3,1:3,co,ip,el) - crystallite_subF0(1:3,1:3,co,ip,el)) * timeFraction else - dt = crystallite_subdt(ipc,ip,el) - F = crystallite_subF(1:3,1:3,ipc,ip,el) + dt = crystallite_subdt(co,ip,el) + F = crystallite_subF(1:3,1:3,co,ip,el) endif - call constitutive_plastic_dependentState(crystallite_partitionedF(1:3,1:3,ipc,ip,el),ipc,ip,el) + call constitutive_plastic_dependentState(crystallite_partitionedF(1:3,1:3,co,ip,el),co,ip,el) - p = material_phaseAt(ipc,el) - m = material_phaseMemberAt(ipc,ip,el) + p = material_phaseAt(co,el) + m = material_phaseMemberAt(co,ip,el) - Lpguess = crystallite_Lp(1:3,1:3,ipc,ip,el) ! take as first guess + Lpguess = crystallite_Lp(1:3,1:3,co,ip,el) ! take as first guess Liguess = constitutive_mech_Li(p)%data(1:3,1:3,m) ! take as first guess - call math_invert33(invFp_current,devNull,error,crystallite_subFp0(1:3,1:3,ipc,ip,el)) + call math_invert33(invFp_current,devNull,error,crystallite_subFp0(1:3,1:3,co,ip,el)) if (error) return ! error - call math_invert33(invFi_current,devNull,error,crystallite_subFi0(1:3,1:3,ipc,ip,el)) + call math_invert33(invFi_current,devNull,error,crystallite_subFi0(1:3,1:3,co,ip,el)) if (error) return ! error A = matmul(F,invFp_current) ! intermediate tensor needed later to calculate dFe_dLp @@ -831,10 +831,10 @@ function integrateStress(ipc,ip,el,timeFraction) result(broken) B = math_I3 - dt*Lpguess Fe = matmul(matmul(A,B), invFi_new) call constitutive_hooke_SandItsTangents(S, dS_dFe, dS_dFi, & - Fe, Fi_new, ipc, ip, el) + Fe, Fi_new, co, ip, el) call constitutive_plastic_LpAndItsTangents(Lp_constitutive, dLp_dS, dLp_dFi, & - S, Fi_new, ipc, ip, el) + S, Fi_new, co, ip, el) !* update current residuum and check for convergence of loop atol_Lp = max(num%rtol_crystalliteStress * max(norm2(Lpguess),norm2(Lp_constitutive)), & ! absolute tolerance from largest acceptable relative error @@ -875,7 +875,7 @@ function integrateStress(ipc,ip,el,timeFraction) result(broken) enddo LpLoop call constitutive_LiAndItsTangents(Li_constitutive, dLi_dS, dLi_dFi, & - S, Fi_new, ipc, ip, el) + S, Fi_new, co, ip, el) !* update current residuum and check for convergence of loop atol_Li = max(num%rtol_crystalliteStress * max(norm2(Liguess),norm2(Li_constitutive)), & ! absolute tolerance from largest acceptable relative error @@ -925,16 +925,16 @@ function integrateStress(ipc,ip,el,timeFraction) result(broken) call math_invert33(Fp_new,devNull,error,invFp_new) if (error) return ! error - p = material_phaseAt(ipc,el) - m = material_phaseMemberAt(ipc,ip,el) + p = material_phaseAt(co,el) + m = material_phaseMemberAt(co,ip,el) - 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_Lp (1:3,1:3,ipc,ip,el) = Lpguess + crystallite_P (1:3,1:3,co,ip,el) = matmul(matmul(F,invFp_new),matmul(S,transpose(invFp_new))) + crystallite_S (1:3,1:3,co,ip,el) = S + crystallite_Lp (1:3,1:3,co,ip,el) = Lpguess constitutive_mech_Li(p)%data(1:3,1:3,m) = Liguess constitutive_mech_Fp(p)%data(1:3,1:3,m) = Fp_new / math_det33(Fp_new)**(1.0_pReal/3.0_pReal) ! regularize constitutive_mech_Fi(p)%data(1:3,1:3,m) = Fi_new - crystallite_Fe (1:3,1:3,ipc,ip,el) = matmul(matmul(F,invFp_new),invFi_new) + crystallite_Fe (1:3,1:3,co,ip,el) = matmul(matmul(F,invFp_new),invFi_new) broken = .false. end function integrateStress diff --git a/src/constitutive_plastic_dislotwin.f90 b/src/constitutive_plastic_dislotwin.f90 index 4234a55b8..0474427fe 100644 --- a/src/constitutive_plastic_dislotwin.f90 +++ b/src/constitutive_plastic_dislotwin.f90 @@ -485,12 +485,12 @@ end function plastic_dislotwin_init !-------------------------------------------------------------------------------------------------- !> @brief Return the homogenized elasticity matrix. !-------------------------------------------------------------------------------------------------- -module function plastic_dislotwin_homogenizedC(ipc,ip,el) result(homogenizedC) +module function plastic_dislotwin_homogenizedC(co,ip,el) result(homogenizedC) real(pReal), dimension(6,6) :: & homogenizedC integer, intent(in) :: & - ipc, & !< component-ID of integration point + co, & !< component-ID of integration point ip, & !< integration point el !< element @@ -498,9 +498,9 @@ module function plastic_dislotwin_homogenizedC(ipc,ip,el) result(homogenizedC) of real(pReal) :: f_unrotated - of = material_phasememberAt(ipc,ip,el) - associate(prm => param(phase_plasticityInstance(material_phaseAt(ipc,el))),& - stt => state(phase_plasticityInstance(material_phaseAT(ipc,el)))) + of = material_phasememberAt(co,ip,el) + associate(prm => param(phase_plasticityInstance(material_phaseAt(co,el))),& + stt => state(phase_plasticityInstance(material_phaseAT(co,el)))) f_unrotated = 1.0_pReal & - sum(stt%f_tw(1:prm%sum_N_tw,of)) & diff --git a/src/damage_nonlocal.f90 b/src/damage_nonlocal.f90 index ac4d8636a..3db63cab2 100644 --- a/src/damage_nonlocal.f90 +++ b/src/damage_nonlocal.f90 @@ -148,12 +148,12 @@ real(pReal) function damage_nonlocal_getMobility(ip,el) ip, & !< integration point number el !< element number integer :: & - ipc + co damage_nonlocal_getMobility = 0.0_pReal - do ipc = 1, homogenization_Nconstituents(material_homogenizationAt(el)) - damage_nonlocal_getMobility = damage_nonlocal_getMobility + lattice_M(material_phaseAt(ipc,el)) + do co = 1, homogenization_Nconstituents(material_homogenizationAt(el)) + damage_nonlocal_getMobility = damage_nonlocal_getMobility + lattice_M(material_phaseAt(co,el)) enddo damage_nonlocal_getMobility = damage_nonlocal_getMobility/& diff --git a/src/kinematics_cleavage_opening.f90 b/src/kinematics_cleavage_opening.f90 index 6fe8ed7f6..a29a290f8 100644 --- a/src/kinematics_cleavage_opening.f90 +++ b/src/kinematics_cleavage_opening.f90 @@ -99,10 +99,10 @@ end function kinematics_cleavage_opening_init !-------------------------------------------------------------------------------------------------- !> @brief contains the constitutive equation for calculating the velocity gradient !-------------------------------------------------------------------------------------------------- -module subroutine kinematics_cleavage_opening_LiAndItsTangent(Ld, dLd_dTstar, S, ipc, ip, el) +module subroutine kinematics_cleavage_opening_LiAndItsTangent(Ld, dLd_dTstar, S, co, ip, el) integer, intent(in) :: & - ipc, & !< grain number + co, & !< grain number ip, & !< integration point number el !< element number real(pReal), intent(in), dimension(3,3) :: & @@ -124,7 +124,7 @@ module subroutine kinematics_cleavage_opening_LiAndItsTangent(Ld, dLd_dTstar, S, Ld = 0.0_pReal dLd_dTstar = 0.0_pReal - associate(prm => param(kinematics_cleavage_opening_instance(material_phaseAt(ipc,el)))) + associate(prm => param(kinematics_cleavage_opening_instance(material_phaseAt(co,el)))) do i = 1,prm%sum_N_cl traction_crit = prm%g_crit(i)* damage(homog)%p(damageOffset)**2.0_pReal diff --git a/src/kinematics_slipplane_opening.f90 b/src/kinematics_slipplane_opening.f90 index b7adb6807..84edab122 100644 --- a/src/kinematics_slipplane_opening.f90 +++ b/src/kinematics_slipplane_opening.f90 @@ -117,10 +117,10 @@ end function kinematics_slipplane_opening_init !-------------------------------------------------------------------------------------------------- !> @brief contains the constitutive equation for calculating the velocity gradient !-------------------------------------------------------------------------------------------------- -module subroutine kinematics_slipplane_opening_LiAndItsTangent(Ld, dLd_dTstar, S, ipc, ip, el) +module subroutine kinematics_slipplane_opening_LiAndItsTangent(Ld, dLd_dTstar, S, co, ip, el) integer, intent(in) :: & - ipc, & !< grain number + co, & !< grain number ip, & !< integration point number el !< element number real(pReal), intent(in), dimension(3,3) :: & @@ -138,7 +138,7 @@ module subroutine kinematics_slipplane_opening_LiAndItsTangent(Ld, dLd_dTstar, S traction_d, traction_t, traction_n, traction_crit, & udotd, dudotd_dt, udott, dudott_dt, udotn, dudotn_dt - phase = material_phaseAt(ipc,el) + phase = material_phaseAt(co,el) instance = kinematics_slipplane_opening_instance(phase) homog = material_homogenizationAt(el) damageOffset = material_homogenizationMemberAt(ip,el) diff --git a/src/kinematics_thermal_expansion.f90 b/src/kinematics_thermal_expansion.f90 index 5265d6172..6d4a39632 100644 --- a/src/kinematics_thermal_expansion.f90 +++ b/src/kinematics_thermal_expansion.f90 @@ -84,10 +84,10 @@ end function kinematics_thermal_expansion_init !-------------------------------------------------------------------------------------------------- !> @brief constitutive equation for calculating the velocity gradient !-------------------------------------------------------------------------------------------------- -module subroutine kinematics_thermal_expansion_LiAndItsTangent(Li, dLi_dTstar, ipc, ip, el) +module subroutine kinematics_thermal_expansion_LiAndItsTangent(Li, dLi_dTstar, co, ip, el) integer, intent(in) :: & - ipc, & !< grain number + co, & !< grain number ip, & !< integration point number el !< element number real(pReal), intent(out), dimension(3,3) :: & @@ -101,7 +101,7 @@ module subroutine kinematics_thermal_expansion_LiAndItsTangent(Li, dLi_dTstar, i real(pReal) :: & T, TDot - phase = material_phaseAt(ipc,el) + phase = material_phaseAt(co,el) homog = material_homogenizationAt(el) T = temperature(homog)%p(material_homogenizationMemberAt(ip,el)) TDot = temperatureRate(homog)%p(material_homogenizationMemberAt(ip,el)) diff --git a/src/source_damage_anisoBrittle.f90 b/src/source_damage_anisoBrittle.f90 index 55d5546fc..0f923ceba 100644 --- a/src/source_damage_anisoBrittle.f90 +++ b/src/source_damage_anisoBrittle.f90 @@ -120,10 +120,10 @@ end function source_damage_anisoBrittle_init !-------------------------------------------------------------------------------------------------- !> @brief calculates derived quantities from state !-------------------------------------------------------------------------------------------------- -module subroutine source_damage_anisoBrittle_dotState(S, ipc, ip, el) +module subroutine source_damage_anisoBrittle_dotState(S, co, ip, el) integer, intent(in) :: & - ipc, & !< component-ID of integration point + co, & !< component-ID of integration point ip, & !< integration point el !< element real(pReal), intent(in), dimension(3,3) :: & @@ -139,8 +139,8 @@ module subroutine source_damage_anisoBrittle_dotState(S, ipc, ip, el) real(pReal) :: & traction_d, traction_t, traction_n, traction_crit - phase = material_phaseAt(ipc,el) - constituent = material_phasememberAt(ipc,ip,el) + phase = material_phaseAt(co,el) + constituent = material_phasememberAt(co,ip,el) sourceOffset = source_damage_anisoBrittle_offset(phase) homog = material_homogenizationAt(el) damageOffset = material_homogenizationMemberAt(ip,el) diff --git a/src/source_damage_anisoDuctile.f90 b/src/source_damage_anisoDuctile.f90 index 912fe1387..6f71fc145 100644 --- a/src/source_damage_anisoDuctile.f90 +++ b/src/source_damage_anisoDuctile.f90 @@ -107,10 +107,10 @@ end function source_damage_anisoDuctile_init !-------------------------------------------------------------------------------------------------- !> @brief calculates derived quantities from state !-------------------------------------------------------------------------------------------------- -module subroutine source_damage_anisoDuctile_dotState(ipc, ip, el) +module subroutine source_damage_anisoDuctile_dotState(co, ip, el) integer, intent(in) :: & - ipc, & !< component-ID of integration point + co, & !< component-ID of integration point ip, & !< integration point el !< element @@ -121,8 +121,8 @@ module subroutine source_damage_anisoDuctile_dotState(ipc, ip, el) damageOffset, & homog - phase = material_phaseAt(ipc,el) - constituent = material_phasememberAt(ipc,ip,el) + phase = material_phaseAt(co,el) + constituent = material_phasememberAt(co,ip,el) sourceOffset = source_damage_anisoDuctile_offset(phase) homog = material_homogenizationAt(el) damageOffset = material_homogenizationMemberAt(ip,el) diff --git a/src/source_damage_isoBrittle.f90 b/src/source_damage_isoBrittle.f90 index 7fcf17ee0..8c768b08d 100644 --- a/src/source_damage_isoBrittle.f90 +++ b/src/source_damage_isoBrittle.f90 @@ -94,10 +94,10 @@ end function source_damage_isoBrittle_init !-------------------------------------------------------------------------------------------------- !> @brief calculates derived quantities from state !-------------------------------------------------------------------------------------------------- -module subroutine source_damage_isoBrittle_deltaState(C, Fe, ipc, ip, el) +module subroutine source_damage_isoBrittle_deltaState(C, Fe, co, ip, el) integer, intent(in) :: & - ipc, & !< component-ID of integration point + co, & !< component-ID of integration point ip, & !< integration point el !< element real(pReal), intent(in), dimension(3,3) :: & @@ -114,8 +114,8 @@ module subroutine source_damage_isoBrittle_deltaState(C, Fe, ipc, ip, el) real(pReal) :: & strainenergy - phase = material_phaseAt(ipc,el) !< phase ID at ipc,ip,el - constituent = material_phasememberAt(ipc,ip,el) !< state array offset for phase ID at ipc,ip,el + phase = material_phaseAt(co,el) !< phase ID at co,ip,el + constituent = material_phasememberAt(co,ip,el) !< state array offset for phase ID at co,ip,el sourceOffset = source_damage_isoBrittle_offset(phase) strain = 0.5_pReal*math_sym33to6(matmul(transpose(Fe),Fe)-math_I3) diff --git a/src/source_damage_isoDuctile.f90 b/src/source_damage_isoDuctile.f90 index b66e220d9..86222bbf9 100644 --- a/src/source_damage_isoDuctile.f90 +++ b/src/source_damage_isoDuctile.f90 @@ -98,10 +98,10 @@ end function source_damage_isoDuctile_init !-------------------------------------------------------------------------------------------------- !> @brief calculates derived quantities from state !-------------------------------------------------------------------------------------------------- -module subroutine source_damage_isoDuctile_dotState(ipc, ip, el) +module subroutine source_damage_isoDuctile_dotState(co, ip, el) integer, intent(in) :: & - ipc, & !< component-ID of integration point + co, & !< component-ID of integration point ip, & !< integration point el !< element @@ -112,8 +112,8 @@ module subroutine source_damage_isoDuctile_dotState(ipc, ip, el) damageOffset, & homog - phase = material_phaseAt(ipc,el) - constituent = material_phasememberAt(ipc,ip,el) + phase = material_phaseAt(co,el) + constituent = material_phasememberAt(co,ip,el) sourceOffset = source_damage_isoDuctile_offset(phase) homog = material_homogenizationAt(el) damageOffset = material_homogenizationMemberAt(ip,el) From fe6a82ecc19d752b878fcd503350086b327d4d76 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Wed, 23 Dec 2020 07:14:07 +0100 Subject: [PATCH 105/148] unifying names --- src/constitutive.f90 | 373 +++++++++++++++++++------------------- src/constitutive_mech.f90 | 294 +++++++++++++++--------------- 2 files changed, 333 insertions(+), 334 deletions(-) diff --git a/src/constitutive.f90 b/src/constitutive.f90 index 80d5b4116..4d0fd5582 100644 --- a/src/constitutive.f90 +++ b/src/constitutive.f90 @@ -347,8 +347,8 @@ module constitutive dS_dFi !< derivative of 2nd P-K stress with respect to intermediate deformation gradient end subroutine constitutive_hooke_SandItsTangents - module subroutine integrateStateFPI(g,i,e) - integer, intent(in) :: e, i, g + module subroutine integrateStateFPI(co,ip,el) + integer, intent(in) :: co, ip, el end subroutine integrateStateFPI end interface @@ -746,19 +746,19 @@ end subroutine constitutive_allocateState !-------------------------------------------------------------------------------------------------- !> @brief Restore data after homog cutback. !-------------------------------------------------------------------------------------------------- -subroutine constitutive_restore(i,e) +subroutine constitutive_restore(ip,el) integer, intent(in) :: & - i, & !< integration point number - e !< element number + ip, & !< integration point number + el !< element number integer :: & - c, & !< constituent number + co, & !< constituent number s - do c = 1,homogenization_Nconstituents(material_homogenizationAt(e)) - do s = 1, phase_Nsources(material_phaseAt(c,e)) - sourceState(material_phaseAt(c,e))%p(s)%state( :,material_phasememberAt(c,i,e)) = & - sourceState(material_phaseAt(c,e))%p(s)%partitionedState0(:,material_phasememberAt(c,i,e)) + do co = 1,homogenization_Nconstituents(material_homogenizationAt(el)) + do s = 1, phase_Nsources(material_phaseAt(co,el)) + sourceState(material_phaseAt(co,el))%p(s)%state( :,material_phasememberAt(co,ip,el)) = & + sourceState(material_phaseAt(co,el))%p(s)%partitionedState0(:,material_phasememberAt(co,ip,el)) enddo enddo @@ -827,7 +827,6 @@ subroutine crystallite_init iMax, & !< maximum number of integration points eMax !< maximum number of elements - class(tNode), pointer :: & num_crystallite, & debug_crystallite, & ! pointer to debug options for crystallite @@ -835,6 +834,7 @@ subroutine crystallite_init phase, & mech + print'(/,a)', ' <<<+- crystallite init -+>>>' debug_crystallite => config_debug%get('crystallite', defaultVal=emptyList) @@ -986,9 +986,9 @@ function crystallite_stress() integer :: & NiterationCrystallite, & ! number of iterations in crystallite loop c, & !< counter in integration point component loop - i, & !< counter in integration point loop - e, & !< counter in element loop - s, p, m + ip, & !< counter in integration point loop + el, & !< counter in element loop + s, ph, me logical, dimension(homogenization_maxNconstituents,discretization_nIPs,discretization_Nelems) :: todo !ToDo: need to set some values to false for different Ngrains real(pReal), dimension(homogenization_maxNconstituents,discretization_nIPs,discretization_Nelems) :: subFrac !ToDo: need to set some values to false for different Ngrains real(pReal), dimension(:,:,:,:,:), allocatable :: & @@ -1003,27 +1003,27 @@ function crystallite_stress() !-------------------------------------------------------------------------------------------------- ! initialize to starting condition crystallite_subStep = 0.0_pReal - !$OMP PARALLEL DO PRIVATE(p,m) - elementLooping1: do e = FEsolving_execElem(1),FEsolving_execElem(2) - do i = FEsolving_execIP(1),FEsolving_execIP(2); do c = 1,homogenization_Nconstituents(material_homogenizationAt(e)) - p = material_phaseAt(c,e) - m = material_phaseMemberAt(c,i,e) - subLi0(1:3,1:3,c,i,e) = constitutive_mech_partionedLi0(p)%data(1:3,1:3,m) - homogenizationRequestsCalculation: if (crystallite_requested(c,i,e)) then - plasticState (material_phaseAt(c,e))%subState0( :,material_phaseMemberAt(c,i,e)) = & - plasticState (material_phaseAt(c,e))%partitionedState0(:,material_phaseMemberAt(c,i,e)) + !$OMP PARALLEL DO PRIVATE(ph,me) + elementLooping1: do el = FEsolving_execElem(1),FEsolving_execElem(2) + do ip = FEsolving_execIP(1),FEsolving_execIP(2); do c = 1,homogenization_Nconstituents(material_homogenizationAt(el)) + ph = material_phaseAt(c,el) + me = material_phaseMemberAt(c,ip,el) + subLi0(1:3,1:3,c,ip,el) = constitutive_mech_partionedLi0(ph)%data(1:3,1:3,me) + homogenizationRequestsCalculation: if (crystallite_requested(c,ip,el)) then + plasticState (material_phaseAt(c,el))%subState0( :,material_phaseMemberAt(c,ip,el)) = & + plasticState (material_phaseAt(c,el))%partitionedState0(:,material_phaseMemberAt(c,ip,el)) - do s = 1, phase_Nsources(material_phaseAt(c,e)) - sourceState(material_phaseAt(c,e))%p(s)%subState0( :,material_phaseMemberAt(c,i,e)) = & - sourceState(material_phaseAt(c,e))%p(s)%partitionedState0(:,material_phaseMemberAt(c,i,e)) + do s = 1, phase_Nsources(material_phaseAt(c,el)) + sourceState(material_phaseAt(c,el))%p(s)%subState0( :,material_phaseMemberAt(c,ip,el)) = & + sourceState(material_phaseAt(c,el))%p(s)%partitionedState0(:,material_phaseMemberAt(c,ip,el)) enddo - crystallite_subFp0(1:3,1:3,c,i,e) = constitutive_mech_partionedFp0(p)%data(1:3,1:3,m) - crystallite_subFi0(1:3,1:3,c,i,e) = constitutive_mech_partionedFi0(p)%data(1:3,1:3,m) - crystallite_subF0(1:3,1:3,c,i,e) = crystallite_partitionedF0(1:3,1:3,c,i,e) - subFrac(c,i,e) = 0.0_pReal - crystallite_subStep(c,i,e) = 1.0_pReal/num%subStepSizeCryst - todo(c,i,e) = .true. - crystallite_converged(c,i,e) = .false. ! pretend failed step of 1/subStepSizeCryst + crystallite_subFp0(1:3,1:3,c,ip,el) = constitutive_mech_partionedFp0(ph)%data(1:3,1:3,me) + crystallite_subFi0(1:3,1:3,c,ip,el) = constitutive_mech_partionedFi0(ph)%data(1:3,1:3,me) + crystallite_subF0(1:3,1:3,c,ip,el) = crystallite_partitionedF0(1:3,1:3,c,ip,el) + subFrac(c,ip,el) = 0.0_pReal + crystallite_subStep(c,ip,el) = 1.0_pReal/num%subStepSizeCryst + todo(c,ip,el) = .true. + crystallite_converged(c,ip,el) = .false. ! pretend failed step of 1/subStepSizeCryst endif homogenizationRequestsCalculation enddo; enddo enddo elementLooping1 @@ -1037,71 +1037,71 @@ function crystallite_stress() if (debugCrystallite%extensive) & print'(a,i6)', '<< CRYST stress >> crystallite iteration ',NiterationCrystallite #endif - !$OMP PARALLEL DO PRIVATE(formerSubStep,p,m) - elementLooping3: do e = FEsolving_execElem(1),FEsolving_execElem(2) - do i = FEsolving_execIP(1),FEsolving_execIP(2) - do c = 1,homogenization_Nconstituents(material_homogenizationAt(e)) - p = material_phaseAt(c,e) - m = material_phaseMemberAt(c,i,e) + !$OMP PARALLEL DO PRIVATE(formerSubStep,ph,me) + elementLooping3: do el = FEsolving_execElem(1),FEsolving_execElem(2) + do ip = FEsolving_execIP(1),FEsolving_execIP(2) + do c = 1,homogenization_Nconstituents(material_homogenizationAt(el)) + ph = material_phaseAt(c,el) + me = material_phaseMemberAt(c,ip,el) !-------------------------------------------------------------------------------------------------- ! wind forward - if (crystallite_converged(c,i,e)) then - formerSubStep = crystallite_subStep(c,i,e) - subFrac(c,i,e) = subFrac(c,i,e) + crystallite_subStep(c,i,e) - crystallite_subStep(c,i,e) = min(1.0_pReal - subFrac(c,i,e), & - num%stepIncreaseCryst * crystallite_subStep(c,i,e)) + if (crystallite_converged(c,ip,el)) then + formerSubStep = crystallite_subStep(c,ip,el) + subFrac(c,ip,el) = subFrac(c,ip,el) + crystallite_subStep(c,ip,el) + crystallite_subStep(c,ip,el) = min(1.0_pReal - subFrac(c,ip,el), & + num%stepIncreaseCryst * crystallite_subStep(c,ip,el)) - todo(c,i,e) = crystallite_subStep(c,i,e) > 0.0_pReal ! still time left to integrate on? + todo(c,ip,el) = crystallite_subStep(c,ip,el) > 0.0_pReal ! still time left to integrate on? - if (todo(c,i,e)) then - crystallite_subF0 (1:3,1:3,c,i,e) = crystallite_subF(1:3,1:3,c,i,e) - subLp0(1:3,1:3,c,i,e) = crystallite_Lp (1:3,1:3,c,i,e) - subLi0(1:3,1:3,c,i,e) = constitutive_mech_Li(p)%data(1:3,1:3,m) - crystallite_subFp0(1:3,1:3,c,i,e) = constitutive_mech_Fp(p)%data(1:3,1:3,m) - crystallite_subFi0(1:3,1:3,c,i,e) = constitutive_mech_Fi(p)%data(1:3,1:3,m) - plasticState( material_phaseAt(c,e))%subState0(:,material_phaseMemberAt(c,i,e)) & - = plasticState(material_phaseAt(c,e))%state( :,material_phaseMemberAt(c,i,e)) - do s = 1, phase_Nsources(material_phaseAt(c,e)) - sourceState( material_phaseAt(c,e))%p(s)%subState0(:,material_phaseMemberAt(c,i,e)) & - = sourceState(material_phaseAt(c,e))%p(s)%state( :,material_phaseMemberAt(c,i,e)) + if (todo(c,ip,el)) then + crystallite_subF0 (1:3,1:3,c,ip,el) = crystallite_subF(1:3,1:3,c,ip,el) + subLp0(1:3,1:3,c,ip,el) = crystallite_Lp (1:3,1:3,c,ip,el) + subLi0(1:3,1:3,c,ip,el) = constitutive_mech_Li(ph)%data(1:3,1:3,me) + crystallite_subFp0(1:3,1:3,c,ip,el) = constitutive_mech_Fp(ph)%data(1:3,1:3,me) + crystallite_subFi0(1:3,1:3,c,ip,el) = constitutive_mech_Fi(ph)%data(1:3,1:3,me) + plasticState( material_phaseAt(c,el))%subState0(:,material_phaseMemberAt(c,ip,el)) & + = plasticState(material_phaseAt(c,el))%state( :,material_phaseMemberAt(c,ip,el)) + do s = 1, phase_Nsources(material_phaseAt(c,el)) + sourceState( material_phaseAt(c,el))%p(s)%subState0(:,material_phaseMemberAt(c,ip,el)) & + = sourceState(material_phaseAt(c,el))%p(s)%state( :,material_phaseMemberAt(c,ip,el)) enddo endif !-------------------------------------------------------------------------------------------------- ! cut back (reduced time and restore) else - crystallite_subStep(c,i,e) = num%subStepSizeCryst * crystallite_subStep(c,i,e) - constitutive_mech_Fp(p)%data(1:3,1:3,m) = crystallite_subFp0(1:3,1:3,c,i,e) - constitutive_mech_Fi(p)%data(1:3,1:3,m) = crystallite_subFi0(1:3,1:3,c,i,e) - crystallite_S (1:3,1:3,c,i,e) = crystallite_S0 (1:3,1:3,c,i,e) - if (crystallite_subStep(c,i,e) < 1.0_pReal) then ! actual (not initial) cutback - crystallite_Lp (1:3,1:3,c,i,e) = subLp0(1:3,1:3,c,i,e) - constitutive_mech_Li(p)%data(1:3,1:3,m) = subLi0(1:3,1:3,c,i,e) + crystallite_subStep(c,ip,el) = num%subStepSizeCryst * crystallite_subStep(c,ip,el) + constitutive_mech_Fp(ph)%data(1:3,1:3,me) = crystallite_subFp0(1:3,1:3,c,ip,el) + constitutive_mech_Fi(ph)%data(1:3,1:3,me) = crystallite_subFi0(1:3,1:3,c,ip,el) + crystallite_S (1:3,1:3,c,ip,el) = crystallite_S0 (1:3,1:3,c,ip,el) + if (crystallite_subStep(c,ip,el) < 1.0_pReal) then ! actual (not initial) cutback + crystallite_Lp (1:3,1:3,c,ip,el) = subLp0(1:3,1:3,c,ip,el) + constitutive_mech_Li(ph)%data(1:3,1:3,me) = subLi0(1:3,1:3,c,ip,el) endif - plasticState (material_phaseAt(c,e))%state( :,material_phaseMemberAt(c,i,e)) & - = plasticState(material_phaseAt(c,e))%subState0(:,material_phaseMemberAt(c,i,e)) - do s = 1, phase_Nsources(material_phaseAt(c,e)) - sourceState( material_phaseAt(c,e))%p(s)%state( :,material_phaseMemberAt(c,i,e)) & - = sourceState(material_phaseAt(c,e))%p(s)%subState0(:,material_phaseMemberAt(c,i,e)) + plasticState (material_phaseAt(c,el))%state( :,material_phaseMemberAt(c,ip,el)) & + = plasticState(material_phaseAt(c,el))%subState0(:,material_phaseMemberAt(c,ip,el)) + do s = 1, phase_Nsources(material_phaseAt(c,el)) + sourceState( material_phaseAt(c,el))%p(s)%state( :,material_phaseMemberAt(c,ip,el)) & + = sourceState(material_phaseAt(c,el))%p(s)%subState0(:,material_phaseMemberAt(c,ip,el)) enddo ! cant restore dotState here, since not yet calculated in first cutback after initialization - todo(c,i,e) = crystallite_subStep(c,i,e) > num%subStepMinCryst ! still on track or already done (beyond repair) + todo(c,ip,el) = crystallite_subStep(c,ip,el) > num%subStepMinCryst ! still on track or already done (beyond repair) endif !-------------------------------------------------------------------------------------------------- ! prepare for integration - if (todo(c,i,e)) then - crystallite_subF(1:3,1:3,c,i,e) = crystallite_subF0(1:3,1:3,c,i,e) & - + crystallite_subStep(c,i,e) *( crystallite_partitionedF (1:3,1:3,c,i,e) & - -crystallite_partitionedF0(1:3,1:3,c,i,e)) - crystallite_Fe(1:3,1:3,c,i,e) = matmul(crystallite_subF(1:3,1:3,c,i,e), & - math_inv33(matmul(constitutive_mech_Fi(p)%data(1:3,1:3,m), & - constitutive_mech_Fp(p)%data(1:3,1:3,m)))) - crystallite_subdt(c,i,e) = crystallite_subStep(c,i,e) * crystallite_dt(c,i,e) - crystallite_converged(c,i,e) = .false. - call integrateState(c,i,e) - call integrateSourceState(c,i,e) + if (todo(c,ip,el)) then + crystallite_subF(1:3,1:3,c,ip,el) = crystallite_subF0(1:3,1:3,c,ip,el) & + + crystallite_subStep(c,ip,el) *( crystallite_partitionedF (1:3,1:3,c,ip,el) & + -crystallite_partitionedF0(1:3,1:3,c,ip,el)) + crystallite_Fe(1:3,1:3,c,ip,el) = matmul(crystallite_subF(1:3,1:3,c,ip,el), & + math_inv33(matmul(constitutive_mech_Fi(ph)%data(1:3,1:3,me), & + constitutive_mech_Fp(ph)%data(1:3,1:3,me)))) + crystallite_subdt(c,ip,el) = crystallite_subStep(c,ip,el) * crystallite_dt(c,ip,el) + crystallite_converged(c,ip,el) = .false. + call integrateState(c,ip,el) + call integrateSourceState(c,ip,el) endif enddo @@ -1117,9 +1117,9 @@ function crystallite_stress() ! return whether converged or not crystallite_stress = .false. - elementLooping5: do e = FEsolving_execElem(1),FEsolving_execElem(2) - do i = FEsolving_execIP(1),FEsolving_execIP(2) - crystallite_stress(i,e) = all(crystallite_converged(:,i,e)) + elementLooping5: do el = FEsolving_execElem(1),FEsolving_execElem(2) + do ip = FEsolving_execIP(1),FEsolving_execIP(2) + crystallite_stress(ip,el) = all(crystallite_converged(:,ip,el)) enddo enddo elementLooping5 @@ -1129,27 +1129,27 @@ end function crystallite_stress !-------------------------------------------------------------------------------------------------- !> @brief Backup data for homog cutback. !-------------------------------------------------------------------------------------------------- -subroutine constitutive_initializeRestorationPoints(i,e) +subroutine constitutive_initializeRestorationPoints(ip,el) integer, intent(in) :: & - i, & !< integration point number - e !< element number + ip, & !< integration point number + el !< element number integer :: & - c, & !< constituent number + co, & !< constituent number s,ph, me - do c = 1,homogenization_Nconstituents(material_homogenizationAt(e)) - ph = material_phaseAt(c,e) - me = material_phaseMemberAt(c,i,e) - crystallite_partitionedLp0(1:3,1:3,c,i,e) = crystallite_Lp0(1:3,1:3,c,i,e) - crystallite_partitionedF0(1:3,1:3,c,i,e) = crystallite_F0(1:3,1:3,c,i,e) - crystallite_partitionedS0(1:3,1:3,c,i,e) = crystallite_S0(1:3,1:3,c,i,e) + do co = 1,homogenization_Nconstituents(material_homogenizationAt(el)) + ph = material_phaseAt(co,el) + me = material_phaseMemberAt(co,ip,el) + crystallite_partitionedLp0(1:3,1:3,co,ip,el) = crystallite_Lp0(1:3,1:3,co,ip,el) + crystallite_partitionedF0(1:3,1:3,co,ip,el) = crystallite_F0(1:3,1:3,co,ip,el) + crystallite_partitionedS0(1:3,1:3,co,ip,el) = crystallite_S0(1:3,1:3,co,ip,el) call mech_initializeRestorationPoints(ph,me) - do s = 1, phase_Nsources(material_phaseAt(c,e)) - sourceState(material_phaseAt(c,e))%p(s)%partitionedState0(:,material_phasememberAt(c,i,e)) = & - sourceState(material_phaseAt(c,e))%p(s)%state0( :,material_phasememberAt(c,i,e)) + do s = 1, phase_Nsources(material_phaseAt(co,el)) + sourceState(material_phaseAt(co,el))%p(s)%partitionedState0(:,material_phasememberAt(co,ip,el)) = & + sourceState(material_phaseAt(co,el))%p(s)%state0( :,material_phasememberAt(co,ip,el)) enddo enddo @@ -1159,23 +1159,23 @@ end subroutine constitutive_initializeRestorationPoints !-------------------------------------------------------------------------------------------------- !> @brief Wind homog inc forward. !-------------------------------------------------------------------------------------------------- -subroutine constitutive_windForward(i,e) +subroutine constitutive_windForward(ip,el) integer, intent(in) :: & - i, & !< integration point number - e !< element number + ip, & !< integration point number + el !< element number integer :: & - c, & !< constituent number + co, & !< constituent number s, ph, me - do c = 1,homogenization_Nconstituents(material_homogenizationAt(e)) - ph = material_phaseAt(c,e) - me = material_phaseMemberAt(c,i,e) - crystallite_partitionedF0 (1:3,1:3,c,i,e) = crystallite_partitionedF(1:3,1:3,c,i,e) - crystallite_partitionedLp0(1:3,1:3,c,i,e) = crystallite_Lp (1:3,1:3,c,i,e) - crystallite_partitionedS0 (1:3,1:3,c,i,e) = crystallite_S (1:3,1:3,c,i,e) + do co = 1,homogenization_Nconstituents(material_homogenizationAt(el)) + ph = material_phaseAt(co,el) + me = material_phaseMemberAt(co,ip,el) + crystallite_partitionedF0 (1:3,1:3,co,ip,el) = crystallite_partitionedF(1:3,1:3,co,ip,el) + crystallite_partitionedLp0(1:3,1:3,co,ip,el) = crystallite_Lp (1:3,1:3,co,ip,el) + crystallite_partitionedS0 (1:3,1:3,co,ip,el) = crystallite_S (1:3,1:3,co,ip,el) call constitutive_mech_windForward(ph,me) - do s = 1, phase_Nsources(material_phaseAt(c,e)) + do s = 1, phase_Nsources(material_phaseAt(co,el)) sourceState(ph)%p(s)%partitionedState0(:,me) = sourceState(ph)%p(s)%state(:,me) enddo enddo @@ -1186,30 +1186,30 @@ end subroutine constitutive_windForward !-------------------------------------------------------------------------------------------------- !> @brief Restore data after homog cutback. !-------------------------------------------------------------------------------------------------- -subroutine crystallite_restore(i,e,includeL) +subroutine crystallite_restore(ip,el,includeL) integer, intent(in) :: & - i, & !< integration point number - e !< element number + ip, & !< integration point number + el !< element number logical, intent(in) :: & includeL !< protect agains fake cutback integer :: & - c, p, m !< constituent number + co, p, m !< constituent number - do c = 1,homogenization_Nconstituents(material_homogenizationAt(e)) - p = material_phaseAt(c,e) - m = material_phaseMemberAt(c,i,e) + do co = 1,homogenization_Nconstituents(material_homogenizationAt(el)) + p = material_phaseAt(co,el) + m = material_phaseMemberAt(co,ip,el) if (includeL) then - crystallite_Lp(1:3,1:3,c,i,e) = crystallite_partitionedLp0(1:3,1:3,c,i,e) + crystallite_Lp(1:3,1:3,co,ip,el) = crystallite_partitionedLp0(1:3,1:3,co,ip,el) constitutive_mech_Li(p)%data(1:3,1:3,m) = constitutive_mech_partionedLi0(p)%data(1:3,1:3,m) endif ! maybe protecting everything from overwriting makes more sense constitutive_mech_Fp(p)%data(1:3,1:3,m) = constitutive_mech_partionedFp0(p)%data(1:3,1:3,m) constitutive_mech_Fi(p)%data(1:3,1:3,m) = constitutive_mech_partionedFi0(p)%data(1:3,1:3,m) - crystallite_S (1:3,1:3,c,i,e) = crystallite_partitionedS0 (1:3,1:3,c,i,e) + crystallite_S (1:3,1:3,co,ip,el) = crystallite_partitionedS0 (1:3,1:3,co,ip,el) - plasticState (material_phaseAt(c,e))%state( :,material_phasememberAt(c,i,e)) = & - plasticState (material_phaseAt(c,e))%partitionedState0(:,material_phasememberAt(c,i,e)) + plasticState (material_phaseAt(co,el))%state( :,material_phasememberAt(co,ip,el)) = & + plasticState (material_phaseAt(co,el))%partitionedState0(:,material_phasememberAt(co,ip,el)) enddo end subroutine crystallite_restore @@ -1218,13 +1218,13 @@ end subroutine crystallite_restore !-------------------------------------------------------------------------------------------------- !> @brief Calculate tangent (dPdF). !-------------------------------------------------------------------------------------------------- -function crystallite_stressTangent(c,i,e) result(dPdF) +function crystallite_stressTangent(co,ip,el) result(dPdF) real(pReal), dimension(3,3,3,3) :: dPdF integer, intent(in) :: & - c, & !< counter in constituent loop - i, & !< counter in integration point loop - e !< counter in element loop + co, & !< counter in constituent loop + ip, & !< counter in integration point loop + el !< counter in element loop integer :: & o, & p, pp, m @@ -1247,21 +1247,21 @@ function crystallite_stressTangent(c,i,e) result(dPdF) real(pReal), dimension(9,9):: temp_99 logical :: error - pp = material_phaseAt(c,e) - m = material_phaseMemberAt(c,i,e) + pp = material_phaseAt(co,el) + m = material_phaseMemberAt(co,ip,el) call constitutive_hooke_SandItsTangents(devNull,dSdFe,dSdFi, & - crystallite_Fe(1:3,1:3,c,i,e), & - constitutive_mech_Fi(pp)%data(1:3,1:3,m),c,i,e) + crystallite_Fe(1:3,1:3,co,ip,el), & + constitutive_mech_Fi(pp)%data(1:3,1:3,m),co,ip,el) call constitutive_LiAndItsTangents(devNull,dLidS,dLidFi, & - crystallite_S (1:3,1:3,c,i,e), & + crystallite_S (1:3,1:3,co,ip,el), & constitutive_mech_Fi(pp)%data(1:3,1:3,m), & - c,i,e) + co,ip,el) invFp = math_inv33(constitutive_mech_Fp(pp)%data(1:3,1:3,m)) invFi = math_inv33(constitutive_mech_Fi(pp)%data(1:3,1:3,m)) - invSubFp0 = math_inv33(crystallite_subFp0(1:3,1:3,c,i,e)) - invSubFi0 = math_inv33(crystallite_subFi0(1:3,1:3,c,i,e)) + invSubFp0 = math_inv33(crystallite_subFp0(1:3,1:3,co,ip,el)) + invSubFi0 = math_inv33(crystallite_subFi0(1:3,1:3,co,ip,el)) if (sum(abs(dLidS)) < tol_math_check) then dFidS = 0.0_pReal @@ -1269,15 +1269,15 @@ function crystallite_stressTangent(c,i,e) result(dPdF) lhs_3333 = 0.0_pReal; rhs_3333 = 0.0_pReal do o=1,3; do p=1,3 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(co,ip,el)*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) & + invFi*invFi(p,o) 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(co,ip,el)*matmul(invSubFi0,dLidS(1:3,1:3,o,p)) enddo; enddo call math_invert(temp_99,error,math_3333to99(lhs_3333)) if (error) then - call IO_warning(warning_ID=600,el=e,ip=i,g=c, & + call IO_warning(warning_ID=600,el=el,ip=ip,g=co, & ext_msg='inversion error in analytic tangent calculation') dFidS = 0.0_pReal else @@ -1287,27 +1287,27 @@ function crystallite_stressTangent(c,i,e) result(dPdF) endif call constitutive_plastic_LpAndItsTangents(devNull,dLpdS,dLpdFi, & - crystallite_S (1:3,1:3,c,i,e), & - constitutive_mech_Fi(pp)%data(1:3,1:3,m),c,i,e) + crystallite_S (1:3,1:3,co,ip,el), & + constitutive_mech_Fi(pp)%data(1:3,1:3,m),co,ip,el) dLpdS = math_mul3333xx3333(dLpdFi,dFidS) + dLpdS !-------------------------------------------------------------------------------------------------- ! calculate dSdF temp_33_1 = transpose(matmul(invFp,invFi)) - temp_33_2 = matmul(crystallite_subF(1:3,1:3,c,i,e),invSubFp0) - temp_33_3 = matmul(matmul(crystallite_subF(1:3,1:3,c,i,e),invFp), invSubFi0) + temp_33_2 = matmul(crystallite_subF(1:3,1:3,co,ip,el),invSubFp0) + temp_33_3 = matmul(matmul(crystallite_subF(1:3,1:3,co,ip,el),invFp), invSubFi0) 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) temp_3333(1:3,1:3,p,o) = matmul(matmul(temp_33_2,dLpdS(1:3,1:3,p,o)), invFi) & + matmul(temp_33_3,dLidS(1:3,1:3,p,o)) enddo; enddo - lhs_3333 = crystallite_subdt(c,i,e)*math_mul3333xx3333(dSdFe,temp_3333) & + lhs_3333 = crystallite_subdt(co,ip,el)*math_mul3333xx3333(dSdFe,temp_3333) & + math_mul3333xx3333(dSdFi,dFidS) call math_invert(temp_99,error,math_eye(9)+math_3333to99(lhs_3333)) if (error) then - call IO_warning(warning_ID=600,el=e,ip=i,g=c, & + call IO_warning(warning_ID=600,el=el,ip=ip,g=co, & ext_msg='inversion error in analytic tangent calculation') dSdF = rhs_3333 else @@ -1318,16 +1318,16 @@ function crystallite_stressTangent(c,i,e) result(dPdF) ! calculate dFpinvdF temp_3333 = math_mul3333xx3333(dLpdS,dSdF) 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(co,ip,el) & * matmul(invSubFp0, matmul(temp_3333(1:3,1:3,p,o),invFi)) enddo; enddo !-------------------------------------------------------------------------------------------------- ! assemble dPdF - temp_33_1 = matmul(crystallite_S(1:3,1:3,c,i,e),transpose(invFp)) + temp_33_1 = matmul(crystallite_S(1:3,1:3,co,ip,el),transpose(invFp)) temp_33_2 = matmul(invFp,temp_33_1) - 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_3 = matmul(crystallite_subF(1:3,1:3,co,ip,el),invFp) + temp_33_4 = matmul(temp_33_3,crystallite_S(1:3,1:3,co,ip,el)) dPdF = 0.0_pReal do p=1,3 @@ -1335,7 +1335,7 @@ function crystallite_stressTangent(c,i,e) result(dPdF) enddo do o=1,3; do p=1,3 dPdF(1:3,1:3,p,o) = dPdF(1:3,1:3,p,o) & - + matmul(matmul(crystallite_subF(1:3,1:3,c,i,e), & + + matmul(matmul(crystallite_subF(1:3,1:3,co,ip,el), & dFpinvdF(1:3,1:3,p,o)),temp_33_1) & + matmul(matmul(temp_33_3,dSdF(1:3,1:3,p,o)), & transpose(invFp)) & @@ -1351,25 +1351,26 @@ end function crystallite_stressTangent subroutine crystallite_orientations integer & - c, & !< counter in integration point component loop - i, & !< counter in integration point loop - e !< counter in element loop + co, & !< counter in integration point component loop + ip, & !< counter in integration point loop + el !< counter in element loop + !$OMP PARALLEL DO - do e = FEsolving_execElem(1),FEsolving_execElem(2) - do i = FEsolving_execIP(1),FEsolving_execIP(2) - do c = 1,homogenization_Nconstituents(material_homogenizationAt(e)) - call crystallite_orientation(c,i,e)%fromMatrix(transpose(math_rotationalPart(crystallite_Fe(1:3,1:3,c,i,e)))) + do el = FEsolving_execElem(1),FEsolving_execElem(2) + do ip = FEsolving_execIP(1),FEsolving_execIP(2) + do co = 1,homogenization_Nconstituents(material_homogenizationAt(el)) + call crystallite_orientation(co,ip,el)%fromMatrix(transpose(math_rotationalPart(crystallite_Fe(1:3,1:3,co,ip,el)))) enddo; enddo; enddo !$OMP END PARALLEL DO nonlocalPresent: if (any(plasticState%nonlocal)) then !$OMP PARALLEL DO - do e = FEsolving_execElem(1),FEsolving_execElem(2) - if (plasticState(material_phaseAt(1,e))%nonlocal) then - do i = FEsolving_execIP(1),FEsolving_execIP(2) + do el = FEsolving_execElem(1),FEsolving_execElem(2) + if (plasticState(material_phaseAt(1,el))%nonlocal) then + do ip = FEsolving_execIP(1),FEsolving_execIP(2) call plastic_nonlocal_updateCompatibility(crystallite_orientation, & - phase_plasticityInstance(material_phaseAt(1,e)),i,e) + phase_plasticityInstance(material_phaseAt(1,el)),ip,el) enddo endif enddo @@ -1403,15 +1404,15 @@ end function crystallite_push33ToRef !> @brief integrate stress, state with adaptive 1st order explicit Euler method !> using Fixed Point Iteration to adapt the stepsize !-------------------------------------------------------------------------------------------------- -subroutine integrateSourceState(g,i,e) +subroutine integrateSourceState(co,ip,el) integer, intent(in) :: & - e, & !< element index in element loop - i, & !< integration point index in ip loop - g !< grain index in grain loop + el, & !< element index in element loop + ip, & !< integration point index in ip loop + co !< grain index in grain loop integer :: & NiterationState, & !< number of iterations in state loop - p, & + ph, & c, & s, & size_pl @@ -1425,51 +1426,51 @@ subroutine integrateSourceState(g,i,e) logical :: & broken - p = material_phaseAt(g,e) - c = material_phaseMemberAt(g,i,e) + ph = material_phaseAt(co,el) + c = material_phaseMemberAt(co,ip,el) - broken = constitutive_thermal_collectDotState(p,c) - broken = broken .or. constitutive_damage_collectDotState(crystallite_S(1:3,1:3,g,i,e), g,i,e,p,c) + broken = constitutive_thermal_collectDotState(ph,c) + broken = broken .or. constitutive_damage_collectDotState(crystallite_S(1:3,1:3,co,ip,el), co,ip,el,ph,c) if(broken) return - do s = 1, phase_Nsources(p) - size_so(s) = sourceState(p)%p(s)%sizeDotState - sourceState(p)%p(s)%state(1:size_so(s),c) = sourceState(p)%p(s)%subState0(1:size_so(s),c) & - + sourceState(p)%p(s)%dotState (1:size_so(s),c) & - * crystallite_subdt(g,i,e) + do s = 1, phase_Nsources(ph) + size_so(s) = sourceState(ph)%p(s)%sizeDotState + sourceState(ph)%p(s)%state(1:size_so(s),c) = sourceState(ph)%p(s)%subState0(1:size_so(s),c) & + + sourceState(ph)%p(s)%dotState (1:size_so(s),c) & + * crystallite_subdt(co,ip,el) source_dotState(1:size_so(s),2,s) = 0.0_pReal enddo iteration: do NiterationState = 1, num%nState - do s = 1, phase_Nsources(p) + do s = 1, phase_Nsources(ph) if(nIterationState > 1) source_dotState(1:size_so(s),2,s) = source_dotState(1:size_so(s),1,s) - source_dotState(1:size_so(s),1,s) = sourceState(p)%p(s)%dotState(:,c) + source_dotState(1:size_so(s),1,s) = sourceState(ph)%p(s)%dotState(:,c) enddo - broken = constitutive_thermal_collectDotState(p,c) - broken = broken .or. constitutive_damage_collectDotState(crystallite_S(1:3,1:3,g,i,e), g,i,e,p,c) + broken = constitutive_thermal_collectDotState(ph,c) + broken = broken .or. constitutive_damage_collectDotState(crystallite_S(1:3,1:3,co,ip,el), co,ip,el,ph,c) if(broken) exit iteration - do s = 1, phase_Nsources(p) - zeta = damper(sourceState(p)%p(s)%dotState(:,c), & + do s = 1, phase_Nsources(ph) + zeta = damper(sourceState(ph)%p(s)%dotState(:,c), & source_dotState(1:size_so(s),1,s),& source_dotState(1:size_so(s),2,s)) - sourceState(p)%p(s)%dotState(:,c) = sourceState(p)%p(s)%dotState(:,c) * zeta & + sourceState(ph)%p(s)%dotState(:,c) = sourceState(ph)%p(s)%dotState(:,c) * zeta & + source_dotState(1:size_so(s),1,s)* (1.0_pReal - zeta) - r(1:size_so(s)) = sourceState(p)%p(s)%state (1:size_so(s),c) & - - sourceState(p)%p(s)%subState0(1:size_so(s),c) & - - sourceState(p)%p(s)%dotState (1:size_so(s),c) * crystallite_subdt(g,i,e) - sourceState(p)%p(s)%state(1:size_so(s),c) = sourceState(p)%p(s)%state(1:size_so(s),c) & + r(1:size_so(s)) = sourceState(ph)%p(s)%state (1:size_so(s),c) & + - sourceState(ph)%p(s)%subState0(1:size_so(s),c) & + - sourceState(ph)%p(s)%dotState (1:size_so(s),c) * crystallite_subdt(co,ip,el) + sourceState(ph)%p(s)%state(1:size_so(s),c) = sourceState(ph)%p(s)%state(1:size_so(s),c) & - r(1:size_so(s)) - crystallite_converged(g,i,e) = & - crystallite_converged(g,i,e) .and. converged(r(1:size_so(s)), & - sourceState(p)%p(s)%state(1:size_so(s),c), & - sourceState(p)%p(s)%atol(1:size_so(s))) + crystallite_converged(co,ip,el) = & + crystallite_converged(co,ip,el) .and. converged(r(1:size_so(s)), & + sourceState(ph)%p(s)%state(1:size_so(s),c), & + sourceState(ph)%p(s)%atol(1:size_so(s))) enddo - if(crystallite_converged(g,i,e)) then - broken = constitutive_damage_deltaState(crystallite_Fe(1:3,1:3,g,i,e),g,i,e,p,c) + if(crystallite_converged(co,ip,el)) then + broken = constitutive_damage_deltaState(crystallite_Fe(1:3,1:3,co,ip,el),co,ip,el,ph,c) exit iteration endif diff --git a/src/constitutive_mech.f90 b/src/constitutive_mech.f90 index 124b4d608..0be59611f 100644 --- a/src/constitutive_mech.f90 +++ b/src/constitutive_mech.f90 @@ -284,7 +284,7 @@ contains module subroutine mech_init integer :: & - p, & + ph, & stiffDegradationCtr class(tNode), pointer :: & num_crystallite, & @@ -304,35 +304,35 @@ module subroutine mech_init allocate(phase_NstiffnessDegradations(phases%length),source=0) allocate(output_constituent(phases%length)) - do p = 1, phases%length - phase => phases%get(p) + do ph = 1, phases%length + phase => phases%get(ph) mech => phase%get('mechanics') #if defined(__GFORTRAN__) - output_constituent(p)%label = output_asStrings(mech) + output_constituent(ph)%label = output_asStrings(mech) #else - output_constituent(p)%label = mech%get_asStrings('output',defaultVal=emptyStringArray) + output_constituent(ph)%label = mech%get_asStrings('output',defaultVal=emptyStringArray) #endif elastic => mech%get('elasticity') if(elastic%get_asString('type') == 'hooke') then - phase_elasticity(p) = ELASTICITY_HOOKE_ID + phase_elasticity(ph) = ELASTICITY_HOOKE_ID else call IO_error(200,ext_msg=elastic%get_asString('type')) endif stiffDegradation => mech%get('stiffness_degradation',defaultVal=emptyList) ! check for stiffness degradation mechanisms - phase_NstiffnessDegradations(p) = stiffDegradation%length + phase_NstiffnessDegradations(ph) = stiffDegradation%length enddo allocate(phase_stiffnessDegradation(maxval(phase_NstiffnessDegradations),phases%length), & source=STIFFNESS_DEGRADATION_undefined_ID) if(maxVal(phase_NstiffnessDegradations)/=0) then - do p = 1, phases%length - phase => phases%get(p) + do ph = 1, phases%length + phase => phases%get(ph) mech => phase%get('mechanics') stiffDegradation => mech%get('stiffness_degradation',defaultVal=emptyList) do stiffDegradationCtr = 1, stiffDegradation%length if(stiffDegradation%get_asString(stiffDegradationCtr) == 'damage') & - phase_stiffnessDegradation(stiffDegradationCtr,p) = STIFFNESS_DEGRADATION_damage_ID + phase_stiffnessDegradation(stiffDegradationCtr,ph) = STIFFNESS_DEGRADATION_damage_ID enddo enddo endif @@ -352,9 +352,9 @@ module subroutine mech_init where(plastic_dislotungsten_init()) phase_plasticity = PLASTICITY_DISLOTUNGSTEN_ID where(plastic_nonlocal_init()) phase_plasticity = PLASTICITY_NONLOCAL_ID - do p = 1, phases%length - phase_elasticityInstance(p) = count(phase_elasticity(1:p) == phase_elasticity(p)) - phase_plasticityInstance(p) = count(phase_plasticity(1:p) == phase_plasticity(p)) + do ph = 1, phases%length + phase_elasticityInstance(ph) = count(phase_elasticity(1:ph) == phase_elasticity(ph)) + phase_plasticityInstance(ph) = count(phase_plasticity(1:ph) == phase_plasticity(ph)) enddo num_crystallite => config_numerics%get('crystallite',defaultVal=emptyDict) @@ -397,15 +397,15 @@ function plastic_active(plastic_label) result(active_plastic) phase, & mech, & pl - integer :: p + integer :: ph phases => config_material%get('phase') allocate(active_plastic(phases%length), source = .false. ) - do p = 1, phases%length - phase => phases%get(p) + do ph = 1, phases%length + phase => phases%get(ph) mech => phase%get('mechanics') pl => mech%get('plasticity') - if(pl%get_asString('type') == plastic_label) active_plastic(p) = .true. + if(pl%get_asString('type') == plastic_label) active_plastic(ph) = .true. enddo end function plastic_active @@ -568,13 +568,13 @@ end subroutine constitutive_plastic_LpAndItsTangents !-------------------------------------------------------------------------------------------------- !> @brief contains the constitutive equation for calculating the rate of change of microstructure !-------------------------------------------------------------------------------------------------- -function mech_collectDotState(subdt, co, ip, el,phase,of) result(broken) +function mech_collectDotState(subdt, co, ip, el,ph,of) result(broken) integer, intent(in) :: & co, & !< component-ID of integration point ip, & !< integration point el, & !< element - phase, & + ph, & of real(pReal), intent(in) :: & subdt !< timestep @@ -588,12 +588,12 @@ function mech_collectDotState(subdt, co, ip, el,phase,of) result(broken) logical :: broken ho = material_homogenizationAt(el) tme = material_homogenizationMemberAt(ip,el) - instance = phase_plasticityInstance(phase) + instance = phase_plasticityInstance(ph) - Mp = matmul(matmul(transpose(constitutive_mech_Fi(phase)%data(1:3,1:3,of)),& - constitutive_mech_Fi(phase)%data(1:3,1:3,of)),crystallite_S(1:3,1:3,co,ip,el)) + Mp = matmul(matmul(transpose(constitutive_mech_Fi(ph)%data(1:3,1:3,of)),& + constitutive_mech_Fi(ph)%data(1:3,1:3,of)),crystallite_S(1:3,1:3,co,ip,el)) - plasticityType: select case (phase_plasticity(phase)) + plasticityType: select case (phase_plasticity(ph)) case (PLASTICITY_ISOTROPIC_ID) plasticityType call plastic_isotropic_dotState(Mp,instance,of) @@ -614,7 +614,7 @@ function mech_collectDotState(subdt, co, ip, el,phase,of) result(broken) call plastic_nonlocal_dotState(Mp,crystallite_partitionedF0,temperature(ho)%p(tme),subdt, & instance,of,ip,el) end select plasticityType - broken = any(IEEE_is_NaN(plasticState(phase)%dotState(:,of))) + broken = any(IEEE_is_NaN(plasticState(ph)%dotState(:,of))) end function mech_collectDotState @@ -624,13 +624,13 @@ end function mech_collectDotState !> @brief for constitutive models having an instantaneous change of state !> will return false if delta state is not needed/supported by the constitutive model !-------------------------------------------------------------------------------------------------- -function constitutive_deltaState(S, Fi, co, ip, el, phase, of) result(broken) +function constitutive_deltaState(S, Fi, co, ip, el, ph, of) result(broken) integer, intent(in) :: & co, & !< component-ID of integration point ip, & !< integration point el, & !< element - phase, & + ph, & of real(pReal), intent(in), dimension(3,3) :: & S, & !< 2nd Piola Kirchhoff stress @@ -645,17 +645,17 @@ function constitutive_deltaState(S, Fi, co, ip, el, phase, of) result(broken) broken Mp = matmul(matmul(transpose(Fi),Fi),S) - instance = phase_plasticityInstance(phase) + instance = phase_plasticityInstance(ph) - plasticityType: select case (phase_plasticity(phase)) + plasticityType: select case (phase_plasticity(ph)) case (PLASTICITY_KINEHARDENING_ID) plasticityType call plastic_kinehardening_deltaState(Mp,instance,of) - broken = any(IEEE_is_NaN(plasticState(phase)%deltaState(:,of))) + broken = any(IEEE_is_NaN(plasticState(ph)%deltaState(:,of))) case (PLASTICITY_NONLOCAL_ID) plasticityType call plastic_nonlocal_deltaState(Mp,instance,of,ip,el) - broken = any(IEEE_is_NaN(plasticState(phase)%deltaState(:,of))) + broken = any(IEEE_is_NaN(plasticState(ph)%deltaState(:,of))) case default broken = .false. @@ -663,13 +663,13 @@ function constitutive_deltaState(S, Fi, co, ip, el, phase, of) result(broken) end select plasticityType if(.not. broken) then - select case(phase_plasticity(phase)) + select case(phase_plasticity(ph)) case (PLASTICITY_NONLOCAL_ID,PLASTICITY_KINEHARDENING_ID) - myOffset = plasticState(phase)%offsetDeltaState - mySize = plasticState(phase)%sizeDeltaState - plasticState(phase)%state(myOffset + 1:myOffset + mySize,of) = & - plasticState(phase)%state(myOffset + 1:myOffset + mySize,of) + plasticState(phase)%deltaState(1:mySize,of) + myOffset = plasticState(ph)%offsetDeltaState + mySize = plasticState(ph)%sizeDeltaState + plasticState(ph)%state(myOffset + 1:myOffset + mySize,of) = & + plasticState(ph)%state(myOffset + 1:myOffset + mySize,of) + plasticState(ph)%deltaState(1:mySize,of) end select endif @@ -944,16 +944,16 @@ end function integrateStress !> @brief integrate stress, state with adaptive 1st order explicit Euler method !> using Fixed Point Iteration to adapt the stepsize !-------------------------------------------------------------------------------------------------- -module subroutine integrateStateFPI(g,i,e) +module subroutine integrateStateFPI(co,ip,el) integer, intent(in) :: & - e, & !< element index in element loop - i, & !< integration point index in ip loop - g !< grain index in grain loop + el, & !< element index in element loop + ip, & !< integration point index in ip loop + co !< grain index in grain loop integer :: & NiterationState, & !< number of iterations in state loop - p, & - c, & + ph, & + me, & s, & size_pl integer, dimension(maxval(phase_Nsources)) :: & @@ -968,45 +968,45 @@ module subroutine integrateStateFPI(g,i,e) logical :: & broken - p = material_phaseAt(g,e) - c = material_phaseMemberAt(g,i,e) + ph = material_phaseAt(co,el) + me = material_phaseMemberAt(co,ip,el) - broken = mech_collectDotState(crystallite_subdt(g,i,e), g,i,e,p,c) + broken = mech_collectDotState(crystallite_subdt(co,ip,el), co,ip,el,ph,me) if(broken) return - size_pl = plasticState(p)%sizeDotState - plasticState(p)%state(1:size_pl,c) = plasticState(p)%subState0(1:size_pl,c) & - + plasticState(p)%dotState (1:size_pl,c) & - * crystallite_subdt(g,i,e) + size_pl = plasticState(ph)%sizeDotState + plasticState(ph)%state(1:size_pl,me) = plasticState(ph)%subState0(1:size_pl,me) & + + plasticState(ph)%dotState (1:size_pl,me) & + * crystallite_subdt(co,ip,el) plastic_dotState(1:size_pl,2) = 0.0_pReal iteration: do NiterationState = 1, num%nState if(nIterationState > 1) plastic_dotState(1:size_pl,2) = plastic_dotState(1:size_pl,1) - plastic_dotState(1:size_pl,1) = plasticState(p)%dotState(:,c) + plastic_dotState(1:size_pl,1) = plasticState(ph)%dotState(:,me) - broken = integrateStress(g,i,e) + broken = integrateStress(co,ip,el) if(broken) exit iteration - broken = mech_collectDotState(crystallite_subdt(g,i,e), g,i,e,p,c) + broken = mech_collectDotState(crystallite_subdt(co,ip,el), co,ip,el,ph,me) if(broken) exit iteration - zeta = damper(plasticState(p)%dotState(:,c),plastic_dotState(1:size_pl,1),& + zeta = damper(plasticState(ph)%dotState(:,me),plastic_dotState(1:size_pl,1),& plastic_dotState(1:size_pl,2)) - plasticState(p)%dotState(:,c) = plasticState(p)%dotState(:,c) * zeta & + plasticState(ph)%dotState(:,me) = plasticState(ph)%dotState(:,me) * zeta & + plastic_dotState(1:size_pl,1) * (1.0_pReal - zeta) - r(1:size_pl) = plasticState(p)%state (1:size_pl,c) & - - plasticState(p)%subState0(1:size_pl,c) & - - plasticState(p)%dotState (1:size_pl,c) * crystallite_subdt(g,i,e) - plasticState(p)%state(1:size_pl,c) = plasticState(p)%state(1:size_pl,c) & + r(1:size_pl) = plasticState(ph)%state (1:size_pl,me) & + - plasticState(ph)%subState0(1:size_pl,me) & + - plasticState(ph)%dotState (1:size_pl,me) * crystallite_subdt(co,ip,el) + plasticState(ph)%state(1:size_pl,me) = plasticState(ph)%state(1:size_pl,me) & - r(1:size_pl) - crystallite_converged(g,i,e) = converged(r(1:size_pl), & - plasticState(p)%state(1:size_pl,c), & - plasticState(p)%atol(1:size_pl)) + crystallite_converged(co,ip,el) = converged(r(1:size_pl), & + plasticState(ph)%state(1:size_pl,me), & + plasticState(ph)%atol(1:size_pl)) - if(crystallite_converged(g,i,e)) then - broken = constitutive_deltaState(crystallite_S(1:3,1:3,g,i,e), & - constitutive_mech_Fi(p)%data(1:3,1:3,c),g,i,e,p,c) + if(crystallite_converged(co,ip,el)) then + broken = constitutive_deltaState(crystallite_S(1:3,1:3,co,ip,el), & + constitutive_mech_Fi(ph)%data(1:3,1:3,me),co,ip,el,ph,me) exit iteration endif @@ -1041,36 +1041,36 @@ end subroutine integrateStateFPI !-------------------------------------------------------------------------------------------------- !> @brief integrate state with 1st order explicit Euler method !-------------------------------------------------------------------------------------------------- -subroutine integrateStateEuler(g,i,e) +subroutine integrateStateEuler(co,ip,el) integer, intent(in) :: & - e, & !< element index in element loop - i, & !< integration point index in ip loop - g !< grain index in grain loop + el, & !< element index in element loop + ip, & !< integration point index in ip loop + co !< grain index in grain loop integer :: & - p, & - c, & + ph, & + me, & sizeDotState logical :: & broken - p = material_phaseAt(g,e) - c = material_phaseMemberAt(g,i,e) + ph = material_phaseAt(co,el) + me = material_phaseMemberAt(co,ip,el) - broken = mech_collectDotState(crystallite_subdt(g,i,e), g,i,e,p,c) + broken = mech_collectDotState(crystallite_subdt(co,ip,el), co,ip,el,ph,me) if(broken) return - sizeDotState = plasticState(p)%sizeDotState - plasticState(p)%state(1:sizeDotState,c) = plasticState(p)%subState0(1:sizeDotState,c) & - + plasticState(p)%dotState (1:sizeDotState,c) & - * crystallite_subdt(g,i,e) + sizeDotState = plasticState(ph)%sizeDotState + plasticState(ph)%state(1:sizeDotState,me) = plasticState(ph)%subState0(1:sizeDotState,me) & + + plasticState(ph)%dotState (1:sizeDotState,me) & + * crystallite_subdt(co,ip,el) - broken = constitutive_deltaState(crystallite_S(1:3,1:3,g,i,e), & - constitutive_mech_Fi(p)%data(1:3,1:3,c),g,i,e,p,c) + broken = constitutive_deltaState(crystallite_S(1:3,1:3,co,ip,el), & + constitutive_mech_Fi(ph)%data(1:3,1:3,me),co,ip,el,ph,me) if(broken) return - broken = integrateStress(g,i,e) - crystallite_converged(g,i,e) = .not. broken + broken = integrateStress(co,ip,el) + crystallite_converged(co,ip,el) = .not. broken end subroutine integrateStateEuler @@ -1078,15 +1078,15 @@ end subroutine integrateStateEuler !-------------------------------------------------------------------------------------------------- !> @brief integrate stress, state with 1st order Euler method with adaptive step size !-------------------------------------------------------------------------------------------------- -subroutine integrateStateAdaptiveEuler(g,i,e) +subroutine integrateStateAdaptiveEuler(co,ip,el) integer, intent(in) :: & - e, & !< element index in element loop - i, & !< integration point index in ip loop - g !< grain index in grain loop + el, & !< element index in element loop + ip, & !< integration point index in ip loop + co !< grain index in grain loop integer :: & - p, & - c, & + ph, & + me, & sizeDotState logical :: & broken @@ -1094,34 +1094,34 @@ subroutine integrateStateAdaptiveEuler(g,i,e) real(pReal), dimension(constitutive_plasticity_maxSizeDotState) :: residuum_plastic - p = material_phaseAt(g,e) - c = material_phaseMemberAt(g,i,e) + ph = material_phaseAt(co,el) + me = material_phaseMemberAt(co,ip,el) - broken = mech_collectDotState(crystallite_subdt(g,i,e), g,i,e,p,c) + broken = mech_collectDotState(crystallite_subdt(co,ip,el), co,ip,el,ph,me) if(broken) return - sizeDotState = plasticState(p)%sizeDotState + sizeDotState = plasticState(ph)%sizeDotState - residuum_plastic(1:sizeDotState) = - plasticState(p)%dotstate(1:sizeDotState,c) * 0.5_pReal * crystallite_subdt(g,i,e) - plasticState(p)%state(1:sizeDotState,c) = plasticState(p)%subState0(1:sizeDotState,c) & - + plasticState(p)%dotstate(1:sizeDotState,c) * crystallite_subdt(g,i,e) + residuum_plastic(1:sizeDotState) = - plasticState(ph)%dotstate(1:sizeDotState,me) * 0.5_pReal * crystallite_subdt(co,ip,el) + plasticState(ph)%state(1:sizeDotState,me) = plasticState(ph)%subState0(1:sizeDotState,me) & + + plasticState(ph)%dotstate(1:sizeDotState,me) * crystallite_subdt(co,ip,el) - broken = constitutive_deltaState(crystallite_S(1:3,1:3,g,i,e), & - constitutive_mech_Fi(p)%data(1:3,1:3,c),g,i,e,p,c) + broken = constitutive_deltaState(crystallite_S(1:3,1:3,co,ip,el), & + constitutive_mech_Fi(ph)%data(1:3,1:3,me),co,ip,el,ph,me) if(broken) return - broken = integrateStress(g,i,e) + broken = integrateStress(co,ip,el) if(broken) return - broken = mech_collectDotState(crystallite_subdt(g,i,e), g,i,e,p,c) + broken = mech_collectDotState(crystallite_subdt(co,ip,el), co,ip,el,ph,me) if(broken) return - sizeDotState = plasticState(p)%sizeDotState - crystallite_converged(g,i,e) = converged(residuum_plastic(1:sizeDotState) & - + 0.5_pReal * plasticState(p)%dotState(:,c) * crystallite_subdt(g,i,e), & - plasticState(p)%state(1:sizeDotState,c), & - plasticState(p)%atol(1:sizeDotState)) + sizeDotState = plasticState(ph)%sizeDotState + crystallite_converged(co,ip,el) = converged(residuum_plastic(1:sizeDotState) & + + 0.5_pReal * plasticState(ph)%dotState(:,me) * crystallite_subdt(co,ip,el), & + plasticState(ph)%state(1:sizeDotState,me), & + plasticState(ph)%atol(1:sizeDotState)) end subroutine integrateStateAdaptiveEuler @@ -1129,9 +1129,9 @@ end subroutine integrateStateAdaptiveEuler !--------------------------------------------------------------------------------------------------- !> @brief Integrate state (including stress integration) with the classic Runge Kutta method !--------------------------------------------------------------------------------------------------- -subroutine integrateStateRK4(g,i,e) +subroutine integrateStateRK4(co,ip,el) - integer, intent(in) :: g,i,e + integer, intent(in) :: co,ip,el real(pReal), dimension(3,3), parameter :: & A = reshape([& @@ -1144,7 +1144,7 @@ subroutine integrateStateRK4(g,i,e) real(pReal), dimension(4), parameter :: & B = [1.0_pReal/6.0_pReal, 1.0_pReal/3.0_pReal, 1.0_pReal/3.0_pReal, 1.0_pReal/6.0_pReal] - call integrateStateRK(g,i,e,A,B,C) + call integrateStateRK(co,ip,el,A,B,C) end subroutine integrateStateRK4 @@ -1152,9 +1152,9 @@ end subroutine integrateStateRK4 !--------------------------------------------------------------------------------------------------- !> @brief Integrate state (including stress integration) with the Cash-Carp method !--------------------------------------------------------------------------------------------------- -subroutine integrateStateRKCK45(g,i,e) +subroutine integrateStateRKCK45(co,ip,el) - integer, intent(in) :: g,i,e + integer, intent(in) :: co,ip,el real(pReal), dimension(5,5), parameter :: & A = reshape([& @@ -1174,7 +1174,7 @@ subroutine integrateStateRKCK45(g,i,e) [2825.0_pReal/27648.0_pReal, .0_pReal, 18575.0_pReal/48384.0_pReal,& 13525.0_pReal/55296.0_pReal, 277.0_pReal/14336.0_pReal, 1._pReal/4._pReal] - call integrateStateRK(g,i,e,A,B,C,DB) + call integrateStateRK(co,ip,el,A,B,C,DB) end subroutine integrateStateRKCK45 @@ -1183,7 +1183,7 @@ end subroutine integrateStateRKCK45 !> @brief Integrate state (including stress integration) with an explicit Runge-Kutta method or an !! embedded explicit Runge-Kutta method !-------------------------------------------------------------------------------------------------- -subroutine integrateStateRK(g,i,e,A,B,CC,DB) +subroutine integrateStateRK(co,ip,el,A,B,CC,DB) real(pReal), dimension(:,:), intent(in) :: A @@ -1191,71 +1191,71 @@ subroutine integrateStateRK(g,i,e,A,B,CC,DB) real(pReal), dimension(:), intent(in), optional :: DB integer, intent(in) :: & - e, & !< element index in element loop - i, & !< integration point index in ip loop - g !< grain index in grain loop + el, & !< element index in element loop + ip, & !< integration point index in ip loop + co !< grain index in grain loop integer :: & stage, & ! stage index in integration stage loop n, & - p, & - c, & + ph, & + me, & sizeDotState logical :: & broken real(pReal), dimension(constitutive_plasticity_maxSizeDotState,size(B)) :: plastic_RKdotState - p = material_phaseAt(g,e) - c = material_phaseMemberAt(g,i,e) + ph = material_phaseAt(co,el) + me = material_phaseMemberAt(co,ip,el) - broken = mech_collectDotState(crystallite_subdt(g,i,e), g,i,e,p,c) + broken = mech_collectDotState(crystallite_subdt(co,ip,el), co,ip,el,ph,me) if(broken) return do stage = 1,size(A,1) - sizeDotState = plasticState(p)%sizeDotState - plastic_RKdotState(1:sizeDotState,stage) = plasticState(p)%dotState(:,c) - plasticState(p)%dotState(:,c) = A(1,stage) * plastic_RKdotState(1:sizeDotState,1) + sizeDotState = plasticState(ph)%sizeDotState + plastic_RKdotState(1:sizeDotState,stage) = plasticState(ph)%dotState(:,me) + plasticState(ph)%dotState(:,me) = A(1,stage) * plastic_RKdotState(1:sizeDotState,1) do n = 2, stage - sizeDotState = plasticState(p)%sizeDotState - plasticState(p)%dotState(:,c) = plasticState(p)%dotState(:,c) & + sizeDotState = plasticState(ph)%sizeDotState + plasticState(ph)%dotState(:,me) = plasticState(ph)%dotState(:,me) & + A(n,stage) * plastic_RKdotState(1:sizeDotState,n) enddo - sizeDotState = plasticState(p)%sizeDotState - plasticState(p)%state(1:sizeDotState,c) = plasticState(p)%subState0(1:sizeDotState,c) & - + plasticState(p)%dotState (1:sizeDotState,c) & - * crystallite_subdt(g,i,e) + sizeDotState = plasticState(ph)%sizeDotState + plasticState(ph)%state(1:sizeDotState,me) = plasticState(ph)%subState0(1:sizeDotState,me) & + + plasticState(ph)%dotState (1:sizeDotState,me) & + * crystallite_subdt(co,ip,el) - broken = integrateStress(g,i,e,CC(stage)) + broken = integrateStress(co,ip,el,CC(stage)) if(broken) exit - broken = mech_collectDotState(crystallite_subdt(g,i,e)*CC(stage), g,i,e,p,c) + broken = mech_collectDotState(crystallite_subdt(co,ip,el)*CC(stage), co,ip,el,ph,me) if(broken) exit enddo if(broken) return - sizeDotState = plasticState(p)%sizeDotState + sizeDotState = plasticState(ph)%sizeDotState - plastic_RKdotState(1:sizeDotState,size(B)) = plasticState (p)%dotState(:,c) - plasticState(p)%dotState(:,c) = matmul(plastic_RKdotState(1:sizeDotState,1:size(B)),B) - plasticState(p)%state(1:sizeDotState,c) = plasticState(p)%subState0(1:sizeDotState,c) & - + plasticState(p)%dotState (1:sizeDotState,c) & - * crystallite_subdt(g,i,e) + plastic_RKdotState(1:sizeDotState,size(B)) = plasticState (ph)%dotState(:,me) + plasticState(ph)%dotState(:,me) = matmul(plastic_RKdotState(1:sizeDotState,1:size(B)),B) + plasticState(ph)%state(1:sizeDotState,me) = plasticState(ph)%subState0(1:sizeDotState,me) & + + plasticState(ph)%dotState (1:sizeDotState,me) & + * crystallite_subdt(co,ip,el) if(present(DB)) & broken = .not. converged( matmul(plastic_RKdotState(1:sizeDotState,1:size(DB)),DB) & - * crystallite_subdt(g,i,e), & - plasticState(p)%state(1:sizeDotState,c), & - plasticState(p)%atol(1:sizeDotState)) + * crystallite_subdt(co,ip,el), & + plasticState(ph)%state(1:sizeDotState,me), & + plasticState(ph)%atol(1:sizeDotState)) if(broken) return - broken = constitutive_deltaState(crystallite_S(1:3,1:3,g,i,e), & - constitutive_mech_Fi(p)%data(1:3,1:3,c),g,i,e,p,c) + broken = constitutive_deltaState(crystallite_S(1:3,1:3,co,ip,el), & + constitutive_mech_Fi(ph)%data(1:3,1:3,me),co,ip,el,ph,me) if(broken) return - broken = integrateStress(g,i,e) - crystallite_converged(g,i,e) = .not. broken + broken = integrateStress(co,ip,el) + crystallite_converged(co,ip,el) = .not. broken end subroutine integrateStateRK @@ -1396,9 +1396,7 @@ end subroutine crystallite_results !-------------------------------------------------------------------------------------------------- module subroutine mech_initializeRestorationPoints(ph,me) - integer, intent(in) :: & - ph, & - me + integer, intent(in) :: ph, me constitutive_mech_partionedFi0(ph)%data(1:3,1:3,me) = constitutive_mech_Fi0(ph)%data(1:3,1:3,me) @@ -1416,12 +1414,12 @@ module subroutine constitutive_mech_windForward(ph,me) integer, intent(in) :: ph, me - constitutive_mech_partionedFp0(ph)%data(1:3,1:3,me) = constitutive_mech_Fp(ph)%data(1:3,1:3,me) - constitutive_mech_partionedFi0(ph)%data(1:3,1:3,me) = constitutive_mech_Fi(ph)%data(1:3,1:3,me) - constitutive_mech_partionedLi0(ph)%data(1:3,1:3,me) = constitutive_mech_Li(ph)%data(1:3,1:3,me) - plasticState(ph)%partitionedState0(:,me) = plasticState(ph)%state(:,me) + constitutive_mech_partionedFp0(ph)%data(1:3,1:3,me) = constitutive_mech_Fp(ph)%data(1:3,1:3,me) + constitutive_mech_partionedFi0(ph)%data(1:3,1:3,me) = constitutive_mech_Fi(ph)%data(1:3,1:3,me) + constitutive_mech_partionedLi0(ph)%data(1:3,1:3,me) = constitutive_mech_Li(ph)%data(1:3,1:3,me) + plasticState(ph)%partitionedState0(:,me) = plasticState(ph)%state(:,me) end subroutine constitutive_mech_windForward From 7ee52afda2a5ea73b1e84ff790d37af26f3a0efd Mon Sep 17 00:00:00 2001 From: Franz Roters Date: Wed, 23 Dec 2020 09:59:47 +0100 Subject: [PATCH 106/148] [skip ci] corrected comment on meaning of F --- src/constitutive_mech.f90 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/constitutive_mech.f90 b/src/constitutive_mech.f90 index 0be59611f..0b6c5c77c 100644 --- a/src/constitutive_mech.f90 +++ b/src/constitutive_mech.f90 @@ -465,11 +465,11 @@ end subroutine constitutive_hooke_SandItsTangents module subroutine constitutive_plastic_dependentState(F, co, ip, el) integer, intent(in) :: & - co, & !< component-ID of integration point + co, & !< component-ID of integration point ip, & !< integration point el !< element real(pReal), intent(in), dimension(3,3) :: & - F !< elastic deformation gradient + F !< deformation gradient integer :: & ho, & !< homogenization @@ -501,7 +501,7 @@ end subroutine constitutive_plastic_dependentState module subroutine constitutive_plastic_LpAndItsTangents(Lp, dLp_dS, dLp_dFi, & S, Fi, co, ip, el) integer, intent(in) :: & - co, & !< component-ID of integration point + co, & !< component-ID of integration point ip, & !< integration point el !< element real(pReal), intent(in), dimension(3,3) :: & @@ -796,7 +796,7 @@ function integrateStress(co,ip,el,timeFraction) result(broken) m = material_phaseMemberAt(co,ip,el) Lpguess = crystallite_Lp(1:3,1:3,co,ip,el) ! take as first guess - Liguess = constitutive_mech_Li(p)%data(1:3,1:3,m) ! take as first guess + Liguess = constitutive_mech_Li(p)%data(1:3,1:3,m) ! take as first guess call math_invert33(invFp_current,devNull,error,crystallite_subFp0(1:3,1:3,co,ip,el)) if (error) return ! error From 2947e7c444ff9fb0d53c8d9345a9285295354b2e Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Wed, 23 Dec 2020 08:12:56 +0100 Subject: [PATCH 107/148] polishing --- src/constitutive.f90 | 158 +++++++++++++++++++------------------- src/constitutive_mech.f90 | 8 +- 2 files changed, 85 insertions(+), 81 deletions(-) diff --git a/src/constitutive.f90 b/src/constitutive.f90 index 4d0fd5582..f069ac726 100644 --- a/src/constitutive.f90 +++ b/src/constitutive.f90 @@ -1250,97 +1250,97 @@ function crystallite_stressTangent(co,ip,el) result(dPdF) pp = material_phaseAt(co,el) m = material_phaseMemberAt(co,ip,el) - call constitutive_hooke_SandItsTangents(devNull,dSdFe,dSdFi, & - crystallite_Fe(1:3,1:3,co,ip,el), & - constitutive_mech_Fi(pp)%data(1:3,1:3,m),co,ip,el) - call constitutive_LiAndItsTangents(devNull,dLidS,dLidFi, & - crystallite_S (1:3,1:3,co,ip,el), & - constitutive_mech_Fi(pp)%data(1:3,1:3,m), & - co,ip,el) + call constitutive_hooke_SandItsTangents(devNull,dSdFe,dSdFi, & + crystallite_Fe(1:3,1:3,co,ip,el), & + constitutive_mech_Fi(pp)%data(1:3,1:3,m),co,ip,el) + call constitutive_LiAndItsTangents(devNull,dLidS,dLidFi, & + crystallite_S (1:3,1:3,co,ip,el), & + constitutive_mech_Fi(pp)%data(1:3,1:3,m), & + co,ip,el) - invFp = math_inv33(constitutive_mech_Fp(pp)%data(1:3,1:3,m)) - invFi = math_inv33(constitutive_mech_Fi(pp)%data(1:3,1:3,m)) - invSubFp0 = math_inv33(crystallite_subFp0(1:3,1:3,co,ip,el)) - invSubFi0 = math_inv33(crystallite_subFi0(1:3,1:3,co,ip,el)) + invFp = math_inv33(constitutive_mech_Fp(pp)%data(1:3,1:3,m)) + invFi = math_inv33(constitutive_mech_Fi(pp)%data(1:3,1:3,m)) + invSubFp0 = math_inv33(crystallite_subFp0(1:3,1:3,co,ip,el)) + invSubFi0 = math_inv33(crystallite_subFi0(1:3,1:3,co,ip,el)) - if (sum(abs(dLidS)) < tol_math_check) then - dFidS = 0.0_pReal - else - lhs_3333 = 0.0_pReal; rhs_3333 = 0.0_pReal - do o=1,3; do p=1,3 - lhs_3333(1:3,1:3,o,p) = lhs_3333(1:3,1:3,o,p) & - + crystallite_subdt(co,ip,el)*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) & - + invFi*invFi(p,o) - rhs_3333(1:3,1:3,o,p) = rhs_3333(1:3,1:3,o,p) & - - crystallite_subdt(co,ip,el)*matmul(invSubFi0,dLidS(1:3,1:3,o,p)) - enddo; enddo - call math_invert(temp_99,error,math_3333to99(lhs_3333)) - if (error) then - call IO_warning(warning_ID=600,el=el,ip=ip,g=co, & - ext_msg='inversion error in analytic tangent calculation') - dFidS = 0.0_pReal - else - dFidS = math_mul3333xx3333(math_99to3333(temp_99),rhs_3333) - endif - dLidS = math_mul3333xx3333(dLidFi,dFidS) + dLidS - endif + if (sum(abs(dLidS)) < tol_math_check) then + dFidS = 0.0_pReal + else + lhs_3333 = 0.0_pReal; rhs_3333 = 0.0_pReal + do o=1,3; do p=1,3 + lhs_3333(1:3,1:3,o,p) = lhs_3333(1:3,1:3,o,p) & + + crystallite_subdt(co,ip,el)*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) & + + invFi*invFi(p,o) + rhs_3333(1:3,1:3,o,p) = rhs_3333(1:3,1:3,o,p) & + - crystallite_subdt(co,ip,el)*matmul(invSubFi0,dLidS(1:3,1:3,o,p)) + enddo; enddo + call math_invert(temp_99,error,math_3333to99(lhs_3333)) + if (error) then + call IO_warning(warning_ID=600,el=el,ip=ip,g=co, & + ext_msg='inversion error in analytic tangent calculation') + dFidS = 0.0_pReal + else + dFidS = math_mul3333xx3333(math_99to3333(temp_99),rhs_3333) + endif + dLidS = math_mul3333xx3333(dLidFi,dFidS) + dLidS + endif - call constitutive_plastic_LpAndItsTangents(devNull,dLpdS,dLpdFi, & - crystallite_S (1:3,1:3,co,ip,el), & - constitutive_mech_Fi(pp)%data(1:3,1:3,m),co,ip,el) - dLpdS = math_mul3333xx3333(dLpdFi,dFidS) + dLpdS + call constitutive_plastic_LpAndItsTangents(devNull,dLpdS,dLpdFi, & + crystallite_S (1:3,1:3,co,ip,el), & + constitutive_mech_Fi(pp)%data(1:3,1:3,m),co,ip,el) + dLpdS = math_mul3333xx3333(dLpdFi,dFidS) + dLpdS !-------------------------------------------------------------------------------------------------- ! calculate dSdF - temp_33_1 = transpose(matmul(invFp,invFi)) - temp_33_2 = matmul(crystallite_subF(1:3,1:3,co,ip,el),invSubFp0) - temp_33_3 = matmul(matmul(crystallite_subF(1:3,1:3,co,ip,el),invFp), invSubFi0) + temp_33_1 = transpose(matmul(invFp,invFi)) + temp_33_2 = matmul(crystallite_subF(1:3,1:3,co,ip,el),invSubFp0) + temp_33_3 = matmul(matmul(crystallite_subF(1:3,1:3,co,ip,el),invFp), invSubFi0) - 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) - temp_3333(1:3,1:3,p,o) = matmul(matmul(temp_33_2,dLpdS(1:3,1:3,p,o)), invFi) & - + matmul(temp_33_3,dLidS(1:3,1:3,p,o)) - enddo; enddo - lhs_3333 = crystallite_subdt(co,ip,el)*math_mul3333xx3333(dSdFe,temp_3333) & - + math_mul3333xx3333(dSdFi,dFidS) + 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) + temp_3333(1:3,1:3,p,o) = matmul(matmul(temp_33_2,dLpdS(1:3,1:3,p,o)), invFi) & + + matmul(temp_33_3,dLidS(1:3,1:3,p,o)) + enddo; enddo + lhs_3333 = crystallite_subdt(co,ip,el)*math_mul3333xx3333(dSdFe,temp_3333) & + + math_mul3333xx3333(dSdFi,dFidS) - call math_invert(temp_99,error,math_eye(9)+math_3333to99(lhs_3333)) - if (error) then - call IO_warning(warning_ID=600,el=el,ip=ip,g=co, & - ext_msg='inversion error in analytic tangent calculation') - dSdF = rhs_3333 - else - dSdF = math_mul3333xx3333(math_99to3333(temp_99),rhs_3333) - endif + call math_invert(temp_99,error,math_eye(9)+math_3333to99(lhs_3333)) + if (error) then + call IO_warning(warning_ID=600,el=el,ip=ip,g=co, & + ext_msg='inversion error in analytic tangent calculation') + dSdF = rhs_3333 + else + dSdF = math_mul3333xx3333(math_99to3333(temp_99),rhs_3333) + endif !-------------------------------------------------------------------------------------------------- ! calculate dFpinvdF - temp_3333 = math_mul3333xx3333(dLpdS,dSdF) - do o=1,3; do p=1,3 - dFpinvdF(1:3,1:3,p,o) = -crystallite_subdt(co,ip,el) & - * matmul(invSubFp0, matmul(temp_3333(1:3,1:3,p,o),invFi)) - enddo; enddo + temp_3333 = math_mul3333xx3333(dLpdS,dSdF) + do o=1,3; do p=1,3 + dFpinvdF(1:3,1:3,p,o) = -crystallite_subdt(co,ip,el) & + * matmul(invSubFp0, matmul(temp_3333(1:3,1:3,p,o),invFi)) + enddo; enddo !-------------------------------------------------------------------------------------------------- ! assemble dPdF - temp_33_1 = matmul(crystallite_S(1:3,1:3,co,ip,el),transpose(invFp)) - temp_33_2 = matmul(invFp,temp_33_1) - temp_33_3 = matmul(crystallite_subF(1:3,1:3,co,ip,el),invFp) - temp_33_4 = matmul(temp_33_3,crystallite_S(1:3,1:3,co,ip,el)) + temp_33_1 = matmul(crystallite_S(1:3,1:3,co,ip,el),transpose(invFp)) + temp_33_2 = matmul(invFp,temp_33_1) + temp_33_3 = matmul(crystallite_subF(1:3,1:3,co,ip,el),invFp) + temp_33_4 = matmul(temp_33_3,crystallite_S(1:3,1:3,co,ip,el)) - dPdF = 0.0_pReal - do p=1,3 - dPdF(p,1:3,p,1:3) = transpose(temp_33_2) - enddo - do o=1,3; do p=1,3 - dPdF(1:3,1:3,p,o) = dPdF(1:3,1:3,p,o) & - + matmul(matmul(crystallite_subF(1:3,1:3,co,ip,el), & - dFpinvdF(1:3,1:3,p,o)),temp_33_1) & - + matmul(matmul(temp_33_3,dSdF(1:3,1:3,p,o)), & - transpose(invFp)) & - + matmul(temp_33_4,transpose(dFpinvdF(1:3,1:3,p,o))) - enddo; enddo + dPdF = 0.0_pReal + do p=1,3 + dPdF(p,1:3,p,1:3) = transpose(temp_33_2) + enddo + do o=1,3; do p=1,3 + dPdF(1:3,1:3,p,o) = dPdF(1:3,1:3,p,o) & + + matmul(matmul(crystallite_subF(1:3,1:3,co,ip,el), & + dFpinvdF(1:3,1:3,p,o)),temp_33_1) & + + matmul(matmul(temp_33_3,dSdF(1:3,1:3,p,o)), & + transpose(invFp)) & + + matmul(temp_33_4,transpose(dFpinvdF(1:3,1:3,p,o))) + enddo; enddo end function crystallite_stressTangent @@ -1385,14 +1385,16 @@ end subroutine crystallite_orientations !-------------------------------------------------------------------------------------------------- function crystallite_push33ToRef(co,ip,el, tensor33) - real(pReal), dimension(3,3) :: crystallite_push33ToRef real(pReal), dimension(3,3), intent(in) :: tensor33 real(pReal), dimension(3,3) :: T integer, intent(in):: & el, & ip, & co + + real(pReal), dimension(3,3) :: crystallite_push33ToRef + T = matmul(material_orientation0(co,ip,el)%asMatrix(), & ! ToDo: initial orientation correct? transpose(math_inv33(crystallite_subF(1:3,1:3,co,ip,el)))) crystallite_push33ToRef = matmul(transpose(T),matmul(tensor33,T)) @@ -1410,6 +1412,7 @@ subroutine integrateSourceState(co,ip,el) el, & !< element index in element loop ip, & !< integration point index in ip loop co !< grain index in grain loop + integer :: & NiterationState, & !< number of iterations in state loop ph, & @@ -1426,6 +1429,7 @@ subroutine integrateSourceState(co,ip,el) logical :: & broken + ph = material_phaseAt(co,el) c = material_phaseMemberAt(co,ip,el) diff --git a/src/constitutive_mech.f90 b/src/constitutive_mech.f90 index 0b6c5c77c..800e67b32 100644 --- a/src/constitutive_mech.f90 +++ b/src/constitutive_mech.f90 @@ -1185,16 +1185,15 @@ end subroutine integrateStateRKCK45 !-------------------------------------------------------------------------------------------------- subroutine integrateStateRK(co,ip,el,A,B,CC,DB) - real(pReal), dimension(:,:), intent(in) :: A real(pReal), dimension(:), intent(in) :: B, CC real(pReal), dimension(:), intent(in), optional :: DB - integer, intent(in) :: & el, & !< element index in element loop ip, & !< integration point index in ip loop co !< grain index in grain loop - integer :: & + + integer :: & stage, & ! stage index in integration stage loop n, & ph, & @@ -1202,7 +1201,8 @@ subroutine integrateStateRK(co,ip,el,A,B,CC,DB) sizeDotState logical :: & broken - real(pReal), dimension(constitutive_plasticity_maxSizeDotState,size(B)) :: plastic_RKdotState + real(pReal), dimension(constitutive_plasticity_maxSizeDotState,size(B)) :: plastic_RKdotState + ph = material_phaseAt(co,el) me = material_phaseMemberAt(co,ip,el) From 53a7622f25a04b9a25cc4b64efeecaa072ab6115 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Wed, 23 Dec 2020 08:14:42 +0100 Subject: [PATCH 108/148] consistent names --- src/constitutive.f90 | 66 ++++++++++++++++++++++---------------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/src/constitutive.f90 b/src/constitutive.f90 index f069ac726..e100095ac 100644 --- a/src/constitutive.f90 +++ b/src/constitutive.f90 @@ -1391,10 +1391,10 @@ function crystallite_push33ToRef(co,ip,el, tensor33) el, & ip, & co - + real(pReal), dimension(3,3) :: crystallite_push33ToRef - + T = matmul(material_orientation0(co,ip,el)%asMatrix(), & ! ToDo: initial orientation correct? transpose(math_inv33(crystallite_subF(1:3,1:3,co,ip,el)))) crystallite_push33ToRef = matmul(transpose(T),matmul(tensor33,T)) @@ -1412,12 +1412,12 @@ subroutine integrateSourceState(co,ip,el) el, & !< element index in element loop ip, & !< integration point index in ip loop co !< grain index in grain loop - + integer :: & NiterationState, & !< number of iterations in state loop ph, & - c, & - s, & + me, & + so, & size_pl integer, dimension(maxval(phase_Nsources)) :: & size_so @@ -1431,50 +1431,50 @@ subroutine integrateSourceState(co,ip,el) ph = material_phaseAt(co,el) - c = material_phaseMemberAt(co,ip,el) + me = material_phaseMemberAt(co,ip,el) - broken = constitutive_thermal_collectDotState(ph,c) - broken = broken .or. constitutive_damage_collectDotState(crystallite_S(1:3,1:3,co,ip,el), co,ip,el,ph,c) + broken = constitutive_thermal_collectDotState(ph,me) + broken = broken .or. constitutive_damage_collectDotState(crystallite_S(1:3,1:3,co,ip,el), co,ip,el,ph,me) if(broken) return - do s = 1, phase_Nsources(ph) - size_so(s) = sourceState(ph)%p(s)%sizeDotState - sourceState(ph)%p(s)%state(1:size_so(s),c) = sourceState(ph)%p(s)%subState0(1:size_so(s),c) & - + sourceState(ph)%p(s)%dotState (1:size_so(s),c) & + do so = 1, phase_Nsources(ph) + size_so(so) = sourceState(ph)%p(so)%sizeDotState + sourceState(ph)%p(so)%state(1:size_so(so),me) = sourceState(ph)%p(so)%subState0(1:size_so(so),me) & + + sourceState(ph)%p(so)%dotState (1:size_so(so),me) & * crystallite_subdt(co,ip,el) - source_dotState(1:size_so(s),2,s) = 0.0_pReal + source_dotState(1:size_so(so),2,so) = 0.0_pReal enddo iteration: do NiterationState = 1, num%nState - do s = 1, phase_Nsources(ph) - if(nIterationState > 1) source_dotState(1:size_so(s),2,s) = source_dotState(1:size_so(s),1,s) - source_dotState(1:size_so(s),1,s) = sourceState(ph)%p(s)%dotState(:,c) + do so = 1, phase_Nsources(ph) + if(nIterationState > 1) source_dotState(1:size_so(so),2,so) = source_dotState(1:size_so(so),1,so) + source_dotState(1:size_so(so),1,so) = sourceState(ph)%p(so)%dotState(:,me) enddo - broken = constitutive_thermal_collectDotState(ph,c) - broken = broken .or. constitutive_damage_collectDotState(crystallite_S(1:3,1:3,co,ip,el), co,ip,el,ph,c) + broken = constitutive_thermal_collectDotState(ph,me) + broken = broken .or. constitutive_damage_collectDotState(crystallite_S(1:3,1:3,co,ip,el), co,ip,el,ph,me) if(broken) exit iteration - do s = 1, phase_Nsources(ph) - zeta = damper(sourceState(ph)%p(s)%dotState(:,c), & - source_dotState(1:size_so(s),1,s),& - source_dotState(1:size_so(s),2,s)) - sourceState(ph)%p(s)%dotState(:,c) = sourceState(ph)%p(s)%dotState(:,c) * zeta & - + source_dotState(1:size_so(s),1,s)* (1.0_pReal - zeta) - r(1:size_so(s)) = sourceState(ph)%p(s)%state (1:size_so(s),c) & - - sourceState(ph)%p(s)%subState0(1:size_so(s),c) & - - sourceState(ph)%p(s)%dotState (1:size_so(s),c) * crystallite_subdt(co,ip,el) - sourceState(ph)%p(s)%state(1:size_so(s),c) = sourceState(ph)%p(s)%state(1:size_so(s),c) & - - r(1:size_so(s)) + do so = 1, phase_Nsources(ph) + zeta = damper(sourceState(ph)%p(so)%dotState(:,me), & + source_dotState(1:size_so(so),1,so),& + source_dotState(1:size_so(so),2,so)) + sourceState(ph)%p(so)%dotState(:,me) = sourceState(ph)%p(so)%dotState(:,me) * zeta & + + source_dotState(1:size_so(so),1,so)* (1.0_pReal - zeta) + r(1:size_so(so)) = sourceState(ph)%p(so)%state (1:size_so(so),me) & + - sourceState(ph)%p(so)%subState0(1:size_so(so),me) & + - sourceState(ph)%p(so)%dotState (1:size_so(so),me) * crystallite_subdt(co,ip,el) + sourceState(ph)%p(so)%state(1:size_so(so),me) = sourceState(ph)%p(so)%state(1:size_so(so),me) & + - r(1:size_so(so)) crystallite_converged(co,ip,el) = & - crystallite_converged(co,ip,el) .and. converged(r(1:size_so(s)), & - sourceState(ph)%p(s)%state(1:size_so(s),c), & - sourceState(ph)%p(s)%atol(1:size_so(s))) + crystallite_converged(co,ip,el) .and. converged(r(1:size_so(so)), & + sourceState(ph)%p(so)%state(1:size_so(so),me), & + sourceState(ph)%p(so)%atol(1:size_so(so))) enddo if(crystallite_converged(co,ip,el)) then - broken = constitutive_damage_deltaState(crystallite_Fe(1:3,1:3,co,ip,el),co,ip,el,ph,c) + broken = constitutive_damage_deltaState(crystallite_Fe(1:3,1:3,co,ip,el),co,ip,el,ph,me) exit iteration endif From b5ec6048a12d5a40f62024605bf2111b5cc3cfed Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Wed, 23 Dec 2020 08:20:29 +0100 Subject: [PATCH 109/148] only needed in constitutive --- src/constitutive.f90 | 26 +++++++++++++++++++++++++ src/material.f90 | 46 -------------------------------------------- 2 files changed, 26 insertions(+), 46 deletions(-) diff --git a/src/constitutive.f90 b/src/constitutive.f90 index e100095ac..6035e8c19 100644 --- a/src/constitutive.f90 +++ b/src/constitutive.f90 @@ -21,6 +21,31 @@ module constitutive implicit none private + enum, bind(c); enumerator :: & + ELASTICITY_UNDEFINED_ID, & + ELASTICITY_HOOKE_ID, & + PLASTICITY_UNDEFINED_ID, & + PLASTICITY_NONE_ID, & + PLASTICITY_ISOTROPIC_ID, & + PLASTICITY_PHENOPOWERLAW_ID, & + PLASTICITY_KINEHARDENING_ID, & + PLASTICITY_DISLOTWIN_ID, & + PLASTICITY_DISLOTUNGSTEN_ID, & + PLASTICITY_NONLOCAL_ID, & + SOURCE_UNDEFINED_ID ,& + SOURCE_THERMAL_DISSIPATION_ID, & + SOURCE_THERMAL_EXTERNALHEAT_ID, & + SOURCE_DAMAGE_ISOBRITTLE_ID, & + SOURCE_DAMAGE_ISODUCTILE_ID, & + SOURCE_DAMAGE_ANISOBRITTLE_ID, & + SOURCE_DAMAGE_ANISODUCTILE_ID, & + KINEMATICS_UNDEFINED_ID ,& + KINEMATICS_CLEAVAGE_OPENING_ID, & + KINEMATICS_SLIPPLANE_OPENING_ID, & + KINEMATICS_THERMAL_EXPANSION_ID, & + STIFFNESS_DEGRADATION_UNDEFINED_ID, & + STIFFNESS_DEGRADATION_DAMAGE_ID + end enum real(pReal), dimension(:,:,:), allocatable, public :: & crystallite_dt !< requested time increment of each grain real(pReal), dimension(:,:,:), allocatable :: & @@ -354,6 +379,7 @@ module constitutive end interface + type(tDebugOptions) :: debugConstitutive public :: & diff --git a/src/material.f90 b/src/material.f90 index 1f2437ad3..581182d22 100644 --- a/src/material.f90 +++ b/src/material.f90 @@ -17,29 +17,6 @@ module material private enum, bind(c); enumerator :: & - ELASTICITY_UNDEFINED_ID, & - ELASTICITY_HOOKE_ID, & - PLASTICITY_UNDEFINED_ID, & - PLASTICITY_NONE_ID, & - PLASTICITY_ISOTROPIC_ID, & - PLASTICITY_PHENOPOWERLAW_ID, & - PLASTICITY_KINEHARDENING_ID, & - PLASTICITY_DISLOTWIN_ID, & - PLASTICITY_DISLOTUNGSTEN_ID, & - PLASTICITY_NONLOCAL_ID, & - SOURCE_UNDEFINED_ID ,& - SOURCE_THERMAL_DISSIPATION_ID, & - SOURCE_THERMAL_EXTERNALHEAT_ID, & - SOURCE_DAMAGE_ISOBRITTLE_ID, & - SOURCE_DAMAGE_ISODUCTILE_ID, & - SOURCE_DAMAGE_ANISOBRITTLE_ID, & - SOURCE_DAMAGE_ANISODUCTILE_ID, & - KINEMATICS_UNDEFINED_ID ,& - KINEMATICS_CLEAVAGE_OPENING_ID, & - KINEMATICS_SLIPPLANE_OPENING_ID, & - KINEMATICS_THERMAL_EXPANSION_ID, & - STIFFNESS_DEGRADATION_UNDEFINED_ID, & - STIFFNESS_DEGRADATION_DAMAGE_ID, & THERMAL_ISOTHERMAL_ID, & THERMAL_CONDUCTION_ID, & DAMAGE_NONE_ID, & @@ -96,29 +73,6 @@ module material public :: & material_init, & - ELASTICITY_UNDEFINED_ID, & - ELASTICITY_HOOKE_ID, & - PLASTICITY_UNDEFINED_ID, & - PLASTICITY_NONE_ID, & - PLASTICITY_ISOTROPIC_ID, & - PLASTICITY_PHENOPOWERLAW_ID, & - PLASTICITY_KINEHARDENING_ID, & - PLASTICITY_DISLOTWIN_ID, & - PLASTICITY_DISLOTUNGSTEN_ID, & - PLASTICITY_NONLOCAL_ID, & - SOURCE_UNDEFINED_ID ,& - SOURCE_THERMAL_DISSIPATION_ID, & - SOURCE_THERMAL_EXTERNALHEAT_ID, & - SOURCE_DAMAGE_ISOBRITTLE_ID, & - SOURCE_DAMAGE_ISODUCTILE_ID, & - SOURCE_DAMAGE_ANISOBRITTLE_ID, & - SOURCE_DAMAGE_ANISODUCTILE_ID, & - KINEMATICS_UNDEFINED_ID ,& - KINEMATICS_CLEAVAGE_OPENING_ID, & - KINEMATICS_SLIPPLANE_OPENING_ID, & - KINEMATICS_THERMAL_EXPANSION_ID, & - STIFFNESS_DEGRADATION_UNDEFINED_ID, & - STIFFNESS_DEGRADATION_DAMAGE_ID, & THERMAL_ISOTHERMAL_ID, & THERMAL_CONDUCTION_ID, & DAMAGE_NONE_ID, & From 2dcff67f692aabe7958e5979c60f8a8fcc00ad7b Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Wed, 23 Dec 2020 08:57:58 +0100 Subject: [PATCH 110/148] standard name --- src/constitutive.f90 | 156 +++++++++++++++++++++---------------------- 1 file changed, 78 insertions(+), 78 deletions(-) diff --git a/src/constitutive.f90 b/src/constitutive.f90 index 6035e8c19..497d84bdf 100644 --- a/src/constitutive.f90 +++ b/src/constitutive.f90 @@ -846,9 +846,9 @@ subroutine crystallite_init Nconstituents, & p, & m, & - c, & !< counter in integration point component loop - i, & !< counter in integration point loop - e, & !< counter in element loop + co, & !< counter in integration point component loop + ip, & !< counter in integration point loop + el, & !< counter in element loop cMax, & !< maximum number of integration point components iMax, & !< maximum number of integration points eMax !< maximum number of elements @@ -954,19 +954,19 @@ subroutine crystallite_init flush(IO_STDOUT) !$OMP PARALLEL DO PRIVATE(p,m) - do e = FEsolving_execElem(1),FEsolving_execElem(2) - do i = FEsolving_execIP(1), FEsolving_execIP(2); do c = 1, homogenization_Nconstituents(material_homogenizationAt(e)) + do el = FEsolving_execElem(1),FEsolving_execElem(2) + do ip = FEsolving_execIP(1), FEsolving_execIP(2); do co = 1, homogenization_Nconstituents(material_homogenizationAt(el)) - p = material_phaseAt(c,e) - m = material_phaseMemberAt(c,i,e) - constitutive_mech_Fp0(p)%data(1:3,1:3,m) = material_orientation0(c,i,e)%asMatrix() ! Fp reflects initial orientation (see 10.1016/j.actamat.2006.01.005) + p = material_phaseAt(co,el) + m = material_phaseMemberAt(co,ip,el) + constitutive_mech_Fp0(p)%data(1:3,1:3,m) = material_orientation0(co,ip,el)%asMatrix() ! Fp reflects initial orientation (see 10.1016/j.actamat.2006.01.005) constitutive_mech_Fp0(p)%data(1:3,1:3,m) = constitutive_mech_Fp0(p)%data(1:3,1:3,m) & / math_det33(constitutive_mech_Fp0(p)%data(1:3,1:3,m))**(1.0_pReal/3.0_pReal) constitutive_mech_Fi0(p)%data(1:3,1:3,m) = math_I3 - crystallite_F0(1:3,1:3,c,i,e) = math_I3 + crystallite_F0(1:3,1:3,co,ip,el) = math_I3 - crystallite_Fe(1:3,1:3,c,i,e) = math_inv33(matmul(constitutive_mech_Fi0(p)%data(1:3,1:3,m), & + crystallite_Fe(1:3,1:3,co,ip,el) = math_inv33(matmul(constitutive_mech_Fi0(p)%data(1:3,1:3,m), & constitutive_mech_Fp0(p)%data(1:3,1:3,m))) ! assuming that euler angles are given in internal strain free configuration constitutive_mech_Fp(p)%data(1:3,1:3,m) = constitutive_mech_Fp0(p)%data(1:3,1:3,m) constitutive_mech_Fi(p)%data(1:3,1:3,m) = constitutive_mech_Fi0(p)%data(1:3,1:3,m) @@ -974,7 +974,7 @@ subroutine crystallite_init constitutive_mech_partionedFi0(p)%data(1:3,1:3,m) = constitutive_mech_Fi0(p)%data(1:3,1:3,m) constitutive_mech_partionedFp0(p)%data(1:3,1:3,m) = constitutive_mech_Fp0(p)%data(1:3,1:3,m) - crystallite_requested(c,i,e) = .true. + crystallite_requested(co,ip,el) = .true. enddo; enddo enddo !$OMP END PARALLEL DO @@ -985,13 +985,13 @@ subroutine crystallite_init call crystallite_orientations() !$OMP PARALLEL DO PRIVATE(p,m) - do e = FEsolving_execElem(1),FEsolving_execElem(2) - do i = FEsolving_execIP(1),FEsolving_execIP(2) - do c = 1,homogenization_Nconstituents(material_homogenizationAt(e)) - p = material_phaseAt(c,e) - m = material_phaseMemberAt(c,i,e) - call constitutive_plastic_dependentState(crystallite_partitionedF0(1:3,1:3,c,i,e), & - c,i,e) ! update dependent state variables to be consistent with basic states + do el = FEsolving_execElem(1),FEsolving_execElem(2) + do ip = FEsolving_execIP(1),FEsolving_execIP(2) + do co = 1,homogenization_Nconstituents(material_homogenizationAt(el)) + p = material_phaseAt(co,el) + m = material_phaseMemberAt(co,ip,el) + call constitutive_plastic_dependentState(crystallite_partitionedF0(1:3,1:3,co,ip,el), & + co,ip,el) ! update dependent state variables to be consistent with basic states enddo enddo enddo @@ -1011,7 +1011,7 @@ function crystallite_stress() formerSubStep integer :: & NiterationCrystallite, & ! number of iterations in crystallite loop - c, & !< counter in integration point component loop + co, & !< counter in integration point component loop ip, & !< counter in integration point loop el, & !< counter in element loop s, ph, me @@ -1031,25 +1031,25 @@ function crystallite_stress() crystallite_subStep = 0.0_pReal !$OMP PARALLEL DO PRIVATE(ph,me) elementLooping1: do el = FEsolving_execElem(1),FEsolving_execElem(2) - do ip = FEsolving_execIP(1),FEsolving_execIP(2); do c = 1,homogenization_Nconstituents(material_homogenizationAt(el)) - ph = material_phaseAt(c,el) - me = material_phaseMemberAt(c,ip,el) - subLi0(1:3,1:3,c,ip,el) = constitutive_mech_partionedLi0(ph)%data(1:3,1:3,me) - homogenizationRequestsCalculation: if (crystallite_requested(c,ip,el)) then - plasticState (material_phaseAt(c,el))%subState0( :,material_phaseMemberAt(c,ip,el)) = & - plasticState (material_phaseAt(c,el))%partitionedState0(:,material_phaseMemberAt(c,ip,el)) + do ip = FEsolving_execIP(1),FEsolving_execIP(2); do co = 1,homogenization_Nconstituents(material_homogenizationAt(el)) + ph = material_phaseAt(co,el) + me = material_phaseMemberAt(co,ip,el) + subLi0(1:3,1:3,co,ip,el) = constitutive_mech_partionedLi0(ph)%data(1:3,1:3,me) + homogenizationRequestsCalculation: if (crystallite_requested(co,ip,el)) then + plasticState (material_phaseAt(co,el))%subState0( :,material_phaseMemberAt(co,ip,el)) = & + plasticState (material_phaseAt(co,el))%partitionedState0(:,material_phaseMemberAt(co,ip,el)) - do s = 1, phase_Nsources(material_phaseAt(c,el)) - sourceState(material_phaseAt(c,el))%p(s)%subState0( :,material_phaseMemberAt(c,ip,el)) = & - sourceState(material_phaseAt(c,el))%p(s)%partitionedState0(:,material_phaseMemberAt(c,ip,el)) + do s = 1, phase_Nsources(material_phaseAt(co,el)) + sourceState(material_phaseAt(co,el))%p(s)%subState0( :,material_phaseMemberAt(co,ip,el)) = & + sourceState(material_phaseAt(co,el))%p(s)%partitionedState0(:,material_phaseMemberAt(co,ip,el)) enddo - crystallite_subFp0(1:3,1:3,c,ip,el) = constitutive_mech_partionedFp0(ph)%data(1:3,1:3,me) - crystallite_subFi0(1:3,1:3,c,ip,el) = constitutive_mech_partionedFi0(ph)%data(1:3,1:3,me) - crystallite_subF0(1:3,1:3,c,ip,el) = crystallite_partitionedF0(1:3,1:3,c,ip,el) - subFrac(c,ip,el) = 0.0_pReal - crystallite_subStep(c,ip,el) = 1.0_pReal/num%subStepSizeCryst - todo(c,ip,el) = .true. - crystallite_converged(c,ip,el) = .false. ! pretend failed step of 1/subStepSizeCryst + crystallite_subFp0(1:3,1:3,co,ip,el) = constitutive_mech_partionedFp0(ph)%data(1:3,1:3,me) + crystallite_subFi0(1:3,1:3,co,ip,el) = constitutive_mech_partionedFi0(ph)%data(1:3,1:3,me) + crystallite_subF0(1:3,1:3,co,ip,el) = crystallite_partitionedF0(1:3,1:3,co,ip,el) + subFrac(co,ip,el) = 0.0_pReal + crystallite_subStep(co,ip,el) = 1.0_pReal/num%subStepSizeCryst + todo(co,ip,el) = .true. + crystallite_converged(co,ip,el) = .false. ! pretend failed step of 1/subStepSizeCryst endif homogenizationRequestsCalculation enddo; enddo enddo elementLooping1 @@ -1066,68 +1066,68 @@ function crystallite_stress() !$OMP PARALLEL DO PRIVATE(formerSubStep,ph,me) elementLooping3: do el = FEsolving_execElem(1),FEsolving_execElem(2) do ip = FEsolving_execIP(1),FEsolving_execIP(2) - do c = 1,homogenization_Nconstituents(material_homogenizationAt(el)) - ph = material_phaseAt(c,el) - me = material_phaseMemberAt(c,ip,el) + do co = 1,homogenization_Nconstituents(material_homogenizationAt(el)) + ph = material_phaseAt(co,el) + me = material_phaseMemberAt(co,ip,el) !-------------------------------------------------------------------------------------------------- ! wind forward - if (crystallite_converged(c,ip,el)) then - formerSubStep = crystallite_subStep(c,ip,el) - subFrac(c,ip,el) = subFrac(c,ip,el) + crystallite_subStep(c,ip,el) - crystallite_subStep(c,ip,el) = min(1.0_pReal - subFrac(c,ip,el), & - num%stepIncreaseCryst * crystallite_subStep(c,ip,el)) + if (crystallite_converged(co,ip,el)) then + formerSubStep = crystallite_subStep(co,ip,el) + subFrac(co,ip,el) = subFrac(co,ip,el) + crystallite_subStep(co,ip,el) + crystallite_subStep(co,ip,el) = min(1.0_pReal - subFrac(co,ip,el), & + num%stepIncreaseCryst * crystallite_subStep(co,ip,el)) - todo(c,ip,el) = crystallite_subStep(c,ip,el) > 0.0_pReal ! still time left to integrate on? + todo(co,ip,el) = crystallite_subStep(co,ip,el) > 0.0_pReal ! still time left to integrate on? - if (todo(c,ip,el)) then - crystallite_subF0 (1:3,1:3,c,ip,el) = crystallite_subF(1:3,1:3,c,ip,el) - subLp0(1:3,1:3,c,ip,el) = crystallite_Lp (1:3,1:3,c,ip,el) - subLi0(1:3,1:3,c,ip,el) = constitutive_mech_Li(ph)%data(1:3,1:3,me) - crystallite_subFp0(1:3,1:3,c,ip,el) = constitutive_mech_Fp(ph)%data(1:3,1:3,me) - crystallite_subFi0(1:3,1:3,c,ip,el) = constitutive_mech_Fi(ph)%data(1:3,1:3,me) - plasticState( material_phaseAt(c,el))%subState0(:,material_phaseMemberAt(c,ip,el)) & - = plasticState(material_phaseAt(c,el))%state( :,material_phaseMemberAt(c,ip,el)) - do s = 1, phase_Nsources(material_phaseAt(c,el)) - sourceState( material_phaseAt(c,el))%p(s)%subState0(:,material_phaseMemberAt(c,ip,el)) & - = sourceState(material_phaseAt(c,el))%p(s)%state( :,material_phaseMemberAt(c,ip,el)) + if (todo(co,ip,el)) then + crystallite_subF0 (1:3,1:3,co,ip,el) = crystallite_subF(1:3,1:3,co,ip,el) + subLp0(1:3,1:3,co,ip,el) = crystallite_Lp (1:3,1:3,co,ip,el) + subLi0(1:3,1:3,co,ip,el) = constitutive_mech_Li(ph)%data(1:3,1:3,me) + crystallite_subFp0(1:3,1:3,co,ip,el) = constitutive_mech_Fp(ph)%data(1:3,1:3,me) + crystallite_subFi0(1:3,1:3,co,ip,el) = constitutive_mech_Fi(ph)%data(1:3,1:3,me) + plasticState( material_phaseAt(co,el))%subState0(:,material_phaseMemberAt(co,ip,el)) & + = plasticState(material_phaseAt(co,el))%state( :,material_phaseMemberAt(co,ip,el)) + do s = 1, phase_Nsources(material_phaseAt(co,el)) + sourceState( material_phaseAt(co,el))%p(s)%subState0(:,material_phaseMemberAt(co,ip,el)) & + = sourceState(material_phaseAt(co,el))%p(s)%state( :,material_phaseMemberAt(co,ip,el)) enddo endif !-------------------------------------------------------------------------------------------------- ! cut back (reduced time and restore) else - crystallite_subStep(c,ip,el) = num%subStepSizeCryst * crystallite_subStep(c,ip,el) - constitutive_mech_Fp(ph)%data(1:3,1:3,me) = crystallite_subFp0(1:3,1:3,c,ip,el) - constitutive_mech_Fi(ph)%data(1:3,1:3,me) = crystallite_subFi0(1:3,1:3,c,ip,el) - crystallite_S (1:3,1:3,c,ip,el) = crystallite_S0 (1:3,1:3,c,ip,el) - if (crystallite_subStep(c,ip,el) < 1.0_pReal) then ! actual (not initial) cutback - crystallite_Lp (1:3,1:3,c,ip,el) = subLp0(1:3,1:3,c,ip,el) - constitutive_mech_Li(ph)%data(1:3,1:3,me) = subLi0(1:3,1:3,c,ip,el) + crystallite_subStep(co,ip,el) = num%subStepSizeCryst * crystallite_subStep(co,ip,el) + constitutive_mech_Fp(ph)%data(1:3,1:3,me) = crystallite_subFp0(1:3,1:3,co,ip,el) + constitutive_mech_Fi(ph)%data(1:3,1:3,me) = crystallite_subFi0(1:3,1:3,co,ip,el) + crystallite_S (1:3,1:3,co,ip,el) = crystallite_S0 (1:3,1:3,co,ip,el) + if (crystallite_subStep(co,ip,el) < 1.0_pReal) then ! actual (not initial) cutback + crystallite_Lp (1:3,1:3,co,ip,el) = subLp0(1:3,1:3,co,ip,el) + constitutive_mech_Li(ph)%data(1:3,1:3,me) = subLi0(1:3,1:3,co,ip,el) endif - plasticState (material_phaseAt(c,el))%state( :,material_phaseMemberAt(c,ip,el)) & - = plasticState(material_phaseAt(c,el))%subState0(:,material_phaseMemberAt(c,ip,el)) - do s = 1, phase_Nsources(material_phaseAt(c,el)) - sourceState( material_phaseAt(c,el))%p(s)%state( :,material_phaseMemberAt(c,ip,el)) & - = sourceState(material_phaseAt(c,el))%p(s)%subState0(:,material_phaseMemberAt(c,ip,el)) + plasticState (material_phaseAt(co,el))%state( :,material_phaseMemberAt(co,ip,el)) & + = plasticState(material_phaseAt(co,el))%subState0(:,material_phaseMemberAt(co,ip,el)) + do s = 1, phase_Nsources(material_phaseAt(co,el)) + sourceState( material_phaseAt(co,el))%p(s)%state( :,material_phaseMemberAt(co,ip,el)) & + = sourceState(material_phaseAt(co,el))%p(s)%subState0(:,material_phaseMemberAt(co,ip,el)) enddo ! cant restore dotState here, since not yet calculated in first cutback after initialization - todo(c,ip,el) = crystallite_subStep(c,ip,el) > num%subStepMinCryst ! still on track or already done (beyond repair) + todo(co,ip,el) = crystallite_subStep(co,ip,el) > num%subStepMinCryst ! still on track or already done (beyond repair) endif !-------------------------------------------------------------------------------------------------- ! prepare for integration - if (todo(c,ip,el)) then - crystallite_subF(1:3,1:3,c,ip,el) = crystallite_subF0(1:3,1:3,c,ip,el) & - + crystallite_subStep(c,ip,el) *( crystallite_partitionedF (1:3,1:3,c,ip,el) & - -crystallite_partitionedF0(1:3,1:3,c,ip,el)) - crystallite_Fe(1:3,1:3,c,ip,el) = matmul(crystallite_subF(1:3,1:3,c,ip,el), & + if (todo(co,ip,el)) then + crystallite_subF(1:3,1:3,co,ip,el) = crystallite_subF0(1:3,1:3,co,ip,el) & + + crystallite_subStep(co,ip,el) *( crystallite_partitionedF (1:3,1:3,co,ip,el) & + -crystallite_partitionedF0(1:3,1:3,co,ip,el)) + crystallite_Fe(1:3,1:3,co,ip,el) = matmul(crystallite_subF(1:3,1:3,co,ip,el), & math_inv33(matmul(constitutive_mech_Fi(ph)%data(1:3,1:3,me), & constitutive_mech_Fp(ph)%data(1:3,1:3,me)))) - crystallite_subdt(c,ip,el) = crystallite_subStep(c,ip,el) * crystallite_dt(c,ip,el) - crystallite_converged(c,ip,el) = .false. - call integrateState(c,ip,el) - call integrateSourceState(c,ip,el) + crystallite_subdt(co,ip,el) = crystallite_subStep(co,ip,el) * crystallite_dt(co,ip,el) + crystallite_converged(co,ip,el) = .false. + call integrateState(co,ip,el) + call integrateSourceState(co,ip,el) endif enddo From a9b674b9e947e41652ba8b3f939b13dc99d098b5 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Wed, 23 Dec 2020 10:05:02 +0100 Subject: [PATCH 111/148] no need for separate loop --- src/constitutive.f90 | 133 +++++++++++++++++++++++++++++++++++++++++ src/homogenization.f90 | 33 ++++------ 2 files changed, 146 insertions(+), 20 deletions(-) diff --git a/src/constitutive.f90 b/src/constitutive.f90 index 497d84bdf..9b1bb33b3 100644 --- a/src/constitutive.f90 +++ b/src/constitutive.f90 @@ -398,6 +398,7 @@ module constitutive converged, & crystallite_init, & crystallite_stress, & + crystallite_stress2, & crystallite_stressTangent, & crystallite_orientations, & crystallite_push33ToRef, & @@ -1152,6 +1153,138 @@ function crystallite_stress() end function crystallite_stress +!-------------------------------------------------------------------------------------------------- +!> @brief calculate stress (P) +!-------------------------------------------------------------------------------------------------- +function crystallite_stress2(co,ip,el) + + integer, intent(in) :: & + co, & + ip, & + el + + logical :: crystallite_stress2 + + real(pReal) :: & + formerSubStep + integer :: & + NiterationCrystallite, & ! number of iterations in crystallite loop + s, ph, me + logical :: todo + real(pReal) :: subFrac !ToDo: need to set some values to false for different Ngrains + real(pReal), dimension(3,3) :: & + subLp0, & !< plastic velocity grad at start of crystallite inc + subLi0 !< intermediate velocity grad at start of crystallite inc + + + + + +!-------------------------------------------------------------------------------------------------- +! initialize to starting condition + crystallite_subStep(co,ip,el) = 0.0_pReal + + ph = material_phaseAt(co,el) + me = material_phaseMemberAt(co,ip,el) + subLi0 = constitutive_mech_partionedLi0(ph)%data(1:3,1:3,me) + subLp0 = crystallite_partitionedLp0(1:3,1:3,co,ip,el) + homogenizationRequestsCalculation: if (crystallite_requested(co,ip,el)) then + plasticState (material_phaseAt(co,el))%subState0( :,material_phaseMemberAt(co,ip,el)) = & + plasticState (material_phaseAt(co,el))%partitionedState0(:,material_phaseMemberAt(co,ip,el)) + + do s = 1, phase_Nsources(material_phaseAt(co,el)) + sourceState(material_phaseAt(co,el))%p(s)%subState0( :,material_phaseMemberAt(co,ip,el)) = & + sourceState(material_phaseAt(co,el))%p(s)%partitionedState0(:,material_phaseMemberAt(co,ip,el)) + enddo + crystallite_subFp0(1:3,1:3,co,ip,el) = constitutive_mech_partionedFp0(ph)%data(1:3,1:3,me) + crystallite_subFi0(1:3,1:3,co,ip,el) = constitutive_mech_partionedFi0(ph)%data(1:3,1:3,me) + crystallite_subF0(1:3,1:3,co,ip,el) = crystallite_partitionedF0(1:3,1:3,co,ip,el) + subFrac = 0.0_pReal + crystallite_subStep(co,ip,el) = 1.0_pReal/num%subStepSizeCryst + todo = .true. + crystallite_converged(co,ip,el) = .false. ! pretend failed step of 1/subStepSizeCryst + endif homogenizationRequestsCalculation + + todo = .true. + NiterationCrystallite = 0 + cutbackLooping: do while (todo) + NiterationCrystallite = NiterationCrystallite + 1 + +!-------------------------------------------------------------------------------------------------- +! wind forward + if (crystallite_converged(co,ip,el)) then + formerSubStep = crystallite_subStep(co,ip,el) + subFrac = subFrac + crystallite_subStep(co,ip,el) + crystallite_subStep(co,ip,el) = min(1.0_pReal - subFrac, & + num%stepIncreaseCryst * crystallite_subStep(co,ip,el)) + + todo = crystallite_subStep(co,ip,el) > 0.0_pReal ! still time left to integrate on? + + if (todo) then + crystallite_subF0 (1:3,1:3,co,ip,el) = crystallite_subF(1:3,1:3,co,ip,el) + subLp0 = crystallite_Lp (1:3,1:3,co,ip,el) + subLi0 = constitutive_mech_Li(ph)%data(1:3,1:3,me) + crystallite_subFp0(1:3,1:3,co,ip,el) = constitutive_mech_Fp(ph)%data(1:3,1:3,me) + crystallite_subFi0(1:3,1:3,co,ip,el) = constitutive_mech_Fi(ph)%data(1:3,1:3,me) + plasticState( material_phaseAt(co,el))%subState0(:,material_phaseMemberAt(co,ip,el)) & + = plasticState(material_phaseAt(co,el))%state( :,material_phaseMemberAt(co,ip,el)) + do s = 1, phase_Nsources(material_phaseAt(co,el)) + sourceState( material_phaseAt(co,el))%p(s)%subState0(:,material_phaseMemberAt(co,ip,el)) & + = sourceState(material_phaseAt(co,el))%p(s)%state( :,material_phaseMemberAt(co,ip,el)) + enddo + endif + +!-------------------------------------------------------------------------------------------------- +! cut back (reduced time and restore) + else + crystallite_subStep(co,ip,el) = num%subStepSizeCryst * crystallite_subStep(co,ip,el) + constitutive_mech_Fp(ph)%data(1:3,1:3,me) = crystallite_subFp0(1:3,1:3,co,ip,el) + constitutive_mech_Fi(ph)%data(1:3,1:3,me) = crystallite_subFi0(1:3,1:3,co,ip,el) + crystallite_S (1:3,1:3,co,ip,el) = crystallite_S0 (1:3,1:3,co,ip,el) + if (crystallite_subStep(co,ip,el) < 1.0_pReal) then ! actual (not initial) cutback + crystallite_Lp (1:3,1:3,co,ip,el) = subLp0 + constitutive_mech_Li(ph)%data(1:3,1:3,me) = subLi0 + endif + plasticState (material_phaseAt(co,el))%state( :,material_phaseMemberAt(co,ip,el)) & + = plasticState(material_phaseAt(co,el))%subState0(:,material_phaseMemberAt(co,ip,el)) + do s = 1, phase_Nsources(material_phaseAt(co,el)) + sourceState( material_phaseAt(co,el))%p(s)%state( :,material_phaseMemberAt(co,ip,el)) & + = sourceState(material_phaseAt(co,el))%p(s)%subState0(:,material_phaseMemberAt(co,ip,el)) + enddo + + ! cant restore dotState here, since not yet calculated in first cutback after initialization + todo = crystallite_subStep(co,ip,el) > num%subStepMinCryst ! still on track or already done (beyond repair) + endif + +!-------------------------------------------------------------------------------------------------- +! prepare for integration + if (todo) then + crystallite_subF(1:3,1:3,co,ip,el) = crystallite_subF0(1:3,1:3,co,ip,el) & + + crystallite_subStep(co,ip,el) *( crystallite_partitionedF (1:3,1:3,co,ip,el) & + -crystallite_partitionedF0(1:3,1:3,co,ip,el)) + crystallite_Fe(1:3,1:3,co,ip,el) = matmul(crystallite_subF(1:3,1:3,co,ip,el), & + math_inv33(matmul(constitutive_mech_Fi(ph)%data(1:3,1:3,me), & + constitutive_mech_Fp(ph)%data(1:3,1:3,me)))) + crystallite_subdt(co,ip,el) = crystallite_subStep(co,ip,el) * crystallite_dt(co,ip,el) + crystallite_converged(co,ip,el) = .false. + call integrateState(co,ip,el) + call integrateSourceState(co,ip,el) + endif + + + +!-------------------------------------------------------------------------------------------------- +! integrate --- requires fully defined state array (basic + dependent state) + if (.not. crystallite_converged(co,ip,el) .and. crystallite_subStep(co,ip,el) > num%subStepMinCryst) & ! do not try non-converged but fully cutbacked any further + todo = .true. + enddo cutbackLooping + +! return whether converged or not + crystallite_stress2 = crystallite_converged(co,ip,el) + +end function crystallite_stress2 + + !-------------------------------------------------------------------------------------------------- !> @brief Backup data for homog cutback. !-------------------------------------------------------------------------------------------------- diff --git a/src/homogenization.f90 b/src/homogenization.f90 index 8ceac0eb8..f7516c5b5 100644 --- a/src/homogenization.f90 +++ b/src/homogenization.f90 @@ -180,7 +180,7 @@ subroutine materialpoint_stressAndItsTangent(dt) NiterationMPstate, & i, & !< integration point number e, & !< element number - myNgrains + myNgrains, co real(pReal), dimension(discretization_nIPs,discretization_Nelems) :: & subFrac, & subStep @@ -285,7 +285,7 @@ subroutine materialpoint_stressAndItsTangent(dt) !-------------------------------------------------------------------------------------------------- ! deformation partitioning - !$OMP PARALLEL DO PRIVATE(myNgrains,m) + !$OMP PARALLEL DO PRIVATE(myNgrains,m,co) elementLooping2: do e = FEsolving_execElem(1),FEsolving_execElem(2) myNgrains = homogenization_Nconstituents(material_homogenizationAt(e)) IpLooping2: do i = FEsolving_execIP(1),FEsolving_execIP(2) @@ -300,19 +300,12 @@ subroutine materialpoint_stressAndItsTangent(dt) else crystallite_requested(1:myNgrains,i,e) = .false. ! calculation for constituents not required anymore endif - enddo IpLooping2 - enddo elementLooping2 - !$OMP END PARALLEL DO + converged(i,e) = .true. + do co = 1, myNgrains + converged(i,e) = converged(i,e) .and. crystallite_stress2(co,i,e) + enddo -!-------------------------------------------------------------------------------------------------- -! crystallite integration - converged = crystallite_stress() !ToDo: MD not sure if that is the best logic -!-------------------------------------------------------------------------------------------------- -! state update - !$OMP PARALLEL DO PRIVATE(m) - elementLooping3: do e = FEsolving_execElem(1),FEsolving_execElem(2) - IpLooping3: do i = FEsolving_execIP(1),FEsolving_execIP(2) if (requested(i,e) .and. .not. doneAndHappy(1,i,e)) then if (.not. converged(i,e)) then doneAndHappy(1:2,i,e) = [.true.,.false.] @@ -326,8 +319,8 @@ subroutine materialpoint_stressAndItsTangent(dt) converged(i,e) = all(doneAndHappy(1:2,i,e)) ! converged if done and happy endif endif - enddo IpLooping3 - enddo elementLooping3 + enddo IpLooping2 + enddo elementLooping2 !$OMP END PARALLEL DO enddo convergenceLooping @@ -339,11 +332,11 @@ subroutine materialpoint_stressAndItsTangent(dt) if (.not. terminallyIll ) then call crystallite_orientations() ! calculate crystal orientations !$OMP PARALLEL DO - elementLooping4: do e = FEsolving_execElem(1),FEsolving_execElem(2) - IpLooping4: do i = FEsolving_execIP(1),FEsolving_execIP(2) + elementLooping3: do e = FEsolving_execElem(1),FEsolving_execElem(2) + IpLooping3: do i = FEsolving_execIP(1),FEsolving_execIP(2) call mech_homogenize(i,e) - enddo IpLooping4 - enddo elementLooping4 + enddo IpLooping3 + enddo elementLooping3 !$OMP END PARALLEL DO else print'(/,a,/)', ' << HOMOG >> Material Point terminally ill' @@ -433,7 +426,7 @@ end subroutine homogenization_results !-------------------------------------------------------------------------------------------------- subroutine homogenization_forward - integer :: ho + integer :: ho do ho = 1, size(material_name_homogenization) homogState (ho)%state0 = homogState (ho)%state From ee37c75de9249490a2190943942a75d26b0fa608 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Wed, 23 Dec 2020 10:41:45 +0100 Subject: [PATCH 112/148] problems with checkout Probably due to large HDF5 files --- .gitmodules | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitmodules b/.gitmodules index 5d17eb0cb..0587fff4c 100644 --- a/.gitmodules +++ b/.gitmodules @@ -2,3 +2,4 @@ path = PRIVATE url = ../PRIVATE.git branch = master + shallow = true From 44d8210f2d59750933586959e5f6d31d43bcbab4 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Wed, 23 Dec 2020 11:07:57 +0100 Subject: [PATCH 113/148] not needed anymore --- src/constitutive.f90 | 160 ++--------------------------------------- src/homogenization.f90 | 2 +- 2 files changed, 5 insertions(+), 157 deletions(-) diff --git a/src/constitutive.f90 b/src/constitutive.f90 index 9b1bb33b3..6331172bf 100644 --- a/src/constitutive.f90 +++ b/src/constitutive.f90 @@ -398,7 +398,6 @@ module constitutive converged, & crystallite_init, & crystallite_stress, & - crystallite_stress2, & crystallite_stressTangent, & crystallite_orientations, & crystallite_push33ToRef, & @@ -1005,165 +1004,14 @@ end subroutine crystallite_init !-------------------------------------------------------------------------------------------------- !> @brief calculate stress (P) !-------------------------------------------------------------------------------------------------- -function crystallite_stress() - - logical, dimension(discretization_nIPs,discretization_Nelems) :: crystallite_stress - real(pReal) :: & - formerSubStep - integer :: & - NiterationCrystallite, & ! number of iterations in crystallite loop - co, & !< counter in integration point component loop - ip, & !< counter in integration point loop - el, & !< counter in element loop - s, ph, me - logical, dimension(homogenization_maxNconstituents,discretization_nIPs,discretization_Nelems) :: todo !ToDo: need to set some values to false for different Ngrains - real(pReal), dimension(homogenization_maxNconstituents,discretization_nIPs,discretization_Nelems) :: subFrac !ToDo: need to set some values to false for different Ngrains - real(pReal), dimension(:,:,:,:,:), allocatable :: & - subLp0,& !< plastic velocity grad at start of crystallite inc - subLi0 !< intermediate velocity grad at start of crystallite inc - - todo = .false. - - allocate(subLi0(3,3,homogenization_maxNconstituents,discretization_nIPs,discretization_Nelems)) - subLp0 = crystallite_partitionedLp0 - -!-------------------------------------------------------------------------------------------------- -! initialize to starting condition - crystallite_subStep = 0.0_pReal - !$OMP PARALLEL DO PRIVATE(ph,me) - elementLooping1: do el = FEsolving_execElem(1),FEsolving_execElem(2) - do ip = FEsolving_execIP(1),FEsolving_execIP(2); do co = 1,homogenization_Nconstituents(material_homogenizationAt(el)) - ph = material_phaseAt(co,el) - me = material_phaseMemberAt(co,ip,el) - subLi0(1:3,1:3,co,ip,el) = constitutive_mech_partionedLi0(ph)%data(1:3,1:3,me) - homogenizationRequestsCalculation: if (crystallite_requested(co,ip,el)) then - plasticState (material_phaseAt(co,el))%subState0( :,material_phaseMemberAt(co,ip,el)) = & - plasticState (material_phaseAt(co,el))%partitionedState0(:,material_phaseMemberAt(co,ip,el)) - - do s = 1, phase_Nsources(material_phaseAt(co,el)) - sourceState(material_phaseAt(co,el))%p(s)%subState0( :,material_phaseMemberAt(co,ip,el)) = & - sourceState(material_phaseAt(co,el))%p(s)%partitionedState0(:,material_phaseMemberAt(co,ip,el)) - enddo - crystallite_subFp0(1:3,1:3,co,ip,el) = constitutive_mech_partionedFp0(ph)%data(1:3,1:3,me) - crystallite_subFi0(1:3,1:3,co,ip,el) = constitutive_mech_partionedFi0(ph)%data(1:3,1:3,me) - crystallite_subF0(1:3,1:3,co,ip,el) = crystallite_partitionedF0(1:3,1:3,co,ip,el) - subFrac(co,ip,el) = 0.0_pReal - crystallite_subStep(co,ip,el) = 1.0_pReal/num%subStepSizeCryst - todo(co,ip,el) = .true. - crystallite_converged(co,ip,el) = .false. ! pretend failed step of 1/subStepSizeCryst - endif homogenizationRequestsCalculation - enddo; enddo - enddo elementLooping1 - !$OMP END PARALLEL DO - - NiterationCrystallite = 0 - cutbackLooping: do while (any(todo(:,FEsolving_execIP(1):FEsolving_execIP(2),FEsolving_execELem(1):FEsolving_execElem(2)))) - NiterationCrystallite = NiterationCrystallite + 1 - -#ifdef DEBUG - if (debugCrystallite%extensive) & - print'(a,i6)', '<< CRYST stress >> crystallite iteration ',NiterationCrystallite -#endif - !$OMP PARALLEL DO PRIVATE(formerSubStep,ph,me) - elementLooping3: do el = FEsolving_execElem(1),FEsolving_execElem(2) - do ip = FEsolving_execIP(1),FEsolving_execIP(2) - do co = 1,homogenization_Nconstituents(material_homogenizationAt(el)) - ph = material_phaseAt(co,el) - me = material_phaseMemberAt(co,ip,el) -!-------------------------------------------------------------------------------------------------- -! wind forward - if (crystallite_converged(co,ip,el)) then - formerSubStep = crystallite_subStep(co,ip,el) - subFrac(co,ip,el) = subFrac(co,ip,el) + crystallite_subStep(co,ip,el) - crystallite_subStep(co,ip,el) = min(1.0_pReal - subFrac(co,ip,el), & - num%stepIncreaseCryst * crystallite_subStep(co,ip,el)) - - todo(co,ip,el) = crystallite_subStep(co,ip,el) > 0.0_pReal ! still time left to integrate on? - - if (todo(co,ip,el)) then - crystallite_subF0 (1:3,1:3,co,ip,el) = crystallite_subF(1:3,1:3,co,ip,el) - subLp0(1:3,1:3,co,ip,el) = crystallite_Lp (1:3,1:3,co,ip,el) - subLi0(1:3,1:3,co,ip,el) = constitutive_mech_Li(ph)%data(1:3,1:3,me) - crystallite_subFp0(1:3,1:3,co,ip,el) = constitutive_mech_Fp(ph)%data(1:3,1:3,me) - crystallite_subFi0(1:3,1:3,co,ip,el) = constitutive_mech_Fi(ph)%data(1:3,1:3,me) - plasticState( material_phaseAt(co,el))%subState0(:,material_phaseMemberAt(co,ip,el)) & - = plasticState(material_phaseAt(co,el))%state( :,material_phaseMemberAt(co,ip,el)) - do s = 1, phase_Nsources(material_phaseAt(co,el)) - sourceState( material_phaseAt(co,el))%p(s)%subState0(:,material_phaseMemberAt(co,ip,el)) & - = sourceState(material_phaseAt(co,el))%p(s)%state( :,material_phaseMemberAt(co,ip,el)) - enddo - endif - -!-------------------------------------------------------------------------------------------------- -! cut back (reduced time and restore) - else - crystallite_subStep(co,ip,el) = num%subStepSizeCryst * crystallite_subStep(co,ip,el) - constitutive_mech_Fp(ph)%data(1:3,1:3,me) = crystallite_subFp0(1:3,1:3,co,ip,el) - constitutive_mech_Fi(ph)%data(1:3,1:3,me) = crystallite_subFi0(1:3,1:3,co,ip,el) - crystallite_S (1:3,1:3,co,ip,el) = crystallite_S0 (1:3,1:3,co,ip,el) - if (crystallite_subStep(co,ip,el) < 1.0_pReal) then ! actual (not initial) cutback - crystallite_Lp (1:3,1:3,co,ip,el) = subLp0(1:3,1:3,co,ip,el) - constitutive_mech_Li(ph)%data(1:3,1:3,me) = subLi0(1:3,1:3,co,ip,el) - endif - plasticState (material_phaseAt(co,el))%state( :,material_phaseMemberAt(co,ip,el)) & - = plasticState(material_phaseAt(co,el))%subState0(:,material_phaseMemberAt(co,ip,el)) - do s = 1, phase_Nsources(material_phaseAt(co,el)) - sourceState( material_phaseAt(co,el))%p(s)%state( :,material_phaseMemberAt(co,ip,el)) & - = sourceState(material_phaseAt(co,el))%p(s)%subState0(:,material_phaseMemberAt(co,ip,el)) - enddo - - ! cant restore dotState here, since not yet calculated in first cutback after initialization - todo(co,ip,el) = crystallite_subStep(co,ip,el) > num%subStepMinCryst ! still on track or already done (beyond repair) - endif - -!-------------------------------------------------------------------------------------------------- -! prepare for integration - if (todo(co,ip,el)) then - crystallite_subF(1:3,1:3,co,ip,el) = crystallite_subF0(1:3,1:3,co,ip,el) & - + crystallite_subStep(co,ip,el) *( crystallite_partitionedF (1:3,1:3,co,ip,el) & - -crystallite_partitionedF0(1:3,1:3,co,ip,el)) - crystallite_Fe(1:3,1:3,co,ip,el) = matmul(crystallite_subF(1:3,1:3,co,ip,el), & - math_inv33(matmul(constitutive_mech_Fi(ph)%data(1:3,1:3,me), & - constitutive_mech_Fp(ph)%data(1:3,1:3,me)))) - crystallite_subdt(co,ip,el) = crystallite_subStep(co,ip,el) * crystallite_dt(co,ip,el) - crystallite_converged(co,ip,el) = .false. - call integrateState(co,ip,el) - call integrateSourceState(co,ip,el) - endif - - enddo - enddo - enddo elementLooping3 - !$OMP END PARALLEL DO - -!-------------------------------------------------------------------------------------------------- -! integrate --- requires fully defined state array (basic + dependent state) - where(.not. crystallite_converged .and. crystallite_subStep > num%subStepMinCryst) & ! do not try non-converged but fully cutbacked any further - todo = .true. ! TODO: again unroll this into proper elementloop to avoid N^2 for single point evaluation - enddo cutbackLooping - -! return whether converged or not - crystallite_stress = .false. - elementLooping5: do el = FEsolving_execElem(1),FEsolving_execElem(2) - do ip = FEsolving_execIP(1),FEsolving_execIP(2) - crystallite_stress(ip,el) = all(crystallite_converged(:,ip,el)) - enddo - enddo elementLooping5 - -end function crystallite_stress - - -!-------------------------------------------------------------------------------------------------- -!> @brief calculate stress (P) -!-------------------------------------------------------------------------------------------------- -function crystallite_stress2(co,ip,el) +function crystallite_stress(co,ip,el) integer, intent(in) :: & co, & ip, & el - logical :: crystallite_stress2 + logical :: crystallite_stress real(pReal) :: & formerSubStep @@ -1280,9 +1128,9 @@ function crystallite_stress2(co,ip,el) enddo cutbackLooping ! return whether converged or not - crystallite_stress2 = crystallite_converged(co,ip,el) + crystallite_stress = crystallite_converged(co,ip,el) -end function crystallite_stress2 +end function crystallite_stress !-------------------------------------------------------------------------------------------------- diff --git a/src/homogenization.f90 b/src/homogenization.f90 index f7516c5b5..91b9a5194 100644 --- a/src/homogenization.f90 +++ b/src/homogenization.f90 @@ -302,7 +302,7 @@ subroutine materialpoint_stressAndItsTangent(dt) endif converged(i,e) = .true. do co = 1, myNgrains - converged(i,e) = converged(i,e) .and. crystallite_stress2(co,i,e) + converged(i,e) = converged(i,e) .and. crystallite_stress(co,i,e) enddo From 73523c8f629281e2ff72452ddfb9e2351fb65520 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Wed, 23 Dec 2020 11:24:02 +0100 Subject: [PATCH 114/148] not a global variable --- src/homogenization.f90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/homogenization.f90 b/src/homogenization.f90 index 91b9a5194..8d90af515 100644 --- a/src/homogenization.f90 +++ b/src/homogenization.f90 @@ -220,7 +220,7 @@ subroutine materialpoint_stressAndItsTangent(dt) any(subStep(FEsolving_execIP(1):FEsolving_execIP(2),& FEsolving_execElem(1):FEsolving_execElem(2)) > num%subStepMinHomog)) - !$OMP PARALLEL DO PRIVATE(m) + !$OMP PARALLEL DO PRIVATE(m,myNgrains) elementLooping1: do e = FEsolving_execElem(1),FEsolving_execElem(2) myNgrains = homogenization_Nconstituents(material_homogenizationAt(e)) IpLooping1: do i = FEsolving_execIP(1),FEsolving_execIP(2) From 026ac07c9e67fb4952d5beeecb1f761af4de3d23 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Wed, 23 Dec 2020 11:37:00 +0100 Subject: [PATCH 115/148] better use one loop --- src/homogenization.f90 | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/src/homogenization.f90 b/src/homogenization.f90 index 8d90af515..117c47652 100644 --- a/src/homogenization.f90 +++ b/src/homogenization.f90 @@ -220,7 +220,7 @@ subroutine materialpoint_stressAndItsTangent(dt) any(subStep(FEsolving_execIP(1):FEsolving_execIP(2),& FEsolving_execElem(1):FEsolving_execElem(2)) > num%subStepMinHomog)) - !$OMP PARALLEL DO PRIVATE(m,myNgrains) + !$OMP PARALLEL DO PRIVATE(m,myNgrains,NiterationMPstate) elementLooping1: do e = FEsolving_execElem(1),FEsolving_execElem(2) myNgrains = homogenization_Nconstituents(material_homogenizationAt(e)) IpLooping1: do i = FEsolving_execIP(1),FEsolving_execIP(2) @@ -270,25 +270,18 @@ subroutine materialpoint_stressAndItsTangent(dt) requested(i,e) = .true. doneAndHappy(1:2,i,e) = [.false.,.true.] endif - enddo IpLooping1 - enddo elementLooping1 - !$OMP END PARALLEL DO + NiterationMPstate = 0 - convergenceLooping: do while (.not. terminallyIll .and. & - any( requested(:,FEsolving_execELem(1):FEsolving_execElem(2)) & - .and. .not. doneAndHappy(1,:,FEsolving_execELem(1):FEsolving_execElem(2)) & - ) .and. & - NiterationMPstate < num%nMPstate) + convergenceLooping: do while (.not. terminallyIll .and. requested(i,e) & + .and. .not. doneAndHappy(1,i,e) & + .and. NiterationMPstate < num%nMPstate) NiterationMPstate = NiterationMPstate + 1 !-------------------------------------------------------------------------------------------------- ! deformation partitioning - !$OMP PARALLEL DO PRIVATE(myNgrains,m,co) - elementLooping2: do e = FEsolving_execElem(1),FEsolving_execElem(2) - myNgrains = homogenization_Nconstituents(material_homogenizationAt(e)) - IpLooping2: do i = FEsolving_execIP(1),FEsolving_execIP(2) + if(requested(i,e) .and. .not. doneAndHappy(1,i,e)) then ! requested but not yet done m = (e-1)*discretization_nIPs + i call mech_partition(homogenization_F0(1:3,1:3,m) & @@ -319,11 +312,11 @@ subroutine materialpoint_stressAndItsTangent(dt) converged(i,e) = all(doneAndHappy(1:2,i,e)) ! converged if done and happy endif endif - enddo IpLooping2 - enddo elementLooping2 - !$OMP END PARALLEL DO enddo convergenceLooping + enddo IpLooping1 + enddo elementLooping1 + !$OMP END PARALLEL DO NiterationHomog = NiterationHomog + 1 From fef525aee1147711e01b4c27357f8a4224fcf4fe Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Wed, 23 Dec 2020 12:15:17 +0100 Subject: [PATCH 116/148] proper indentation --- src/constitutive.f90 | 145 ++++++++++++++++++++----------------------- 1 file changed, 69 insertions(+), 76 deletions(-) diff --git a/src/constitutive.f90 b/src/constitutive.f90 index 6331172bf..da115bf0f 100644 --- a/src/constitutive.f90 +++ b/src/constitutive.f90 @@ -1025,33 +1025,30 @@ function crystallite_stress(co,ip,el) subLi0 !< intermediate velocity grad at start of crystallite inc - - - !-------------------------------------------------------------------------------------------------- ! initialize to starting condition crystallite_subStep(co,ip,el) = 0.0_pReal - ph = material_phaseAt(co,el) - me = material_phaseMemberAt(co,ip,el) - subLi0 = constitutive_mech_partionedLi0(ph)%data(1:3,1:3,me) - subLp0 = crystallite_partitionedLp0(1:3,1:3,co,ip,el) - homogenizationRequestsCalculation: if (crystallite_requested(co,ip,el)) then - plasticState (material_phaseAt(co,el))%subState0( :,material_phaseMemberAt(co,ip,el)) = & - plasticState (material_phaseAt(co,el))%partitionedState0(:,material_phaseMemberAt(co,ip,el)) + ph = material_phaseAt(co,el) + me = material_phaseMemberAt(co,ip,el) + subLi0 = constitutive_mech_partionedLi0(ph)%data(1:3,1:3,me) + subLp0 = crystallite_partitionedLp0(1:3,1:3,co,ip,el) + homogenizationRequestsCalculation: if (crystallite_requested(co,ip,el)) then + plasticState (material_phaseAt(co,el))%subState0( :,material_phaseMemberAt(co,ip,el)) = & + plasticState (material_phaseAt(co,el))%partitionedState0(:,material_phaseMemberAt(co,ip,el)) - do s = 1, phase_Nsources(material_phaseAt(co,el)) - sourceState(material_phaseAt(co,el))%p(s)%subState0( :,material_phaseMemberAt(co,ip,el)) = & - sourceState(material_phaseAt(co,el))%p(s)%partitionedState0(:,material_phaseMemberAt(co,ip,el)) - enddo - crystallite_subFp0(1:3,1:3,co,ip,el) = constitutive_mech_partionedFp0(ph)%data(1:3,1:3,me) - crystallite_subFi0(1:3,1:3,co,ip,el) = constitutive_mech_partionedFi0(ph)%data(1:3,1:3,me) - crystallite_subF0(1:3,1:3,co,ip,el) = crystallite_partitionedF0(1:3,1:3,co,ip,el) - subFrac = 0.0_pReal - crystallite_subStep(co,ip,el) = 1.0_pReal/num%subStepSizeCryst - todo = .true. - crystallite_converged(co,ip,el) = .false. ! pretend failed step of 1/subStepSizeCryst - endif homogenizationRequestsCalculation + do s = 1, phase_Nsources(material_phaseAt(co,el)) + sourceState(material_phaseAt(co,el))%p(s)%subState0( :,material_phaseMemberAt(co,ip,el)) = & + sourceState(material_phaseAt(co,el))%p(s)%partitionedState0(:,material_phaseMemberAt(co,ip,el)) + enddo + crystallite_subFp0(1:3,1:3,co,ip,el) = constitutive_mech_partionedFp0(ph)%data(1:3,1:3,me) + crystallite_subFi0(1:3,1:3,co,ip,el) = constitutive_mech_partionedFi0(ph)%data(1:3,1:3,me) + crystallite_subF0(1:3,1:3,co,ip,el) = crystallite_partitionedF0(1:3,1:3,co,ip,el) + subFrac = 0.0_pReal + crystallite_subStep(co,ip,el) = 1.0_pReal/num%subStepSizeCryst + todo = .true. + crystallite_converged(co,ip,el) = .false. ! pretend failed step of 1/subStepSizeCryst + endif homogenizationRequestsCalculation todo = .true. NiterationCrystallite = 0 @@ -1060,70 +1057,66 @@ function crystallite_stress(co,ip,el) !-------------------------------------------------------------------------------------------------- ! wind forward - if (crystallite_converged(co,ip,el)) then - formerSubStep = crystallite_subStep(co,ip,el) - subFrac = subFrac + crystallite_subStep(co,ip,el) - crystallite_subStep(co,ip,el) = min(1.0_pReal - subFrac, & - num%stepIncreaseCryst * crystallite_subStep(co,ip,el)) + if (crystallite_converged(co,ip,el)) then + formerSubStep = crystallite_subStep(co,ip,el) + subFrac = subFrac + crystallite_subStep(co,ip,el) + crystallite_subStep(co,ip,el) = min(1.0_pReal - subFrac, & + num%stepIncreaseCryst * crystallite_subStep(co,ip,el)) - todo = crystallite_subStep(co,ip,el) > 0.0_pReal ! still time left to integrate on? + todo = crystallite_subStep(co,ip,el) > 0.0_pReal ! still time left to integrate on? - if (todo) then - crystallite_subF0 (1:3,1:3,co,ip,el) = crystallite_subF(1:3,1:3,co,ip,el) - subLp0 = crystallite_Lp (1:3,1:3,co,ip,el) - subLi0 = constitutive_mech_Li(ph)%data(1:3,1:3,me) - crystallite_subFp0(1:3,1:3,co,ip,el) = constitutive_mech_Fp(ph)%data(1:3,1:3,me) - crystallite_subFi0(1:3,1:3,co,ip,el) = constitutive_mech_Fi(ph)%data(1:3,1:3,me) - plasticState( material_phaseAt(co,el))%subState0(:,material_phaseMemberAt(co,ip,el)) & - = plasticState(material_phaseAt(co,el))%state( :,material_phaseMemberAt(co,ip,el)) - do s = 1, phase_Nsources(material_phaseAt(co,el)) - sourceState( material_phaseAt(co,el))%p(s)%subState0(:,material_phaseMemberAt(co,ip,el)) & - = sourceState(material_phaseAt(co,el))%p(s)%state( :,material_phaseMemberAt(co,ip,el)) - enddo - endif + if (todo) then + crystallite_subF0 (1:3,1:3,co,ip,el) = crystallite_subF(1:3,1:3,co,ip,el) + subLp0 = crystallite_Lp (1:3,1:3,co,ip,el) + subLi0 = constitutive_mech_Li(ph)%data(1:3,1:3,me) + crystallite_subFp0(1:3,1:3,co,ip,el) = constitutive_mech_Fp(ph)%data(1:3,1:3,me) + crystallite_subFi0(1:3,1:3,co,ip,el) = constitutive_mech_Fi(ph)%data(1:3,1:3,me) + plasticState( material_phaseAt(co,el))%subState0(:,material_phaseMemberAt(co,ip,el)) & + = plasticState(material_phaseAt(co,el))%state( :,material_phaseMemberAt(co,ip,el)) + do s = 1, phase_Nsources(material_phaseAt(co,el)) + sourceState( material_phaseAt(co,el))%p(s)%subState0(:,material_phaseMemberAt(co,ip,el)) & + = sourceState(material_phaseAt(co,el))%p(s)%state( :,material_phaseMemberAt(co,ip,el)) + enddo + endif !-------------------------------------------------------------------------------------------------- ! cut back (reduced time and restore) - else - crystallite_subStep(co,ip,el) = num%subStepSizeCryst * crystallite_subStep(co,ip,el) - constitutive_mech_Fp(ph)%data(1:3,1:3,me) = crystallite_subFp0(1:3,1:3,co,ip,el) - constitutive_mech_Fi(ph)%data(1:3,1:3,me) = crystallite_subFi0(1:3,1:3,co,ip,el) - crystallite_S (1:3,1:3,co,ip,el) = crystallite_S0 (1:3,1:3,co,ip,el) - if (crystallite_subStep(co,ip,el) < 1.0_pReal) then ! actual (not initial) cutback - crystallite_Lp (1:3,1:3,co,ip,el) = subLp0 - constitutive_mech_Li(ph)%data(1:3,1:3,me) = subLi0 - endif - plasticState (material_phaseAt(co,el))%state( :,material_phaseMemberAt(co,ip,el)) & - = plasticState(material_phaseAt(co,el))%subState0(:,material_phaseMemberAt(co,ip,el)) - do s = 1, phase_Nsources(material_phaseAt(co,el)) - sourceState( material_phaseAt(co,el))%p(s)%state( :,material_phaseMemberAt(co,ip,el)) & - = sourceState(material_phaseAt(co,el))%p(s)%subState0(:,material_phaseMemberAt(co,ip,el)) - enddo + else + crystallite_subStep(co,ip,el) = num%subStepSizeCryst * crystallite_subStep(co,ip,el) + constitutive_mech_Fp(ph)%data(1:3,1:3,me) = crystallite_subFp0(1:3,1:3,co,ip,el) + constitutive_mech_Fi(ph)%data(1:3,1:3,me) = crystallite_subFi0(1:3,1:3,co,ip,el) + crystallite_S (1:3,1:3,co,ip,el) = crystallite_S0 (1:3,1:3,co,ip,el) + if (crystallite_subStep(co,ip,el) < 1.0_pReal) then ! actual (not initial) cutback + crystallite_Lp (1:3,1:3,co,ip,el) = subLp0 + constitutive_mech_Li(ph)%data(1:3,1:3,me) = subLi0 + endif + plasticState (material_phaseAt(co,el))%state( :,material_phaseMemberAt(co,ip,el)) & + = plasticState(material_phaseAt(co,el))%subState0(:,material_phaseMemberAt(co,ip,el)) + do s = 1, phase_Nsources(material_phaseAt(co,el)) + sourceState( material_phaseAt(co,el))%p(s)%state( :,material_phaseMemberAt(co,ip,el)) & + = sourceState(material_phaseAt(co,el))%p(s)%subState0(:,material_phaseMemberAt(co,ip,el)) + enddo - ! cant restore dotState here, since not yet calculated in first cutback after initialization - todo = crystallite_subStep(co,ip,el) > num%subStepMinCryst ! still on track or already done (beyond repair) - endif + ! cant restore dotState here, since not yet calculated in first cutback after initialization + todo = crystallite_subStep(co,ip,el) > num%subStepMinCryst ! still on track or already done (beyond repair) + endif !-------------------------------------------------------------------------------------------------- ! prepare for integration - if (todo) then - crystallite_subF(1:3,1:3,co,ip,el) = crystallite_subF0(1:3,1:3,co,ip,el) & - + crystallite_subStep(co,ip,el) *( crystallite_partitionedF (1:3,1:3,co,ip,el) & - -crystallite_partitionedF0(1:3,1:3,co,ip,el)) - crystallite_Fe(1:3,1:3,co,ip,el) = matmul(crystallite_subF(1:3,1:3,co,ip,el), & - math_inv33(matmul(constitutive_mech_Fi(ph)%data(1:3,1:3,me), & - constitutive_mech_Fp(ph)%data(1:3,1:3,me)))) - crystallite_subdt(co,ip,el) = crystallite_subStep(co,ip,el) * crystallite_dt(co,ip,el) - crystallite_converged(co,ip,el) = .false. - call integrateState(co,ip,el) - call integrateSourceState(co,ip,el) - endif + if (todo) then + crystallite_subF(1:3,1:3,co,ip,el) = crystallite_subF0(1:3,1:3,co,ip,el) & + + crystallite_subStep(co,ip,el) *( crystallite_partitionedF (1:3,1:3,co,ip,el) & + -crystallite_partitionedF0(1:3,1:3,co,ip,el)) + crystallite_Fe(1:3,1:3,co,ip,el) = matmul(crystallite_subF(1:3,1:3,co,ip,el), & + math_inv33(matmul(constitutive_mech_Fi(ph)%data(1:3,1:3,me), & + constitutive_mech_Fp(ph)%data(1:3,1:3,me)))) + crystallite_subdt(co,ip,el) = crystallite_subStep(co,ip,el) * crystallite_dt(co,ip,el) + crystallite_converged(co,ip,el) = .false. + call integrateState(co,ip,el) + call integrateSourceState(co,ip,el) + endif - - -!-------------------------------------------------------------------------------------------------- -! integrate --- requires fully defined state array (basic + dependent state) - if (.not. crystallite_converged(co,ip,el) .and. crystallite_subStep(co,ip,el) > num%subStepMinCryst) & ! do not try non-converged but fully cutbacked any further + if (.not. crystallite_converged(co,ip,el) .and. crystallite_subStep(co,ip,el) > num%subStepMinCryst) & ! do not try non-converged but fully cutbacked any further todo = .true. enddo cutbackLooping From b12f882ad4bc69ba464eecf1beb65db56f3443eb Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Wed, 23 Dec 2020 12:25:56 +0100 Subject: [PATCH 117/148] avoid global variables --- src/constitutive.f90 | 32 +++++++++++++------------------- src/homogenization.f90 | 23 ++++++++++------------- 2 files changed, 23 insertions(+), 32 deletions(-) diff --git a/src/constitutive.f90 b/src/constitutive.f90 index da115bf0f..266a3623d 100644 --- a/src/constitutive.f90 +++ b/src/constitutive.f90 @@ -72,8 +72,6 @@ module constitutive real(pReal), dimension(:,:,:,:,:), allocatable, public :: & crystallite_partitionedF !< def grad to be reached at end of homog inc - logical, dimension(:,:,:), allocatable, public :: & - crystallite_requested !< used by upper level (homogenization) to request crystallite calculation logical, dimension(:,:,:), allocatable :: & crystallite_converged !< convergence flag @@ -889,7 +887,6 @@ subroutine crystallite_init allocate(crystallite_orientation(cMax,iMax,eMax)) - allocate(crystallite_requested(cMax,iMax,eMax), source=.false.) allocate(crystallite_converged(cMax,iMax,eMax), source=.true.) num_crystallite => config_numerics%get('crystallite',defaultVal=emptyDict) @@ -974,7 +971,6 @@ subroutine crystallite_init constitutive_mech_partionedFi0(p)%data(1:3,1:3,m) = constitutive_mech_Fi0(p)%data(1:3,1:3,m) constitutive_mech_partionedFp0(p)%data(1:3,1:3,m) = constitutive_mech_Fp0(p)%data(1:3,1:3,m) - crystallite_requested(co,ip,el) = .true. enddo; enddo enddo !$OMP END PARALLEL DO @@ -1033,22 +1029,20 @@ function crystallite_stress(co,ip,el) me = material_phaseMemberAt(co,ip,el) subLi0 = constitutive_mech_partionedLi0(ph)%data(1:3,1:3,me) subLp0 = crystallite_partitionedLp0(1:3,1:3,co,ip,el) - homogenizationRequestsCalculation: if (crystallite_requested(co,ip,el)) then - plasticState (material_phaseAt(co,el))%subState0( :,material_phaseMemberAt(co,ip,el)) = & - plasticState (material_phaseAt(co,el))%partitionedState0(:,material_phaseMemberAt(co,ip,el)) + plasticState (material_phaseAt(co,el))%subState0( :,material_phaseMemberAt(co,ip,el)) = & + plasticState (material_phaseAt(co,el))%partitionedState0(:,material_phaseMemberAt(co,ip,el)) - do s = 1, phase_Nsources(material_phaseAt(co,el)) - sourceState(material_phaseAt(co,el))%p(s)%subState0( :,material_phaseMemberAt(co,ip,el)) = & - sourceState(material_phaseAt(co,el))%p(s)%partitionedState0(:,material_phaseMemberAt(co,ip,el)) - enddo - crystallite_subFp0(1:3,1:3,co,ip,el) = constitutive_mech_partionedFp0(ph)%data(1:3,1:3,me) - crystallite_subFi0(1:3,1:3,co,ip,el) = constitutive_mech_partionedFi0(ph)%data(1:3,1:3,me) - crystallite_subF0(1:3,1:3,co,ip,el) = crystallite_partitionedF0(1:3,1:3,co,ip,el) - subFrac = 0.0_pReal - crystallite_subStep(co,ip,el) = 1.0_pReal/num%subStepSizeCryst - todo = .true. - crystallite_converged(co,ip,el) = .false. ! pretend failed step of 1/subStepSizeCryst - endif homogenizationRequestsCalculation + do s = 1, phase_Nsources(material_phaseAt(co,el)) + sourceState(material_phaseAt(co,el))%p(s)%subState0( :,material_phaseMemberAt(co,ip,el)) = & + sourceState(material_phaseAt(co,el))%p(s)%partitionedState0(:,material_phaseMemberAt(co,ip,el)) + enddo + crystallite_subFp0(1:3,1:3,co,ip,el) = constitutive_mech_partionedFp0(ph)%data(1:3,1:3,me) + crystallite_subFi0(1:3,1:3,co,ip,el) = constitutive_mech_partionedFi0(ph)%data(1:3,1:3,me) + crystallite_subF0(1:3,1:3,co,ip,el) = crystallite_partitionedF0(1:3,1:3,co,ip,el) + subFrac = 0.0_pReal + crystallite_subStep(co,ip,el) = 1.0_pReal/num%subStepSizeCryst + todo = .true. + crystallite_converged(co,ip,el) = .false. ! pretend failed step of 1/subStepSizeCryst todo = .true. NiterationCrystallite = 0 diff --git a/src/homogenization.f90 b/src/homogenization.f90 index 117c47652..c0568b048 100644 --- a/src/homogenization.f90 +++ b/src/homogenization.f90 @@ -272,12 +272,12 @@ subroutine materialpoint_stressAndItsTangent(dt) endif - NiterationMPstate = 0 + NiterationMPstate = 0 - convergenceLooping: do while (.not. terminallyIll .and. requested(i,e) & - .and. .not. doneAndHappy(1,i,e) & - .and. NiterationMPstate < num%nMPstate) - NiterationMPstate = NiterationMPstate + 1 + convergenceLooping: do while (.not. terminallyIll .and. requested(i,e) & + .and. .not. doneAndHappy(1,i,e) & + .and. NiterationMPstate < num%nMPstate) + NiterationMPstate = NiterationMPstate + 1 !-------------------------------------------------------------------------------------------------- ! deformation partitioning @@ -289,14 +289,11 @@ subroutine materialpoint_stressAndItsTangent(dt) *(subStep(i,e)+subFrac(i,e)), & i,e) crystallite_dt(1:myNgrains,i,e) = dt*subStep(i,e) ! propagate materialpoint dt to grains - crystallite_requested(1:myNgrains,i,e) = .true. ! request calculation for constituents - else - crystallite_requested(1:myNgrains,i,e) = .false. ! calculation for constituents not required anymore + converged(i,e) = .true. + do co = 1, myNgrains + converged(i,e) = converged(i,e) .and. crystallite_stress(co,i,e) + enddo endif - converged(i,e) = .true. - do co = 1, myNgrains - converged(i,e) = converged(i,e) .and. crystallite_stress(co,i,e) - enddo if (requested(i,e) .and. .not. doneAndHappy(1,i,e)) then @@ -313,7 +310,7 @@ subroutine materialpoint_stressAndItsTangent(dt) endif endif - enddo convergenceLooping + enddo convergenceLooping enddo IpLooping1 enddo elementLooping1 !$OMP END PARALLEL DO From 7d6c6159a99ac6b35c8d9708922dd7ad5b2b2417 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Wed, 23 Dec 2020 13:22:11 +0100 Subject: [PATCH 118/148] consisten names --- src/constitutive.f90 | 58 ++++++++++++++++++++++---------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/src/constitutive.f90 b/src/constitutive.f90 index 266a3623d..c85ae0553 100644 --- a/src/constitutive.f90 +++ b/src/constitutive.f90 @@ -842,8 +842,8 @@ subroutine crystallite_init integer :: & Nconstituents, & - p, & - m, & + ph, & + me, & co, & !< counter in integration point component loop ip, & !< counter in integration point loop el, & !< counter in element loop @@ -931,18 +931,18 @@ subroutine crystallite_init allocate(constitutive_mech_Li(phases%length)) allocate(constitutive_mech_Li0(phases%length)) allocate(constitutive_mech_partionedLi0(phases%length)) - do p = 1, phases%length - Nconstituents = count(material_phaseAt == p) * discretization_nIPs + do ph = 1, phases%length + Nconstituents = count(material_phaseAt == ph) * discretization_nIPs - allocate(constitutive_mech_Fi(p)%data(3,3,Nconstituents)) - allocate(constitutive_mech_Fi0(p)%data(3,3,Nconstituents)) - allocate(constitutive_mech_partionedFi0(p)%data(3,3,Nconstituents)) - allocate(constitutive_mech_Fp(p)%data(3,3,Nconstituents)) - allocate(constitutive_mech_Fp0(p)%data(3,3,Nconstituents)) - allocate(constitutive_mech_partionedFp0(p)%data(3,3,Nconstituents)) - allocate(constitutive_mech_Li(p)%data(3,3,Nconstituents)) - allocate(constitutive_mech_Li0(p)%data(3,3,Nconstituents)) - allocate(constitutive_mech_partionedLi0(p)%data(3,3,Nconstituents)) + allocate(constitutive_mech_Fi(ph)%data(3,3,Nconstituents)) + allocate(constitutive_mech_Fi0(ph)%data(3,3,Nconstituents)) + allocate(constitutive_mech_partionedFi0(ph)%data(3,3,Nconstituents)) + allocate(constitutive_mech_Fp(ph)%data(3,3,Nconstituents)) + allocate(constitutive_mech_Fp0(ph)%data(3,3,Nconstituents)) + allocate(constitutive_mech_partionedFp0(ph)%data(3,3,Nconstituents)) + allocate(constitutive_mech_Li(ph)%data(3,3,Nconstituents)) + allocate(constitutive_mech_Li0(ph)%data(3,3,Nconstituents)) + allocate(constitutive_mech_partionedLi0(ph)%data(3,3,Nconstituents)) enddo print'(a42,1x,i10)', ' # of elements: ', eMax @@ -950,26 +950,26 @@ subroutine crystallite_init print'(a42,1x,i10)', 'max # of constituents/integration point: ', cMax flush(IO_STDOUT) - !$OMP PARALLEL DO PRIVATE(p,m) + !$OMP PARALLEL DO PRIVATE(ph,me) do el = FEsolving_execElem(1),FEsolving_execElem(2) do ip = FEsolving_execIP(1), FEsolving_execIP(2); do co = 1, homogenization_Nconstituents(material_homogenizationAt(el)) - p = material_phaseAt(co,el) - m = material_phaseMemberAt(co,ip,el) - constitutive_mech_Fp0(p)%data(1:3,1:3,m) = material_orientation0(co,ip,el)%asMatrix() ! Fp reflects initial orientation (see 10.1016/j.actamat.2006.01.005) - constitutive_mech_Fp0(p)%data(1:3,1:3,m) = constitutive_mech_Fp0(p)%data(1:3,1:3,m) & - / math_det33(constitutive_mech_Fp0(p)%data(1:3,1:3,m))**(1.0_pReal/3.0_pReal) - constitutive_mech_Fi0(p)%data(1:3,1:3,m) = math_I3 + ph = material_phaseAt(co,el) + me = material_phaseMemberAt(co,ip,el) + constitutive_mech_Fp0(ph)%data(1:3,1:3,me) = material_orientation0(co,ip,el)%asMatrix() ! Fp reflects initial orientation (see 10.1016/j.actamat.2006.01.005) + constitutive_mech_Fp0(ph)%data(1:3,1:3,me) = constitutive_mech_Fp0(ph)%data(1:3,1:3,me) & + / math_det33(constitutive_mech_Fp0(ph)%data(1:3,1:3,me))**(1.0_pReal/3.0_pReal) + constitutive_mech_Fi0(ph)%data(1:3,1:3,me) = math_I3 crystallite_F0(1:3,1:3,co,ip,el) = math_I3 - crystallite_Fe(1:3,1:3,co,ip,el) = math_inv33(matmul(constitutive_mech_Fi0(p)%data(1:3,1:3,m), & - constitutive_mech_Fp0(p)%data(1:3,1:3,m))) ! assuming that euler angles are given in internal strain free configuration - constitutive_mech_Fp(p)%data(1:3,1:3,m) = constitutive_mech_Fp0(p)%data(1:3,1:3,m) - constitutive_mech_Fi(p)%data(1:3,1:3,m) = constitutive_mech_Fi0(p)%data(1:3,1:3,m) + crystallite_Fe(1:3,1:3,co,ip,el) = math_inv33(matmul(constitutive_mech_Fi0(ph)%data(1:3,1:3,me), & + constitutive_mech_Fp0(ph)%data(1:3,1:3,me))) ! assuming that euler angles are given in internal strain free configuration + constitutive_mech_Fp(ph)%data(1:3,1:3,me) = constitutive_mech_Fp0(ph)%data(1:3,1:3,me) + constitutive_mech_Fi(ph)%data(1:3,1:3,me) = constitutive_mech_Fi0(ph)%data(1:3,1:3,me) - constitutive_mech_partionedFi0(p)%data(1:3,1:3,m) = constitutive_mech_Fi0(p)%data(1:3,1:3,m) - constitutive_mech_partionedFp0(p)%data(1:3,1:3,m) = constitutive_mech_Fp0(p)%data(1:3,1:3,m) + constitutive_mech_partionedFi0(ph)%data(1:3,1:3,me) = constitutive_mech_Fi0(ph)%data(1:3,1:3,me) + constitutive_mech_partionedFp0(ph)%data(1:3,1:3,me) = constitutive_mech_Fp0(ph)%data(1:3,1:3,me) enddo; enddo enddo @@ -980,12 +980,12 @@ subroutine crystallite_init call crystallite_orientations() - !$OMP PARALLEL DO PRIVATE(p,m) + !$OMP PARALLEL DO PRIVATE(ph,me) do el = FEsolving_execElem(1),FEsolving_execElem(2) do ip = FEsolving_execIP(1),FEsolving_execIP(2) do co = 1,homogenization_Nconstituents(material_homogenizationAt(el)) - p = material_phaseAt(co,el) - m = material_phaseMemberAt(co,ip,el) + ph = material_phaseAt(co,el) + me = material_phaseMemberAt(co,ip,el) call constitutive_plastic_dependentState(crystallite_partitionedF0(1:3,1:3,co,ip,el), & co,ip,el) ! update dependent state variables to be consistent with basic states enddo From a91a3975f68ae35863cd3bcee2c3b36927079318 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Wed, 23 Dec 2020 13:31:30 +0100 Subject: [PATCH 119/148] not needed as global variable --- src/constitutive.f90 | 36 +++++++++++++++--------------------- 1 file changed, 15 insertions(+), 21 deletions(-) diff --git a/src/constitutive.f90 b/src/constitutive.f90 index c85ae0553..1a03f3c50 100644 --- a/src/constitutive.f90 +++ b/src/constitutive.f90 @@ -49,8 +49,7 @@ module constitutive real(pReal), dimension(:,:,:), allocatable, public :: & crystallite_dt !< requested time increment of each grain real(pReal), dimension(:,:,:), allocatable :: & - crystallite_subdt, & !< substepped time increment of each grain - crystallite_subStep !< size of next integration step + crystallite_subdt !< substepped time increment of each grain type(rotation), dimension(:,:,:), allocatable :: & crystallite_orientation !< current orientation real(pReal), dimension(:,:,:,:,:), allocatable :: & @@ -882,7 +881,7 @@ subroutine crystallite_init source = crystallite_partitionedF) allocate(crystallite_dt(cMax,iMax,eMax),source=0.0_pReal) - allocate(crystallite_subdt,crystallite_subStep, & + allocate(crystallite_subdt, & source = crystallite_dt) allocate(crystallite_orientation(cMax,iMax,eMax)) @@ -1015,16 +1014,12 @@ function crystallite_stress(co,ip,el) NiterationCrystallite, & ! number of iterations in crystallite loop s, ph, me logical :: todo - real(pReal) :: subFrac !ToDo: need to set some values to false for different Ngrains + real(pReal) :: subFrac,subStep real(pReal), dimension(3,3) :: & subLp0, & !< plastic velocity grad at start of crystallite inc subLi0 !< intermediate velocity grad at start of crystallite inc -!-------------------------------------------------------------------------------------------------- -! initialize to starting condition - crystallite_subStep(co,ip,el) = 0.0_pReal - ph = material_phaseAt(co,el) me = material_phaseMemberAt(co,ip,el) subLi0 = constitutive_mech_partionedLi0(ph)%data(1:3,1:3,me) @@ -1040,7 +1035,7 @@ function crystallite_stress(co,ip,el) crystallite_subFi0(1:3,1:3,co,ip,el) = constitutive_mech_partionedFi0(ph)%data(1:3,1:3,me) crystallite_subF0(1:3,1:3,co,ip,el) = crystallite_partitionedF0(1:3,1:3,co,ip,el) subFrac = 0.0_pReal - crystallite_subStep(co,ip,el) = 1.0_pReal/num%subStepSizeCryst + subStep = 1.0_pReal/num%subStepSizeCryst todo = .true. crystallite_converged(co,ip,el) = .false. ! pretend failed step of 1/subStepSizeCryst @@ -1052,12 +1047,11 @@ function crystallite_stress(co,ip,el) !-------------------------------------------------------------------------------------------------- ! wind forward if (crystallite_converged(co,ip,el)) then - formerSubStep = crystallite_subStep(co,ip,el) - subFrac = subFrac + crystallite_subStep(co,ip,el) - crystallite_subStep(co,ip,el) = min(1.0_pReal - subFrac, & - num%stepIncreaseCryst * crystallite_subStep(co,ip,el)) + formerSubStep = subStep + subFrac = subFrac + subStep + subStep = min(1.0_pReal - subFrac, num%stepIncreaseCryst * subStep) - todo = crystallite_subStep(co,ip,el) > 0.0_pReal ! still time left to integrate on? + todo = subStep > 0.0_pReal ! still time left to integrate on? if (todo) then crystallite_subF0 (1:3,1:3,co,ip,el) = crystallite_subF(1:3,1:3,co,ip,el) @@ -1076,11 +1070,11 @@ function crystallite_stress(co,ip,el) !-------------------------------------------------------------------------------------------------- ! cut back (reduced time and restore) else - crystallite_subStep(co,ip,el) = num%subStepSizeCryst * crystallite_subStep(co,ip,el) + subStep = num%subStepSizeCryst * subStep constitutive_mech_Fp(ph)%data(1:3,1:3,me) = crystallite_subFp0(1:3,1:3,co,ip,el) constitutive_mech_Fi(ph)%data(1:3,1:3,me) = crystallite_subFi0(1:3,1:3,co,ip,el) crystallite_S (1:3,1:3,co,ip,el) = crystallite_S0 (1:3,1:3,co,ip,el) - if (crystallite_subStep(co,ip,el) < 1.0_pReal) then ! actual (not initial) cutback + if (subStep < 1.0_pReal) then ! actual (not initial) cutback crystallite_Lp (1:3,1:3,co,ip,el) = subLp0 constitutive_mech_Li(ph)%data(1:3,1:3,me) = subLi0 endif @@ -1092,25 +1086,25 @@ function crystallite_stress(co,ip,el) enddo ! cant restore dotState here, since not yet calculated in first cutback after initialization - todo = crystallite_subStep(co,ip,el) > num%subStepMinCryst ! still on track or already done (beyond repair) + todo = subStep > num%subStepMinCryst ! still on track or already done (beyond repair) endif !-------------------------------------------------------------------------------------------------- ! prepare for integration if (todo) then crystallite_subF(1:3,1:3,co,ip,el) = crystallite_subF0(1:3,1:3,co,ip,el) & - + crystallite_subStep(co,ip,el) *( crystallite_partitionedF (1:3,1:3,co,ip,el) & - -crystallite_partitionedF0(1:3,1:3,co,ip,el)) + + subStep *( crystallite_partitionedF (1:3,1:3,co,ip,el) & + -crystallite_partitionedF0(1:3,1:3,co,ip,el)) crystallite_Fe(1:3,1:3,co,ip,el) = matmul(crystallite_subF(1:3,1:3,co,ip,el), & math_inv33(matmul(constitutive_mech_Fi(ph)%data(1:3,1:3,me), & constitutive_mech_Fp(ph)%data(1:3,1:3,me)))) - crystallite_subdt(co,ip,el) = crystallite_subStep(co,ip,el) * crystallite_dt(co,ip,el) + crystallite_subdt(co,ip,el) = subStep * crystallite_dt(co,ip,el) crystallite_converged(co,ip,el) = .false. call integrateState(co,ip,el) call integrateSourceState(co,ip,el) endif - if (.not. crystallite_converged(co,ip,el) .and. crystallite_subStep(co,ip,el) > num%subStepMinCryst) & ! do not try non-converged but fully cutbacked any further + if (.not. crystallite_converged(co,ip,el) .and. subStep > num%subStepMinCryst) & ! do not try non-converged but fully cutbacked any further todo = .true. enddo cutbackLooping From 972e041f597b0075e8a3207d080b6e8f7bbea025 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Wed, 23 Dec 2020 14:03:15 +0100 Subject: [PATCH 120/148] modernizing --- src/constitutive.f90 | 31 +++++++++++++------------------ src/homogenization_mech.f90 | 7 +++++++ 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/src/constitutive.f90 b/src/constitutive.f90 index 1a03f3c50..c4b97d1bd 100644 --- a/src/constitutive.f90 +++ b/src/constitutive.f90 @@ -22,8 +22,6 @@ module constitutive implicit none private enum, bind(c); enumerator :: & - ELASTICITY_UNDEFINED_ID, & - ELASTICITY_HOOKE_ID, & PLASTICITY_UNDEFINED_ID, & PLASTICITY_NONE_ID, & PLASTICITY_ISOTROPIC_ID, & @@ -42,9 +40,7 @@ module constitutive KINEMATICS_UNDEFINED_ID ,& KINEMATICS_CLEAVAGE_OPENING_ID, & KINEMATICS_SLIPPLANE_OPENING_ID, & - KINEMATICS_THERMAL_EXPANSION_ID, & - STIFFNESS_DEGRADATION_UNDEFINED_ID, & - STIFFNESS_DEGRADATION_DAMAGE_ID + KINEMATICS_THERMAL_EXPANSION_ID end enum real(pReal), dimension(:,:,:), allocatable, public :: & crystallite_dt !< requested time increment of each grain @@ -691,18 +687,18 @@ end function constitutive_thermal_collectDotState !> @brief for constitutive models having an instantaneous change of state !> will return false if delta state is not needed/supported by the constitutive model !-------------------------------------------------------------------------------------------------- -function constitutive_damage_deltaState(Fe, co, ip, el, phase, of) result(broken) +function constitutive_damage_deltaState(Fe, co, ip, el, ph, of) result(broken) integer, intent(in) :: & co, & !< component-ID of integration point ip, & !< integration point el, & !< element - phase, & + ph, & of real(pReal), intent(in), dimension(3,3) :: & Fe !< elastic deformation gradient integer :: & - i, & + so, & myOffset, & mySize logical :: & @@ -711,19 +707,19 @@ function constitutive_damage_deltaState(Fe, co, ip, el, phase, of) result(broken broken = .false. - sourceLoop: do i = 1, phase_Nsources(phase) + sourceLoop: do so = 1, phase_Nsources(ph) - sourceType: select case (phase_source(i,phase)) + sourceType: select case (phase_source(so,ph)) case (SOURCE_damage_isoBrittle_ID) sourceType call source_damage_isoBrittle_deltaState (constitutive_homogenizedC(co,ip,el), Fe, & co, ip, el) - broken = any(IEEE_is_NaN(sourceState(phase)%p(i)%deltaState(:,of))) + broken = any(IEEE_is_NaN(sourceState(ph)%p(so)%deltaState(:,of))) if(.not. broken) then - myOffset = sourceState(phase)%p(i)%offsetDeltaState - mySize = sourceState(phase)%p(i)%sizeDeltaState - sourceState(phase)%p(i)%state(myOffset + 1: myOffset + mySize,of) = & - sourceState(phase)%p(i)%state(myOffset + 1: myOffset + mySize,of) + sourceState(phase)%p(i)%deltaState(1:mySize,of) + myOffset = sourceState(ph)%p(so)%offsetDeltaState + mySize = sourceState(ph)%p(so)%sizeDeltaState + sourceState(ph)%p(so)%state(myOffset + 1: myOffset + mySize,of) = & + sourceState(ph)%p(so)%state(myOffset + 1: myOffset + mySize,of) + sourceState(ph)%p(so)%deltaState(1:mySize,of) endif end select sourceType @@ -1405,13 +1401,12 @@ subroutine integrateSourceState(co,ip,el) NiterationState, & !< number of iterations in state loop ph, & me, & - so, & - size_pl + so integer, dimension(maxval(phase_Nsources)) :: & size_so real(pReal) :: & zeta - real(pReal), dimension(max(constitutive_plasticity_maxSizeDotState,constitutive_source_maxSizeDotState)) :: & + real(pReal), dimension(constitutive_source_maxSizeDotState) :: & r ! state residuum real(pReal), dimension(constitutive_source_maxSizeDotState,2,maxval(phase_Nsources)) :: source_dotState logical :: & diff --git a/src/homogenization_mech.f90 b/src/homogenization_mech.f90 index b0641be07..7fff6f55b 100644 --- a/src/homogenization_mech.f90 +++ b/src/homogenization_mech.f90 @@ -4,6 +4,13 @@ !-------------------------------------------------------------------------------------------------- submodule(homogenization) homogenization_mech + + enum, bind(c); enumerator :: & + ELASTICITY_UNDEFINED_ID, & + ELASTICITY_HOOKE_ID, & + STIFFNESS_DEGRADATION_UNDEFINED_ID, & + STIFFNESS_DEGRADATION_DAMAGE_ID + end enum interface module subroutine mech_none_init From 8ac880c0addf6f8b523ccf39a890bb956bd4d729 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Wed, 23 Dec 2020 14:10:26 +0100 Subject: [PATCH 121/148] don't clutter with statements that are never used --- src/homogenization.f90 | 30 +----- src/homogenization_mech_RGC.f90 | 178 +------------------------------- 2 files changed, 4 insertions(+), 204 deletions(-) diff --git a/src/homogenization.f90 b/src/homogenization.f90 index c0568b048..d8119f740 100644 --- a/src/homogenization.f90 +++ b/src/homogenization.f90 @@ -48,20 +48,6 @@ module homogenization type(tNumerics) :: num - type :: tDebugOptions - logical :: & - basic, & - extensive, & - selective - integer :: & - element, & - ip, & - grain - end type tDebugOptions - - type(tDebugOptions) :: debugHomog - - !-------------------------------------------------------------------------------------------------- interface @@ -125,24 +111,10 @@ subroutine homogenization_init class (tNode) , pointer :: & num_homog, & - num_homogGeneric, & - debug_homogenization + num_homogGeneric print'(/,a)', ' <<<+- homogenization init -+>>>'; flush(IO_STDOUT) - debug_homogenization => config_debug%get('homogenization', defaultVal=emptyList) - debugHomog%basic = debug_homogenization%contains('basic') - debugHomog%extensive = debug_homogenization%contains('extensive') - debugHomog%selective = debug_homogenization%contains('selective') - debugHomog%element = config_debug%get_asInt('element',defaultVal = 1) - debugHomog%ip = config_debug%get_asInt('integrationpoint',defaultVal = 1) - debugHomog%grain = config_debug%get_asInt('grain',defaultVal = 1) - - if (debugHomog%grain < 1 & - .or. debugHomog%grain > homogenization_Nconstituents(material_homogenizationAt(debugHomog%element))) & - call IO_error(602,ext_msg='constituent', el=debugHomog%element, g=debugHomog%grain) - - num_homog => config_numerics%get('homogenization',defaultVal=emptyDict) num_homogGeneric => num_homog%get('generic',defaultVal=emptyDict) diff --git a/src/homogenization_mech_RGC.f90 b/src/homogenization_mech_RGC.f90 index 0a9d0ac92..a89008e96 100644 --- a/src/homogenization_mech_RGC.f90 +++ b/src/homogenization_mech_RGC.f90 @@ -18,8 +18,6 @@ submodule(homogenization:homogenization_mech) homogenization_mech_RGC real(pReal), dimension(:), allocatable :: & D_alpha, & a_g - integer :: & - of_debug = 0 character(len=pStringLen), allocatable, dimension(:) :: & output end type tParameters @@ -151,12 +149,6 @@ module subroutine mech_RGC_init(num_homogMech) st0 => state0(homogenization_typeInstance(h)), & dst => dependentState(homogenization_typeInstance(h))) -#ifdef DEBUG - if (h==material_homogenizationAt(debugHomog%element)) then - prm%of_debug = material_homogenizationMemberAt(debugHomog%ip,debugHomog%element) - endif -#endif - #if defined (__GFORTRAN__) prm%output = output_asStrings(homogMech) #else @@ -239,17 +231,6 @@ module subroutine mech_RGC_partitionDeformation(F,avgF,instance,of) F(i,j,iGrain) = F(i,j,iGrain) + aVect(i)*nVect(j) ! calculating deformation relaxations due to interface relaxation enddo F(1:3,1:3,iGrain) = F(1:3,1:3,iGrain) + avgF ! resulting relaxed deformation gradient - -#ifdef DEBUG - if (debugHomog%extensive) then - print'(a,i3)',' Deformation gradient of grain: ',iGrain - do i = 1,3 - print'(1x,3(e15.8,1x))',(F(i,j,iGrain), j = 1,3) - enddo - print*,' ' - flush(IO_STDOUT) - endif -#endif enddo end associate @@ -273,10 +254,6 @@ module procedure mech_RGC_updateState logical :: error real(pReal), dimension(:,:), allocatable :: tract,jmatrix,jnverse,smatrix,pmatrix,rmatrix real(pReal), dimension(:), allocatable :: resid,relax,p_relax,p_resid,drelax -#ifdef DEBUG - integer, dimension(3) :: stresLoc - integer, dimension(2) :: residLoc -#endif zeroTimeStep: if(dEq0(dt)) then mech_RGC_updateState = .true. ! pretend everything is fine and return @@ -303,16 +280,6 @@ module procedure mech_RGC_updateState relax = stt%relaxationVector(:,of) drelax = stt%relaxationVector(:,of) - st0%relaxationVector(:,of) -#ifdef DEBUG - if (debugHomog%extensive) then - print*, 'Obtained state: ' - do i = 1,size(stt%relaxationVector(:,of)) - print'(1x,2(e15.8,1x))', stt%relaxationVector(i,of) - enddo - print*,' ' - endif -#endif - !-------------------------------------------------------------------------------------------------- ! computing interface mismatch and stress penalty tensor for all interfaces of all grains call stressPenalty(R,NN,avgF,F,ip,el,instance,of) @@ -353,13 +320,6 @@ module procedure mech_RGC_updateState enddo enddo -#ifdef DEBUG - if (debugHomog%extensive) then - print'(a,i3)',' Traction at interface: ',iNum - print'(1x,3(e15.8,1x))',(tract(iNum,j), j = 1,3) - print*,' ' - endif -#endif enddo !-------------------------------------------------------------------------------------------------- @@ -367,29 +327,12 @@ module procedure mech_RGC_updateState stresMax = maxval(abs(P)) ! get the maximum of first Piola-Kirchhoff (material) stress residMax = maxval(abs(tract)) ! get the maximum of the residual -#ifdef DEBUG - if (debugHomog%extensive .and. prm%of_debug == of) then - stresLoc = maxloc(abs(P)) - residLoc = maxloc(abs(tract)) - print'(a,i2,1x,i4)',' RGC residual check ... ',ip,el - print'(a,e15.8,a,i3,a,i2,i2)', ' Max stress: ',stresMax, & - '@ grain ',stresLoc(3),' in component ',stresLoc(1),stresLoc(2) - print'(a,e15.8,a,i3,a,i2)',' Max residual: ',residMax, & - ' @ iface ',residLoc(1),' in direction ',residLoc(2) - flush(IO_STDOUT) - endif -#endif - mech_RGC_updateState = .false. !-------------------------------------------------------------------------------------------------- ! If convergence reached => done and happy if (residMax < num%rtol*stresMax .or. residMax < num%atol) then mech_RGC_updateState = .true. -#ifdef DEBUG - if (debugHomog%extensive .and. prm%of_debug == of) & - print*, '... done and happy'; flush(IO_STDOUT) -#endif !-------------------------------------------------------------------------------------------------- ! compute/update the state for postResult, i.e., all energy densities computed by time-integration @@ -406,41 +349,14 @@ module procedure mech_RGC_updateState dst%relaxationRate_avg(of) = sum(abs(drelax))/dt/real(3*nIntFaceTot,pReal) dst%relaxationRate_max(of) = maxval(abs(drelax))/dt -#ifdef DEBUG - if (debugHomog%extensive .and. prm%of_debug == of) then - print'(a,e15.8)', ' Constitutive work: ',stt%work(of) - print'(a,3(1x,e15.8))', ' Magnitude mismatch: ',dst%mismatch(1,of), & - dst%mismatch(2,of), & - dst%mismatch(3,of) - print'(a,e15.8)', ' Penalty energy: ', stt%penaltyEnergy(of) - print'(a,e15.8,/)', ' Volume discrepancy: ', dst%volumeDiscrepancy(of) - print'(a,e15.8)', ' Maximum relaxation rate: ', dst%relaxationRate_max(of) - print'(a,e15.8,/)', ' Average relaxation rate: ', dst%relaxationRate_avg(of) - flush(IO_STDOUT) - endif -#endif - return !-------------------------------------------------------------------------------------------------- ! if residual blows-up => done but unhappy elseif (residMax > num%relMax*stresMax .or. residMax > num%absMax) then ! try to restart when residual blows up exceeding maximum bound mech_RGC_updateState = [.true.,.false.] ! with direct cut-back - -#ifdef DEBUG - if (debugHomog%extensive .and. prm%of_debug == of) & - print'(a,/)', ' ... broken'; flush(IO_STDOUT) -#endif - return - - else ! proceed with computing the Jacobian and state update -#ifdef DEBUG - if (debugHomog%extensive .and. prm%of_debug == of) & - print'(a,/)', ' ... not yet done'; flush(IO_STDOUT) -#endif - - endif + endif !--------------------------------------------------------------------------------------------------- ! construct the global Jacobian matrix for updating the global relaxation vector array when @@ -492,17 +408,6 @@ module procedure mech_RGC_updateState enddo enddo -#ifdef DEBUG - if (debugHomog%extensive) then - print*, 'Jacobian matrix of stress' - do i = 1,3*nIntFaceTot - print'(1x,100(e11.4,1x))',(smatrix(i,j), j = 1,3*nIntFaceTot) - enddo - print*,' ' - flush(IO_STDOUT) - endif -#endif - !-------------------------------------------------------------------------------------------------- ! ... of the stress penalty tangent (mismatch penalty and volume penalty, computed using numerical ! perturbation method) "pmatrix" @@ -552,16 +457,6 @@ module procedure mech_RGC_updateState pmatrix(:,ipert) = p_resid/num%pPert enddo -#ifdef DEBUG - if (debugHomog%extensive) then - print*, 'Jacobian matrix of penalty' - do i = 1,3*nIntFaceTot - print'(1x,100(e11.4,1x))',(pmatrix(i,j), j = 1,3*nIntFaceTot) - enddo - print*,' ' - flush(IO_STDOUT) - endif -#endif !-------------------------------------------------------------------------------------------------- ! ... of the numerical viscosity traction "rmatrix" @@ -571,48 +466,16 @@ module procedure mech_RGC_updateState (abs(drelax(i))/(num%refRelaxRate*dt))**(num%viscPower - 1.0_pReal) ! only in the main diagonal term enddo -#ifdef DEBUG - if (debugHomog%extensive) then - print*, 'Jacobian matrix of penalty' - do i = 1,3*nIntFaceTot - print'(1x,100(e11.4,1x))',(rmatrix(i,j), j = 1,3*nIntFaceTot) - enddo - print*,' ' - flush(IO_STDOUT) - endif -#endif !-------------------------------------------------------------------------------------------------- ! The overall Jacobian matrix summarizing contributions of smatrix, pmatrix, rmatrix allocate(jmatrix(3*nIntFaceTot,3*nIntFaceTot)); jmatrix = smatrix + pmatrix + rmatrix -#ifdef DEBUG - if (debugHomog%extensive) then - print*, 'Jacobian matrix (total)' - do i = 1,3*nIntFaceTot - print'(1x,100(e11.4,1x))',(jmatrix(i,j), j = 1,3*nIntFaceTot) - enddo - print*,' ' - flush(IO_STDOUT) - endif -#endif - !-------------------------------------------------------------------------------------------------- ! computing the update of the state variable (relaxation vectors) using the Jacobian matrix allocate(jnverse(3*nIntFaceTot,3*nIntFaceTot),source=0.0_pReal) call math_invert(jnverse,error,jmatrix) -#ifdef DEBUG - if (debugHomog%extensive) then - print*, 'Jacobian inverse' - do i = 1,3*nIntFaceTot - print'(1x,100(e11.4,1x))',(jnverse(i,j), j = 1,3*nIntFaceTot) - enddo - print*,' ' - flush(IO_STDOUT) - endif -#endif - !-------------------------------------------------------------------------------------------------- ! calculate the state update (global relaxation vectors) for the next Newton-Raphson iteration drelax = 0.0_pReal @@ -629,17 +492,6 @@ module procedure mech_RGC_updateState !$OMP END CRITICAL (write2out) endif -#ifdef DEBUG - if (debugHomog%extensive) then - print*, 'Returned state: ' - do i = 1,size(stt%relaxationVector(:,of)) - print'(1x,2(e15.8,1x))', stt%relaxationVector(i,of) - enddo - print*,' ' - flush(IO_STDOUT) - endif -#endif - end associate contains @@ -676,12 +528,6 @@ module procedure mech_RGC_updateState associate(prm => param(instance)) -#ifdef DEBUG - if (debugHomog%extensive .and. prm%of_debug == of) then - print'(a,2(1x,i3))', ' Correction factor: ',ip,el - print*, surfCorr - endif -#endif !----------------------------------------------------------------------------------------------- ! computing the mismatch and penalty stress tensor of all grains @@ -717,13 +563,7 @@ module procedure mech_RGC_updateState enddo; enddo nDefNorm = max(nDefToler,sqrt(nDefNorm)) ! approximation to zero mismatch if mismatch is zero (singularity) nMis(abs(intFace(1)),iGrain) = nMis(abs(intFace(1)),iGrain) + nDefNorm ! total amount of mismatch experienced by the grain (at all six interfaces) -#ifdef DEBUG - if (debugHomog%extensive .and. prm%of_debug == of) then - print'(a,i2,a,i3)',' Mismatch to face: ',intFace(1),' neighbor grain: ',iGNghb - print*, transpose(nDef) - print'(a,e11.4)', ' with magnitude: ',nDefNorm - endif -#endif + !------------------------------------------------------------------------------------------- ! compute the stress penalty of all interfaces @@ -735,12 +575,7 @@ module procedure mech_RGC_updateState *tanh(nDefNorm/num%xSmoo) enddo; enddo;enddo; enddo enddo interfaceLoop -#ifdef DEBUG - if (debugHomog%extensive .and. prm%of_debug == of) then - print'(a,i2)', ' Penalty of grain: ',iGrain - print*, transpose(rPen(1:3,1:3,iGrain)) - endif -#endif + enddo grainLoop @@ -783,13 +618,6 @@ module procedure mech_RGC_updateState vPen(:,:,i) = -1.0_pReal/real(nGrain,pReal)*num%volDiscrMod*num%volDiscrPow/num%maxVolDiscr* & sign((abs(vDiscrep)/num%maxVolDiscr)**(num%volDiscrPow - 1.0),vDiscrep)* & gVol(i)*transpose(math_inv33(fDef(:,:,i))) - -#ifdef DEBUG - if (debugHomog%extensive .and. param(instance)%of_debug == of) then - print'(a,i2)',' Volume penalty of grain: ',i - print*, transpose(vPen(:,:,i)) - endif -#endif enddo end subroutine volumePenalty From be4616368b2caec351f438561f9c2c36ac627238 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Wed, 23 Dec 2020 14:24:44 +0100 Subject: [PATCH 122/148] new names --- src/homogenization.f90 | 140 ++++++++++++++++++++--------------------- 1 file changed, 70 insertions(+), 70 deletions(-) diff --git a/src/homogenization.f90 b/src/homogenization.f90 index d8119f740..00bb5fc6a 100644 --- a/src/homogenization.f90 +++ b/src/homogenization.f90 @@ -150,8 +150,8 @@ subroutine materialpoint_stressAndItsTangent(dt) integer :: & NiterationHomog, & NiterationMPstate, & - i, & !< integration point number - e, & !< element number + ip, & !< integration point number + el, & !< element number myNgrains, co real(pReal), dimension(discretization_nIPs,discretization_Nelems) :: & subFrac, & @@ -161,28 +161,28 @@ subroutine materialpoint_stressAndItsTangent(dt) converged logical, dimension(2,discretization_nIPs,discretization_Nelems) :: & doneAndHappy - integer :: m + integer :: ce !-------------------------------------------------------------------------------------------------- ! initialize restoration points - do e = FEsolving_execElem(1),FEsolving_execElem(2) - do i = FEsolving_execIP(1),FEsolving_execIP(2); + do el = FEsolving_execElem(1),FEsolving_execElem(2) + do ip = FEsolving_execIP(1),FEsolving_execIP(2); - call constitutive_initializeRestorationPoints(i,e) + call constitutive_initializeRestorationPoints(ip,el) - subFrac(i,e) = 0.0_pReal - converged(i,e) = .false. ! pretend failed step ... - subStep(i,e) = 1.0_pReal/num%subStepSizeHomog ! ... larger then the requested calculation - requested(i,e) = .true. ! everybody requires calculation + subFrac(ip,el) = 0.0_pReal + converged(ip,el) = .false. ! pretend failed step ... + subStep(ip,el) = 1.0_pReal/num%subStepSizeHomog ! ... larger then the requested calculation + requested(ip,el) = .true. ! everybody requires calculation - if (homogState(material_homogenizationAt(e))%sizeState > 0) & - homogState(material_homogenizationAt(e))%subState0(:,material_homogenizationMemberAt(i,e)) = & - homogState(material_homogenizationAt(e))%State0( :,material_homogenizationMemberAt(i,e)) + if (homogState(material_homogenizationAt(el))%sizeState > 0) & + homogState(material_homogenizationAt(el))%subState0(:,material_homogenizationMemberAt(ip,el)) = & + homogState(material_homogenizationAt(el))%State0( :,material_homogenizationMemberAt(ip,el)) - if (damageState(material_homogenizationAt(e))%sizeState > 0) & - damageState(material_homogenizationAt(e))%subState0(:,material_homogenizationMemberAt(i,e)) = & - damageState(material_homogenizationAt(e))%State0( :,material_homogenizationMemberAt(i,e)) + if (damageState(material_homogenizationAt(el))%sizeState > 0) & + damageState(material_homogenizationAt(el))%subState0(:,material_homogenizationMemberAt(ip,el)) = & + damageState(material_homogenizationAt(el))%State0( :,material_homogenizationMemberAt(ip,el)) enddo enddo @@ -192,93 +192,93 @@ subroutine materialpoint_stressAndItsTangent(dt) any(subStep(FEsolving_execIP(1):FEsolving_execIP(2),& FEsolving_execElem(1):FEsolving_execElem(2)) > num%subStepMinHomog)) - !$OMP PARALLEL DO PRIVATE(m,myNgrains,NiterationMPstate) - elementLooping1: do e = FEsolving_execElem(1),FEsolving_execElem(2) - myNgrains = homogenization_Nconstituents(material_homogenizationAt(e)) - IpLooping1: do i = FEsolving_execIP(1),FEsolving_execIP(2) + !$OMP PARALLEL DO PRIVATE(ce,myNgrains,NiterationMPstate) + elementLooping1: do el = FEsolving_execElem(1),FEsolving_execElem(2) + myNgrains = homogenization_Nconstituents(material_homogenizationAt(el)) + IpLooping1: do ip = FEsolving_execIP(1),FEsolving_execIP(2) - if (converged(i,e)) then - subFrac(i,e) = subFrac(i,e) + subStep(i,e) - subStep(i,e) = min(1.0_pReal-subFrac(i,e),num%stepIncreaseHomog*subStep(i,e)) ! introduce flexibility for step increase/acceleration + if (converged(ip,el)) then + subFrac(ip,el) = subFrac(ip,el) + subStep(ip,el) + subStep(ip,el) = min(1.0_pReal-subFrac(ip,el),num%stepIncreaseHomog*subStep(ip,el)) ! introduce flexibility for step increase/acceleration - steppingNeeded: if (subStep(i,e) > num%subStepMinHomog) then + steppingNeeded: if (subStep(ip,el) > num%subStepMinHomog) then ! wind forward grain starting point - call constitutive_windForward(i,e) + call constitutive_windForward(ip,el) - if(homogState(material_homogenizationAt(e))%sizeState > 0) & - homogState(material_homogenizationAt(e))%subState0(:,material_homogenizationMemberAt(i,e)) = & - homogState(material_homogenizationAt(e))%State (:,material_homogenizationMemberAt(i,e)) - if(damageState(material_homogenizationAt(e))%sizeState > 0) & - damageState(material_homogenizationAt(e))%subState0(:,material_homogenizationMemberAt(i,e)) = & - damageState(material_homogenizationAt(e))%State (:,material_homogenizationMemberAt(i,e)) + if(homogState(material_homogenizationAt(el))%sizeState > 0) & + homogState(material_homogenizationAt(el))%subState0(:,material_homogenizationMemberAt(ip,el)) = & + homogState(material_homogenizationAt(el))%State (:,material_homogenizationMemberAt(ip,el)) + if(damageState(material_homogenizationAt(el))%sizeState > 0) & + damageState(material_homogenizationAt(el))%subState0(:,material_homogenizationMemberAt(ip,el)) = & + damageState(material_homogenizationAt(el))%State (:,material_homogenizationMemberAt(ip,el)) endif steppingNeeded else - if ( (myNgrains == 1 .and. subStep(i,e) <= 1.0 ) .or. & ! single grain already tried internal subStepping in crystallite - num%subStepSizeHomog * subStep(i,e) <= num%subStepMinHomog ) then ! would require too small subStep + if ( (myNgrains == 1 .and. subStep(ip,el) <= 1.0 ) .or. & ! single grain already tried internal subStepping in crystallite + num%subStepSizeHomog * subStep(ip,el) <= num%subStepMinHomog ) then ! would require too small subStep ! cutback makes no sense if (.not. terminallyIll) then ! so first signals terminally ill... - print*, ' Integration point ', i,' at element ', e, ' terminally ill' + print*, ' Integration point ', ip,' at element ', el, ' terminally ill' endif terminallyIll = .true. ! ...and kills all others else ! cutback makes sense - subStep(i,e) = num%subStepSizeHomog * subStep(i,e) ! crystallite had severe trouble, so do a significant cutback + subStep(ip,el) = num%subStepSizeHomog * subStep(ip,el) ! crystallite had severe trouble, so do a significant cutback - call crystallite_restore(i,e,subStep(i,e) < 1.0_pReal) - call constitutive_restore(i,e) + call crystallite_restore(ip,el,subStep(ip,el) < 1.0_pReal) + call constitutive_restore(ip,el) - if(homogState(material_homogenizationAt(e))%sizeState > 0) & - homogState(material_homogenizationAt(e))%State( :,material_homogenizationMemberAt(i,e)) = & - homogState(material_homogenizationAt(e))%subState0(:,material_homogenizationMemberAt(i,e)) - if(damageState(material_homogenizationAt(e))%sizeState > 0) & - damageState(material_homogenizationAt(e))%State( :,material_homogenizationMemberAt(i,e)) = & - damageState(material_homogenizationAt(e))%subState0(:,material_homogenizationMemberAt(i,e)) + if(homogState(material_homogenizationAt(el))%sizeState > 0) & + homogState(material_homogenizationAt(el))%State( :,material_homogenizationMemberAt(ip,el)) = & + homogState(material_homogenizationAt(el))%subState0(:,material_homogenizationMemberAt(ip,el)) + if(damageState(material_homogenizationAt(el))%sizeState > 0) & + damageState(material_homogenizationAt(el))%State( :,material_homogenizationMemberAt(ip,el)) = & + damageState(material_homogenizationAt(el))%subState0(:,material_homogenizationMemberAt(ip,el)) endif endif - if (subStep(i,e) > num%subStepMinHomog) then - requested(i,e) = .true. - doneAndHappy(1:2,i,e) = [.false.,.true.] + if (subStep(ip,el) > num%subStepMinHomog) then + requested(ip,el) = .true. + doneAndHappy(1:2,ip,el) = [.false.,.true.] endif NiterationMPstate = 0 - convergenceLooping: do while (.not. terminallyIll .and. requested(i,e) & - .and. .not. doneAndHappy(1,i,e) & + convergenceLooping: do while (.not. terminallyIll .and. requested(ip,el) & + .and. .not. doneAndHappy(1,ip,el) & .and. NiterationMPstate < num%nMPstate) NiterationMPstate = NiterationMPstate + 1 !-------------------------------------------------------------------------------------------------- ! deformation partitioning - if(requested(i,e) .and. .not. doneAndHappy(1,i,e)) then ! requested but not yet done - m = (e-1)*discretization_nIPs + i - call mech_partition(homogenization_F0(1:3,1:3,m) & - + (homogenization_F(1:3,1:3,m)-homogenization_F0(1:3,1:3,m))& - *(subStep(i,e)+subFrac(i,e)), & - i,e) - crystallite_dt(1:myNgrains,i,e) = dt*subStep(i,e) ! propagate materialpoint dt to grains - converged(i,e) = .true. + if(requested(ip,el) .and. .not. doneAndHappy(1,ip,el)) then ! requested but not yet done + ce = (el-1)*discretization_nIPs + ip + call mech_partition(homogenization_F0(1:3,1:3,ce) & + + (homogenization_F(1:3,1:3,ce)-homogenization_F0(1:3,1:3,ce))& + *(subStep(ip,el)+subFrac(ip,el)), & + ip,el) + crystallite_dt(1:myNgrains,ip,el) = dt*subStep(ip,el) ! propagate materialpoint dt to grains + converged(ip,el) = .true. do co = 1, myNgrains - converged(i,e) = converged(i,e) .and. crystallite_stress(co,i,e) + converged(ip,el) = converged(ip,el) .and. crystallite_stress(co,ip,el) enddo endif - if (requested(i,e) .and. .not. doneAndHappy(1,i,e)) then - if (.not. converged(i,e)) then - doneAndHappy(1:2,i,e) = [.true.,.false.] + if (requested(ip,el) .and. .not. doneAndHappy(1,ip,el)) then + if (.not. converged(ip,el)) then + doneAndHappy(1:2,ip,el) = [.true.,.false.] else - m = (e-1)*discretization_nIPs + i - doneAndHappy(1:2,i,e) = updateState(dt*subStep(i,e), & - homogenization_F0(1:3,1:3,m) & - + (homogenization_F(1:3,1:3,m)-homogenization_F0(1:3,1:3,m)) & - *(subStep(i,e)+subFrac(i,e)), & - i,e) - converged(i,e) = all(doneAndHappy(1:2,i,e)) ! converged if done and happy + ce = (el-1)*discretization_nIPs + ip + doneAndHappy(1:2,ip,el) = updateState(dt*subStep(ip,el), & + homogenization_F0(1:3,1:3,ce) & + + (homogenization_F(1:3,1:3,ce)-homogenization_F0(1:3,1:3,ce)) & + *(subStep(ip,el)+subFrac(ip,el)), & + ip,el) + converged(ip,el) = all(doneAndHappy(1:2,ip,el)) ! converged if done and happy endif endif @@ -294,9 +294,9 @@ subroutine materialpoint_stressAndItsTangent(dt) if (.not. terminallyIll ) then call crystallite_orientations() ! calculate crystal orientations !$OMP PARALLEL DO - elementLooping3: do e = FEsolving_execElem(1),FEsolving_execElem(2) - IpLooping3: do i = FEsolving_execIP(1),FEsolving_execIP(2) - call mech_homogenize(i,e) + elementLooping3: do el = FEsolving_execElem(1),FEsolving_execElem(2) + IpLooping3: do ip = FEsolving_execIP(1),FEsolving_execIP(2) + call mech_homogenize(ip,el) enddo IpLooping3 enddo elementLooping3 !$OMP END PARALLEL DO From 12b1c7e641ae19672de94dbe7af04298eea3f9e8 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Wed, 23 Dec 2020 14:37:12 +0100 Subject: [PATCH 123/148] one loop is enough --- src/constitutive_mech.f90 | 7 +++++++ src/homogenization.f90 | 23 ++++++++++------------- src/homogenization_mech.f90 | 6 ------ 3 files changed, 17 insertions(+), 19 deletions(-) diff --git a/src/constitutive_mech.f90 b/src/constitutive_mech.f90 index 800e67b32..197169c7a 100644 --- a/src/constitutive_mech.f90 +++ b/src/constitutive_mech.f90 @@ -3,6 +3,13 @@ !---------------------------------------------------------------------------------------------------- submodule(constitutive) constitutive_mech + enum, bind(c); enumerator :: & + ELASTICITY_UNDEFINED_ID, & + ELASTICITY_HOOKE_ID, & + STIFFNESS_DEGRADATION_UNDEFINED_ID, & + STIFFNESS_DEGRADATION_DAMAGE_ID + end enum + integer(kind(ELASTICITY_undefined_ID)), dimension(:), allocatable :: & phase_elasticity !< elasticity of each phase integer(kind(SOURCE_undefined_ID)), dimension(:,:), allocatable :: & diff --git a/src/homogenization.f90 b/src/homogenization.f90 index 00bb5fc6a..8334e99b2 100644 --- a/src/homogenization.f90 +++ b/src/homogenization.f90 @@ -164,11 +164,13 @@ subroutine materialpoint_stressAndItsTangent(dt) integer :: ce -!-------------------------------------------------------------------------------------------------- -! initialize restoration points + +!$OMP PARALLEL DO PRIVATE(ce,myNgrains,NiterationMPstate,NiterationHomog) do el = FEsolving_execElem(1),FEsolving_execElem(2) do ip = FEsolving_execIP(1),FEsolving_execIP(2); +!-------------------------------------------------------------------------------------------------- +! initialize restoration points call constitutive_initializeRestorationPoints(ip,el) subFrac(ip,el) = 0.0_pReal @@ -183,19 +185,12 @@ subroutine materialpoint_stressAndItsTangent(dt) if (damageState(material_homogenizationAt(el))%sizeState > 0) & damageState(material_homogenizationAt(el))%subState0(:,material_homogenizationMemberAt(ip,el)) = & damageState(material_homogenizationAt(el))%State0( :,material_homogenizationMemberAt(ip,el)) - enddo - enddo NiterationHomog = 0 - cutBackLooping: do while (.not. terminallyIll .and. & - any(subStep(FEsolving_execIP(1):FEsolving_execIP(2),& - FEsolving_execElem(1):FEsolving_execElem(2)) > num%subStepMinHomog)) + cutBackLooping: do while (.not. terminallyIll .and. subStep(ip,el) > num%subStepMinHomog) - !$OMP PARALLEL DO PRIVATE(ce,myNgrains,NiterationMPstate) - elementLooping1: do el = FEsolving_execElem(1),FEsolving_execElem(2) myNgrains = homogenization_Nconstituents(material_homogenizationAt(el)) - IpLooping1: do ip = FEsolving_execIP(1),FEsolving_execIP(2) if (converged(ip,el)) then subFrac(ip,el) = subFrac(ip,el) + subStep(ip,el) @@ -283,14 +278,16 @@ subroutine materialpoint_stressAndItsTangent(dt) endif enddo convergenceLooping - enddo IpLooping1 - enddo elementLooping1 - !$OMP END PARALLEL DO + NiterationHomog = NiterationHomog + 1 enddo cutBackLooping + enddo + enddo + !$OMP END PARALLEL DO + if (.not. terminallyIll ) then call crystallite_orientations() ! calculate crystal orientations !$OMP PARALLEL DO diff --git a/src/homogenization_mech.f90 b/src/homogenization_mech.f90 index 7fff6f55b..56f1e554f 100644 --- a/src/homogenization_mech.f90 +++ b/src/homogenization_mech.f90 @@ -5,12 +5,6 @@ submodule(homogenization) homogenization_mech - enum, bind(c); enumerator :: & - ELASTICITY_UNDEFINED_ID, & - ELASTICITY_HOOKE_ID, & - STIFFNESS_DEGRADATION_UNDEFINED_ID, & - STIFFNESS_DEGRADATION_DAMAGE_ID - end enum interface module subroutine mech_none_init From 18458d34e969327714ad8f866663279b142275ff Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Wed, 23 Dec 2020 14:57:53 +0100 Subject: [PATCH 124/148] no global variables --- src/constitutive.f90 | 11 ++++------- src/homogenization.f90 | 3 +-- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/src/constitutive.f90 b/src/constitutive.f90 index c4b97d1bd..63f1efd3e 100644 --- a/src/constitutive.f90 +++ b/src/constitutive.f90 @@ -42,8 +42,6 @@ module constitutive KINEMATICS_SLIPPLANE_OPENING_ID, & KINEMATICS_THERMAL_EXPANSION_ID end enum - real(pReal), dimension(:,:,:), allocatable, public :: & - crystallite_dt !< requested time increment of each grain real(pReal), dimension(:,:,:), allocatable :: & crystallite_subdt !< substepped time increment of each grain type(rotation), dimension(:,:,:), allocatable :: & @@ -876,9 +874,7 @@ subroutine crystallite_init crystallite_subFp0,crystallite_subFi0, & source = crystallite_partitionedF) - allocate(crystallite_dt(cMax,iMax,eMax),source=0.0_pReal) - allocate(crystallite_subdt, & - source = crystallite_dt) + allocate(crystallite_subdt(cMax,iMax,eMax),source=0.0_pReal) allocate(crystallite_orientation(cMax,iMax,eMax)) @@ -995,8 +991,9 @@ end subroutine crystallite_init !-------------------------------------------------------------------------------------------------- !> @brief calculate stress (P) !-------------------------------------------------------------------------------------------------- -function crystallite_stress(co,ip,el) +function crystallite_stress(dt,co,ip,el) + real(pReal), intent(in) :: dt integer, intent(in) :: & co, & ip, & @@ -1094,7 +1091,7 @@ function crystallite_stress(co,ip,el) crystallite_Fe(1:3,1:3,co,ip,el) = matmul(crystallite_subF(1:3,1:3,co,ip,el), & math_inv33(matmul(constitutive_mech_Fi(ph)%data(1:3,1:3,me), & constitutive_mech_Fp(ph)%data(1:3,1:3,me)))) - crystallite_subdt(co,ip,el) = subStep * crystallite_dt(co,ip,el) + crystallite_subdt(co,ip,el) = subStep * dt crystallite_converged(co,ip,el) = .false. call integrateState(co,ip,el) call integrateSourceState(co,ip,el) diff --git a/src/homogenization.f90 b/src/homogenization.f90 index 8334e99b2..58311d6ad 100644 --- a/src/homogenization.f90 +++ b/src/homogenization.f90 @@ -255,10 +255,9 @@ subroutine materialpoint_stressAndItsTangent(dt) + (homogenization_F(1:3,1:3,ce)-homogenization_F0(1:3,1:3,ce))& *(subStep(ip,el)+subFrac(ip,el)), & ip,el) - crystallite_dt(1:myNgrains,ip,el) = dt*subStep(ip,el) ! propagate materialpoint dt to grains converged(ip,el) = .true. do co = 1, myNgrains - converged(ip,el) = converged(ip,el) .and. crystallite_stress(co,ip,el) + converged(ip,el) = converged(ip,el) .and. crystallite_stress(dt*subStep(ip,el),co,ip,el) enddo endif From ea25b22f13488e06a83a36a692e225ee9ebb1e1d Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Wed, 23 Dec 2020 15:03:03 +0100 Subject: [PATCH 125/148] standard names --- src/constitutive.f90 | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/src/constitutive.f90 b/src/constitutive.f90 index 63f1efd3e..ad6708d72 100644 --- a/src/constitutive.f90 +++ b/src/constitutive.f90 @@ -407,12 +407,13 @@ contains subroutine constitutive_init integer :: & - p, & !< counter in phase loop - s !< counter in source loop + ph, & !< counter in phase loop + so !< counter in source loop class (tNode), pointer :: & debug_constitutive, & phases + debug_constitutive => config_debug%get('constitutive', defaultVal=emptyList) debugConstitutive%basic = debug_constitutive%contains('basic') debugConstitutive%extensive = debug_constitutive%contains('extensive') @@ -423,26 +424,26 @@ subroutine constitutive_init !-------------------------------------------------------------------------------------------------- ! initialize constitutive laws + print'(/,a)', ' <<<+- constitutive init -+>>>'; flush(IO_STDOUT) call mech_init call damage_init call thermal_init - print'(/,a)', ' <<<+- constitutive init -+>>>'; flush(IO_STDOUT) phases => config_material%get('phase') constitutive_source_maxSizeDotState = 0 - PhaseLoop2:do p = 1,phases%length + PhaseLoop2:do ph = 1,phases%length !-------------------------------------------------------------------------------------------------- ! partition and initialize state - plasticState(p)%partitionedState0 = plasticState(p)%state0 - plasticState(p)%state = plasticState(p)%partitionedState0 - forall(s = 1:phase_Nsources(p)) - sourceState(p)%p(s)%partitionedState0 = sourceState(p)%p(s)%state0 - sourceState(p)%p(s)%state = sourceState(p)%p(s)%partitionedState0 + plasticState(ph)%partitionedState0 = plasticState(ph)%state0 + plasticState(ph)%state = plasticState(ph)%partitionedState0 + forall(so = 1:phase_Nsources(ph)) + sourceState(ph)%p(so)%partitionedState0 = sourceState(ph)%p(so)%state0 + sourceState(ph)%p(so)%state = sourceState(ph)%p(so)%partitionedState0 end forall constitutive_source_maxSizeDotState = max(constitutive_source_maxSizeDotState, & - maxval(sourceState(p)%p%sizeDotState)) + maxval(sourceState(ph)%p%sizeDotState)) enddo PhaseLoop2 constitutive_plasticity_maxSizeDotState = maxval(plasticState%sizeDotState) @@ -617,26 +618,26 @@ end subroutine constitutive_LiAndItsTangents !-------------------------------------------------------------------------------------------------- !> @brief contains the constitutive equation for calculating the rate of change of microstructure !-------------------------------------------------------------------------------------------------- -function constitutive_damage_collectDotState(S, co, ip, el,phase,of) result(broken) +function constitutive_damage_collectDotState(S, co, ip, el,ph,of) result(broken) integer, intent(in) :: & co, & !< component-ID of integration point ip, & !< integration point el, & !< element - phase, & + ph, & of real(pReal), intent(in), dimension(3,3) :: & S !< 2nd Piola Kirchhoff stress (vector notation) integer :: & - i !< counter in source loop + so !< counter in source loop logical :: broken broken = .false. - SourceLoop: do i = 1, phase_Nsources(phase) + SourceLoop: do so = 1, phase_Nsources(ph) - sourceType: select case (phase_source(i,phase)) + sourceType: select case (phase_source(so,ph)) case (SOURCE_damage_anisoBrittle_ID) sourceType call source_damage_anisoBrittle_dotState(S, co, ip, el) ! correct stress? @@ -649,7 +650,7 @@ function constitutive_damage_collectDotState(S, co, ip, el,phase,of) result(brok end select sourceType - broken = broken .or. any(IEEE_is_NaN(sourceState(phase)%p(i)%dotState(:,of))) + broken = broken .or. any(IEEE_is_NaN(sourceState(ph)%p(so)%dotState(:,of))) enddo SourceLoop From 895cad6506d8cf1b25bf97e67f9cfe177f454bf7 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Wed, 23 Dec 2020 17:14:26 +0100 Subject: [PATCH 126/148] only needed per point --- src/homogenization.f90 | 70 ++++++++++++++++++++---------------------- 1 file changed, 34 insertions(+), 36 deletions(-) diff --git a/src/homogenization.f90 b/src/homogenization.f90 index 58311d6ad..fba0c4f45 100644 --- a/src/homogenization.f90 +++ b/src/homogenization.f90 @@ -152,31 +152,29 @@ subroutine materialpoint_stressAndItsTangent(dt) NiterationMPstate, & ip, & !< integration point number el, & !< element number - myNgrains, co - real(pReal), dimension(discretization_nIPs,discretization_Nelems) :: & + myNgrains, co, ce + real(pReal) :: & subFrac, & subStep - logical, dimension(discretization_nIPs,discretization_Nelems) :: & + logical :: & requested, & converged - logical, dimension(2,discretization_nIPs,discretization_Nelems) :: & + logical, dimension(2) :: & doneAndHappy - integer :: ce - -!$OMP PARALLEL DO PRIVATE(ce,myNgrains,NiterationMPstate,NiterationHomog) +!$OMP PARALLEL DO PRIVATE(ce,myNgrains,NiterationMPstate,NiterationHomog,subFrac,converged,subStep,requested,doneAndHappy) do el = FEsolving_execElem(1),FEsolving_execElem(2) - do ip = FEsolving_execIP(1),FEsolving_execIP(2); + do ip = FEsolving_execIP(1),FEsolving_execIP(2) !-------------------------------------------------------------------------------------------------- ! initialize restoration points call constitutive_initializeRestorationPoints(ip,el) - subFrac(ip,el) = 0.0_pReal - converged(ip,el) = .false. ! pretend failed step ... - subStep(ip,el) = 1.0_pReal/num%subStepSizeHomog ! ... larger then the requested calculation - requested(ip,el) = .true. ! everybody requires calculation + subFrac = 0.0_pReal + converged = .false. ! pretend failed step ... + subStep = 1.0_pReal/num%subStepSizeHomog ! ... larger then the requested calculation + requested = .true. ! everybody requires calculation if (homogState(material_homogenizationAt(el))%sizeState > 0) & homogState(material_homogenizationAt(el))%subState0(:,material_homogenizationMemberAt(ip,el)) = & @@ -188,15 +186,15 @@ subroutine materialpoint_stressAndItsTangent(dt) NiterationHomog = 0 - cutBackLooping: do while (.not. terminallyIll .and. subStep(ip,el) > num%subStepMinHomog) + cutBackLooping: do while (.not. terminallyIll .and. subStep > num%subStepMinHomog) myNgrains = homogenization_Nconstituents(material_homogenizationAt(el)) - if (converged(ip,el)) then - subFrac(ip,el) = subFrac(ip,el) + subStep(ip,el) - subStep(ip,el) = min(1.0_pReal-subFrac(ip,el),num%stepIncreaseHomog*subStep(ip,el)) ! introduce flexibility for step increase/acceleration + if (converged) then + subFrac = subFrac + subStep + subStep = min(1.0_pReal-subFrac,num%stepIncreaseHomog*subStep) ! introduce flexibility for step increase/acceleration - steppingNeeded: if (subStep(ip,el) > num%subStepMinHomog) then + steppingNeeded: if (subStep > num%subStepMinHomog) then ! wind forward grain starting point call constitutive_windForward(ip,el) @@ -211,17 +209,17 @@ subroutine materialpoint_stressAndItsTangent(dt) endif steppingNeeded else - if ( (myNgrains == 1 .and. subStep(ip,el) <= 1.0 ) .or. & ! single grain already tried internal subStepping in crystallite - num%subStepSizeHomog * subStep(ip,el) <= num%subStepMinHomog ) then ! would require too small subStep + if ( (myNgrains == 1 .and. subStep <= 1.0 ) .or. & ! single grain already tried internal subStepping in crystallite + num%subStepSizeHomog * subStep <= num%subStepMinHomog ) then ! would require too small subStep ! cutback makes no sense if (.not. terminallyIll) then ! so first signals terminally ill... print*, ' Integration point ', ip,' at element ', el, ' terminally ill' endif terminallyIll = .true. ! ...and kills all others else ! cutback makes sense - subStep(ip,el) = num%subStepSizeHomog * subStep(ip,el) ! crystallite had severe trouble, so do a significant cutback + subStep = num%subStepSizeHomog * subStep ! crystallite had severe trouble, so do a significant cutback - call crystallite_restore(ip,el,subStep(ip,el) < 1.0_pReal) + call crystallite_restore(ip,el,subStep < 1.0_pReal) call constitutive_restore(ip,el) if(homogState(material_homogenizationAt(el))%sizeState > 0) & @@ -233,46 +231,46 @@ subroutine materialpoint_stressAndItsTangent(dt) endif endif - if (subStep(ip,el) > num%subStepMinHomog) then - requested(ip,el) = .true. - doneAndHappy(1:2,ip,el) = [.false.,.true.] + if (subStep > num%subStepMinHomog) then + requested = .true. + doneAndHappy = [.false.,.true.] endif NiterationMPstate = 0 - convergenceLooping: do while (.not. terminallyIll .and. requested(ip,el) & - .and. .not. doneAndHappy(1,ip,el) & + convergenceLooping: do while (.not. terminallyIll .and. requested & + .and. .not. doneAndHappy(1) & .and. NiterationMPstate < num%nMPstate) NiterationMPstate = NiterationMPstate + 1 !-------------------------------------------------------------------------------------------------- ! deformation partitioning - if(requested(ip,el) .and. .not. doneAndHappy(1,ip,el)) then ! requested but not yet done + if(requested .and. .not. doneAndHappy(1)) then ! requested but not yet done ce = (el-1)*discretization_nIPs + ip call mech_partition(homogenization_F0(1:3,1:3,ce) & + (homogenization_F(1:3,1:3,ce)-homogenization_F0(1:3,1:3,ce))& - *(subStep(ip,el)+subFrac(ip,el)), & + *(subStep+subFrac), & ip,el) - converged(ip,el) = .true. + converged = .true. do co = 1, myNgrains - converged(ip,el) = converged(ip,el) .and. crystallite_stress(dt*subStep(ip,el),co,ip,el) + converged = converged .and. crystallite_stress(dt*subStep,co,ip,el) enddo endif - if (requested(ip,el) .and. .not. doneAndHappy(1,ip,el)) then - if (.not. converged(ip,el)) then - doneAndHappy(1:2,ip,el) = [.true.,.false.] + if (requested .and. .not. doneAndHappy(1)) then + if (.not. converged) then + doneAndHappy = [.true.,.false.] else ce = (el-1)*discretization_nIPs + ip - doneAndHappy(1:2,ip,el) = updateState(dt*subStep(ip,el), & + doneAndHappy = updateState(dt*subStep, & homogenization_F0(1:3,1:3,ce) & + (homogenization_F(1:3,1:3,ce)-homogenization_F0(1:3,1:3,ce)) & - *(subStep(ip,el)+subFrac(ip,el)), & + *(subStep+subFrac), & ip,el) - converged(ip,el) = all(doneAndHappy(1:2,ip,el)) ! converged if done and happy + converged = all(doneAndHappy) endif endif From 36affc93bf0bc2ecc96727ae3dc9837dc545000b Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Wed, 23 Dec 2020 17:30:19 +0100 Subject: [PATCH 127/148] mech is responsible for stiffness --- src/constitutive.f90 | 61 ++++++++++++++++++--------------------- src/constitutive_mech.f90 | 34 +++++++++++++++++++++- 2 files changed, 61 insertions(+), 34 deletions(-) diff --git a/src/constitutive.f90 b/src/constitutive.f90 index ad6708d72..adb00f1c6 100644 --- a/src/constitutive.f90 +++ b/src/constitutive.f90 @@ -21,6 +21,7 @@ module constitutive implicit none private + enum, bind(c); enumerator :: & PLASTICITY_UNDEFINED_ID, & PLASTICITY_NONE_ID, & @@ -118,7 +119,7 @@ module constitutive procedure(integrateStateFPI), pointer :: integrateState - integer(kind(PLASTICITY_undefined_ID)), dimension(:), allocatable :: & + integer(kind(PLASTICITY_undefined_ID)), dimension(:), allocatable, public :: & phase_plasticity !< plasticity of each phase integer(kind(SOURCE_undefined_ID)), dimension(:,:), allocatable :: & @@ -186,6 +187,11 @@ module constitutive ! == cleaned:end =================================================================================== + module function constitutive_homogenizedC(co,ip,el) result(C) + integer, intent(in) :: co, ip, el + real(pReal), dimension(6,6) :: C + end function constitutive_homogenizedC + module subroutine source_damage_anisoBrittle_dotState(S, co, ip, el) integer, intent(in) :: & co, & !< component-ID of integration point @@ -240,14 +246,7 @@ module constitutive dTDot_dT end subroutine constitutive_thermal_getRateAndItsTangents - module function plastic_dislotwin_homogenizedC(co,ip,el) result(homogenizedC) - real(pReal), dimension(6,6) :: & - homogenizedC - integer, intent(in) :: & - co, & !< component-ID of integration point - ip, & !< integration point - el !< element - end function plastic_dislotwin_homogenizedC + module subroutine plastic_nonlocal_updateCompatibility(orientation,instance,i,e) integer, intent(in) :: & @@ -396,7 +395,26 @@ module constitutive crystallite_restartRead, & constitutive_initializeRestorationPoints, & constitutive_windForward, & - crystallite_restore + crystallite_restore, & + PLASTICITY_UNDEFINED_ID, & + PLASTICITY_NONE_ID, & + PLASTICITY_ISOTROPIC_ID, & + PLASTICITY_PHENOPOWERLAW_ID, & + PLASTICITY_KINEHARDENING_ID, & + PLASTICITY_DISLOTWIN_ID, & + PLASTICITY_DISLOTUNGSTEN_ID, & + PLASTICITY_NONLOCAL_ID, & + SOURCE_UNDEFINED_ID ,& + SOURCE_THERMAL_DISSIPATION_ID, & + SOURCE_THERMAL_EXTERNALHEAT_ID, & + SOURCE_DAMAGE_ISOBRITTLE_ID, & + SOURCE_DAMAGE_ISODUCTILE_ID, & + SOURCE_DAMAGE_ANISOBRITTLE_ID, & + SOURCE_DAMAGE_ANISODUCTILE_ID, & + KINEMATICS_UNDEFINED_ID ,& + KINEMATICS_CLEAVAGE_OPENING_ID, & + KINEMATICS_SLIPPLANE_OPENING_ID, & + KINEMATICS_THERMAL_EXPANSION_ID contains @@ -512,29 +530,6 @@ function kinematics_active(kinematics_label,kinematics_length) result(active_ki end function kinematics_active -!-------------------------------------------------------------------------------------------------- -!> @brief returns the homogenize elasticity matrix -!> ToDo: homogenizedC66 would be more consistent -!-------------------------------------------------------------------------------------------------- -function constitutive_homogenizedC(co,ip,el) - - real(pReal), dimension(6,6) :: & - constitutive_homogenizedC - integer, intent(in) :: & - co, & !< component-ID of integration point - ip, & !< integration point - el !< element - - plasticityType: select case (phase_plasticity(material_phaseAt(co,el))) - case (PLASTICITY_DISLOTWIN_ID) plasticityType - constitutive_homogenizedC = plastic_dislotwin_homogenizedC(co,ip,el) - case default plasticityType - constitutive_homogenizedC = lattice_C66(1:6,1:6,material_phaseAt(co,el)) - end select plasticityType - -end function constitutive_homogenizedC - - !-------------------------------------------------------------------------------------------------- !> @brief contains the constitutive equation for calculating the velocity gradient ! ToDo: MD: S is Mi? diff --git a/src/constitutive_mech.f90 b/src/constitutive_mech.f90 index 197169c7a..b8e2a5b5a 100644 --- a/src/constitutive_mech.f90 +++ b/src/constitutive_mech.f90 @@ -9,7 +9,7 @@ submodule(constitutive) constitutive_mech STIFFNESS_DEGRADATION_UNDEFINED_ID, & STIFFNESS_DEGRADATION_DAMAGE_ID end enum - + integer(kind(ELASTICITY_undefined_ID)), dimension(:), allocatable :: & phase_elasticity !< elasticity of each phase integer(kind(SOURCE_undefined_ID)), dimension(:,:), allocatable :: & @@ -273,6 +273,15 @@ submodule(constitutive) constitutive_mech character(len=*), intent(in) :: group end subroutine plastic_nonlocal_results + module function plastic_dislotwin_homogenizedC(co,ip,el) result(homogenizedC) + real(pReal), dimension(6,6) :: & + homogenizedC + integer, intent(in) :: & + co, & !< component-ID of integration point + ip, & !< integration point + el !< element + end function plastic_dislotwin_homogenizedC + end interface type :: tOutput !< new requested output (per phase) @@ -1449,5 +1458,28 @@ module subroutine constitutive_mech_forward() end subroutine constitutive_mech_forward + + +!-------------------------------------------------------------------------------------------------- +!> @brief returns the homogenize elasticity matrix +!> ToDo: homogenizedC66 would be more consistent +!-------------------------------------------------------------------------------------------------- +module function constitutive_homogenizedC(co,ip,el) result(C) + + real(pReal), dimension(6,6) :: C + integer, intent(in) :: & + co, & !< component-ID of integration point + ip, & !< integration point + el !< element + + plasticityType: select case (phase_plasticity(material_phaseAt(co,el))) + case (PLASTICITY_DISLOTWIN_ID) plasticityType + C = plastic_dislotwin_homogenizedC(co,ip,el) + case default plasticityType + C = lattice_C66(1:6,1:6,material_phaseAt(co,el)) + end select plasticityType + +end function constitutive_homogenizedC + end submodule constitutive_mech From 935b531d271e9e6e1060e2b9a5fbbf0e5b45f95e Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Thu, 24 Dec 2020 08:53:02 +0100 Subject: [PATCH 128/148] cleaning+renaming --- src/constitutive.f90 | 102 ++++++++++++++++++-------------------- src/constitutive_mech.f90 | 68 ++++++++++++------------- 2 files changed, 80 insertions(+), 90 deletions(-) diff --git a/src/constitutive.f90 b/src/constitutive.f90 index adb00f1c6..4e29f3f96 100644 --- a/src/constitutive.f90 +++ b/src/constitutive.f90 @@ -973,8 +973,7 @@ subroutine crystallite_init do co = 1,homogenization_Nconstituents(material_homogenizationAt(el)) ph = material_phaseAt(co,el) me = material_phaseMemberAt(co,ip,el) - call constitutive_plastic_dependentState(crystallite_partitionedF0(1:3,1:3,co,ip,el), & - co,ip,el) ! update dependent state variables to be consistent with basic states + call constitutive_plastic_dependentState(crystallite_partitionedF0(1:3,1:3,co,ip,el),co,ip,el) ! update dependent state variables to be consistent with basic states enddo enddo enddo @@ -1035,66 +1034,63 @@ function crystallite_stress(dt,co,ip,el) !-------------------------------------------------------------------------------------------------- ! wind forward - if (crystallite_converged(co,ip,el)) then - formerSubStep = subStep - subFrac = subFrac + subStep - subStep = min(1.0_pReal - subFrac, num%stepIncreaseCryst * subStep) + if (crystallite_converged(co,ip,el)) then + formerSubStep = subStep + subFrac = subFrac + subStep + subStep = min(1.0_pReal - subFrac, num%stepIncreaseCryst * subStep) - todo = subStep > 0.0_pReal ! still time left to integrate on? - - if (todo) then - crystallite_subF0 (1:3,1:3,co,ip,el) = crystallite_subF(1:3,1:3,co,ip,el) - subLp0 = crystallite_Lp (1:3,1:3,co,ip,el) - subLi0 = constitutive_mech_Li(ph)%data(1:3,1:3,me) - crystallite_subFp0(1:3,1:3,co,ip,el) = constitutive_mech_Fp(ph)%data(1:3,1:3,me) - crystallite_subFi0(1:3,1:3,co,ip,el) = constitutive_mech_Fi(ph)%data(1:3,1:3,me) - plasticState( material_phaseAt(co,el))%subState0(:,material_phaseMemberAt(co,ip,el)) & - = plasticState(material_phaseAt(co,el))%state( :,material_phaseMemberAt(co,ip,el)) - do s = 1, phase_Nsources(material_phaseAt(co,el)) - sourceState( material_phaseAt(co,el))%p(s)%subState0(:,material_phaseMemberAt(co,ip,el)) & - = sourceState(material_phaseAt(co,el))%p(s)%state( :,material_phaseMemberAt(co,ip,el)) - enddo - endif + todo = subStep > 0.0_pReal ! still time left to integrate on? + if (todo) then + crystallite_subF0 (1:3,1:3,co,ip,el) = crystallite_subF(1:3,1:3,co,ip,el) + subLp0 = crystallite_Lp (1:3,1:3,co,ip,el) + subLi0 = constitutive_mech_Li(ph)%data(1:3,1:3,me) + crystallite_subFp0(1:3,1:3,co,ip,el) = constitutive_mech_Fp(ph)%data(1:3,1:3,me) + crystallite_subFi0(1:3,1:3,co,ip,el) = constitutive_mech_Fi(ph)%data(1:3,1:3,me) + plasticState( material_phaseAt(co,el))%subState0(:,material_phaseMemberAt(co,ip,el)) & + = plasticState(material_phaseAt(co,el))%state( :,material_phaseMemberAt(co,ip,el)) + do s = 1, phase_Nsources(material_phaseAt(co,el)) + sourceState( material_phaseAt(co,el))%p(s)%subState0(:,material_phaseMemberAt(co,ip,el)) & + = sourceState(material_phaseAt(co,el))%p(s)%state( :,material_phaseMemberAt(co,ip,el)) + enddo + endif !-------------------------------------------------------------------------------------------------- ! cut back (reduced time and restore) - else - subStep = num%subStepSizeCryst * subStep - constitutive_mech_Fp(ph)%data(1:3,1:3,me) = crystallite_subFp0(1:3,1:3,co,ip,el) - constitutive_mech_Fi(ph)%data(1:3,1:3,me) = crystallite_subFi0(1:3,1:3,co,ip,el) - crystallite_S (1:3,1:3,co,ip,el) = crystallite_S0 (1:3,1:3,co,ip,el) - if (subStep < 1.0_pReal) then ! actual (not initial) cutback - crystallite_Lp (1:3,1:3,co,ip,el) = subLp0 - constitutive_mech_Li(ph)%data(1:3,1:3,me) = subLi0 - endif - plasticState (material_phaseAt(co,el))%state( :,material_phaseMemberAt(co,ip,el)) & - = plasticState(material_phaseAt(co,el))%subState0(:,material_phaseMemberAt(co,ip,el)) - do s = 1, phase_Nsources(material_phaseAt(co,el)) - sourceState( material_phaseAt(co,el))%p(s)%state( :,material_phaseMemberAt(co,ip,el)) & - = sourceState(material_phaseAt(co,el))%p(s)%subState0(:,material_phaseMemberAt(co,ip,el)) - enddo + else + subStep = num%subStepSizeCryst * subStep + constitutive_mech_Fp(ph)%data(1:3,1:3,me) = crystallite_subFp0(1:3,1:3,co,ip,el) + constitutive_mech_Fi(ph)%data(1:3,1:3,me) = crystallite_subFi0(1:3,1:3,co,ip,el) + crystallite_S (1:3,1:3,co,ip,el) = crystallite_S0 (1:3,1:3,co,ip,el) + if (subStep < 1.0_pReal) then ! actual (not initial) cutback + crystallite_Lp (1:3,1:3,co,ip,el) = subLp0 + constitutive_mech_Li(ph)%data(1:3,1:3,me) = subLi0 + endif + plasticState (material_phaseAt(co,el))%state( :,material_phaseMemberAt(co,ip,el)) & + = plasticState(material_phaseAt(co,el))%subState0(:,material_phaseMemberAt(co,ip,el)) + do s = 1, phase_Nsources(material_phaseAt(co,el)) + sourceState( material_phaseAt(co,el))%p(s)%state( :,material_phaseMemberAt(co,ip,el)) & + = sourceState(material_phaseAt(co,el))%p(s)%subState0(:,material_phaseMemberAt(co,ip,el)) + enddo - ! cant restore dotState here, since not yet calculated in first cutback after initialization - todo = subStep > num%subStepMinCryst ! still on track or already done (beyond repair) - endif + ! cant restore dotState here, since not yet calculated in first cutback after initialization + todo = subStep > num%subStepMinCryst ! still on track or already done (beyond repair) + endif !-------------------------------------------------------------------------------------------------- ! prepare for integration - if (todo) then - crystallite_subF(1:3,1:3,co,ip,el) = crystallite_subF0(1:3,1:3,co,ip,el) & - + subStep *( crystallite_partitionedF (1:3,1:3,co,ip,el) & - -crystallite_partitionedF0(1:3,1:3,co,ip,el)) - crystallite_Fe(1:3,1:3,co,ip,el) = matmul(crystallite_subF(1:3,1:3,co,ip,el), & - math_inv33(matmul(constitutive_mech_Fi(ph)%data(1:3,1:3,me), & - constitutive_mech_Fp(ph)%data(1:3,1:3,me)))) - crystallite_subdt(co,ip,el) = subStep * dt - crystallite_converged(co,ip,el) = .false. - call integrateState(co,ip,el) - call integrateSourceState(co,ip,el) - endif + if (todo) then + crystallite_subF(1:3,1:3,co,ip,el) = crystallite_subF0(1:3,1:3,co,ip,el) & + + subStep *( crystallite_partitionedF (1:3,1:3,co,ip,el) & + -crystallite_partitionedF0(1:3,1:3,co,ip,el)) + crystallite_Fe(1:3,1:3,co,ip,el) = matmul(crystallite_subF(1:3,1:3,co,ip,el), & + math_inv33(matmul(constitutive_mech_Fi(ph)%data(1:3,1:3,me), & + constitutive_mech_Fp(ph)%data(1:3,1:3,me)))) + crystallite_subdt(co,ip,el) = subStep * dt + crystallite_converged(co,ip,el) = .false. + call integrateState(co,ip,el) + call integrateSourceState(co,ip,el) + endif - if (.not. crystallite_converged(co,ip,el) .and. subStep > num%subStepMinCryst) & ! do not try non-converged but fully cutbacked any further - todo = .true. enddo cutbackLooping ! return whether converged or not diff --git a/src/constitutive_mech.f90 b/src/constitutive_mech.f90 index b8e2a5b5a..6a60b4ade 100644 --- a/src/constitutive_mech.f90 +++ b/src/constitutive_mech.f90 @@ -791,6 +791,8 @@ function integrateStress(co,ip,el,timeFraction) result(broken) o, & p, & m, & + ph, & + me, & jacoCounterLp, & jacoCounterLi ! counters to check for Jacobian update logical :: error,broken @@ -808,11 +810,11 @@ function integrateStress(co,ip,el,timeFraction) result(broken) call constitutive_plastic_dependentState(crystallite_partitionedF(1:3,1:3,co,ip,el),co,ip,el) - p = material_phaseAt(co,el) - m = material_phaseMemberAt(co,ip,el) + ph = material_phaseAt(co,el) + me = material_phaseMemberAt(co,ip,el) Lpguess = crystallite_Lp(1:3,1:3,co,ip,el) ! take as first guess - Liguess = constitutive_mech_Li(p)%data(1:3,1:3,m) ! take as first guess + Liguess = constitutive_mech_Li(ph)%data(1:3,1:3,me) ! take as first guess call math_invert33(invFp_current,devNull,error,crystallite_subFp0(1:3,1:3,co,ip,el)) if (error) return ! error @@ -941,15 +943,12 @@ function integrateStress(co,ip,el,timeFraction) result(broken) call math_invert33(Fp_new,devNull,error,invFp_new) if (error) return ! error - p = material_phaseAt(co,el) - m = material_phaseMemberAt(co,ip,el) - crystallite_P (1:3,1:3,co,ip,el) = matmul(matmul(F,invFp_new),matmul(S,transpose(invFp_new))) crystallite_S (1:3,1:3,co,ip,el) = S crystallite_Lp (1:3,1:3,co,ip,el) = Lpguess - constitutive_mech_Li(p)%data(1:3,1:3,m) = Liguess - constitutive_mech_Fp(p)%data(1:3,1:3,m) = Fp_new / math_det33(Fp_new)**(1.0_pReal/3.0_pReal) ! regularize - constitutive_mech_Fi(p)%data(1:3,1:3,m) = Fi_new + constitutive_mech_Li(ph)%data(1:3,1:3,me) = Liguess + constitutive_mech_Fp(ph)%data(1:3,1:3,me) = Fp_new / math_det33(Fp_new)**(1.0_pReal/3.0_pReal) ! regularize + constitutive_mech_Fi(ph)%data(1:3,1:3,me) = Fi_new crystallite_Fe (1:3,1:3,co,ip,el) = matmul(matmul(F,invFp_new),invFi_new) broken = .false. @@ -970,17 +969,13 @@ module subroutine integrateStateFPI(co,ip,el) NiterationState, & !< number of iterations in state loop ph, & me, & - s, & size_pl - integer, dimension(maxval(phase_Nsources)) :: & - size_so real(pReal) :: & zeta - real(pReal), dimension(max(constitutive_plasticity_maxSizeDotState,constitutive_source_maxSizeDotState)) :: & + real(pReal), dimension(constitutive_plasticity_maxSizeDotState) :: & r ! state residuum real(pReal), dimension(constitutive_plasticity_maxSizeDotState,2) :: & plastic_dotState - real(pReal), dimension(constitutive_source_maxSizeDotState,2,maxval(phase_Nsources)) :: source_dotState logical :: & broken @@ -1199,10 +1194,10 @@ end subroutine integrateStateRKCK45 !> @brief Integrate state (including stress integration) with an explicit Runge-Kutta method or an !! embedded explicit Runge-Kutta method !-------------------------------------------------------------------------------------------------- -subroutine integrateStateRK(co,ip,el,A,B,CC,DB) +subroutine integrateStateRK(co,ip,el,A,B,C,DB) real(pReal), dimension(:,:), intent(in) :: A - real(pReal), dimension(:), intent(in) :: B, CC + real(pReal), dimension(:), intent(in) :: B, C real(pReal), dimension(:), intent(in), optional :: DB integer, intent(in) :: & el, & !< element index in element loop @@ -1242,10 +1237,10 @@ subroutine integrateStateRK(co,ip,el,A,B,CC,DB) + plasticState(ph)%dotState (1:sizeDotState,me) & * crystallite_subdt(co,ip,el) - broken = integrateStress(co,ip,el,CC(stage)) + broken = integrateStress(co,ip,el,C(stage)) if(broken) exit - broken = mech_collectDotState(crystallite_subdt(co,ip,el)*CC(stage), co,ip,el,ph,me) + broken = mech_collectDotState(crystallite_subdt(co,ip,el)*C(stage), co,ip,el,ph,me) if(broken) exit enddo @@ -1277,7 +1272,6 @@ subroutine integrateStateRK(co,ip,el,A,B,CC,DB) end subroutine integrateStateRK - !-------------------------------------------------------------------------------------------------- !> @brief writes crystallite results to HDF5 output file !-------------------------------------------------------------------------------------------------- @@ -1354,22 +1348,22 @@ subroutine crystallite_results(group,ph) !------------------------------------------------------------------------------------------------ !> @brief select tensors for output !------------------------------------------------------------------------------------------------ - function select_tensors(dataset,instance) + function select_tensors(dataset,ph) - integer, intent(in) :: instance + integer, intent(in) :: ph real(pReal), dimension(:,:,:,:,:), intent(in) :: dataset real(pReal), allocatable, dimension(:,:,:) :: select_tensors - integer :: e,i,c,j + integer :: el,ip,co,j - allocate(select_tensors(3,3,count(material_phaseAt==instance)*discretization_nIPs)) + allocate(select_tensors(3,3,count(material_phaseAt==ph)*discretization_nIPs)) j=0 - do e = 1, size(material_phaseAt,2) - do i = 1, discretization_nIPs - do c = 1, size(material_phaseAt,1) !ToDo: this needs to be changed for varying Ngrains - if (material_phaseAt(c,e) == instance) then + do el = 1, size(material_phaseAt,2) + do ip = 1, discretization_nIPs + do co = 1, size(material_phaseAt,1) !ToDo: this needs to be changed for varying Ngrains + if (material_phaseAt(co,el) == ph) then j = j + 1 - select_tensors(1:3,1:3,j) = dataset(1:3,1:3,c,i,e) + select_tensors(1:3,1:3,j) = dataset(1:3,1:3,co,ip,el) endif enddo enddo @@ -1381,22 +1375,22 @@ subroutine crystallite_results(group,ph) !-------------------------------------------------------------------------------------------------- !> @brief select rotations for output !-------------------------------------------------------------------------------------------------- - function select_rotations(dataset,instance) + function select_rotations(dataset,ph) - integer, intent(in) :: instance + integer, intent(in) :: ph type(rotation), dimension(:,:,:), intent(in) :: dataset real(pReal), allocatable, dimension(:,:) :: select_rotations - integer :: e,i,c,j + integer :: el,ip,co,j - allocate(select_rotations(4,count(material_phaseAt==instance)*homogenization_maxNconstituents*discretization_nIPs)) + allocate(select_rotations(4,count(material_phaseAt==ph)*homogenization_maxNconstituents*discretization_nIPs)) j=0 - do e = 1, size(material_phaseAt,2) - do i = 1, discretization_nIPs - do c = 1, size(material_phaseAt,1) !ToDo: this needs to be changed for varying Ngrains - if (material_phaseAt(c,e) == instance) then + do el = 1, size(material_phaseAt,2) + do ip = 1, discretization_nIPs + do co = 1, size(material_phaseAt,1) !ToDo: this needs to be changed for varying Ngrains + if (material_phaseAt(co,el) == ph) then j = j + 1 - select_rotations(1:4,j) = dataset(c,i,e)%asQuaternion() + select_rotations(1:4,j) = dataset(co,ip,el)%asQuaternion() endif enddo enddo From acc998d242e765f36e4dfd9ed568d0400d1e0584 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Thu, 24 Dec 2020 10:22:41 +0100 Subject: [PATCH 129/148] should become mech only --- src/constitutive.f90 | 126 +++----------------------------------- src/constitutive_mech.f90 | 120 +++++++++++++++++++++++++++++++++++- 2 files changed, 127 insertions(+), 119 deletions(-) diff --git a/src/constitutive.f90 b/src/constitutive.f90 index 4e29f3f96..461a67c9a 100644 --- a/src/constitutive.f90 +++ b/src/constitutive.f90 @@ -117,7 +117,7 @@ module constitutive type(tDebugOptions) :: debugCrystallite - procedure(integrateStateFPI), pointer :: integrateState + integer(kind(PLASTICITY_undefined_ID)), dimension(:), allocatable, public :: & phase_plasticity !< plasticity of each phase @@ -187,6 +187,12 @@ module constitutive ! == cleaned:end =================================================================================== + module function crystallite_stress(dt,co,ip,el) + real(pReal), intent(in) :: dt + integer, intent(in) :: co, ip, el + logical :: crystallite_stress + end function crystallite_stress + module function constitutive_homogenizedC(co,ip,el) result(C) integer, intent(in) :: co, ip, el real(pReal), dimension(6,6) :: C @@ -362,10 +368,6 @@ module constitutive dS_dFi !< derivative of 2nd P-K stress with respect to intermediate deformation gradient end subroutine constitutive_hooke_SandItsTangents - module subroutine integrateStateFPI(co,ip,el) - integer, intent(in) :: co, ip, el - end subroutine integrateStateFPI - end interface @@ -392,6 +394,7 @@ module constitutive crystallite_orientations, & crystallite_push33ToRef, & crystallite_restartWrite, & + integrateSourceState, & crystallite_restartRead, & constitutive_initializeRestorationPoints, & constitutive_windForward, & @@ -983,120 +986,7 @@ subroutine crystallite_init end subroutine crystallite_init -!-------------------------------------------------------------------------------------------------- -!> @brief calculate stress (P) -!-------------------------------------------------------------------------------------------------- -function crystallite_stress(dt,co,ip,el) - real(pReal), intent(in) :: dt - integer, intent(in) :: & - co, & - ip, & - el - - logical :: crystallite_stress - - real(pReal) :: & - formerSubStep - integer :: & - NiterationCrystallite, & ! number of iterations in crystallite loop - s, ph, me - logical :: todo - real(pReal) :: subFrac,subStep - real(pReal), dimension(3,3) :: & - subLp0, & !< plastic velocity grad at start of crystallite inc - subLi0 !< intermediate velocity grad at start of crystallite inc - - - ph = material_phaseAt(co,el) - me = material_phaseMemberAt(co,ip,el) - subLi0 = constitutive_mech_partionedLi0(ph)%data(1:3,1:3,me) - subLp0 = crystallite_partitionedLp0(1:3,1:3,co,ip,el) - plasticState (material_phaseAt(co,el))%subState0( :,material_phaseMemberAt(co,ip,el)) = & - plasticState (material_phaseAt(co,el))%partitionedState0(:,material_phaseMemberAt(co,ip,el)) - - do s = 1, phase_Nsources(material_phaseAt(co,el)) - sourceState(material_phaseAt(co,el))%p(s)%subState0( :,material_phaseMemberAt(co,ip,el)) = & - sourceState(material_phaseAt(co,el))%p(s)%partitionedState0(:,material_phaseMemberAt(co,ip,el)) - enddo - crystallite_subFp0(1:3,1:3,co,ip,el) = constitutive_mech_partionedFp0(ph)%data(1:3,1:3,me) - crystallite_subFi0(1:3,1:3,co,ip,el) = constitutive_mech_partionedFi0(ph)%data(1:3,1:3,me) - crystallite_subF0(1:3,1:3,co,ip,el) = crystallite_partitionedF0(1:3,1:3,co,ip,el) - subFrac = 0.0_pReal - subStep = 1.0_pReal/num%subStepSizeCryst - todo = .true. - crystallite_converged(co,ip,el) = .false. ! pretend failed step of 1/subStepSizeCryst - - todo = .true. - NiterationCrystallite = 0 - cutbackLooping: do while (todo) - NiterationCrystallite = NiterationCrystallite + 1 - -!-------------------------------------------------------------------------------------------------- -! wind forward - if (crystallite_converged(co,ip,el)) then - formerSubStep = subStep - subFrac = subFrac + subStep - subStep = min(1.0_pReal - subFrac, num%stepIncreaseCryst * subStep) - - todo = subStep > 0.0_pReal ! still time left to integrate on? - - if (todo) then - crystallite_subF0 (1:3,1:3,co,ip,el) = crystallite_subF(1:3,1:3,co,ip,el) - subLp0 = crystallite_Lp (1:3,1:3,co,ip,el) - subLi0 = constitutive_mech_Li(ph)%data(1:3,1:3,me) - crystallite_subFp0(1:3,1:3,co,ip,el) = constitutive_mech_Fp(ph)%data(1:3,1:3,me) - crystallite_subFi0(1:3,1:3,co,ip,el) = constitutive_mech_Fi(ph)%data(1:3,1:3,me) - plasticState( material_phaseAt(co,el))%subState0(:,material_phaseMemberAt(co,ip,el)) & - = plasticState(material_phaseAt(co,el))%state( :,material_phaseMemberAt(co,ip,el)) - do s = 1, phase_Nsources(material_phaseAt(co,el)) - sourceState( material_phaseAt(co,el))%p(s)%subState0(:,material_phaseMemberAt(co,ip,el)) & - = sourceState(material_phaseAt(co,el))%p(s)%state( :,material_phaseMemberAt(co,ip,el)) - enddo - endif -!-------------------------------------------------------------------------------------------------- -! cut back (reduced time and restore) - else - subStep = num%subStepSizeCryst * subStep - constitutive_mech_Fp(ph)%data(1:3,1:3,me) = crystallite_subFp0(1:3,1:3,co,ip,el) - constitutive_mech_Fi(ph)%data(1:3,1:3,me) = crystallite_subFi0(1:3,1:3,co,ip,el) - crystallite_S (1:3,1:3,co,ip,el) = crystallite_S0 (1:3,1:3,co,ip,el) - if (subStep < 1.0_pReal) then ! actual (not initial) cutback - crystallite_Lp (1:3,1:3,co,ip,el) = subLp0 - constitutive_mech_Li(ph)%data(1:3,1:3,me) = subLi0 - endif - plasticState (material_phaseAt(co,el))%state( :,material_phaseMemberAt(co,ip,el)) & - = plasticState(material_phaseAt(co,el))%subState0(:,material_phaseMemberAt(co,ip,el)) - do s = 1, phase_Nsources(material_phaseAt(co,el)) - sourceState( material_phaseAt(co,el))%p(s)%state( :,material_phaseMemberAt(co,ip,el)) & - = sourceState(material_phaseAt(co,el))%p(s)%subState0(:,material_phaseMemberAt(co,ip,el)) - enddo - - ! cant restore dotState here, since not yet calculated in first cutback after initialization - todo = subStep > num%subStepMinCryst ! still on track or already done (beyond repair) - endif - -!-------------------------------------------------------------------------------------------------- -! prepare for integration - if (todo) then - crystallite_subF(1:3,1:3,co,ip,el) = crystallite_subF0(1:3,1:3,co,ip,el) & - + subStep *( crystallite_partitionedF (1:3,1:3,co,ip,el) & - -crystallite_partitionedF0(1:3,1:3,co,ip,el)) - crystallite_Fe(1:3,1:3,co,ip,el) = matmul(crystallite_subF(1:3,1:3,co,ip,el), & - math_inv33(matmul(constitutive_mech_Fi(ph)%data(1:3,1:3,me), & - constitutive_mech_Fp(ph)%data(1:3,1:3,me)))) - crystallite_subdt(co,ip,el) = subStep * dt - crystallite_converged(co,ip,el) = .false. - call integrateState(co,ip,el) - call integrateSourceState(co,ip,el) - endif - - enddo cutbackLooping - -! return whether converged or not - crystallite_stress = crystallite_converged(co,ip,el) - -end function crystallite_stress !-------------------------------------------------------------------------------------------------- diff --git a/src/constitutive_mech.f90 b/src/constitutive_mech.f90 index 6a60b4ade..d448b0505 100644 --- a/src/constitutive_mech.f90 +++ b/src/constitutive_mech.f90 @@ -290,6 +290,8 @@ submodule(constitutive) constitutive_mech end type tOutput type(tOutput), allocatable, dimension(:) :: output_constituent + procedure(integrateStateFPI), pointer :: integrateState + contains @@ -959,7 +961,7 @@ end function integrateStress !> @brief integrate stress, state with adaptive 1st order explicit Euler method !> using Fixed Point Iteration to adapt the stepsize !-------------------------------------------------------------------------------------------------- -module subroutine integrateStateFPI(co,ip,el) +subroutine integrateStateFPI(co,ip,el) integer, intent(in) :: & el, & !< element index in element loop @@ -1475,5 +1477,121 @@ module function constitutive_homogenizedC(co,ip,el) result(C) end function constitutive_homogenizedC + +!-------------------------------------------------------------------------------------------------- +!> @brief calculate stress (P) +!-------------------------------------------------------------------------------------------------- +module function crystallite_stress(dt,co,ip,el) + + real(pReal), intent(in) :: dt + integer, intent(in) :: & + co, & + ip, & + el + + logical :: crystallite_stress + + real(pReal) :: & + formerSubStep + integer :: & + NiterationCrystallite, & ! number of iterations in crystallite loop + s, ph, me + logical :: todo + real(pReal) :: subFrac,subStep + real(pReal), dimension(3,3) :: & + subLp0, & !< plastic velocity grad at start of crystallite inc + subLi0 !< intermediate velocity grad at start of crystallite inc + + + ph = material_phaseAt(co,el) + me = material_phaseMemberAt(co,ip,el) + subLi0 = constitutive_mech_partionedLi0(ph)%data(1:3,1:3,me) + subLp0 = crystallite_partitionedLp0(1:3,1:3,co,ip,el) + plasticState (material_phaseAt(co,el))%subState0( :,material_phaseMemberAt(co,ip,el)) = & + plasticState (material_phaseAt(co,el))%partitionedState0(:,material_phaseMemberAt(co,ip,el)) + + do s = 1, phase_Nsources(material_phaseAt(co,el)) + sourceState(material_phaseAt(co,el))%p(s)%subState0( :,material_phaseMemberAt(co,ip,el)) = & + sourceState(material_phaseAt(co,el))%p(s)%partitionedState0(:,material_phaseMemberAt(co,ip,el)) + enddo + crystallite_subFp0(1:3,1:3,co,ip,el) = constitutive_mech_partionedFp0(ph)%data(1:3,1:3,me) + crystallite_subFi0(1:3,1:3,co,ip,el) = constitutive_mech_partionedFi0(ph)%data(1:3,1:3,me) + crystallite_subF0(1:3,1:3,co,ip,el) = crystallite_partitionedF0(1:3,1:3,co,ip,el) + subFrac = 0.0_pReal + subStep = 1.0_pReal/num%subStepSizeCryst + todo = .true. + crystallite_converged(co,ip,el) = .false. ! pretend failed step of 1/subStepSizeCryst + + todo = .true. + NiterationCrystallite = 0 + cutbackLooping: do while (todo) + NiterationCrystallite = NiterationCrystallite + 1 + +!-------------------------------------------------------------------------------------------------- +! wind forward + if (crystallite_converged(co,ip,el)) then + formerSubStep = subStep + subFrac = subFrac + subStep + subStep = min(1.0_pReal - subFrac, num%stepIncreaseCryst * subStep) + + todo = subStep > 0.0_pReal ! still time left to integrate on? + + if (todo) then + crystallite_subF0 (1:3,1:3,co,ip,el) = crystallite_subF(1:3,1:3,co,ip,el) + subLp0 = crystallite_Lp (1:3,1:3,co,ip,el) + subLi0 = constitutive_mech_Li(ph)%data(1:3,1:3,me) + crystallite_subFp0(1:3,1:3,co,ip,el) = constitutive_mech_Fp(ph)%data(1:3,1:3,me) + crystallite_subFi0(1:3,1:3,co,ip,el) = constitutive_mech_Fi(ph)%data(1:3,1:3,me) + plasticState( material_phaseAt(co,el))%subState0(:,material_phaseMemberAt(co,ip,el)) & + = plasticState(material_phaseAt(co,el))%state( :,material_phaseMemberAt(co,ip,el)) + do s = 1, phase_Nsources(material_phaseAt(co,el)) + sourceState( material_phaseAt(co,el))%p(s)%subState0(:,material_phaseMemberAt(co,ip,el)) & + = sourceState(material_phaseAt(co,el))%p(s)%state( :,material_phaseMemberAt(co,ip,el)) + enddo + endif +!-------------------------------------------------------------------------------------------------- +! cut back (reduced time and restore) + else + subStep = num%subStepSizeCryst * subStep + constitutive_mech_Fp(ph)%data(1:3,1:3,me) = crystallite_subFp0(1:3,1:3,co,ip,el) + constitutive_mech_Fi(ph)%data(1:3,1:3,me) = crystallite_subFi0(1:3,1:3,co,ip,el) + crystallite_S (1:3,1:3,co,ip,el) = crystallite_S0 (1:3,1:3,co,ip,el) + if (subStep < 1.0_pReal) then ! actual (not initial) cutback + crystallite_Lp (1:3,1:3,co,ip,el) = subLp0 + constitutive_mech_Li(ph)%data(1:3,1:3,me) = subLi0 + endif + plasticState (material_phaseAt(co,el))%state( :,material_phaseMemberAt(co,ip,el)) & + = plasticState(material_phaseAt(co,el))%subState0(:,material_phaseMemberAt(co,ip,el)) + do s = 1, phase_Nsources(material_phaseAt(co,el)) + sourceState( material_phaseAt(co,el))%p(s)%state( :,material_phaseMemberAt(co,ip,el)) & + = sourceState(material_phaseAt(co,el))%p(s)%subState0(:,material_phaseMemberAt(co,ip,el)) + enddo + + ! cant restore dotState here, since not yet calculated in first cutback after initialization + todo = subStep > num%subStepMinCryst ! still on track or already done (beyond repair) + endif + +!-------------------------------------------------------------------------------------------------- +! prepare for integration + if (todo) then + crystallite_subF(1:3,1:3,co,ip,el) = crystallite_subF0(1:3,1:3,co,ip,el) & + + subStep *( crystallite_partitionedF (1:3,1:3,co,ip,el) & + -crystallite_partitionedF0(1:3,1:3,co,ip,el)) + crystallite_Fe(1:3,1:3,co,ip,el) = matmul(crystallite_subF(1:3,1:3,co,ip,el), & + math_inv33(matmul(constitutive_mech_Fi(ph)%data(1:3,1:3,me), & + constitutive_mech_Fp(ph)%data(1:3,1:3,me)))) + crystallite_subdt(co,ip,el) = subStep * dt + crystallite_converged(co,ip,el) = .false. + call integrateState(co,ip,el) + call integrateSourceState(co,ip,el) + endif + + enddo cutbackLooping + +! return whether converged or not + crystallite_stress = crystallite_converged(co,ip,el) + +end function crystallite_stress + end submodule constitutive_mech From 45d318c7b4506cc2f3f38b42540d78d935b0450c Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Thu, 24 Dec 2020 10:36:48 +0100 Subject: [PATCH 130/148] better use explicit arguments --- src/constitutive_mech.f90 | 44 +++++++++++++++++---------------------- 1 file changed, 19 insertions(+), 25 deletions(-) diff --git a/src/constitutive_mech.f90 b/src/constitutive_mech.f90 index d448b0505..6d15fa8f1 100644 --- a/src/constitutive_mech.f90 +++ b/src/constitutive_mech.f90 @@ -737,15 +737,15 @@ end subroutine mech_results !> @brief calculation of stress (P) with time integration based on a residuum in Lp and !> intermediate acceleration of the Newton-Raphson correction !-------------------------------------------------------------------------------------------------- -function integrateStress(co,ip,el,timeFraction) result(broken) +function integrateStress(F,Delta_t,co,ip,el) result(broken) + real(pReal), dimension(3,3), intent(in) :: F + real(pReal), intent(in) :: Delta_t integer, intent(in):: el, & ! element index ip, & ! integration point index - co ! grain index - real(pReal), optional, intent(in) :: timeFraction ! fraction of timestep + co ! grain index - real(pReal), dimension(3,3):: F, & ! deformation gradient at end of timestep - Fp_new, & ! plastic deformation gradient at end of timestep + real(pReal), dimension(3,3):: Fp_new, & ! plastic deformation gradient at end of timestep invFp_new, & ! inverse of Fp_new invFp_current, & ! inverse of Fp_current Lpguess, & ! current guess for plastic velocity gradient @@ -783,7 +783,6 @@ function integrateStress(co,ip,el,timeFraction) result(broken) dLi_dS real(pReal) steplengthLp, & steplengthLi, & - dt, & ! time increment atol_Lp, & atol_Li, & devNull @@ -801,15 +800,6 @@ function integrateStress(co,ip,el,timeFraction) result(broken) broken = .true. - if (present(timeFraction)) then - dt = crystallite_subdt(co,ip,el) * timeFraction - F = crystallite_subF0(1:3,1:3,co,ip,el) & - + (crystallite_subF(1:3,1:3,co,ip,el) - crystallite_subF0(1:3,1:3,co,ip,el)) * timeFraction - else - dt = crystallite_subdt(co,ip,el) - F = crystallite_subF(1:3,1:3,co,ip,el) - endif - call constitutive_plastic_dependentState(crystallite_partitionedF(1:3,1:3,co,ip,el),co,ip,el) ph = material_phaseAt(co,el) @@ -835,7 +825,7 @@ function integrateStress(co,ip,el,timeFraction) result(broken) NiterationStressLi = NiterationStressLi + 1 if (NiterationStressLi>num%nStress) return ! error - invFi_new = matmul(invFi_current,math_I3 - dt*Liguess) + invFi_new = matmul(invFi_current,math_I3 - Delta_t*Liguess) Fi_new = math_inv33(invFi_new) jacoCounterLp = 0 @@ -848,7 +838,7 @@ function integrateStress(co,ip,el,timeFraction) result(broken) NiterationStressLp = NiterationStressLp + 1 if (NiterationStressLp>num%nStress) return ! error - B = math_I3 - dt*Lpguess + B = math_I3 - Delta_t*Lpguess Fe = matmul(matmul(A,B), invFi_new) call constitutive_hooke_SandItsTangents(S, dS_dFe, dS_dFi, & Fe, Fi_new, co, ip, el) @@ -880,7 +870,7 @@ function integrateStress(co,ip,el,timeFraction) result(broken) jacoCounterLp = jacoCounterLp + 1 do o=1,3; do p=1,3 - dFe_dLp(o,1:3,p,1:3) = - dt * A(o,p)*transpose(invFi_new) ! dFe_dLp(i,j,k,l) = -dt * A(i,k) invFi(l,j) + dFe_dLp(o,1:3,p,1:3) = - Delta_t * A(o,p)*transpose(invFi_new) ! dFe_dLp(i,j,k,l) = -Delta_t * A(i,k) invFi(l,j) enddo; enddo dRLp_dLp = math_eye(9) & - math_3333to99(math_mul3333xx3333(math_mul3333xx3333(dLp_dS,dS_dFe),dFe_dLp)) @@ -921,8 +911,8 @@ function integrateStress(co,ip,el,timeFraction) result(broken) temp_33 = matmul(matmul(A,B),invFi_current) do o=1,3; do p=1,3 - dFe_dLi(1:3,o,1:3,p) = -dt*math_I3(o,p)*temp_33 ! dFe_dLp(i,j,k,l) = -dt * A(i,k) invFi(l,j) - dFi_dLi(1:3,o,1:3,p) = -dt*math_I3(o,p)*invFi_current + dFe_dLi(1:3,o,1:3,p) = -Delta_t*math_I3(o,p)*temp_33 ! dFe_dLp(i,j,k,l) = -Delta_t * A(i,k) invFi(l,j) + dFi_dLi(1:3,o,1:3,p) = -Delta_t*math_I3(o,p)*invFi_current enddo; enddo do o=1,3; do p=1,3 dFi_dLi(1:3,1:3,o,p) = matmul(matmul(Fi_new,dFi_dLi(1:3,1:3,o,p)),Fi_new) @@ -998,7 +988,7 @@ subroutine integrateStateFPI(co,ip,el) if(nIterationState > 1) plastic_dotState(1:size_pl,2) = plastic_dotState(1:size_pl,1) plastic_dotState(1:size_pl,1) = plasticState(ph)%dotState(:,me) - broken = integrateStress(co,ip,el) + broken = integrateStress(crystallite_subF(1:3,1:3,co,ip,el),crystallite_subdt(co,ip,el),co,ip,el) if(broken) exit iteration broken = mech_collectDotState(crystallite_subdt(co,ip,el), co,ip,el,ph,me) @@ -1082,7 +1072,7 @@ subroutine integrateStateEuler(co,ip,el) constitutive_mech_Fi(ph)%data(1:3,1:3,me),co,ip,el,ph,me) if(broken) return - broken = integrateStress(co,ip,el) + broken = integrateStress(crystallite_subF(1:3,1:3,co,ip,el),crystallite_subdt(co,ip,el),co,ip,el) crystallite_converged(co,ip,el) = .not. broken end subroutine integrateStateEuler @@ -1123,7 +1113,7 @@ subroutine integrateStateAdaptiveEuler(co,ip,el) constitutive_mech_Fi(ph)%data(1:3,1:3,me),co,ip,el,ph,me) if(broken) return - broken = integrateStress(co,ip,el) + broken = integrateStress(crystallite_subF(1:3,1:3,co,ip,el),crystallite_subdt(co,ip,el),co,ip,el) if(broken) return broken = mech_collectDotState(crystallite_subdt(co,ip,el), co,ip,el,ph,me) @@ -1215,6 +1205,7 @@ subroutine integrateStateRK(co,ip,el,A,B,C,DB) logical :: & broken real(pReal), dimension(constitutive_plasticity_maxSizeDotState,size(B)) :: plastic_RKdotState + real(pReal), dimension(3,3) :: F ph = material_phaseAt(co,el) @@ -1239,7 +1230,10 @@ subroutine integrateStateRK(co,ip,el,A,B,C,DB) + plasticState(ph)%dotState (1:sizeDotState,me) & * crystallite_subdt(co,ip,el) - broken = integrateStress(co,ip,el,C(stage)) + F = crystallite_subF0(1:3,1:3,co,ip,el) & + + (crystallite_subF(1:3,1:3,co,ip,el) - crystallite_subF0(1:3,1:3,co,ip,el)) * C(stage) + + broken = integrateStress(F,crystallite_subdt(co,ip,el) * C(stage),co,ip,el) if(broken) exit broken = mech_collectDotState(crystallite_subdt(co,ip,el)*C(stage), co,ip,el,ph,me) @@ -1267,7 +1261,7 @@ subroutine integrateStateRK(co,ip,el,A,B,C,DB) constitutive_mech_Fi(ph)%data(1:3,1:3,me),co,ip,el,ph,me) if(broken) return - broken = integrateStress(co,ip,el) + broken = integrateStress(crystallite_subF(1:3,1:3,co,ip,el),crystallite_subdt(co,ip,el),co,ip,el) crystallite_converged(co,ip,el) = .not. broken From 3e0361227c4ed8309f1381df90e1623d2ffc3d8f Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Thu, 24 Dec 2020 11:20:34 +0100 Subject: [PATCH 131/148] not needed as global variable --- src/constitutive.f90 | 3 +- src/constitutive_mech.f90 | 102 ++++++++++++++++++++------------------ 2 files changed, 55 insertions(+), 50 deletions(-) diff --git a/src/constitutive.f90 b/src/constitutive.f90 index 461a67c9a..f4b5feca6 100644 --- a/src/constitutive.f90 +++ b/src/constitutive.f90 @@ -50,7 +50,6 @@ module constitutive real(pReal), dimension(:,:,:,:,:), allocatable :: & crystallite_F0, & !< def grad at start of FE inc crystallite_subF, & !< def grad to be reached at end of crystallite inc - crystallite_subF0, & !< def grad at start of crystallite inc crystallite_Fe, & !< current "elastic" def grad (end of converged time step) crystallite_subFp0,& !< plastic def grad at start of crystallite inc crystallite_subFi0,& !< intermediate def grad at start of crystallite inc @@ -869,7 +868,7 @@ subroutine crystallite_init crystallite_partitionedLp0, & crystallite_S,crystallite_P, & crystallite_Fe,crystallite_Lp, & - crystallite_subF,crystallite_subF0, & + crystallite_subF, & crystallite_subFp0,crystallite_subFi0, & source = crystallite_partitionedF) diff --git a/src/constitutive_mech.f90 b/src/constitutive_mech.f90 index 6d15fa8f1..a419a9564 100644 --- a/src/constitutive_mech.f90 +++ b/src/constitutive_mech.f90 @@ -951,8 +951,10 @@ end function integrateStress !> @brief integrate stress, state with adaptive 1st order explicit Euler method !> using Fixed Point Iteration to adapt the stepsize !-------------------------------------------------------------------------------------------------- -subroutine integrateStateFPI(co,ip,el) +subroutine integrateStateFPI(F_0,F,Delta_t,co,ip,el) + real(pReal), intent(in),dimension(3,3) :: F_0,F + real(pReal), intent(in) :: Delta_t integer, intent(in) :: & el, & !< element index in element loop ip, & !< integration point index in ip loop @@ -974,13 +976,12 @@ subroutine integrateStateFPI(co,ip,el) ph = material_phaseAt(co,el) me = material_phaseMemberAt(co,ip,el) - broken = mech_collectDotState(crystallite_subdt(co,ip,el), co,ip,el,ph,me) + broken = mech_collectDotState(Delta_t, co,ip,el,ph,me) if(broken) return size_pl = plasticState(ph)%sizeDotState plasticState(ph)%state(1:size_pl,me) = plasticState(ph)%subState0(1:size_pl,me) & - + plasticState(ph)%dotState (1:size_pl,me) & - * crystallite_subdt(co,ip,el) + + plasticState(ph)%dotState (1:size_pl,me) * Delta_t plastic_dotState(1:size_pl,2) = 0.0_pReal iteration: do NiterationState = 1, num%nState @@ -988,10 +989,10 @@ subroutine integrateStateFPI(co,ip,el) if(nIterationState > 1) plastic_dotState(1:size_pl,2) = plastic_dotState(1:size_pl,1) plastic_dotState(1:size_pl,1) = plasticState(ph)%dotState(:,me) - broken = integrateStress(crystallite_subF(1:3,1:3,co,ip,el),crystallite_subdt(co,ip,el),co,ip,el) + broken = integrateStress(F,Delta_t,co,ip,el) if(broken) exit iteration - broken = mech_collectDotState(crystallite_subdt(co,ip,el), co,ip,el,ph,me) + broken = mech_collectDotState(Delta_t, co,ip,el,ph,me) if(broken) exit iteration zeta = damper(plasticState(ph)%dotState(:,me),plastic_dotState(1:size_pl,1),& @@ -999,10 +1000,10 @@ subroutine integrateStateFPI(co,ip,el) plasticState(ph)%dotState(:,me) = plasticState(ph)%dotState(:,me) * zeta & + plastic_dotState(1:size_pl,1) * (1.0_pReal - zeta) r(1:size_pl) = plasticState(ph)%state (1:size_pl,me) & - - plasticState(ph)%subState0(1:size_pl,me) & - - plasticState(ph)%dotState (1:size_pl,me) * crystallite_subdt(co,ip,el) + - plasticState(ph)%subState0(1:size_pl,me) & + - plasticState(ph)%dotState (1:size_pl,me) * Delta_t plasticState(ph)%state(1:size_pl,me) = plasticState(ph)%state(1:size_pl,me) & - - r(1:size_pl) + - r(1:size_pl) crystallite_converged(co,ip,el) = converged(r(1:size_pl), & plasticState(ph)%state(1:size_pl,me), & plasticState(ph)%atol(1:size_pl)) @@ -1044,8 +1045,10 @@ end subroutine integrateStateFPI !-------------------------------------------------------------------------------------------------- !> @brief integrate state with 1st order explicit Euler method !-------------------------------------------------------------------------------------------------- -subroutine integrateStateEuler(co,ip,el) +subroutine integrateStateEuler(F_0,F,Delta_t,co,ip,el) + real(pReal), intent(in),dimension(3,3) :: F_0,F + real(pReal), intent(in) :: Delta_t integer, intent(in) :: & el, & !< element index in element loop ip, & !< integration point index in ip loop @@ -1060,19 +1063,18 @@ subroutine integrateStateEuler(co,ip,el) ph = material_phaseAt(co,el) me = material_phaseMemberAt(co,ip,el) - broken = mech_collectDotState(crystallite_subdt(co,ip,el), co,ip,el,ph,me) + broken = mech_collectDotState(Delta_t, co,ip,el,ph,me) if(broken) return sizeDotState = plasticState(ph)%sizeDotState plasticState(ph)%state(1:sizeDotState,me) = plasticState(ph)%subState0(1:sizeDotState,me) & - + plasticState(ph)%dotState (1:sizeDotState,me) & - * crystallite_subdt(co,ip,el) + + plasticState(ph)%dotState (1:sizeDotState,me) * Delta_t broken = constitutive_deltaState(crystallite_S(1:3,1:3,co,ip,el), & constitutive_mech_Fi(ph)%data(1:3,1:3,me),co,ip,el,ph,me) if(broken) return - broken = integrateStress(crystallite_subF(1:3,1:3,co,ip,el),crystallite_subdt(co,ip,el),co,ip,el) + broken = integrateStress(F,Delta_t,co,ip,el) crystallite_converged(co,ip,el) = .not. broken end subroutine integrateStateEuler @@ -1081,8 +1083,10 @@ end subroutine integrateStateEuler !-------------------------------------------------------------------------------------------------- !> @brief integrate stress, state with 1st order Euler method with adaptive step size !-------------------------------------------------------------------------------------------------- -subroutine integrateStateAdaptiveEuler(co,ip,el) +subroutine integrateStateAdaptiveEuler(F_0,F,Delta_t,co,ip,el) + real(pReal), intent(in),dimension(3,3) :: F_0,F + real(pReal), intent(in) :: Delta_t integer, intent(in) :: & el, & !< element index in element loop ip, & !< integration point index in ip loop @@ -1100,29 +1104,29 @@ subroutine integrateStateAdaptiveEuler(co,ip,el) ph = material_phaseAt(co,el) me = material_phaseMemberAt(co,ip,el) - broken = mech_collectDotState(crystallite_subdt(co,ip,el), co,ip,el,ph,me) + broken = mech_collectDotState(Delta_t, co,ip,el,ph,me) if(broken) return sizeDotState = plasticState(ph)%sizeDotState - residuum_plastic(1:sizeDotState) = - plasticState(ph)%dotstate(1:sizeDotState,me) * 0.5_pReal * crystallite_subdt(co,ip,el) + residuum_plastic(1:sizeDotState) = - plasticState(ph)%dotstate(1:sizeDotState,me) * 0.5_pReal * Delta_t plasticState(ph)%state(1:sizeDotState,me) = plasticState(ph)%subState0(1:sizeDotState,me) & - + plasticState(ph)%dotstate(1:sizeDotState,me) * crystallite_subdt(co,ip,el) + + plasticState(ph)%dotstate(1:sizeDotState,me) * Delta_t broken = constitutive_deltaState(crystallite_S(1:3,1:3,co,ip,el), & constitutive_mech_Fi(ph)%data(1:3,1:3,me),co,ip,el,ph,me) if(broken) return - broken = integrateStress(crystallite_subF(1:3,1:3,co,ip,el),crystallite_subdt(co,ip,el),co,ip,el) + broken = integrateStress(F,Delta_t,co,ip,el) if(broken) return - broken = mech_collectDotState(crystallite_subdt(co,ip,el), co,ip,el,ph,me) + broken = mech_collectDotState(Delta_t, co,ip,el,ph,me) if(broken) return sizeDotState = plasticState(ph)%sizeDotState crystallite_converged(co,ip,el) = converged(residuum_plastic(1:sizeDotState) & - + 0.5_pReal * plasticState(ph)%dotState(:,me) * crystallite_subdt(co,ip,el), & + + 0.5_pReal * plasticState(ph)%dotState(:,me) * Delta_t, & plasticState(ph)%state(1:sizeDotState,me), & plasticState(ph)%atol(1:sizeDotState)) @@ -1132,8 +1136,10 @@ end subroutine integrateStateAdaptiveEuler !--------------------------------------------------------------------------------------------------- !> @brief Integrate state (including stress integration) with the classic Runge Kutta method !--------------------------------------------------------------------------------------------------- -subroutine integrateStateRK4(co,ip,el) +subroutine integrateStateRK4(F_0,F,Delta_t,co,ip,el) + real(pReal), intent(in),dimension(3,3) :: F_0,F + real(pReal), intent(in) :: Delta_t integer, intent(in) :: co,ip,el real(pReal), dimension(3,3), parameter :: & @@ -1147,7 +1153,7 @@ subroutine integrateStateRK4(co,ip,el) real(pReal), dimension(4), parameter :: & B = [1.0_pReal/6.0_pReal, 1.0_pReal/3.0_pReal, 1.0_pReal/3.0_pReal, 1.0_pReal/6.0_pReal] - call integrateStateRK(co,ip,el,A,B,C) + call integrateStateRK(F_0,F,Delta_t,co,ip,el,A,B,C) end subroutine integrateStateRK4 @@ -1155,8 +1161,10 @@ end subroutine integrateStateRK4 !--------------------------------------------------------------------------------------------------- !> @brief Integrate state (including stress integration) with the Cash-Carp method !--------------------------------------------------------------------------------------------------- -subroutine integrateStateRKCK45(co,ip,el) +subroutine integrateStateRKCK45(F_0,F,Delta_t,co,ip,el) + real(pReal), intent(in),dimension(3,3) :: F_0,F + real(pReal), intent(in) :: Delta_t integer, intent(in) :: co,ip,el real(pReal), dimension(5,5), parameter :: & @@ -1177,7 +1185,7 @@ subroutine integrateStateRKCK45(co,ip,el) [2825.0_pReal/27648.0_pReal, .0_pReal, 18575.0_pReal/48384.0_pReal,& 13525.0_pReal/55296.0_pReal, 277.0_pReal/14336.0_pReal, 1._pReal/4._pReal] - call integrateStateRK(co,ip,el,A,B,C,DB) + call integrateStateRK(F_0,F,Delta_t,co,ip,el,A,B,C,DB) end subroutine integrateStateRKCK45 @@ -1186,8 +1194,10 @@ end subroutine integrateStateRKCK45 !> @brief Integrate state (including stress integration) with an explicit Runge-Kutta method or an !! embedded explicit Runge-Kutta method !-------------------------------------------------------------------------------------------------- -subroutine integrateStateRK(co,ip,el,A,B,C,DB) +subroutine integrateStateRK(F_0,F,Delta_t,co,ip,el,A,B,C,DB) + real(pReal), intent(in),dimension(3,3) :: F_0,F + real(pReal), intent(in) :: Delta_t real(pReal), dimension(:,:), intent(in) :: A real(pReal), dimension(:), intent(in) :: B, C real(pReal), dimension(:), intent(in), optional :: DB @@ -1205,16 +1215,15 @@ subroutine integrateStateRK(co,ip,el,A,B,C,DB) logical :: & broken real(pReal), dimension(constitutive_plasticity_maxSizeDotState,size(B)) :: plastic_RKdotState - real(pReal), dimension(3,3) :: F ph = material_phaseAt(co,el) me = material_phaseMemberAt(co,ip,el) - broken = mech_collectDotState(crystallite_subdt(co,ip,el), co,ip,el,ph,me) + broken = mech_collectDotState(Delta_t,co,ip,el,ph,me) if(broken) return - do stage = 1,size(A,1) + do stage = 1, size(A,1) sizeDotState = plasticState(ph)%sizeDotState plastic_RKdotState(1:sizeDotState,stage) = plasticState(ph)%dotState(:,me) plasticState(ph)%dotState(:,me) = A(1,stage) * plastic_RKdotState(1:sizeDotState,1) @@ -1227,16 +1236,12 @@ subroutine integrateStateRK(co,ip,el,A,B,C,DB) sizeDotState = plasticState(ph)%sizeDotState plasticState(ph)%state(1:sizeDotState,me) = plasticState(ph)%subState0(1:sizeDotState,me) & - + plasticState(ph)%dotState (1:sizeDotState,me) & - * crystallite_subdt(co,ip,el) + + plasticState(ph)%dotState (1:sizeDotState,me) * Delta_t - F = crystallite_subF0(1:3,1:3,co,ip,el) & - + (crystallite_subF(1:3,1:3,co,ip,el) - crystallite_subF0(1:3,1:3,co,ip,el)) * C(stage) - - broken = integrateStress(F,crystallite_subdt(co,ip,el) * C(stage),co,ip,el) + broken = integrateStress(F_0 + (F - F_0) * Delta_t,Delta_t * C(stage),co,ip,el) if(broken) exit - broken = mech_collectDotState(crystallite_subdt(co,ip,el)*C(stage), co,ip,el,ph,me) + broken = mech_collectDotState(Delta_t*C(stage),co,ip,el,ph,me) if(broken) exit enddo @@ -1247,13 +1252,12 @@ subroutine integrateStateRK(co,ip,el,A,B,C,DB) plastic_RKdotState(1:sizeDotState,size(B)) = plasticState (ph)%dotState(:,me) plasticState(ph)%dotState(:,me) = matmul(plastic_RKdotState(1:sizeDotState,1:size(B)),B) plasticState(ph)%state(1:sizeDotState,me) = plasticState(ph)%subState0(1:sizeDotState,me) & - + plasticState(ph)%dotState (1:sizeDotState,me) & - * crystallite_subdt(co,ip,el) + + plasticState(ph)%dotState (1:sizeDotState,me) * Delta_t + if(present(DB)) & - broken = .not. converged( matmul(plastic_RKdotState(1:sizeDotState,1:size(DB)),DB) & - * crystallite_subdt(co,ip,el), & - plasticState(ph)%state(1:sizeDotState,me), & - plasticState(ph)%atol(1:sizeDotState)) + broken = .not. converged(matmul(plastic_RKdotState(1:sizeDotState,1:size(DB)),DB) * Delta_t, & + plasticState(ph)%state(1:sizeDotState,me), & + plasticState(ph)%atol(1:sizeDotState)) if(broken) return @@ -1261,7 +1265,7 @@ subroutine integrateStateRK(co,ip,el,A,B,C,DB) constitutive_mech_Fi(ph)%data(1:3,1:3,me),co,ip,el,ph,me) if(broken) return - broken = integrateStress(crystallite_subF(1:3,1:3,co,ip,el),crystallite_subdt(co,ip,el),co,ip,el) + broken = integrateStress(F,Delta_t,co,ip,el) crystallite_converged(co,ip,el) = .not. broken @@ -1494,7 +1498,8 @@ module function crystallite_stress(dt,co,ip,el) real(pReal) :: subFrac,subStep real(pReal), dimension(3,3) :: & subLp0, & !< plastic velocity grad at start of crystallite inc - subLi0 !< intermediate velocity grad at start of crystallite inc + subLi0, & !< intermediate velocity grad at start of crystallite inc + subF0 ph = material_phaseAt(co,el) @@ -1510,7 +1515,7 @@ module function crystallite_stress(dt,co,ip,el) enddo crystallite_subFp0(1:3,1:3,co,ip,el) = constitutive_mech_partionedFp0(ph)%data(1:3,1:3,me) crystallite_subFi0(1:3,1:3,co,ip,el) = constitutive_mech_partionedFi0(ph)%data(1:3,1:3,me) - crystallite_subF0(1:3,1:3,co,ip,el) = crystallite_partitionedF0(1:3,1:3,co,ip,el) + subF0 = crystallite_partitionedF0(1:3,1:3,co,ip,el) subFrac = 0.0_pReal subStep = 1.0_pReal/num%subStepSizeCryst todo = .true. @@ -1531,7 +1536,7 @@ module function crystallite_stress(dt,co,ip,el) todo = subStep > 0.0_pReal ! still time left to integrate on? if (todo) then - crystallite_subF0 (1:3,1:3,co,ip,el) = crystallite_subF(1:3,1:3,co,ip,el) + subF0 = crystallite_subF(1:3,1:3,co,ip,el) subLp0 = crystallite_Lp (1:3,1:3,co,ip,el) subLi0 = constitutive_mech_Li(ph)%data(1:3,1:3,me) crystallite_subFp0(1:3,1:3,co,ip,el) = constitutive_mech_Fp(ph)%data(1:3,1:3,me) @@ -1568,7 +1573,7 @@ module function crystallite_stress(dt,co,ip,el) !-------------------------------------------------------------------------------------------------- ! prepare for integration if (todo) then - crystallite_subF(1:3,1:3,co,ip,el) = crystallite_subF0(1:3,1:3,co,ip,el) & + crystallite_subF(1:3,1:3,co,ip,el) = subF0 & + subStep *( crystallite_partitionedF (1:3,1:3,co,ip,el) & -crystallite_partitionedF0(1:3,1:3,co,ip,el)) crystallite_Fe(1:3,1:3,co,ip,el) = matmul(crystallite_subF(1:3,1:3,co,ip,el), & @@ -1576,7 +1581,8 @@ module function crystallite_stress(dt,co,ip,el) constitutive_mech_Fp(ph)%data(1:3,1:3,me)))) crystallite_subdt(co,ip,el) = subStep * dt crystallite_converged(co,ip,el) = .false. - call integrateState(co,ip,el) + call integrateState(subF0,crystallite_subF(1:3,1:3,co,ip,el),& + crystallite_subdt(co,ip,el),co,ip,el) call integrateSourceState(co,ip,el) endif From 4bd7aa9abb79a87775d1f3f6690bfd70fbeef9df Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Thu, 24 Dec 2020 11:54:09 +0100 Subject: [PATCH 132/148] typo --- src/constitutive.f90 | 28 ++++++++++++++-------------- src/constitutive_mech.f90 | 19 +++++++++---------- 2 files changed, 23 insertions(+), 24 deletions(-) diff --git a/src/constitutive.f90 b/src/constitutive.f90 index f4b5feca6..7e380f8cd 100644 --- a/src/constitutive.f90 +++ b/src/constitutive.f90 @@ -76,13 +76,13 @@ module constitutive type(tTensorContainer), dimension(:), allocatable :: & constitutive_mech_Fi, & constitutive_mech_Fi0, & - constitutive_mech_partionedFi0, & + constitutive_mech_partitionedFi0, & constitutive_mech_Li, & constitutive_mech_Li0, & - constitutive_mech_partionedLi0, & + constitutive_mech_partitionedLi0, & constitutive_mech_Fp, & constitutive_mech_Fp0, & - constitutive_mech_partionedFp0 + constitutive_mech_partitionedFp0 type :: tNumerics @@ -913,25 +913,25 @@ subroutine crystallite_init allocate(constitutive_mech_Fi(phases%length)) allocate(constitutive_mech_Fi0(phases%length)) - allocate(constitutive_mech_partionedFi0(phases%length)) + allocate(constitutive_mech_partitionedFi0(phases%length)) allocate(constitutive_mech_Fp(phases%length)) allocate(constitutive_mech_Fp0(phases%length)) - allocate(constitutive_mech_partionedFp0(phases%length)) + allocate(constitutive_mech_partitionedFp0(phases%length)) allocate(constitutive_mech_Li(phases%length)) allocate(constitutive_mech_Li0(phases%length)) - allocate(constitutive_mech_partionedLi0(phases%length)) + allocate(constitutive_mech_partitionedLi0(phases%length)) do ph = 1, phases%length Nconstituents = count(material_phaseAt == ph) * discretization_nIPs allocate(constitutive_mech_Fi(ph)%data(3,3,Nconstituents)) allocate(constitutive_mech_Fi0(ph)%data(3,3,Nconstituents)) - allocate(constitutive_mech_partionedFi0(ph)%data(3,3,Nconstituents)) + allocate(constitutive_mech_partitionedFi0(ph)%data(3,3,Nconstituents)) allocate(constitutive_mech_Fp(ph)%data(3,3,Nconstituents)) allocate(constitutive_mech_Fp0(ph)%data(3,3,Nconstituents)) - allocate(constitutive_mech_partionedFp0(ph)%data(3,3,Nconstituents)) + allocate(constitutive_mech_partitionedFp0(ph)%data(3,3,Nconstituents)) allocate(constitutive_mech_Li(ph)%data(3,3,Nconstituents)) allocate(constitutive_mech_Li0(ph)%data(3,3,Nconstituents)) - allocate(constitutive_mech_partionedLi0(ph)%data(3,3,Nconstituents)) + allocate(constitutive_mech_partitionedLi0(ph)%data(3,3,Nconstituents)) enddo print'(a42,1x,i10)', ' # of elements: ', eMax @@ -957,8 +957,8 @@ subroutine crystallite_init constitutive_mech_Fp(ph)%data(1:3,1:3,me) = constitutive_mech_Fp0(ph)%data(1:3,1:3,me) constitutive_mech_Fi(ph)%data(1:3,1:3,me) = constitutive_mech_Fi0(ph)%data(1:3,1:3,me) - constitutive_mech_partionedFi0(ph)%data(1:3,1:3,me) = constitutive_mech_Fi0(ph)%data(1:3,1:3,me) - constitutive_mech_partionedFp0(ph)%data(1:3,1:3,me) = constitutive_mech_Fp0(ph)%data(1:3,1:3,me) + constitutive_mech_partitionedFi0(ph)%data(1:3,1:3,me) = constitutive_mech_Fi0(ph)%data(1:3,1:3,me) + constitutive_mech_partitionedFp0(ph)%data(1:3,1:3,me) = constitutive_mech_Fp0(ph)%data(1:3,1:3,me) enddo; enddo enddo @@ -1063,11 +1063,11 @@ subroutine crystallite_restore(ip,el,includeL) m = material_phaseMemberAt(co,ip,el) if (includeL) then crystallite_Lp(1:3,1:3,co,ip,el) = crystallite_partitionedLp0(1:3,1:3,co,ip,el) - constitutive_mech_Li(p)%data(1:3,1:3,m) = constitutive_mech_partionedLi0(p)%data(1:3,1:3,m) + constitutive_mech_Li(p)%data(1:3,1:3,m) = constitutive_mech_partitionedLi0(p)%data(1:3,1:3,m) endif ! maybe protecting everything from overwriting makes more sense - constitutive_mech_Fp(p)%data(1:3,1:3,m) = constitutive_mech_partionedFp0(p)%data(1:3,1:3,m) - constitutive_mech_Fi(p)%data(1:3,1:3,m) = constitutive_mech_partionedFi0(p)%data(1:3,1:3,m) + constitutive_mech_Fp(p)%data(1:3,1:3,m) = constitutive_mech_partitionedFp0(p)%data(1:3,1:3,m) + constitutive_mech_Fi(p)%data(1:3,1:3,m) = constitutive_mech_partitionedFi0(p)%data(1:3,1:3,m) crystallite_S (1:3,1:3,co,ip,el) = crystallite_partitionedS0 (1:3,1:3,co,ip,el) plasticState (material_phaseAt(co,el))%state( :,material_phasememberAt(co,ip,el)) = & diff --git a/src/constitutive_mech.f90 b/src/constitutive_mech.f90 index a419a9564..b2194ab93 100644 --- a/src/constitutive_mech.f90 +++ b/src/constitutive_mech.f90 @@ -1409,9 +1409,9 @@ module subroutine mech_initializeRestorationPoints(ph,me) integer, intent(in) :: ph, me - constitutive_mech_partionedFi0(ph)%data(1:3,1:3,me) = constitutive_mech_Fi0(ph)%data(1:3,1:3,me) - constitutive_mech_partionedFp0(ph)%data(1:3,1:3,me) = constitutive_mech_Fp0(ph)%data(1:3,1:3,me) - constitutive_mech_partionedLi0(ph)%data(1:3,1:3,me) = constitutive_mech_Li0(ph)%data(1:3,1:3,me) + constitutive_mech_partitionedFi0(ph)%data(1:3,1:3,me) = constitutive_mech_Fi0(ph)%data(1:3,1:3,me) + constitutive_mech_partitionedFp0(ph)%data(1:3,1:3,me) = constitutive_mech_Fp0(ph)%data(1:3,1:3,me) + constitutive_mech_partitionedLi0(ph)%data(1:3,1:3,me) = constitutive_mech_Li0(ph)%data(1:3,1:3,me) plasticState(ph)%partitionedState0(:,me) = plasticState(ph)%state0(:,me) end subroutine mech_initializeRestorationPoints @@ -1425,9 +1425,9 @@ module subroutine constitutive_mech_windForward(ph,me) integer, intent(in) :: ph, me - constitutive_mech_partionedFp0(ph)%data(1:3,1:3,me) = constitutive_mech_Fp(ph)%data(1:3,1:3,me) - constitutive_mech_partionedFi0(ph)%data(1:3,1:3,me) = constitutive_mech_Fi(ph)%data(1:3,1:3,me) - constitutive_mech_partionedLi0(ph)%data(1:3,1:3,me) = constitutive_mech_Li(ph)%data(1:3,1:3,me) + constitutive_mech_partitionedFp0(ph)%data(1:3,1:3,me) = constitutive_mech_Fp(ph)%data(1:3,1:3,me) + constitutive_mech_partitionedFi0(ph)%data(1:3,1:3,me) = constitutive_mech_Fi(ph)%data(1:3,1:3,me) + constitutive_mech_partitionedLi0(ph)%data(1:3,1:3,me) = constitutive_mech_Li(ph)%data(1:3,1:3,me) plasticState(ph)%partitionedState0(:,me) = plasticState(ph)%state(:,me) @@ -1504,7 +1504,7 @@ module function crystallite_stress(dt,co,ip,el) ph = material_phaseAt(co,el) me = material_phaseMemberAt(co,ip,el) - subLi0 = constitutive_mech_partionedLi0(ph)%data(1:3,1:3,me) + subLi0 = constitutive_mech_partitionedLi0(ph)%data(1:3,1:3,me) subLp0 = crystallite_partitionedLp0(1:3,1:3,co,ip,el) plasticState (material_phaseAt(co,el))%subState0( :,material_phaseMemberAt(co,ip,el)) = & plasticState (material_phaseAt(co,el))%partitionedState0(:,material_phaseMemberAt(co,ip,el)) @@ -1513,8 +1513,8 @@ module function crystallite_stress(dt,co,ip,el) sourceState(material_phaseAt(co,el))%p(s)%subState0( :,material_phaseMemberAt(co,ip,el)) = & sourceState(material_phaseAt(co,el))%p(s)%partitionedState0(:,material_phaseMemberAt(co,ip,el)) enddo - crystallite_subFp0(1:3,1:3,co,ip,el) = constitutive_mech_partionedFp0(ph)%data(1:3,1:3,me) - crystallite_subFi0(1:3,1:3,co,ip,el) = constitutive_mech_partionedFi0(ph)%data(1:3,1:3,me) + crystallite_subFp0(1:3,1:3,co,ip,el) = constitutive_mech_partitionedFp0(ph)%data(1:3,1:3,me) + crystallite_subFi0(1:3,1:3,co,ip,el) = constitutive_mech_partitionedFi0(ph)%data(1:3,1:3,me) subF0 = crystallite_partitionedF0(1:3,1:3,co,ip,el) subFrac = 0.0_pReal subStep = 1.0_pReal/num%subStepSizeCryst @@ -1566,7 +1566,6 @@ module function crystallite_stress(dt,co,ip,el) = sourceState(material_phaseAt(co,el))%p(s)%subState0(:,material_phaseMemberAt(co,ip,el)) enddo - ! cant restore dotState here, since not yet calculated in first cutback after initialization todo = subStep > num%subStepMinCryst ! still on track or already done (beyond repair) endif From edef98fd067812d527d97234821d8b06e9ef7de9 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Thu, 24 Dec 2020 12:44:26 +0100 Subject: [PATCH 133/148] proper indentation --- src/homogenization.f90 | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/src/homogenization.f90 b/src/homogenization.f90 index fba0c4f45..27fdb6064 100644 --- a/src/homogenization.f90 +++ b/src/homogenization.f90 @@ -184,11 +184,10 @@ subroutine materialpoint_stressAndItsTangent(dt) damageState(material_homogenizationAt(el))%subState0(:,material_homogenizationMemberAt(ip,el)) = & damageState(material_homogenizationAt(el))%State0( :,material_homogenizationMemberAt(ip,el)) - NiterationHomog = 0 + NiterationHomog = 0 + cutBackLooping: do while (.not. terminallyIll .and. subStep > num%subStepMinHomog) - cutBackLooping: do while (.not. terminallyIll .and. subStep > num%subStepMinHomog) - - myNgrains = homogenization_Nconstituents(material_homogenizationAt(el)) + myNgrains = homogenization_Nconstituents(material_homogenizationAt(el)) if (converged) then subFrac = subFrac + subStep @@ -238,7 +237,6 @@ subroutine materialpoint_stressAndItsTangent(dt) NiterationMPstate = 0 - convergenceLooping: do while (.not. terminallyIll .and. requested & .and. .not. doneAndHappy(1) & .and. NiterationMPstate < num%nMPstate) @@ -275,15 +273,12 @@ subroutine materialpoint_stressAndItsTangent(dt) endif enddo convergenceLooping + NiterationHomog = NiterationHomog + 1 - - NiterationHomog = NiterationHomog + 1 - - enddo cutBackLooping - - enddo + enddo cutBackLooping enddo - !$OMP END PARALLEL DO + enddo + !$OMP END PARALLEL DO if (.not. terminallyIll ) then call crystallite_orientations() ! calculate crystal orientations From 6d5c3a5d12587975c2da3eba9c95f787d5dd62de Mon Sep 17 00:00:00 2001 From: Test User Date: Thu, 24 Dec 2020 20:02:59 +0100 Subject: [PATCH 134/148] [skip ci] updated version information after successful test of v3.0.0-alpha2-97-g10bbeb561 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 3e5a7aa8c..616042312 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v3.0.0-alpha2-75-gac45427e9 +v3.0.0-alpha2-97-g10bbeb561 From 5f5d9ed908454b38e35617581a71c36861f85b27 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 27 Dec 2020 08:43:57 +0100 Subject: [PATCH 135/148] wrong time increment --- src/constitutive_mech.f90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/constitutive_mech.f90 b/src/constitutive_mech.f90 index b2194ab93..7a2224ede 100644 --- a/src/constitutive_mech.f90 +++ b/src/constitutive_mech.f90 @@ -1238,7 +1238,7 @@ subroutine integrateStateRK(F_0,F,Delta_t,co,ip,el,A,B,C,DB) plasticState(ph)%state(1:sizeDotState,me) = plasticState(ph)%subState0(1:sizeDotState,me) & + plasticState(ph)%dotState (1:sizeDotState,me) * Delta_t - broken = integrateStress(F_0 + (F - F_0) * Delta_t,Delta_t * C(stage),co,ip,el) + broken = integrateStress(F_0 + (F - F_0) * Delta_t * C(stage),Delta_t * C(stage),co,ip,el) if(broken) exit broken = mech_collectDotState(Delta_t*C(stage),co,ip,el,ph,me) From 4796afdd92f7b576c36bf62017fd8ba1b036899f Mon Sep 17 00:00:00 2001 From: Philip Eisenlohr Date: Mon, 28 Dec 2020 12:10:21 -0500 Subject: [PATCH 136/148] fix for broken representation of no-rotation orientations and averaging weights --- python/damask/_orientation.py | 6 +++--- python/damask/_rotation.py | 14 +++++++++++--- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/python/damask/_orientation.py b/python/damask/_orientation.py index 05301561f..e6434813e 100644 --- a/python/damask/_orientation.py +++ b/python/damask/_orientation.py @@ -226,9 +226,9 @@ class Orientation(Rotation): """ return super().__eq__(other) \ - and self.family == other.family \ - and self.lattice == other.lattice \ - and self.parameters == other.parameters + and hasattr(other, 'family') and self.family == other.family \ + and hasattr(other, 'lattice') and self.lattice == other.lattice \ + and hasattr(other, 'parameters') and self.parameters == other.parameters def __matmul__(self,other): diff --git a/python/damask/_rotation.py b/python/damask/_rotation.py index 780e81891..8d3050ab8 100644 --- a/python/damask/_rotation.py +++ b/python/damask/_rotation.py @@ -204,8 +204,16 @@ class Rotation: def append(self,other): - """Extend rotation array along first dimension with other array.""" - return self.copy(rotation=np.vstack((self.quaternion,other.quaternion))) + """ + Extend rotation array along first dimension with other array(s). + + Parameters + ---------- + other : Rotation or list of Rotations. + + """ + return self.copy(rotation=np.vstack(tuple(map(lambda x:x.quaternion, + [self]+other if type(other) == list else [self,other])))) def flatten(self,order = 'C'): @@ -263,7 +271,7 @@ class Rotation: """Intermediate representation supporting quaternion averaging.""" return np.einsum('...i,...j',quat,quat) - if not weights: + if weights is None: weights = np.ones(self.shape,dtype=float) eig, vec = np.linalg.eig(np.sum(_M(self.quaternion) * weights[...,np.newaxis,np.newaxis],axis=-3) \ From da62daf15d37b6a1d42a1b23d171b3f82e4f6120 Mon Sep 17 00:00:00 2001 From: Philip Eisenlohr Date: Mon, 28 Dec 2020 12:26:09 -0500 Subject: [PATCH 137/148] added test for appending rotation lists; better check for type==list --- python/damask/_rotation.py | 2 +- python/tests/test_Rotation.py | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/python/damask/_rotation.py b/python/damask/_rotation.py index 8d3050ab8..78029b59a 100644 --- a/python/damask/_rotation.py +++ b/python/damask/_rotation.py @@ -213,7 +213,7 @@ class Rotation: """ return self.copy(rotation=np.vstack(tuple(map(lambda x:x.quaternion, - [self]+other if type(other) == list else [self,other])))) + [self]+other if isinstance(other,list) else [self,other])))) def flatten(self,order = 'C'): diff --git a/python/tests/test_Rotation.py b/python/tests/test_Rotation.py index c60029046..36e3a3ac9 100644 --- a/python/tests/test_Rotation.py +++ b/python/tests/test_Rotation.py @@ -800,6 +800,14 @@ class TestRotation: print(f'append 2x {shape} --> {s.shape}') assert s[0,...] == r[0,...] and s[-1,...] == p[-1,...] + @pytest.mark.parametrize('shape',[None,1,(1,),(4,2),(3,3,2)]) + def test_append_list(self,shape): + r = Rotation.from_random(shape=shape) + p = Rotation.from_random(shape=shape) + s = r.append([r,p]) + print(f'append 3x {shape} --> {s.shape}') + assert s[0,...] == r[0,...] and s[-1,...] == p[-1,...] + @pytest.mark.parametrize('quat,standardized',[ ([-1,0,0,0],[1,0,0,0]), ([-0.5,-0.5,-0.5,-0.5],[0.5,0.5,0.5,0.5]), From 2791f3d192da8179f3f980aa56bbcbd9ddb3beb6 Mon Sep 17 00:00:00 2001 From: Test User Date: Tue, 29 Dec 2020 00:33:12 +0100 Subject: [PATCH 138/148] [skip ci] updated version information after successful test of v3.0.0-alpha2-101-gab2a4a987 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 616042312..cb10a9c4f 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v3.0.0-alpha2-97-g10bbeb561 +v3.0.0-alpha2-101-gab2a4a987 From 0f28d8048b1bc7316f3f381fef96b9a9c9bd0196 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 2 Jan 2021 17:57:11 +0100 Subject: [PATCH 139/148] KISS --- src/commercialFEM_fileList.f90 | 1 - src/quaternions.f90 | 534 --------------------------------- src/rotations.f90 | 83 +++-- 3 files changed, 57 insertions(+), 561 deletions(-) delete mode 100644 src/quaternions.f90 diff --git a/src/commercialFEM_fileList.f90 b/src/commercialFEM_fileList.f90 index 08e7b9c1c..3e3e017eb 100644 --- a/src/commercialFEM_fileList.f90 +++ b/src/commercialFEM_fileList.f90 @@ -11,7 +11,6 @@ #include "config.f90" #include "LAPACK_interface.f90" #include "math.f90" -#include "quaternions.f90" #include "rotations.f90" #include "FEsolving.f90" #include "element.f90" diff --git a/src/quaternions.f90 b/src/quaternions.f90 deleted file mode 100644 index c5c43e3c1..000000000 --- a/src/quaternions.f90 +++ /dev/null @@ -1,534 +0,0 @@ -!--------------------------------------------------------------------------------------------------- -!> @author Martin Diehl, Max-Planck-Institut für Eisenforschung GmbH -!> @author Philip Eisenlohr, Michigan State University -!> @brief general quaternion math, not limited to unit quaternions -!> @details w is the real part, (x, y, z) are the imaginary parts. -!> @details https://en.wikipedia.org/wiki/Quaternion -!--------------------------------------------------------------------------------------------------- -module quaternions - use prec - - implicit none - private - - real(pReal), parameter, public :: P = -1.0_pReal !< parameter for orientation conversion. - - type, public :: quaternion - real(pReal), private :: w = 0.0_pReal - real(pReal), private :: x = 0.0_pReal - real(pReal), private :: y = 0.0_pReal - real(pReal), private :: z = 0.0_pReal - - - contains - procedure, private :: add__ - procedure, private :: pos__ - generic, public :: operator(+) => add__,pos__ - - procedure, private :: sub__ - procedure, private :: neg__ - generic, public :: operator(-) => sub__,neg__ - - procedure, private :: mul_quat__ - procedure, private :: mul_scal__ - generic, public :: operator(*) => mul_quat__, mul_scal__ - - procedure, private :: div_quat__ - procedure, private :: div_scal__ - generic, public :: operator(/) => div_quat__, div_scal__ - - procedure, private :: eq__ - generic, public :: operator(==) => eq__ - - procedure, private :: neq__ - generic, public :: operator(/=) => neq__ - - procedure, private :: pow_quat__ - procedure, private :: pow_scal__ - generic, public :: operator(**) => pow_quat__, pow_scal__ - - procedure, public :: abs => abs__ - procedure, public :: conjg => conjg__ - procedure, public :: real => real__ - procedure, public :: aimag => aimag__ - - procedure, public :: homomorphed - procedure, public :: asArray - procedure, public :: inverse - - end type - - interface assignment (=) - module procedure assign_quat__ - module procedure assign_vec__ - end interface assignment (=) - - interface quaternion - module procedure init__ - end interface quaternion - - interface abs - procedure abs__ - end interface abs - - interface dot_product - procedure dot_product__ - end interface dot_product - - interface conjg - module procedure conjg__ - end interface conjg - - interface exp - module procedure exp__ - end interface exp - - interface log - module procedure log__ - end interface log - - interface real - module procedure real__ - end interface real - - interface aimag - module procedure aimag__ - end interface aimag - - public :: & - quaternions_init, & - assignment(=), & - conjg, aimag, & - log, exp, & - abs, dot_product, & - inverse, & - real - -contains - - -!-------------------------------------------------------------------------------------------------- -!> @brief Do self test. -!-------------------------------------------------------------------------------------------------- -subroutine quaternions_init - - print'(/,a)', ' <<<+- quaternions init -+>>>'; flush(6) - - call selfTest - -end subroutine quaternions_init - - -!--------------------------------------------------------------------------------------------------- -!> @brief construct a quaternion from a 4-vector -!--------------------------------------------------------------------------------------------------- -type(quaternion) pure function init__(array) - - real(pReal), intent(in), dimension(4) :: array - - init__%w = array(1) - init__%x = array(2) - init__%y = array(3) - init__%z = array(4) - -end function init__ - - -!--------------------------------------------------------------------------------------------------- -!> @brief assign a quaternion -!--------------------------------------------------------------------------------------------------- -elemental pure subroutine assign_quat__(self,other) - - type(quaternion), intent(out) :: self - type(quaternion), intent(in) :: other - - self = [other%w,other%x,other%y,other%z] - -end subroutine assign_quat__ - - -!--------------------------------------------------------------------------------------------------- -!> @brief assign a 4-vector -!--------------------------------------------------------------------------------------------------- -pure subroutine assign_vec__(self,other) - - type(quaternion), intent(out) :: self - real(pReal), intent(in), dimension(4) :: other - - self%w = other(1) - self%x = other(2) - self%y = other(3) - self%z = other(4) - -end subroutine assign_vec__ - - -!--------------------------------------------------------------------------------------------------- -!> @brief add a quaternion -!--------------------------------------------------------------------------------------------------- -type(quaternion) elemental pure function add__(self,other) - - class(quaternion), intent(in) :: self,other - - add__ = [ self%w, self%x, self%y ,self%z] & - + [other%w, other%x, other%y,other%z] - -end function add__ - - -!--------------------------------------------------------------------------------------------------- -!> @brief return (unary positive operator) -!--------------------------------------------------------------------------------------------------- -type(quaternion) elemental pure function pos__(self) - - class(quaternion), intent(in) :: self - - pos__ = self * (+1.0_pReal) - -end function pos__ - - -!--------------------------------------------------------------------------------------------------- -!> @brief subtract a quaternion -!--------------------------------------------------------------------------------------------------- -type(quaternion) elemental pure function sub__(self,other) - - class(quaternion), intent(in) :: self,other - - sub__ = [ self%w, self%x, self%y ,self%z] & - - [other%w, other%x, other%y,other%z] - -end function sub__ - - -!--------------------------------------------------------------------------------------------------- -!> @brief negate (unary negative operator) -!--------------------------------------------------------------------------------------------------- -type(quaternion) elemental pure function neg__(self) - - class(quaternion), intent(in) :: self - - neg__ = self * (-1.0_pReal) - -end function neg__ - - -!--------------------------------------------------------------------------------------------------- -!> @brief multiply with a quaternion -!--------------------------------------------------------------------------------------------------- -type(quaternion) elemental pure function mul_quat__(self,other) - - class(quaternion), intent(in) :: self, other - - mul_quat__%w = self%w*other%w - self%x*other%x - self%y*other%y - self%z*other%z - mul_quat__%x = self%w*other%x + self%x*other%w + P * (self%y*other%z - self%z*other%y) - mul_quat__%y = self%w*other%y + self%y*other%w + P * (self%z*other%x - self%x*other%z) - mul_quat__%z = self%w*other%z + self%z*other%w + P * (self%x*other%y - self%y*other%x) - -end function mul_quat__ - - -!--------------------------------------------------------------------------------------------------- -!> @brief multiply with a scalar -!--------------------------------------------------------------------------------------------------- -type(quaternion) elemental pure function mul_scal__(self,scal) - - class(quaternion), intent(in) :: self - real(pReal), intent(in) :: scal - - mul_scal__ = [self%w,self%x,self%y,self%z]*scal - -end function mul_scal__ - - -!--------------------------------------------------------------------------------------------------- -!> @brief divide by a quaternion -!--------------------------------------------------------------------------------------------------- -type(quaternion) elemental pure function div_quat__(self,other) - - class(quaternion), intent(in) :: self, other - - div_quat__ = self * (conjg(other)/(abs(other)**2.0_pReal)) - -end function div_quat__ - - -!--------------------------------------------------------------------------------------------------- -!> @brief divide by a scalar -!--------------------------------------------------------------------------------------------------- -type(quaternion) elemental pure function div_scal__(self,scal) - - class(quaternion), intent(in) :: self - real(pReal), intent(in) :: scal - - div_scal__ = [self%w,self%x,self%y,self%z]/scal - -end function div_scal__ - - -!--------------------------------------------------------------------------------------------------- -!> @brief test equality -!--------------------------------------------------------------------------------------------------- -logical elemental pure function eq__(self,other) - - class(quaternion), intent(in) :: self,other - - eq__ = all(dEq([ self%w, self%x, self%y, self%z], & - [other%w,other%x,other%y,other%z])) - -end function eq__ - - -!--------------------------------------------------------------------------------------------------- -!> @brief test inequality -!--------------------------------------------------------------------------------------------------- -logical elemental pure function neq__(self,other) - - class(quaternion), intent(in) :: self,other - - neq__ = .not. self%eq__(other) - -end function neq__ - - -!--------------------------------------------------------------------------------------------------- -!> @brief raise to the power of a quaternion -!--------------------------------------------------------------------------------------------------- -type(quaternion) elemental pure function pow_quat__(self,expon) - - class(quaternion), intent(in) :: self - type(quaternion), intent(in) :: expon - - pow_quat__ = exp(log(self)*expon) - -end function pow_quat__ - - -!--------------------------------------------------------------------------------------------------- -!> @brief raise to the power of a scalar -!--------------------------------------------------------------------------------------------------- -type(quaternion) elemental pure function pow_scal__(self,expon) - - class(quaternion), intent(in) :: self - real(pReal), intent(in) :: expon - - pow_scal__ = exp(log(self)*expon) - -end function pow_scal__ - - -!--------------------------------------------------------------------------------------------------- -!> @brief take exponential -!--------------------------------------------------------------------------------------------------- -type(quaternion) elemental pure function exp__(a) - - class(quaternion), intent(in) :: a - real(pReal) :: absImag - - absImag = norm2(aimag(a)) - - exp__ = merge(exp(a%w) * [ cos(absImag), & - a%x/absImag * sin(absImag), & - a%y/absImag * sin(absImag), & - a%z/absImag * sin(absImag)], & - IEEE_value(1.0_pReal,IEEE_SIGNALING_NAN), & - dNeq0(absImag)) - -end function exp__ - - -!--------------------------------------------------------------------------------------------------- -!> @brief take logarithm -!--------------------------------------------------------------------------------------------------- -type(quaternion) elemental pure function log__(a) - - class(quaternion), intent(in) :: a - real(pReal) :: absImag - - absImag = norm2(aimag(a)) - - log__ = merge([log(abs(a)), & - a%x/absImag * acos(a%w/abs(a)), & - a%y/absImag * acos(a%w/abs(a)), & - a%z/absImag * acos(a%w/abs(a))], & - IEEE_value(1.0_pReal,IEEE_SIGNALING_NAN), & - dNeq0(absImag)) - -end function log__ - - -!--------------------------------------------------------------------------------------------------- -!> @brief return norm -!--------------------------------------------------------------------------------------------------- -real(pReal) elemental pure function abs__(self) - - class(quaternion), intent(in) :: self - - abs__ = norm2([self%w,self%x,self%y,self%z]) - -end function abs__ - - -!--------------------------------------------------------------------------------------------------- -!> @brief calculate dot product -!--------------------------------------------------------------------------------------------------- -real(pReal) elemental pure function dot_product__(a,b) - - class(quaternion), intent(in) :: a,b - - dot_product__ = a%w*b%w + a%x*b%x + a%y*b%y + a%z*b%z - -end function dot_product__ - - -!--------------------------------------------------------------------------------------------------- -!> @brief take conjugate complex -!--------------------------------------------------------------------------------------------------- -type(quaternion) elemental pure function conjg__(self) - - class(quaternion), intent(in) :: self - - conjg__ = [self%w,-self%x,-self%y,-self%z] - -end function conjg__ - - -!--------------------------------------------------------------------------------------------------- -!> @brief homomorph -!--------------------------------------------------------------------------------------------------- -type(quaternion) elemental pure function homomorphed(self) - - class(quaternion), intent(in) :: self - - homomorphed = - self - -end function homomorphed - - -!--------------------------------------------------------------------------------------------------- -!> @brief return as plain array -!--------------------------------------------------------------------------------------------------- -pure function asArray(self) - - real(pReal), dimension(4) :: asArray - class(quaternion), intent(in) :: self - - asArray = [self%w,self%x,self%y,self%z] - -end function asArray - - -!--------------------------------------------------------------------------------------------------- -!> @brief real part (scalar) -!--------------------------------------------------------------------------------------------------- -pure function real__(self) - - real(pReal) :: real__ - class(quaternion), intent(in) :: self - - real__ = self%w - -end function real__ - - -!--------------------------------------------------------------------------------------------------- -!> @brief imaginary part (3-vector) -!--------------------------------------------------------------------------------------------------- -pure function aimag__(self) - - real(pReal), dimension(3) :: aimag__ - class(quaternion), intent(in) :: self - - aimag__ = [self%x,self%y,self%z] - -end function aimag__ - - -!--------------------------------------------------------------------------------------------------- -!> @brief inverse -!--------------------------------------------------------------------------------------------------- -type(quaternion) elemental pure function inverse(self) - - class(quaternion), intent(in) :: self - - inverse = conjg(self)/abs(self)**2.0_pReal - -end function inverse - - -!-------------------------------------------------------------------------------------------------- -!> @brief check correctness of some quaternions functions -!-------------------------------------------------------------------------------------------------- -subroutine selfTest - - real(pReal), dimension(4) :: qu - type(quaternion) :: q, q_2 - - if(dNeq(abs(P),1.0_pReal)) error stop 'P not in {-1,+1}' - - call random_number(qu) - qu = (qu-0.5_pReal) * 2.0_pReal - q = quaternion(qu) - - q_2= qu - if(any(dNeq(q%asArray(),q_2%asArray()))) error stop 'assign_vec__' - - q_2 = q + q - if(any(dNeq(q_2%asArray(),2.0_pReal*qu))) error stop 'add__' - - q_2 = q - q - if(any(dNeq0(q_2%asArray()))) error stop 'sub__' - - q_2 = q * 5.0_pReal - if(any(dNeq(q_2%asArray(),5.0_pReal*qu))) error stop 'mul__' - - q_2 = q / 0.5_pReal - if(any(dNeq(q_2%asArray(),2.0_pReal*qu))) error stop 'div__' - - q_2 = q * 0.3_pReal - if(dNeq0(abs(q)) .and. q_2 == q) error stop 'eq__' - - q_2 = q - if(q_2 /= q) error stop 'neq__' - - if(dNeq(abs(q),norm2(qu))) error stop 'abs__' - if(dNeq(abs(q)**2.0_pReal, real(q*q%conjg()),1.0e-14_pReal)) & - error stop 'abs__/*conjg' - - if(any(dNeq(q%asArray(),qu))) error stop 'eq__' - if(dNeq(q%real(), qu(1))) error stop 'real()' - if(any(dNeq(q%aimag(), qu(2:4)))) error stop 'aimag()' - - q_2 = q%homomorphed() - if(q /= q_2* (-1.0_pReal)) error stop 'homomorphed' - if(dNeq(q_2%real(), qu(1)* (-1.0_pReal))) error stop 'homomorphed/real' - if(any(dNeq(q_2%aimag(),qu(2:4)*(-1.0_pReal)))) error stop 'homomorphed/aimag' - - q_2 = conjg(q) - if(dNeq(abs(q),abs(q_2))) error stop 'conjg/abs' - if(q /= conjg(q_2)) error stop 'conjg/involution' - if(dNeq(q_2%real(), q%real())) error stop 'conjg/real' - if(any(dNeq(q_2%aimag(),q%aimag()*(-1.0_pReal)))) error stop 'conjg/aimag' - - if(abs(q) > 0.0_pReal) then - q_2 = q * q%inverse() - if( dNeq(real(q_2), 1.0_pReal,1.0e-15_pReal)) error stop 'inverse/real' - if(any(dNeq0(aimag(q_2), 1.0e-15_pReal))) error stop 'inverse/aimag' - - q_2 = q/abs(q) - q_2 = conjg(q_2) - inverse(q_2) - if(any(dNeq0(q_2%asArray(),1.0e-15_pReal))) error stop 'inverse/conjg' - endif - if(dNeq(dot_product(qu,qu),dot_product(q,q))) error stop 'dot_product' - -#if !(defined(__GFORTRAN__) && __GNUC__ < 9) - if (norm2(aimag(q)) > 0.0_pReal) then - if (dNeq0(abs(q-exp(log(q))),1.0e-13_pReal)) error stop 'exp/log' - if (dNeq0(abs(q-log(exp(q))),1.0e-13_pReal)) error stop 'log/exp' - endif -#endif - -end subroutine selfTest - - -end module quaternions diff --git a/src/rotations.f90 b/src/rotations.f90 index 888e73762..73f8a16a1 100644 --- a/src/rotations.f90 +++ b/src/rotations.f90 @@ -47,16 +47,16 @@ !--------------------------------------------------------------------------------------------------- module rotations - use prec use IO use math - use quaternions implicit none private + real(pReal), parameter :: P = -1.0_pReal !< parameter for orientation conversion. + type, public :: rotation - type(quaternion) :: q + real(pReal), dimension(4) :: q contains procedure, public :: asQuaternion procedure, public :: asEulers @@ -103,7 +103,6 @@ contains !-------------------------------------------------------------------------------------------------- subroutine rotations_init - call quaternions_init print'(/,a)', ' <<<+- rotations init -+>>>'; flush(IO_STDOUT) print*, 'Rowenhorst et al., Modelling and Simulation in Materials Science and Engineering 23:083501, 2015' @@ -122,7 +121,7 @@ pure function asQuaternion(self) class(rotation), intent(in) :: self real(pReal), dimension(4) :: asQuaternion - asQuaternion = self%q%asArray() + asQuaternion = self%q end function asQuaternion !--------------------------------------------------------------------------------------------------- @@ -131,7 +130,7 @@ pure function asEulers(self) class(rotation), intent(in) :: self real(pReal), dimension(3) :: asEulers - asEulers = qu2eu(self%q%asArray()) + asEulers = qu2eu(self%q) end function asEulers !--------------------------------------------------------------------------------------------------- @@ -140,7 +139,7 @@ pure function asAxisAngle(self) class(rotation), intent(in) :: self real(pReal), dimension(4) :: asAxisAngle - asAxisAngle = qu2ax(self%q%asArray()) + asAxisAngle = qu2ax(self%q) end function asAxisAngle !--------------------------------------------------------------------------------------------------- @@ -149,7 +148,7 @@ pure function asMatrix(self) class(rotation), intent(in) :: self real(pReal), dimension(3,3) :: asMatrix - asMatrix = qu2om(self%q%asArray()) + asMatrix = qu2om(self%q) end function asMatrix !--------------------------------------------------------------------------------------------------- @@ -158,7 +157,7 @@ pure function asRodrigues(self) class(rotation), intent(in) :: self real(pReal), dimension(4) :: asRodrigues - asRodrigues = qu2ro(self%q%asArray()) + asRodrigues = qu2ro(self%q) end function asRodrigues !--------------------------------------------------------------------------------------------------- @@ -167,7 +166,7 @@ pure function asHomochoric(self) class(rotation), intent(in) :: self real(pReal), dimension(3) :: asHomochoric - asHomochoric = qu2ho(self%q%asArray()) + asHomochoric = qu2ho(self%q) end function asHomochoric @@ -259,7 +258,7 @@ pure elemental function rotRot__(self,R) result(rRot) type(rotation) :: rRot class(rotation), intent(in) :: self,R - rRot = rotation(self%q*R%q) + rRot = rotation(multiply_quaternion(self%q,R%q)) call rRot%standardize() end function rotRot__ @@ -272,14 +271,14 @@ pure elemental subroutine standardize(self) class(rotation), intent(inout) :: self - if (real(self%q) < 0.0_pReal) self%q = self%q%homomorphed() + if (self%q(1) < 0.0_pReal) self%q = - self%q end subroutine standardize !--------------------------------------------------------------------------------------------------- !> @author Marc De Graef, Carnegie Mellon University -!> @brief rotate a vector passively (default) or actively +!> @brief Rotate a vector passively (default) or actively. !--------------------------------------------------------------------------------------------------- pure function rotVector(self,v,active) result(vRot) @@ -288,9 +287,8 @@ pure function rotVector(self,v,active) result(vRot) real(pReal), intent(in), dimension(3) :: v logical, intent(in), optional :: active - real(pReal), dimension(3) :: v_normed - type(quaternion) :: q - logical :: passive + real(pReal), dimension(4) :: v_normed, q + logical :: passive if (present(active)) then passive = .not. active @@ -301,13 +299,13 @@ pure function rotVector(self,v,active) result(vRot) if (dEq0(norm2(v))) then vRot = v else - v_normed = v/norm2(v) + v_normed = [0.0_pReal,v]/norm2(v) if (passive) then - q = self%q * (quaternion([0.0_pReal, v_normed(1), v_normed(2), v_normed(3)]) * conjg(self%q) ) + q = multiply_quaternion(self%q, multiply_quaternion(v_normed, conjugate_quaternion(self%q))) else - q = conjg(self%q) * (quaternion([0.0_pReal, v_normed(1), v_normed(2), v_normed(3)]) * self%q ) + q = multiply_quaternion(conjugate_quaternion(self%q), multiply_quaternion(v_normed, self%q)) endif - vRot = q%aimag()*norm2(v) + vRot = q(2:4)*norm2(v) endif end function rotVector @@ -315,8 +313,8 @@ end function rotVector !--------------------------------------------------------------------------------------------------- !> @author Marc De Graef, Carnegie Mellon University -!> @brief rotate a rank-2 tensor passively (default) or actively -!> @details: rotation is based on rotation matrix +!> @brief Rotate a rank-2 tensor passively (default) or actively. +!> @details: Rotation is based on rotation matrix !--------------------------------------------------------------------------------------------------- pure function rotTensor2(self,T,active) result(tRot) @@ -403,7 +401,7 @@ pure elemental function misorientation(self,other) type(rotation) :: misorientation class(rotation), intent(in) :: self, other - misorientation%q = other%q * conjg(self%q) + misorientation%q = multiply_quaternion(other%q, [self%q(1),-self%q(2:4)]) end function misorientation @@ -1338,7 +1336,7 @@ end function cu2ho !-------------------------------------------------------------------------- !> @author Marc De Graef, Carnegie Mellon University !> @author Martin Diehl, Max-Planck-Institut für Eisenforschung GmbH -!> @brief determine to which pyramid a point in a cubic grid belongs +!> @brief Determine to which pyramid a point in a cubic grid belongs. !-------------------------------------------------------------------------- pure function GetPyramidOrder(xyz) @@ -1362,7 +1360,39 @@ end function GetPyramidOrder !-------------------------------------------------------------------------------------------------- -!> @brief check correctness of some rotations functions +!> @brief Multiply two quaternions. +!-------------------------------------------------------------------------------------------------- +pure function multiply_quaternion(qu1,qu2) + + real(pReal), dimension(4), intent(in) :: qu1, qu2 + real(pReal), dimension(4) :: multiply_quaternion + + + multiply_quaternion(1) = qu1(1)*qu2(1) - qu1(2)*qu2(2) - qu1(3)*qu2(3) - qu1(4)*qu2(4) + multiply_quaternion(2) = qu1(1)*qu2(2) + qu1(2)*qu2(1) + P * (qu1(3)*qu2(4) - qu1(4)*qu2(3)) + multiply_quaternion(3) = qu1(1)*qu2(3) + qu1(3)*qu2(1) + P * (qu1(4)*qu2(2) - qu1(2)*qu2(4)) + multiply_quaternion(4) = qu1(1)*qu2(4) + qu1(4)*qu2(1) + P * (qu1(2)*qu2(3) - qu1(3)*qu2(2)) + +end function multiply_quaternion + + +!-------------------------------------------------------------------------------------------------- +!> @brief Calculate conjugate complex of a quaternion. +!-------------------------------------------------------------------------------------------------- +pure function conjugate_quaternion(qu) + + real(pReal), dimension(4), intent(in) :: qu + real(pReal), dimension(4) :: conjugate_quaternion + + + conjugate_quaternion = [qu(1), -qu(2), -qu(3), -qu(4)] + + +end function conjugate_quaternion + + +!-------------------------------------------------------------------------------------------------- +!> @brief Check correctness of some rotations functions. !-------------------------------------------------------------------------------------------------- subroutine selfTest @@ -1374,7 +1404,8 @@ subroutine selfTest real :: A,B integer :: i - do i=1,10 + + do i = 1, 10 #if defined(__GFORTRAN__) && __GNUC__<9 if(i<7) cycle From e8b3e0f3eea3d12ba657aaf13524f7434a07e83f Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Mon, 4 Jan 2021 10:01:24 +0100 Subject: [PATCH 140/148] fail as early as possible --- CMakeLists.txt | 2 +- src/DAMASK_interface.f90 | 6 ------ 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8db6dd0c0..198528b59 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,7 @@ include (FindPkgConfig REQUIRED) # Dummy project to determine compiler names and version project (Prerequisites LANGUAGES) set(ENV{PKG_CONFIG_PATH} "$ENV{PETSC_DIR}/$ENV{PETSC_ARCH}/lib/pkgconfig") -pkg_search_module (PETSC REQUIRED PETSc>3.12.0) +pkg_check_modules (PETSC REQUIRED PETSc>=3.12.0 PETSc<3.15.0) pkg_get_variable (CMAKE_Fortran_COMPILER PETSc fcompiler) pkg_get_variable (CMAKE_C_COMPILER PETSc ccompiler) diff --git a/src/DAMASK_interface.f90 b/src/DAMASK_interface.f90 index d38020225..c43e354a2 100644 --- a/src/DAMASK_interface.f90 +++ b/src/DAMASK_interface.f90 @@ -54,12 +54,6 @@ subroutine DAMASK_interface_init =================================================================================================== -- WRONG PETSc VERSION --- WRONG PETSc VERSION --- WRONG PETSc VERSION --- WRONG PETSc VERSION -- =================================================================================================== -============ THIS VERSION OF DAMASK REQUIRES A DIFFERENT PETSc VERSION ======================== -=============== THIS VERSION OF DAMASK REQUIRES A DIFFERENT PETSc VERSION ===================== -================== THIS VERSION OF DAMASK REQUIRES A DIFFERENT PETSc VERSION ================== -=================================================================================================== --- WRONG PETSc VERSION --- WRONG PETSc VERSION --- WRONG PETSc VERSION --- WRONG PETSc VERSION -- -=================================================================================================== #endif character(len=pPathLen*3+pStringLen) :: & From 69c11383cfd4e5f7d91a82b1001087bf67c21743 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Wed, 6 Jan 2021 13:37:45 +0100 Subject: [PATCH 141/148] better use function --- src/rotations.f90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rotations.f90 b/src/rotations.f90 index 73f8a16a1..57dd16b53 100644 --- a/src/rotations.f90 +++ b/src/rotations.f90 @@ -401,7 +401,7 @@ pure elemental function misorientation(self,other) type(rotation) :: misorientation class(rotation), intent(in) :: self, other - misorientation%q = multiply_quaternion(other%q, [self%q(1),-self%q(2:4)]) + misorientation%q = multiply_quaternion(other%q, conjugate_quaternion(self%q)) end function misorientation From 437d91495bd54e29af1ba1b4e555a513844ea1f1 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Wed, 6 Jan 2021 14:24:02 +0100 Subject: [PATCH 142/148] No FEsolving --- src/CPFEM.f90 | 5 +- src/CPFEM2.f90 | 1 - src/DAMASK_marc.f90 | 1 - src/FEsolving.f90 | 15 ---- src/commercialFEM_fileList.f90 | 1 - src/constitutive.f90 | 55 ++++++-------- src/grid/discretization_grid.f90 | 4 -- src/grid/grid_mech_FEM.f90 | 1 - src/grid/grid_mech_spectral_basic.f90 | 1 - src/grid/grid_mech_spectral_polarisation.f90 | 1 - src/grid/spectral_utilities.f90 | 4 +- src/homogenization.f90 | 76 +++++++++----------- src/homogenization_mech.f90 | 24 +++---- src/marc/discretization_marc.f90 | 4 -- src/mesh/DAMASK_mesh.f90 | 1 - src/mesh/FEM_utilities.f90 | 2 +- src/mesh/discretization_mesh.f90 | 6 +- 17 files changed, 72 insertions(+), 130 deletions(-) delete mode 100644 src/FEsolving.f90 diff --git a/src/CPFEM.f90 b/src/CPFEM.f90 index abbcce04a..240688a8c 100644 --- a/src/CPFEM.f90 +++ b/src/CPFEM.f90 @@ -5,7 +5,6 @@ !-------------------------------------------------------------------------------------------------- module CPFEM use prec - use FEsolving use math use rotations use YAML_types @@ -197,11 +196,9 @@ subroutine CPFEM_general(mode, ffn, ffn1, temperature_inp, dt, elFE, ip, cauchyS CPFEM_dcsde(1:6,1:6,ip,elCP) = ODD_JACOBIAN * math_eye(6) else validCalculation - FEsolving_execElem = elCP - FEsolving_execIP = ip if (debugCPFEM%extensive) & print'(a,i8,1x,i2)', '<< CPFEM >> calculation for elFE ip ',elFE,ip - call materialpoint_stressAndItsTangent(dt) + call materialpoint_stressAndItsTangent(dt,[ip,ip],[elCP,elCP]) terminalIllness: if (terminallyIll) then diff --git a/src/CPFEM2.f90 b/src/CPFEM2.f90 index 44b93d1cb..5a500875d 100644 --- a/src/CPFEM2.f90 +++ b/src/CPFEM2.f90 @@ -6,7 +6,6 @@ module CPFEM2 use prec use config - use FEsolving use math use rotations use YAML_types diff --git a/src/DAMASK_marc.f90 b/src/DAMASK_marc.f90 index ea7430c6b..0ad68445c 100644 --- a/src/DAMASK_marc.f90 +++ b/src/DAMASK_marc.f90 @@ -176,7 +176,6 @@ subroutine hypela2(d,g,e,de,s,t,dt,ngens,m,nn,kcus,matus,ndi,nshear,disp, & use DAMASK_interface use config use YAML_types - use FEsolving use discretization_marc use homogenization use CPFEM diff --git a/src/FEsolving.f90 b/src/FEsolving.f90 deleted file mode 100644 index 3fc1482d3..000000000 --- a/src/FEsolving.f90 +++ /dev/null @@ -1,15 +0,0 @@ -!-------------------------------------------------------------------------------------------------- -!> @author Franz Roters, Max-Planck-Institut für Eisenforschung GmbH -!> @author Philip Eisenlohr, Max-Planck-Institut für Eisenforschung GmbH -!> @brief global variables for flow control -!-------------------------------------------------------------------------------------------------- -module FEsolving - - implicit none - public - - integer, dimension(2) :: & - FEsolving_execElem, & !< for ping-pong scheme always whole range, otherwise one specific element - FEsolving_execIP !< for ping-pong scheme always range to max IP, otherwise one specific IP - -end module FEsolving diff --git a/src/commercialFEM_fileList.f90 b/src/commercialFEM_fileList.f90 index 08e7b9c1c..d8ab6390d 100644 --- a/src/commercialFEM_fileList.f90 +++ b/src/commercialFEM_fileList.f90 @@ -13,7 +13,6 @@ #include "math.f90" #include "quaternions.f90" #include "rotations.f90" -#include "FEsolving.f90" #include "element.f90" #include "HDF5_utilities.f90" #include "results.f90" diff --git a/src/constitutive.f90 b/src/constitutive.f90 index 7e380f8cd..b3fb0b246 100644 --- a/src/constitutive.f90 +++ b/src/constitutive.f90 @@ -16,7 +16,6 @@ module constitutive use parallelization use HDF5_utilities use DAMASK_interface - use FEsolving use results implicit none @@ -940,8 +939,8 @@ subroutine crystallite_init flush(IO_STDOUT) !$OMP PARALLEL DO PRIVATE(ph,me) - do el = FEsolving_execElem(1),FEsolving_execElem(2) - do ip = FEsolving_execIP(1), FEsolving_execIP(2); do co = 1, homogenization_Nconstituents(material_homogenizationAt(el)) + do el = 1, size(material_phaseMemberAt,3) + do ip = 1, size(material_phaseMemberAt,2); do co = 1, homogenization_Nconstituents(material_homogenizationAt(el)) ph = material_phaseAt(co,el) me = material_phaseMemberAt(co,ip,el) @@ -967,14 +966,14 @@ subroutine crystallite_init crystallite_partitionedF0 = crystallite_F0 crystallite_partitionedF = crystallite_F0 - call crystallite_orientations() !$OMP PARALLEL DO PRIVATE(ph,me) - do el = FEsolving_execElem(1),FEsolving_execElem(2) - do ip = FEsolving_execIP(1),FEsolving_execIP(2) + do el = 1, size(material_phaseMemberAt,3) + do ip = 1, size(material_phaseMemberAt,2) do co = 1,homogenization_Nconstituents(material_homogenizationAt(el)) ph = material_phaseAt(co,el) me = material_phaseMemberAt(co,ip,el) + call crystallite_orientations(co,ip,el) call constitutive_plastic_dependentState(crystallite_partitionedF0(1:3,1:3,co,ip,el),co,ip,el) ! update dependent state variables to be consistent with basic states enddo enddo @@ -1089,7 +1088,7 @@ function crystallite_stressTangent(co,ip,el) result(dPdF) el !< counter in element loop integer :: & o, & - p, pp, m + p, ph, me real(pReal), dimension(3,3) :: devNull, & invSubFp0,invSubFi0,invFp,invFi, & @@ -1109,19 +1108,19 @@ function crystallite_stressTangent(co,ip,el) result(dPdF) real(pReal), dimension(9,9):: temp_99 logical :: error - pp = material_phaseAt(co,el) - m = material_phaseMemberAt(co,ip,el) + ph = material_phaseAt(co,el) + me = material_phaseMemberAt(co,ip,el) call constitutive_hooke_SandItsTangents(devNull,dSdFe,dSdFi, & crystallite_Fe(1:3,1:3,co,ip,el), & - constitutive_mech_Fi(pp)%data(1:3,1:3,m),co,ip,el) + constitutive_mech_Fi(ph)%data(1:3,1:3,me),co,ip,el) call constitutive_LiAndItsTangents(devNull,dLidS,dLidFi, & crystallite_S (1:3,1:3,co,ip,el), & - constitutive_mech_Fi(pp)%data(1:3,1:3,m), & + constitutive_mech_Fi(ph)%data(1:3,1:3,me), & co,ip,el) - invFp = math_inv33(constitutive_mech_Fp(pp)%data(1:3,1:3,m)) - invFi = math_inv33(constitutive_mech_Fi(pp)%data(1:3,1:3,m)) + invFp = math_inv33(constitutive_mech_Fp(ph)%data(1:3,1:3,me)) + invFi = math_inv33(constitutive_mech_Fi(ph)%data(1:3,1:3,me)) invSubFp0 = math_inv33(crystallite_subFp0(1:3,1:3,co,ip,el)) invSubFi0 = math_inv33(crystallite_subFi0(1:3,1:3,co,ip,el)) @@ -1150,7 +1149,7 @@ function crystallite_stressTangent(co,ip,el) result(dPdF) call constitutive_plastic_LpAndItsTangents(devNull,dLpdS,dLpdFi, & crystallite_S (1:3,1:3,co,ip,el), & - constitutive_mech_Fi(pp)%data(1:3,1:3,m),co,ip,el) + constitutive_mech_Fi(ph)%data(1:3,1:3,me),co,ip,el) dLpdS = math_mul3333xx3333(dLpdFi,dFidS) + dLpdS !-------------------------------------------------------------------------------------------------- @@ -1210,34 +1209,20 @@ end function crystallite_stressTangent !-------------------------------------------------------------------------------------------------- !> @brief calculates orientations !-------------------------------------------------------------------------------------------------- -subroutine crystallite_orientations +subroutine crystallite_orientations(co,ip,el) - integer & + integer, intent(in) :: & co, & !< counter in integration point component loop ip, & !< counter in integration point loop el !< counter in element loop - !$OMP PARALLEL DO - do el = FEsolving_execElem(1),FEsolving_execElem(2) - do ip = FEsolving_execIP(1),FEsolving_execIP(2) - do co = 1,homogenization_Nconstituents(material_homogenizationAt(el)) - call crystallite_orientation(co,ip,el)%fromMatrix(transpose(math_rotationalPart(crystallite_Fe(1:3,1:3,co,ip,el)))) - enddo; enddo; enddo - !$OMP END PARALLEL DO + call crystallite_orientation(co,ip,el)%fromMatrix(transpose(math_rotationalPart(crystallite_Fe(1:3,1:3,co,ip,el)))) + + if (plasticState(material_phaseAt(1,el))%nonlocal) & + call plastic_nonlocal_updateCompatibility(crystallite_orientation, & + phase_plasticityInstance(material_phaseAt(1,el)),ip,el) - nonlocalPresent: if (any(plasticState%nonlocal)) then - !$OMP PARALLEL DO - do el = FEsolving_execElem(1),FEsolving_execElem(2) - if (plasticState(material_phaseAt(1,el))%nonlocal) then - do ip = FEsolving_execIP(1),FEsolving_execIP(2) - call plastic_nonlocal_updateCompatibility(crystallite_orientation, & - phase_plasticityInstance(material_phaseAt(1,el)),ip,el) - enddo - endif - enddo - !$OMP END PARALLEL DO - endif nonlocalPresent end subroutine crystallite_orientations diff --git a/src/grid/discretization_grid.f90 b/src/grid/discretization_grid.f90 index 1b3700c14..48ad5b7e1 100644 --- a/src/grid/discretization_grid.f90 +++ b/src/grid/discretization_grid.f90 @@ -19,7 +19,6 @@ module discretization_grid use results use discretization use geometry_plastic_nonlocal - use FEsolving implicit none private @@ -117,9 +116,6 @@ subroutine discretization_grid_init(restart) (grid(1)+1) * (grid(2)+1) * grid3,& ! ...unless not last process worldrank+1==worldsize)) - FEsolving_execElem = [1,product(myGrid)] ! parallel loop bounds set to comprise all elements - FEsolving_execIP = [1,1] ! parallel loop bounds set to comprise the only IP - !-------------------------------------------------------------------------------------------------- ! store geometry information for post processing if(.not. restart) then diff --git a/src/grid/grid_mech_FEM.f90 b/src/grid/grid_mech_FEM.f90 index cdf806b35..003f568c6 100644 --- a/src/grid/grid_mech_FEM.f90 +++ b/src/grid/grid_mech_FEM.f90 @@ -18,7 +18,6 @@ module grid_mech_FEM use math use rotations use spectral_utilities - use FEsolving use config use homogenization use discretization diff --git a/src/grid/grid_mech_spectral_basic.f90 b/src/grid/grid_mech_spectral_basic.f90 index ebaaf3b55..9bc36165f 100644 --- a/src/grid/grid_mech_spectral_basic.f90 +++ b/src/grid/grid_mech_spectral_basic.f90 @@ -18,7 +18,6 @@ module grid_mech_spectral_basic use math use rotations use spectral_utilities - use FEsolving use config use homogenization use discretization_grid diff --git a/src/grid/grid_mech_spectral_polarisation.f90 b/src/grid/grid_mech_spectral_polarisation.f90 index 9f2a17c97..7160c1adc 100644 --- a/src/grid/grid_mech_spectral_polarisation.f90 +++ b/src/grid/grid_mech_spectral_polarisation.f90 @@ -18,7 +18,6 @@ module grid_mech_spectral_polarisation use math use rotations use spectral_utilities - use FEsolving use config use homogenization use discretization_grid diff --git a/src/grid/spectral_utilities.f90 b/src/grid/spectral_utilities.f90 index c0c84233d..e8bae223a 100644 --- a/src/grid/spectral_utilities.f90 +++ b/src/grid/spectral_utilities.f90 @@ -810,9 +810,9 @@ subroutine utilities_constitutiveResponse(P,P_av,C_volAvg,C_minmaxAvg,& print'(/,a)', ' ... evaluating constitutive response ......................................' flush(IO_STDOUT) - homogenization_F = reshape(F,[3,3,product(grid(1:2))*grid3]) ! set materialpoint target F to estimated field + homogenization_F = reshape(F,[3,3,product(grid(1:2))*grid3]) ! set materialpoint target F to estimated field - call materialpoint_stressAndItsTangent(timeinc) ! calculate P field + call materialpoint_stressAndItsTangent(timeinc,[1,1],[1,product(grid(1:2))*grid3]) ! calculate P field P = reshape(homogenization_P, [3,3,grid(1),grid(2),grid3]) P_av = sum(sum(sum(P,dim=5),dim=4),dim=3) * wgt ! average of P diff --git a/src/homogenization.f90 b/src/homogenization.f90 index 27fdb6064..ebf5fd50d 100644 --- a/src/homogenization.f90 +++ b/src/homogenization.f90 @@ -11,7 +11,6 @@ module homogenization use math use material use constitutive - use FEsolving use discretization use thermal_isothermal use thermal_conduction @@ -144,27 +143,29 @@ end subroutine homogenization_init !-------------------------------------------------------------------------------------------------- !> @brief parallelized calculation of stress and corresponding tangent at material points !-------------------------------------------------------------------------------------------------- -subroutine materialpoint_stressAndItsTangent(dt) +subroutine materialpoint_stressAndItsTangent(dt,FEsolving_execIP,FEsolving_execElem) real(pReal), intent(in) :: dt !< time increment + integer, dimension(2), intent(in) :: FEsolving_execElem, FEsolving_execIP integer :: & NiterationHomog, & NiterationMPstate, & ip, & !< integration point number el, & !< element number - myNgrains, co, ce + myNgrains, co, ce, ho real(pReal) :: & subFrac, & subStep logical :: & - requested, & converged logical, dimension(2) :: & doneAndHappy -!$OMP PARALLEL DO PRIVATE(ce,myNgrains,NiterationMPstate,NiterationHomog,subFrac,converged,subStep,requested,doneAndHappy) +!$OMP PARALLEL DO PRIVATE(ce,ho,myNgrains,NiterationMPstate,NiterationHomog,subFrac,converged,subStep,doneAndHappy) do el = FEsolving_execElem(1),FEsolving_execElem(2) + ho = material_homogenizationAt(el) + myNgrains = homogenization_Nconstituents(ho) do ip = FEsolving_execIP(1),FEsolving_execIP(2) !-------------------------------------------------------------------------------------------------- @@ -174,21 +175,19 @@ subroutine materialpoint_stressAndItsTangent(dt) subFrac = 0.0_pReal converged = .false. ! pretend failed step ... subStep = 1.0_pReal/num%subStepSizeHomog ! ... larger then the requested calculation - requested = .true. ! everybody requires calculation - if (homogState(material_homogenizationAt(el))%sizeState > 0) & - homogState(material_homogenizationAt(el))%subState0(:,material_homogenizationMemberAt(ip,el)) = & - homogState(material_homogenizationAt(el))%State0( :,material_homogenizationMemberAt(ip,el)) + if (homogState(ho)%sizeState > 0) & + homogState(ho)%subState0(:,material_homogenizationMemberAt(ip,el)) = & + homogState(ho)%State0( :,material_homogenizationMemberAt(ip,el)) + + if (damageState(ho)%sizeState > 0) & + damageState(ho)%subState0(:,material_homogenizationMemberAt(ip,el)) = & + damageState(ho)%State0( :,material_homogenizationMemberAt(ip,el)) - if (damageState(material_homogenizationAt(el))%sizeState > 0) & - damageState(material_homogenizationAt(el))%subState0(:,material_homogenizationMemberAt(ip,el)) = & - damageState(material_homogenizationAt(el))%State0( :,material_homogenizationMemberAt(ip,el)) NiterationHomog = 0 cutBackLooping: do while (.not. terminallyIll .and. subStep > num%subStepMinHomog) - myNgrains = homogenization_Nconstituents(material_homogenizationAt(el)) - if (converged) then subFrac = subFrac + subStep subStep = min(1.0_pReal-subFrac,num%stepIncreaseHomog*subStep) ! introduce flexibility for step increase/acceleration @@ -198,22 +197,20 @@ subroutine materialpoint_stressAndItsTangent(dt) ! wind forward grain starting point call constitutive_windForward(ip,el) - if(homogState(material_homogenizationAt(el))%sizeState > 0) & - homogState(material_homogenizationAt(el))%subState0(:,material_homogenizationMemberAt(ip,el)) = & - homogState(material_homogenizationAt(el))%State (:,material_homogenizationMemberAt(ip,el)) - if(damageState(material_homogenizationAt(el))%sizeState > 0) & - damageState(material_homogenizationAt(el))%subState0(:,material_homogenizationMemberAt(ip,el)) = & - damageState(material_homogenizationAt(el))%State (:,material_homogenizationMemberAt(ip,el)) + if(homogState(ho)%sizeState > 0) & + homogState(ho)%subState0(:,material_homogenizationMemberAt(ip,el)) = & + homogState(ho)%State (:,material_homogenizationMemberAt(ip,el)) + if(damageState(ho)%sizeState > 0) & + damageState(ho)%subState0(:,material_homogenizationMemberAt(ip,el)) = & + damageState(ho)%State (:,material_homogenizationMemberAt(ip,el)) endif steppingNeeded - else if ( (myNgrains == 1 .and. subStep <= 1.0 ) .or. & ! single grain already tried internal subStepping in crystallite num%subStepSizeHomog * subStep <= num%subStepMinHomog ) then ! would require too small subStep ! cutback makes no sense - if (.not. terminallyIll) then ! so first signals terminally ill... + if (.not. terminallyIll) & ! so first signals terminally ill... print*, ' Integration point ', ip,' at element ', el, ' terminally ill' - endif terminallyIll = .true. ! ...and kills all others else ! cutback makes sense subStep = num%subStepSizeHomog * subStep ! crystallite had severe trouble, so do a significant cutback @@ -221,23 +218,19 @@ subroutine materialpoint_stressAndItsTangent(dt) call crystallite_restore(ip,el,subStep < 1.0_pReal) call constitutive_restore(ip,el) - if(homogState(material_homogenizationAt(el))%sizeState > 0) & - homogState(material_homogenizationAt(el))%State( :,material_homogenizationMemberAt(ip,el)) = & - homogState(material_homogenizationAt(el))%subState0(:,material_homogenizationMemberAt(ip,el)) - if(damageState(material_homogenizationAt(el))%sizeState > 0) & - damageState(material_homogenizationAt(el))%State( :,material_homogenizationMemberAt(ip,el)) = & - damageState(material_homogenizationAt(el))%subState0(:,material_homogenizationMemberAt(ip,el)) + if(homogState(ho)%sizeState > 0) & + homogState(ho)%State( :,material_homogenizationMemberAt(ip,el)) = & + homogState(ho)%subState0(:,material_homogenizationMemberAt(ip,el)) + if(damageState(ho)%sizeState > 0) & + damageState(ho)%State( :,material_homogenizationMemberAt(ip,el)) = & + damageState(ho)%subState0(:,material_homogenizationMemberAt(ip,el)) endif endif - if (subStep > num%subStepMinHomog) then - requested = .true. - doneAndHappy = [.false.,.true.] - endif - + if (subStep > num%subStepMinHomog) doneAndHappy = [.false.,.true.] NiterationMPstate = 0 - convergenceLooping: do while (.not. terminallyIll .and. requested & + convergenceLooping: do while (.not. terminallyIll & .and. .not. doneAndHappy(1) & .and. NiterationMPstate < num%nMPstate) NiterationMPstate = NiterationMPstate + 1 @@ -245,7 +238,7 @@ subroutine materialpoint_stressAndItsTangent(dt) !-------------------------------------------------------------------------------------------------- ! deformation partitioning - if(requested .and. .not. doneAndHappy(1)) then ! requested but not yet done + if (.not. doneAndHappy(1)) then ce = (el-1)*discretization_nIPs + ip call mech_partition(homogenization_F0(1:3,1:3,ce) & + (homogenization_F(1:3,1:3,ce)-homogenization_F0(1:3,1:3,ce))& @@ -255,10 +248,7 @@ subroutine materialpoint_stressAndItsTangent(dt) do co = 1, myNgrains converged = converged .and. crystallite_stress(dt*subStep,co,ip,el) enddo - endif - - if (requested .and. .not. doneAndHappy(1)) then if (.not. converged) then doneAndHappy = [.true.,.false.] else @@ -281,10 +271,14 @@ subroutine materialpoint_stressAndItsTangent(dt) !$OMP END PARALLEL DO if (.not. terminallyIll ) then - call crystallite_orientations() ! calculate crystal orientations - !$OMP PARALLEL DO + !$OMP PARALLEL DO PRIVATE(ho,myNgrains) elementLooping3: do el = FEsolving_execElem(1),FEsolving_execElem(2) + ho = material_homogenizationAt(el) + myNgrains = homogenization_Nconstituents(ho) IpLooping3: do ip = FEsolving_execIP(1),FEsolving_execIP(2) + do co = 1, myNgrains + call crystallite_orientations(co,ip,el) + enddo call mech_homogenize(ip,el) enddo IpLooping3 enddo elementLooping3 diff --git a/src/homogenization_mech.f90 b/src/homogenization_mech.f90 index 56f1e554f..e4499e9b7 100644 --- a/src/homogenization_mech.f90 +++ b/src/homogenization_mech.f90 @@ -128,35 +128,35 @@ module subroutine mech_homogenize(ip,el) integer, intent(in) :: & ip, & !< integration point el !< element number - integer :: c,m + integer :: co,ce real(pReal) :: dPdFs(3,3,3,3,homogenization_Nconstituents(material_homogenizationAt(el))) - m = (el-1)* discretization_nIPs + ip + ce = (el-1)* discretization_nIPs + ip chosenHomogenization: select case(homogenization_type(material_homogenizationAt(el))) case (HOMOGENIZATION_NONE_ID) chosenHomogenization - homogenization_P(1:3,1:3,m) = crystallite_P(1:3,1:3,1,ip,el) - homogenization_dPdF(1:3,1:3,1:3,1:3,m) = crystallite_stressTangent(1,ip,el) + homogenization_P(1:3,1:3,ce) = crystallite_P(1:3,1:3,1,ip,el) + homogenization_dPdF(1:3,1:3,1:3,1:3,ce) = crystallite_stressTangent(1,ip,el) case (HOMOGENIZATION_ISOSTRAIN_ID) chosenHomogenization - do c = 1, homogenization_Nconstituents(material_homogenizationAt(el)) - dPdFs(:,:,:,:,c) = crystallite_stressTangent(c,ip,el) + do co = 1, homogenization_Nconstituents(material_homogenizationAt(el)) + dPdFs(:,:,:,:,co) = crystallite_stressTangent(co,ip,el) enddo call mech_isostrain_averageStressAndItsTangent(& - homogenization_P(1:3,1:3,m), & - homogenization_dPdF(1:3,1:3,1:3,1:3,m),& + homogenization_P(1:3,1:3,ce), & + homogenization_dPdF(1:3,1:3,1:3,1:3,ce),& crystallite_P(1:3,1:3,1:homogenization_Nconstituents(material_homogenizationAt(el)),ip,el), & dPdFs, & homogenization_typeInstance(material_homogenizationAt(el))) case (HOMOGENIZATION_RGC_ID) chosenHomogenization - do c = 1, homogenization_Nconstituents(material_homogenizationAt(el)) - dPdFs(:,:,:,:,c) = crystallite_stressTangent(c,ip,el) + do co = 1, homogenization_Nconstituents(material_homogenizationAt(el)) + dPdFs(:,:,:,:,co) = crystallite_stressTangent(co,ip,el) enddo call mech_RGC_averageStressAndItsTangent(& - homogenization_P(1:3,1:3,m), & - homogenization_dPdF(1:3,1:3,1:3,1:3,m),& + homogenization_P(1:3,1:3,ce), & + homogenization_dPdF(1:3,1:3,1:3,1:3,ce),& crystallite_P(1:3,1:3,1:homogenization_Nconstituents(material_homogenizationAt(el)),ip,el), & dPdFs, & homogenization_typeInstance(material_homogenizationAt(el))) diff --git a/src/marc/discretization_marc.f90 b/src/marc/discretization_marc.f90 index ca0b54b73..675e57bd3 100644 --- a/src/marc/discretization_marc.f90 +++ b/src/marc/discretization_marc.f90 @@ -12,7 +12,6 @@ module discretization_marc use DAMASK_interface use IO use config - use FEsolving use element use discretization use geometry_plastic_nonlocal @@ -89,9 +88,6 @@ subroutine discretization_marc_init if (debug_e < 1 .or. debug_e > nElems) call IO_error(602,ext_msg='element') if (debug_i < 1 .or. debug_i > elem%nIPs) call IO_error(602,ext_msg='IP') - FEsolving_execElem = [1,nElems] - FEsolving_execIP = [1,elem%nIPs] - allocate(cellNodeDefinition(elem%nNodes-1)) allocate(connectivity_cell(elem%NcellNodesPerCell,elem%nIPs,nElems)) call buildCells(connectivity_cell,cellNodeDefinition,& diff --git a/src/mesh/DAMASK_mesh.f90 b/src/mesh/DAMASK_mesh.f90 index 1e353892c..7369520c1 100644 --- a/src/mesh/DAMASK_mesh.f90 +++ b/src/mesh/DAMASK_mesh.f90 @@ -15,7 +15,6 @@ program DAMASK_mesh use IO use math use CPFEM2 - use FEsolving use config use discretization_mesh use FEM_Utilities diff --git a/src/mesh/FEM_utilities.f90 b/src/mesh/FEM_utilities.f90 index cb81f1f0c..2f3633e11 100644 --- a/src/mesh/FEM_utilities.f90 +++ b/src/mesh/FEM_utilities.f90 @@ -160,7 +160,7 @@ subroutine utilities_constitutiveResponse(timeinc,P_av,forwardData) print'(/,a)', ' ... evaluating constitutive response ......................................' - call materialpoint_stressAndItsTangent(timeinc) ! calculate P field + call materialpoint_stressAndItsTangent(timeinc,[1,mesh_maxNips],[1,mesh_NcpElems]) ! calculate P field cutBack = .false. ! reset cutBack status diff --git a/src/mesh/discretization_mesh.f90 b/src/mesh/discretization_mesh.f90 index 7dbd05e46..21c5feace 100644 --- a/src/mesh/discretization_mesh.f90 +++ b/src/mesh/discretization_mesh.f90 @@ -18,7 +18,6 @@ module discretization_mesh use config use discretization use results - use FEsolving use FEM_quadrature use YAML_types use prec @@ -30,7 +29,7 @@ module discretization_mesh mesh_Nboundaries, & mesh_NcpElemsGlobal - integer :: & + integer, public, protected :: & mesh_NcpElems !< total number of CP elements in mesh !!!! BEGIN DEPRECATED !!!!! @@ -174,9 +173,6 @@ subroutine discretization_mesh_init(restart) if (debug_element < 1 .or. debug_element > mesh_NcpElems) call IO_error(602,ext_msg='element') if (debug_ip < 1 .or. debug_ip > mesh_maxNips) call IO_error(602,ext_msg='IP') - FEsolving_execElem = [1,mesh_NcpElems] ! parallel loop bounds set to comprise all DAMASK elements - FEsolving_execIP = [1,mesh_maxNips] - allocate(mesh_node0(3,mesh_Nnodes),source=0.0_pReal) call discretization_init(materialAt,& From 959c18c85e4ca397453dc3db15096ef7eb3e9108 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Wed, 6 Jan 2021 14:24:52 +0100 Subject: [PATCH 143/148] No crystallite _converged --- src/CPFEM.f90 | 5 +- src/CPFEM2.f90 | 1 - src/DAMASK_marc.f90 | 1 - src/FEsolving.f90 | 15 ---- src/commercialFEM_fileList.f90 | 1 - src/constitutive.f90 | 83 ++++++++------------ src/constitutive_mech.f90 | 73 +++++++---------- src/grid/discretization_grid.f90 | 4 - src/grid/grid_mech_FEM.f90 | 1 - src/grid/grid_mech_spectral_basic.f90 | 1 - src/grid/grid_mech_spectral_polarisation.f90 | 1 - src/grid/spectral_utilities.f90 | 4 +- src/homogenization.f90 | 76 +++++++++--------- src/homogenization_mech.f90 | 24 +++--- src/marc/discretization_marc.f90 | 4 - src/mesh/DAMASK_mesh.f90 | 1 - src/mesh/FEM_utilities.f90 | 2 +- src/mesh/discretization_mesh.f90 | 6 +- 18 files changed, 113 insertions(+), 190 deletions(-) delete mode 100644 src/FEsolving.f90 diff --git a/src/CPFEM.f90 b/src/CPFEM.f90 index abbcce04a..240688a8c 100644 --- a/src/CPFEM.f90 +++ b/src/CPFEM.f90 @@ -5,7 +5,6 @@ !-------------------------------------------------------------------------------------------------- module CPFEM use prec - use FEsolving use math use rotations use YAML_types @@ -197,11 +196,9 @@ subroutine CPFEM_general(mode, ffn, ffn1, temperature_inp, dt, elFE, ip, cauchyS CPFEM_dcsde(1:6,1:6,ip,elCP) = ODD_JACOBIAN * math_eye(6) else validCalculation - FEsolving_execElem = elCP - FEsolving_execIP = ip if (debugCPFEM%extensive) & print'(a,i8,1x,i2)', '<< CPFEM >> calculation for elFE ip ',elFE,ip - call materialpoint_stressAndItsTangent(dt) + call materialpoint_stressAndItsTangent(dt,[ip,ip],[elCP,elCP]) terminalIllness: if (terminallyIll) then diff --git a/src/CPFEM2.f90 b/src/CPFEM2.f90 index 44b93d1cb..5a500875d 100644 --- a/src/CPFEM2.f90 +++ b/src/CPFEM2.f90 @@ -6,7 +6,6 @@ module CPFEM2 use prec use config - use FEsolving use math use rotations use YAML_types diff --git a/src/DAMASK_marc.f90 b/src/DAMASK_marc.f90 index ea7430c6b..0ad68445c 100644 --- a/src/DAMASK_marc.f90 +++ b/src/DAMASK_marc.f90 @@ -176,7 +176,6 @@ subroutine hypela2(d,g,e,de,s,t,dt,ngens,m,nn,kcus,matus,ndi,nshear,disp, & use DAMASK_interface use config use YAML_types - use FEsolving use discretization_marc use homogenization use CPFEM diff --git a/src/FEsolving.f90 b/src/FEsolving.f90 deleted file mode 100644 index 3fc1482d3..000000000 --- a/src/FEsolving.f90 +++ /dev/null @@ -1,15 +0,0 @@ -!-------------------------------------------------------------------------------------------------- -!> @author Franz Roters, Max-Planck-Institut für Eisenforschung GmbH -!> @author Philip Eisenlohr, Max-Planck-Institut für Eisenforschung GmbH -!> @brief global variables for flow control -!-------------------------------------------------------------------------------------------------- -module FEsolving - - implicit none - public - - integer, dimension(2) :: & - FEsolving_execElem, & !< for ping-pong scheme always whole range, otherwise one specific element - FEsolving_execIP !< for ping-pong scheme always range to max IP, otherwise one specific IP - -end module FEsolving diff --git a/src/commercialFEM_fileList.f90 b/src/commercialFEM_fileList.f90 index 08e7b9c1c..d8ab6390d 100644 --- a/src/commercialFEM_fileList.f90 +++ b/src/commercialFEM_fileList.f90 @@ -13,7 +13,6 @@ #include "math.f90" #include "quaternions.f90" #include "rotations.f90" -#include "FEsolving.f90" #include "element.f90" #include "HDF5_utilities.f90" #include "results.f90" diff --git a/src/constitutive.f90 b/src/constitutive.f90 index 7e380f8cd..e65ce864d 100644 --- a/src/constitutive.f90 +++ b/src/constitutive.f90 @@ -16,7 +16,6 @@ module constitutive use parallelization use HDF5_utilities use DAMASK_interface - use FEsolving use results implicit none @@ -65,10 +64,6 @@ module constitutive real(pReal), dimension(:,:,:,:,:), allocatable, public :: & crystallite_partitionedF !< def grad to be reached at end of homog inc - logical, dimension(:,:,:), allocatable :: & - crystallite_converged !< convergence flag - - type :: tTensorContainer real(pReal), dimension(:,:,:), allocatable :: data end type @@ -186,10 +181,10 @@ module constitutive ! == cleaned:end =================================================================================== - module function crystallite_stress(dt,co,ip,el) + module function crystallite_stress(dt,co,ip,el) result(converged_) real(pReal), intent(in) :: dt integer, intent(in) :: co, ip, el - logical :: crystallite_stress + logical :: converged_ end function crystallite_stress module function constitutive_homogenizedC(co,ip,el) result(C) @@ -873,10 +868,8 @@ subroutine crystallite_init source = crystallite_partitionedF) allocate(crystallite_subdt(cMax,iMax,eMax),source=0.0_pReal) - allocate(crystallite_orientation(cMax,iMax,eMax)) - allocate(crystallite_converged(cMax,iMax,eMax), source=.true.) num_crystallite => config_numerics%get('crystallite',defaultVal=emptyDict) @@ -940,8 +933,8 @@ subroutine crystallite_init flush(IO_STDOUT) !$OMP PARALLEL DO PRIVATE(ph,me) - do el = FEsolving_execElem(1),FEsolving_execElem(2) - do ip = FEsolving_execIP(1), FEsolving_execIP(2); do co = 1, homogenization_Nconstituents(material_homogenizationAt(el)) + do el = 1, size(material_phaseMemberAt,3) + do ip = 1, size(material_phaseMemberAt,2); do co = 1, homogenization_Nconstituents(material_homogenizationAt(el)) ph = material_phaseAt(co,el) me = material_phaseMemberAt(co,ip,el) @@ -967,14 +960,14 @@ subroutine crystallite_init crystallite_partitionedF0 = crystallite_F0 crystallite_partitionedF = crystallite_F0 - call crystallite_orientations() !$OMP PARALLEL DO PRIVATE(ph,me) - do el = FEsolving_execElem(1),FEsolving_execElem(2) - do ip = FEsolving_execIP(1),FEsolving_execIP(2) + do el = 1, size(material_phaseMemberAt,3) + do ip = 1, size(material_phaseMemberAt,2) do co = 1,homogenization_Nconstituents(material_homogenizationAt(el)) ph = material_phaseAt(co,el) me = material_phaseMemberAt(co,ip,el) + call crystallite_orientations(co,ip,el) call constitutive_plastic_dependentState(crystallite_partitionedF0(1:3,1:3,co,ip,el),co,ip,el) ! update dependent state variables to be consistent with basic states enddo enddo @@ -1089,7 +1082,7 @@ function crystallite_stressTangent(co,ip,el) result(dPdF) el !< counter in element loop integer :: & o, & - p, pp, m + p, ph, me real(pReal), dimension(3,3) :: devNull, & invSubFp0,invSubFi0,invFp,invFi, & @@ -1109,19 +1102,19 @@ function crystallite_stressTangent(co,ip,el) result(dPdF) real(pReal), dimension(9,9):: temp_99 logical :: error - pp = material_phaseAt(co,el) - m = material_phaseMemberAt(co,ip,el) + ph = material_phaseAt(co,el) + me = material_phaseMemberAt(co,ip,el) call constitutive_hooke_SandItsTangents(devNull,dSdFe,dSdFi, & crystallite_Fe(1:3,1:3,co,ip,el), & - constitutive_mech_Fi(pp)%data(1:3,1:3,m),co,ip,el) + constitutive_mech_Fi(ph)%data(1:3,1:3,me),co,ip,el) call constitutive_LiAndItsTangents(devNull,dLidS,dLidFi, & crystallite_S (1:3,1:3,co,ip,el), & - constitutive_mech_Fi(pp)%data(1:3,1:3,m), & + constitutive_mech_Fi(ph)%data(1:3,1:3,me), & co,ip,el) - invFp = math_inv33(constitutive_mech_Fp(pp)%data(1:3,1:3,m)) - invFi = math_inv33(constitutive_mech_Fi(pp)%data(1:3,1:3,m)) + invFp = math_inv33(constitutive_mech_Fp(ph)%data(1:3,1:3,me)) + invFi = math_inv33(constitutive_mech_Fi(ph)%data(1:3,1:3,me)) invSubFp0 = math_inv33(crystallite_subFp0(1:3,1:3,co,ip,el)) invSubFi0 = math_inv33(crystallite_subFi0(1:3,1:3,co,ip,el)) @@ -1150,7 +1143,7 @@ function crystallite_stressTangent(co,ip,el) result(dPdF) call constitutive_plastic_LpAndItsTangents(devNull,dLpdS,dLpdFi, & crystallite_S (1:3,1:3,co,ip,el), & - constitutive_mech_Fi(pp)%data(1:3,1:3,m),co,ip,el) + constitutive_mech_Fi(ph)%data(1:3,1:3,me),co,ip,el) dLpdS = math_mul3333xx3333(dLpdFi,dFidS) + dLpdS !-------------------------------------------------------------------------------------------------- @@ -1210,34 +1203,20 @@ end function crystallite_stressTangent !-------------------------------------------------------------------------------------------------- !> @brief calculates orientations !-------------------------------------------------------------------------------------------------- -subroutine crystallite_orientations +subroutine crystallite_orientations(co,ip,el) - integer & + integer, intent(in) :: & co, & !< counter in integration point component loop ip, & !< counter in integration point loop el !< counter in element loop - !$OMP PARALLEL DO - do el = FEsolving_execElem(1),FEsolving_execElem(2) - do ip = FEsolving_execIP(1),FEsolving_execIP(2) - do co = 1,homogenization_Nconstituents(material_homogenizationAt(el)) - call crystallite_orientation(co,ip,el)%fromMatrix(transpose(math_rotationalPart(crystallite_Fe(1:3,1:3,co,ip,el)))) - enddo; enddo; enddo - !$OMP END PARALLEL DO + call crystallite_orientation(co,ip,el)%fromMatrix(transpose(math_rotationalPart(crystallite_Fe(1:3,1:3,co,ip,el)))) + + if (plasticState(material_phaseAt(1,el))%nonlocal) & + call plastic_nonlocal_updateCompatibility(crystallite_orientation, & + phase_plasticityInstance(material_phaseAt(1,el)),ip,el) - nonlocalPresent: if (any(plasticState%nonlocal)) then - !$OMP PARALLEL DO - do el = FEsolving_execElem(1),FEsolving_execElem(2) - if (plasticState(material_phaseAt(1,el))%nonlocal) then - do ip = FEsolving_execIP(1),FEsolving_execIP(2) - call plastic_nonlocal_updateCompatibility(crystallite_orientation, & - phase_plasticityInstance(material_phaseAt(1,el)),ip,el) - enddo - endif - enddo - !$OMP END PARALLEL DO - endif nonlocalPresent end subroutine crystallite_orientations @@ -1268,7 +1247,7 @@ end function crystallite_push33ToRef !> @brief integrate stress, state with adaptive 1st order explicit Euler method !> using Fixed Point Iteration to adapt the stepsize !-------------------------------------------------------------------------------------------------- -subroutine integrateSourceState(co,ip,el) +function integrateSourceState(co,ip,el) result(broken) integer, intent(in) :: & el, & !< element index in element loop @@ -1288,12 +1267,13 @@ subroutine integrateSourceState(co,ip,el) r ! state residuum real(pReal), dimension(constitutive_source_maxSizeDotState,2,maxval(phase_Nsources)) :: source_dotState logical :: & - broken + broken, converged_ ph = material_phaseAt(co,el) me = material_phaseMemberAt(co,ip,el) + converged_ = .true. broken = constitutive_thermal_collectDotState(ph,me) broken = broken .or. constitutive_damage_collectDotState(crystallite_S(1:3,1:3,co,ip,el), co,ip,el,ph,me) if(broken) return @@ -1328,19 +1308,20 @@ subroutine integrateSourceState(co,ip,el) - sourceState(ph)%p(so)%dotState (1:size_so(so),me) * crystallite_subdt(co,ip,el) sourceState(ph)%p(so)%state(1:size_so(so),me) = sourceState(ph)%p(so)%state(1:size_so(so),me) & - r(1:size_so(so)) - crystallite_converged(co,ip,el) = & - crystallite_converged(co,ip,el) .and. converged(r(1:size_so(so)), & - sourceState(ph)%p(so)%state(1:size_so(so),me), & - sourceState(ph)%p(so)%atol(1:size_so(so))) + converged_ = converged_ .and. converged(r(1:size_so(so)), & + sourceState(ph)%p(so)%state(1:size_so(so),me), & + sourceState(ph)%p(so)%atol(1:size_so(so))) enddo - if(crystallite_converged(co,ip,el)) then + if(converged_) then broken = constitutive_damage_deltaState(crystallite_Fe(1:3,1:3,co,ip,el),co,ip,el,ph,me) exit iteration endif enddo iteration + broken = broken .or. .not. converged_ + contains @@ -1364,7 +1345,7 @@ subroutine integrateSourceState(co,ip,el) end function damper -end subroutine integrateSourceState +end function integrateSourceState !-------------------------------------------------------------------------------------------------- diff --git a/src/constitutive_mech.f90 b/src/constitutive_mech.f90 index 7a2224ede..de6f2ae9f 100644 --- a/src/constitutive_mech.f90 +++ b/src/constitutive_mech.f90 @@ -951,7 +951,7 @@ end function integrateStress !> @brief integrate stress, state with adaptive 1st order explicit Euler method !> using Fixed Point Iteration to adapt the stepsize !-------------------------------------------------------------------------------------------------- -subroutine integrateStateFPI(F_0,F,Delta_t,co,ip,el) +function integrateStateFPI(F_0,F,Delta_t,co,ip,el) result(broken) real(pReal), intent(in),dimension(3,3) :: F_0,F real(pReal), intent(in) :: Delta_t @@ -1004,11 +1004,7 @@ subroutine integrateStateFPI(F_0,F,Delta_t,co,ip,el) - plasticState(ph)%dotState (1:size_pl,me) * Delta_t plasticState(ph)%state(1:size_pl,me) = plasticState(ph)%state(1:size_pl,me) & - r(1:size_pl) - crystallite_converged(co,ip,el) = converged(r(1:size_pl), & - plasticState(ph)%state(1:size_pl,me), & - plasticState(ph)%atol(1:size_pl)) - - if(crystallite_converged(co,ip,el)) then + if (converged(r(1:size_pl),plasticState(ph)%state(1:size_pl,me),plasticState(ph)%atol(1:size_pl))) then broken = constitutive_deltaState(crystallite_S(1:3,1:3,co,ip,el), & constitutive_mech_Fi(ph)%data(1:3,1:3,me),co,ip,el,ph,me) exit iteration @@ -1016,7 +1012,6 @@ subroutine integrateStateFPI(F_0,F,Delta_t,co,ip,el) enddo iteration - contains !-------------------------------------------------------------------------------------------------- @@ -1039,13 +1034,13 @@ subroutine integrateStateFPI(F_0,F,Delta_t,co,ip,el) end function damper -end subroutine integrateStateFPI +end function integrateStateFPI !-------------------------------------------------------------------------------------------------- !> @brief integrate state with 1st order explicit Euler method !-------------------------------------------------------------------------------------------------- -subroutine integrateStateEuler(F_0,F,Delta_t,co,ip,el) +function integrateStateEuler(F_0,F,Delta_t,co,ip,el) result(broken) real(pReal), intent(in),dimension(3,3) :: F_0,F real(pReal), intent(in) :: Delta_t @@ -1075,15 +1070,14 @@ subroutine integrateStateEuler(F_0,F,Delta_t,co,ip,el) if(broken) return broken = integrateStress(F,Delta_t,co,ip,el) - crystallite_converged(co,ip,el) = .not. broken -end subroutine integrateStateEuler +end function integrateStateEuler !-------------------------------------------------------------------------------------------------- !> @brief integrate stress, state with 1st order Euler method with adaptive step size !-------------------------------------------------------------------------------------------------- -subroutine integrateStateAdaptiveEuler(F_0,F,Delta_t,co,ip,el) +function integrateStateAdaptiveEuler(F_0,F,Delta_t,co,ip,el) result(broken) real(pReal), intent(in),dimension(3,3) :: F_0,F real(pReal), intent(in) :: Delta_t @@ -1123,24 +1117,22 @@ subroutine integrateStateAdaptiveEuler(F_0,F,Delta_t,co,ip,el) broken = mech_collectDotState(Delta_t, co,ip,el,ph,me) if(broken) return + broken = .not. converged(residuum_plastic(1:sizeDotState) + 0.5_pReal * plasticState(ph)%dotState(:,me) * Delta_t, & + plasticState(ph)%state(1:sizeDotState,me), & + plasticState(ph)%atol(1:sizeDotState)) - sizeDotState = plasticState(ph)%sizeDotState - crystallite_converged(co,ip,el) = converged(residuum_plastic(1:sizeDotState) & - + 0.5_pReal * plasticState(ph)%dotState(:,me) * Delta_t, & - plasticState(ph)%state(1:sizeDotState,me), & - plasticState(ph)%atol(1:sizeDotState)) - -end subroutine integrateStateAdaptiveEuler +end function integrateStateAdaptiveEuler !--------------------------------------------------------------------------------------------------- !> @brief Integrate state (including stress integration) with the classic Runge Kutta method !--------------------------------------------------------------------------------------------------- -subroutine integrateStateRK4(F_0,F,Delta_t,co,ip,el) +function integrateStateRK4(F_0,F,Delta_t,co,ip,el) result(broken) real(pReal), intent(in),dimension(3,3) :: F_0,F real(pReal), intent(in) :: Delta_t integer, intent(in) :: co,ip,el + logical :: broken real(pReal), dimension(3,3), parameter :: & A = reshape([& @@ -1153,19 +1145,20 @@ subroutine integrateStateRK4(F_0,F,Delta_t,co,ip,el) real(pReal), dimension(4), parameter :: & B = [1.0_pReal/6.0_pReal, 1.0_pReal/3.0_pReal, 1.0_pReal/3.0_pReal, 1.0_pReal/6.0_pReal] - call integrateStateRK(F_0,F,Delta_t,co,ip,el,A,B,C) + broken = integrateStateRK(F_0,F,Delta_t,co,ip,el,A,B,C) -end subroutine integrateStateRK4 +end function integrateStateRK4 !--------------------------------------------------------------------------------------------------- !> @brief Integrate state (including stress integration) with the Cash-Carp method !--------------------------------------------------------------------------------------------------- -subroutine integrateStateRKCK45(F_0,F,Delta_t,co,ip,el) +function integrateStateRKCK45(F_0,F,Delta_t,co,ip,el) result(broken) real(pReal), intent(in),dimension(3,3) :: F_0,F real(pReal), intent(in) :: Delta_t integer, intent(in) :: co,ip,el + logical :: broken real(pReal), dimension(5,5), parameter :: & A = reshape([& @@ -1185,16 +1178,16 @@ subroutine integrateStateRKCK45(F_0,F,Delta_t,co,ip,el) [2825.0_pReal/27648.0_pReal, .0_pReal, 18575.0_pReal/48384.0_pReal,& 13525.0_pReal/55296.0_pReal, 277.0_pReal/14336.0_pReal, 1._pReal/4._pReal] - call integrateStateRK(F_0,F,Delta_t,co,ip,el,A,B,C,DB) + broken = integrateStateRK(F_0,F,Delta_t,co,ip,el,A,B,C,DB) -end subroutine integrateStateRKCK45 +end function integrateStateRKCK45 !-------------------------------------------------------------------------------------------------- !> @brief Integrate state (including stress integration) with an explicit Runge-Kutta method or an !! embedded explicit Runge-Kutta method !-------------------------------------------------------------------------------------------------- -subroutine integrateStateRK(F_0,F,Delta_t,co,ip,el,A,B,C,DB) +function integrateStateRK(F_0,F,Delta_t,co,ip,el,A,B,C,DB) result(broken) real(pReal), intent(in),dimension(3,3) :: F_0,F real(pReal), intent(in) :: Delta_t @@ -1205,15 +1198,14 @@ subroutine integrateStateRK(F_0,F,Delta_t,co,ip,el,A,B,C,DB) el, & !< element index in element loop ip, & !< integration point index in ip loop co !< grain index in grain loop + logical :: broken - integer :: & + integer :: & stage, & ! stage index in integration stage loop n, & ph, & me, & sizeDotState - logical :: & - broken real(pReal), dimension(constitutive_plasticity_maxSizeDotState,size(B)) :: plastic_RKdotState @@ -1266,10 +1258,8 @@ subroutine integrateStateRK(F_0,F,Delta_t,co,ip,el,A,B,C,DB) if(broken) return broken = integrateStress(F,Delta_t,co,ip,el) - crystallite_converged(co,ip,el) = .not. broken - -end subroutine integrateStateRK +end function integrateStateRK !-------------------------------------------------------------------------------------------------- @@ -1479,15 +1469,14 @@ end function constitutive_homogenizedC !-------------------------------------------------------------------------------------------------- !> @brief calculate stress (P) !-------------------------------------------------------------------------------------------------- -module function crystallite_stress(dt,co,ip,el) +module function crystallite_stress(dt,co,ip,el) result(converged_) real(pReal), intent(in) :: dt integer, intent(in) :: & co, & ip, & el - - logical :: crystallite_stress + logical :: converged_ real(pReal) :: & formerSubStep @@ -1519,7 +1508,7 @@ module function crystallite_stress(dt,co,ip,el) subFrac = 0.0_pReal subStep = 1.0_pReal/num%subStepSizeCryst todo = .true. - crystallite_converged(co,ip,el) = .false. ! pretend failed step of 1/subStepSizeCryst + converged_ = .false. ! pretend failed step of 1/subStepSizeCryst todo = .true. NiterationCrystallite = 0 @@ -1528,7 +1517,7 @@ module function crystallite_stress(dt,co,ip,el) !-------------------------------------------------------------------------------------------------- ! wind forward - if (crystallite_converged(co,ip,el)) then + if (converged_) then formerSubStep = subStep subFrac = subFrac + subStep subStep = min(1.0_pReal - subFrac, num%stepIncreaseCryst * subStep) @@ -1579,17 +1568,13 @@ module function crystallite_stress(dt,co,ip,el) math_inv33(matmul(constitutive_mech_Fi(ph)%data(1:3,1:3,me), & constitutive_mech_Fp(ph)%data(1:3,1:3,me)))) crystallite_subdt(co,ip,el) = subStep * dt - crystallite_converged(co,ip,el) = .false. - call integrateState(subF0,crystallite_subF(1:3,1:3,co,ip,el),& - crystallite_subdt(co,ip,el),co,ip,el) - call integrateSourceState(co,ip,el) + converged_ = .not. integrateState(subF0,crystallite_subF(1:3,1:3,co,ip,el),& + crystallite_subdt(co,ip,el),co,ip,el) + converged_ = converged_ .and. .not. integrateSourceState(co,ip,el) endif enddo cutbackLooping -! return whether converged or not - crystallite_stress = crystallite_converged(co,ip,el) - end function crystallite_stress end submodule constitutive_mech diff --git a/src/grid/discretization_grid.f90 b/src/grid/discretization_grid.f90 index 1b3700c14..48ad5b7e1 100644 --- a/src/grid/discretization_grid.f90 +++ b/src/grid/discretization_grid.f90 @@ -19,7 +19,6 @@ module discretization_grid use results use discretization use geometry_plastic_nonlocal - use FEsolving implicit none private @@ -117,9 +116,6 @@ subroutine discretization_grid_init(restart) (grid(1)+1) * (grid(2)+1) * grid3,& ! ...unless not last process worldrank+1==worldsize)) - FEsolving_execElem = [1,product(myGrid)] ! parallel loop bounds set to comprise all elements - FEsolving_execIP = [1,1] ! parallel loop bounds set to comprise the only IP - !-------------------------------------------------------------------------------------------------- ! store geometry information for post processing if(.not. restart) then diff --git a/src/grid/grid_mech_FEM.f90 b/src/grid/grid_mech_FEM.f90 index cdf806b35..003f568c6 100644 --- a/src/grid/grid_mech_FEM.f90 +++ b/src/grid/grid_mech_FEM.f90 @@ -18,7 +18,6 @@ module grid_mech_FEM use math use rotations use spectral_utilities - use FEsolving use config use homogenization use discretization diff --git a/src/grid/grid_mech_spectral_basic.f90 b/src/grid/grid_mech_spectral_basic.f90 index ebaaf3b55..9bc36165f 100644 --- a/src/grid/grid_mech_spectral_basic.f90 +++ b/src/grid/grid_mech_spectral_basic.f90 @@ -18,7 +18,6 @@ module grid_mech_spectral_basic use math use rotations use spectral_utilities - use FEsolving use config use homogenization use discretization_grid diff --git a/src/grid/grid_mech_spectral_polarisation.f90 b/src/grid/grid_mech_spectral_polarisation.f90 index 9f2a17c97..7160c1adc 100644 --- a/src/grid/grid_mech_spectral_polarisation.f90 +++ b/src/grid/grid_mech_spectral_polarisation.f90 @@ -18,7 +18,6 @@ module grid_mech_spectral_polarisation use math use rotations use spectral_utilities - use FEsolving use config use homogenization use discretization_grid diff --git a/src/grid/spectral_utilities.f90 b/src/grid/spectral_utilities.f90 index c0c84233d..e8bae223a 100644 --- a/src/grid/spectral_utilities.f90 +++ b/src/grid/spectral_utilities.f90 @@ -810,9 +810,9 @@ subroutine utilities_constitutiveResponse(P,P_av,C_volAvg,C_minmaxAvg,& print'(/,a)', ' ... evaluating constitutive response ......................................' flush(IO_STDOUT) - homogenization_F = reshape(F,[3,3,product(grid(1:2))*grid3]) ! set materialpoint target F to estimated field + homogenization_F = reshape(F,[3,3,product(grid(1:2))*grid3]) ! set materialpoint target F to estimated field - call materialpoint_stressAndItsTangent(timeinc) ! calculate P field + call materialpoint_stressAndItsTangent(timeinc,[1,1],[1,product(grid(1:2))*grid3]) ! calculate P field P = reshape(homogenization_P, [3,3,grid(1),grid(2),grid3]) P_av = sum(sum(sum(P,dim=5),dim=4),dim=3) * wgt ! average of P diff --git a/src/homogenization.f90 b/src/homogenization.f90 index 27fdb6064..ebf5fd50d 100644 --- a/src/homogenization.f90 +++ b/src/homogenization.f90 @@ -11,7 +11,6 @@ module homogenization use math use material use constitutive - use FEsolving use discretization use thermal_isothermal use thermal_conduction @@ -144,27 +143,29 @@ end subroutine homogenization_init !-------------------------------------------------------------------------------------------------- !> @brief parallelized calculation of stress and corresponding tangent at material points !-------------------------------------------------------------------------------------------------- -subroutine materialpoint_stressAndItsTangent(dt) +subroutine materialpoint_stressAndItsTangent(dt,FEsolving_execIP,FEsolving_execElem) real(pReal), intent(in) :: dt !< time increment + integer, dimension(2), intent(in) :: FEsolving_execElem, FEsolving_execIP integer :: & NiterationHomog, & NiterationMPstate, & ip, & !< integration point number el, & !< element number - myNgrains, co, ce + myNgrains, co, ce, ho real(pReal) :: & subFrac, & subStep logical :: & - requested, & converged logical, dimension(2) :: & doneAndHappy -!$OMP PARALLEL DO PRIVATE(ce,myNgrains,NiterationMPstate,NiterationHomog,subFrac,converged,subStep,requested,doneAndHappy) +!$OMP PARALLEL DO PRIVATE(ce,ho,myNgrains,NiterationMPstate,NiterationHomog,subFrac,converged,subStep,doneAndHappy) do el = FEsolving_execElem(1),FEsolving_execElem(2) + ho = material_homogenizationAt(el) + myNgrains = homogenization_Nconstituents(ho) do ip = FEsolving_execIP(1),FEsolving_execIP(2) !-------------------------------------------------------------------------------------------------- @@ -174,21 +175,19 @@ subroutine materialpoint_stressAndItsTangent(dt) subFrac = 0.0_pReal converged = .false. ! pretend failed step ... subStep = 1.0_pReal/num%subStepSizeHomog ! ... larger then the requested calculation - requested = .true. ! everybody requires calculation - if (homogState(material_homogenizationAt(el))%sizeState > 0) & - homogState(material_homogenizationAt(el))%subState0(:,material_homogenizationMemberAt(ip,el)) = & - homogState(material_homogenizationAt(el))%State0( :,material_homogenizationMemberAt(ip,el)) + if (homogState(ho)%sizeState > 0) & + homogState(ho)%subState0(:,material_homogenizationMemberAt(ip,el)) = & + homogState(ho)%State0( :,material_homogenizationMemberAt(ip,el)) + + if (damageState(ho)%sizeState > 0) & + damageState(ho)%subState0(:,material_homogenizationMemberAt(ip,el)) = & + damageState(ho)%State0( :,material_homogenizationMemberAt(ip,el)) - if (damageState(material_homogenizationAt(el))%sizeState > 0) & - damageState(material_homogenizationAt(el))%subState0(:,material_homogenizationMemberAt(ip,el)) = & - damageState(material_homogenizationAt(el))%State0( :,material_homogenizationMemberAt(ip,el)) NiterationHomog = 0 cutBackLooping: do while (.not. terminallyIll .and. subStep > num%subStepMinHomog) - myNgrains = homogenization_Nconstituents(material_homogenizationAt(el)) - if (converged) then subFrac = subFrac + subStep subStep = min(1.0_pReal-subFrac,num%stepIncreaseHomog*subStep) ! introduce flexibility for step increase/acceleration @@ -198,22 +197,20 @@ subroutine materialpoint_stressAndItsTangent(dt) ! wind forward grain starting point call constitutive_windForward(ip,el) - if(homogState(material_homogenizationAt(el))%sizeState > 0) & - homogState(material_homogenizationAt(el))%subState0(:,material_homogenizationMemberAt(ip,el)) = & - homogState(material_homogenizationAt(el))%State (:,material_homogenizationMemberAt(ip,el)) - if(damageState(material_homogenizationAt(el))%sizeState > 0) & - damageState(material_homogenizationAt(el))%subState0(:,material_homogenizationMemberAt(ip,el)) = & - damageState(material_homogenizationAt(el))%State (:,material_homogenizationMemberAt(ip,el)) + if(homogState(ho)%sizeState > 0) & + homogState(ho)%subState0(:,material_homogenizationMemberAt(ip,el)) = & + homogState(ho)%State (:,material_homogenizationMemberAt(ip,el)) + if(damageState(ho)%sizeState > 0) & + damageState(ho)%subState0(:,material_homogenizationMemberAt(ip,el)) = & + damageState(ho)%State (:,material_homogenizationMemberAt(ip,el)) endif steppingNeeded - else if ( (myNgrains == 1 .and. subStep <= 1.0 ) .or. & ! single grain already tried internal subStepping in crystallite num%subStepSizeHomog * subStep <= num%subStepMinHomog ) then ! would require too small subStep ! cutback makes no sense - if (.not. terminallyIll) then ! so first signals terminally ill... + if (.not. terminallyIll) & ! so first signals terminally ill... print*, ' Integration point ', ip,' at element ', el, ' terminally ill' - endif terminallyIll = .true. ! ...and kills all others else ! cutback makes sense subStep = num%subStepSizeHomog * subStep ! crystallite had severe trouble, so do a significant cutback @@ -221,23 +218,19 @@ subroutine materialpoint_stressAndItsTangent(dt) call crystallite_restore(ip,el,subStep < 1.0_pReal) call constitutive_restore(ip,el) - if(homogState(material_homogenizationAt(el))%sizeState > 0) & - homogState(material_homogenizationAt(el))%State( :,material_homogenizationMemberAt(ip,el)) = & - homogState(material_homogenizationAt(el))%subState0(:,material_homogenizationMemberAt(ip,el)) - if(damageState(material_homogenizationAt(el))%sizeState > 0) & - damageState(material_homogenizationAt(el))%State( :,material_homogenizationMemberAt(ip,el)) = & - damageState(material_homogenizationAt(el))%subState0(:,material_homogenizationMemberAt(ip,el)) + if(homogState(ho)%sizeState > 0) & + homogState(ho)%State( :,material_homogenizationMemberAt(ip,el)) = & + homogState(ho)%subState0(:,material_homogenizationMemberAt(ip,el)) + if(damageState(ho)%sizeState > 0) & + damageState(ho)%State( :,material_homogenizationMemberAt(ip,el)) = & + damageState(ho)%subState0(:,material_homogenizationMemberAt(ip,el)) endif endif - if (subStep > num%subStepMinHomog) then - requested = .true. - doneAndHappy = [.false.,.true.] - endif - + if (subStep > num%subStepMinHomog) doneAndHappy = [.false.,.true.] NiterationMPstate = 0 - convergenceLooping: do while (.not. terminallyIll .and. requested & + convergenceLooping: do while (.not. terminallyIll & .and. .not. doneAndHappy(1) & .and. NiterationMPstate < num%nMPstate) NiterationMPstate = NiterationMPstate + 1 @@ -245,7 +238,7 @@ subroutine materialpoint_stressAndItsTangent(dt) !-------------------------------------------------------------------------------------------------- ! deformation partitioning - if(requested .and. .not. doneAndHappy(1)) then ! requested but not yet done + if (.not. doneAndHappy(1)) then ce = (el-1)*discretization_nIPs + ip call mech_partition(homogenization_F0(1:3,1:3,ce) & + (homogenization_F(1:3,1:3,ce)-homogenization_F0(1:3,1:3,ce))& @@ -255,10 +248,7 @@ subroutine materialpoint_stressAndItsTangent(dt) do co = 1, myNgrains converged = converged .and. crystallite_stress(dt*subStep,co,ip,el) enddo - endif - - if (requested .and. .not. doneAndHappy(1)) then if (.not. converged) then doneAndHappy = [.true.,.false.] else @@ -281,10 +271,14 @@ subroutine materialpoint_stressAndItsTangent(dt) !$OMP END PARALLEL DO if (.not. terminallyIll ) then - call crystallite_orientations() ! calculate crystal orientations - !$OMP PARALLEL DO + !$OMP PARALLEL DO PRIVATE(ho,myNgrains) elementLooping3: do el = FEsolving_execElem(1),FEsolving_execElem(2) + ho = material_homogenizationAt(el) + myNgrains = homogenization_Nconstituents(ho) IpLooping3: do ip = FEsolving_execIP(1),FEsolving_execIP(2) + do co = 1, myNgrains + call crystallite_orientations(co,ip,el) + enddo call mech_homogenize(ip,el) enddo IpLooping3 enddo elementLooping3 diff --git a/src/homogenization_mech.f90 b/src/homogenization_mech.f90 index 56f1e554f..e4499e9b7 100644 --- a/src/homogenization_mech.f90 +++ b/src/homogenization_mech.f90 @@ -128,35 +128,35 @@ module subroutine mech_homogenize(ip,el) integer, intent(in) :: & ip, & !< integration point el !< element number - integer :: c,m + integer :: co,ce real(pReal) :: dPdFs(3,3,3,3,homogenization_Nconstituents(material_homogenizationAt(el))) - m = (el-1)* discretization_nIPs + ip + ce = (el-1)* discretization_nIPs + ip chosenHomogenization: select case(homogenization_type(material_homogenizationAt(el))) case (HOMOGENIZATION_NONE_ID) chosenHomogenization - homogenization_P(1:3,1:3,m) = crystallite_P(1:3,1:3,1,ip,el) - homogenization_dPdF(1:3,1:3,1:3,1:3,m) = crystallite_stressTangent(1,ip,el) + homogenization_P(1:3,1:3,ce) = crystallite_P(1:3,1:3,1,ip,el) + homogenization_dPdF(1:3,1:3,1:3,1:3,ce) = crystallite_stressTangent(1,ip,el) case (HOMOGENIZATION_ISOSTRAIN_ID) chosenHomogenization - do c = 1, homogenization_Nconstituents(material_homogenizationAt(el)) - dPdFs(:,:,:,:,c) = crystallite_stressTangent(c,ip,el) + do co = 1, homogenization_Nconstituents(material_homogenizationAt(el)) + dPdFs(:,:,:,:,co) = crystallite_stressTangent(co,ip,el) enddo call mech_isostrain_averageStressAndItsTangent(& - homogenization_P(1:3,1:3,m), & - homogenization_dPdF(1:3,1:3,1:3,1:3,m),& + homogenization_P(1:3,1:3,ce), & + homogenization_dPdF(1:3,1:3,1:3,1:3,ce),& crystallite_P(1:3,1:3,1:homogenization_Nconstituents(material_homogenizationAt(el)),ip,el), & dPdFs, & homogenization_typeInstance(material_homogenizationAt(el))) case (HOMOGENIZATION_RGC_ID) chosenHomogenization - do c = 1, homogenization_Nconstituents(material_homogenizationAt(el)) - dPdFs(:,:,:,:,c) = crystallite_stressTangent(c,ip,el) + do co = 1, homogenization_Nconstituents(material_homogenizationAt(el)) + dPdFs(:,:,:,:,co) = crystallite_stressTangent(co,ip,el) enddo call mech_RGC_averageStressAndItsTangent(& - homogenization_P(1:3,1:3,m), & - homogenization_dPdF(1:3,1:3,1:3,1:3,m),& + homogenization_P(1:3,1:3,ce), & + homogenization_dPdF(1:3,1:3,1:3,1:3,ce),& crystallite_P(1:3,1:3,1:homogenization_Nconstituents(material_homogenizationAt(el)),ip,el), & dPdFs, & homogenization_typeInstance(material_homogenizationAt(el))) diff --git a/src/marc/discretization_marc.f90 b/src/marc/discretization_marc.f90 index ca0b54b73..675e57bd3 100644 --- a/src/marc/discretization_marc.f90 +++ b/src/marc/discretization_marc.f90 @@ -12,7 +12,6 @@ module discretization_marc use DAMASK_interface use IO use config - use FEsolving use element use discretization use geometry_plastic_nonlocal @@ -89,9 +88,6 @@ subroutine discretization_marc_init if (debug_e < 1 .or. debug_e > nElems) call IO_error(602,ext_msg='element') if (debug_i < 1 .or. debug_i > elem%nIPs) call IO_error(602,ext_msg='IP') - FEsolving_execElem = [1,nElems] - FEsolving_execIP = [1,elem%nIPs] - allocate(cellNodeDefinition(elem%nNodes-1)) allocate(connectivity_cell(elem%NcellNodesPerCell,elem%nIPs,nElems)) call buildCells(connectivity_cell,cellNodeDefinition,& diff --git a/src/mesh/DAMASK_mesh.f90 b/src/mesh/DAMASK_mesh.f90 index 1e353892c..7369520c1 100644 --- a/src/mesh/DAMASK_mesh.f90 +++ b/src/mesh/DAMASK_mesh.f90 @@ -15,7 +15,6 @@ program DAMASK_mesh use IO use math use CPFEM2 - use FEsolving use config use discretization_mesh use FEM_Utilities diff --git a/src/mesh/FEM_utilities.f90 b/src/mesh/FEM_utilities.f90 index cb81f1f0c..2f3633e11 100644 --- a/src/mesh/FEM_utilities.f90 +++ b/src/mesh/FEM_utilities.f90 @@ -160,7 +160,7 @@ subroutine utilities_constitutiveResponse(timeinc,P_av,forwardData) print'(/,a)', ' ... evaluating constitutive response ......................................' - call materialpoint_stressAndItsTangent(timeinc) ! calculate P field + call materialpoint_stressAndItsTangent(timeinc,[1,mesh_maxNips],[1,mesh_NcpElems]) ! calculate P field cutBack = .false. ! reset cutBack status diff --git a/src/mesh/discretization_mesh.f90 b/src/mesh/discretization_mesh.f90 index 7dbd05e46..21c5feace 100644 --- a/src/mesh/discretization_mesh.f90 +++ b/src/mesh/discretization_mesh.f90 @@ -18,7 +18,6 @@ module discretization_mesh use config use discretization use results - use FEsolving use FEM_quadrature use YAML_types use prec @@ -30,7 +29,7 @@ module discretization_mesh mesh_Nboundaries, & mesh_NcpElemsGlobal - integer :: & + integer, public, protected :: & mesh_NcpElems !< total number of CP elements in mesh !!!! BEGIN DEPRECATED !!!!! @@ -174,9 +173,6 @@ subroutine discretization_mesh_init(restart) if (debug_element < 1 .or. debug_element > mesh_NcpElems) call IO_error(602,ext_msg='element') if (debug_ip < 1 .or. debug_ip > mesh_maxNips) call IO_error(602,ext_msg='IP') - FEsolving_execElem = [1,mesh_NcpElems] ! parallel loop bounds set to comprise all DAMASK elements - FEsolving_execIP = [1,mesh_maxNips] - allocate(mesh_node0(3,mesh_Nnodes),source=0.0_pReal) call discretization_init(materialAt,& From b0e5936b7ad8892f8bad96ff6297c6dda2cbbf5f Mon Sep 17 00:00:00 2001 From: Test User Date: Wed, 6 Jan 2021 17:36:47 +0100 Subject: [PATCH 144/148] [skip ci] updated version information after successful test of v3.0.0-alpha2-153-gf8dd5df0c --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index cb10a9c4f..c6d828650 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v3.0.0-alpha2-101-gab2a4a987 +v3.0.0-alpha2-153-gf8dd5df0c From a1e80c91e22a2bb5d6f8c5d94d9234fe7a17d1e1 Mon Sep 17 00:00:00 2001 From: Test User Date: Wed, 6 Jan 2021 19:28:09 +0100 Subject: [PATCH 145/148] [skip ci] updated version information after successful test of v3.0.0-alpha2-155-g6ae574693 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index cb10a9c4f..3994387c0 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v3.0.0-alpha2-101-gab2a4a987 +v3.0.0-alpha2-155-g6ae574693 From f4e3c872a03cfda383ea1aa58cc4d970a880b4b9 Mon Sep 17 00:00:00 2001 From: Test User Date: Wed, 6 Jan 2021 21:18:40 +0100 Subject: [PATCH 146/148] [skip ci] updated version information after successful test of v3.0.0-alpha2-157-g455916bc2 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index cb10a9c4f..f1a4a5928 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v3.0.0-alpha2-101-gab2a4a987 +v3.0.0-alpha2-157-g455916bc2 From a6c46fc2b15302b90fa16f19a48f0844ec0e0158 Mon Sep 17 00:00:00 2001 From: Test User Date: Wed, 6 Jan 2021 23:13:08 +0100 Subject: [PATCH 147/148] [skip ci] updated version information after successful test of v3.0.0-alpha2-160-g3c5fc3982 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index cb10a9c4f..f903b99b1 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v3.0.0-alpha2-101-gab2a4a987 +v3.0.0-alpha2-160-g3c5fc3982 From 6f65de27fcf718c98ba5a3275c5f86e63ebe5a34 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Thu, 7 Jan 2021 14:59:12 +0100 Subject: [PATCH 148/148] not used was only used for reporting (see v.2.0.0) --- examples/FEM/polyXtal/material.yaml | 2 +- src/constitutive.f90 | 218 +++++++++++++--------------- src/constitutive_mech.f90 | 148 +++++++++++-------- src/homogenization.f90 | 144 ++++++------------ src/homogenization_mech.f90 | 60 +++++++- src/homogenization_mech_RGC.f90 | 82 +++++------ src/lattice.f90 | 34 +++-- src/math.f90 | 7 +- src/prec.f90 | 32 ++-- 9 files changed, 365 insertions(+), 362 deletions(-) diff --git a/examples/FEM/polyXtal/material.yaml b/examples/FEM/polyXtal/material.yaml index c7d17657d..333073150 100644 --- a/examples/FEM/polyXtal/material.yaml +++ b/examples/FEM/polyXtal/material.yaml @@ -5,8 +5,8 @@ homogenization: phase: Aluminum: + lattice: cF mechanics: - lattice: cF output: [F, P, F_e, F_p, L_p] elasticity: {C_11: 106.75e9, C_12: 60.41e9, C_44: 28.34e9, type: hooke} plasticity: diff --git a/src/constitutive.f90 b/src/constitutive.f90 index e65ce864d..696611549 100644 --- a/src/constitutive.f90 +++ b/src/constitutive.f90 @@ -48,7 +48,6 @@ module constitutive crystallite_orientation !< current orientation real(pReal), dimension(:,:,:,:,:), allocatable :: & crystallite_F0, & !< def grad at start of FE inc - crystallite_subF, & !< def grad to be reached at end of crystallite inc crystallite_Fe, & !< current "elastic" def grad (end of converged time step) crystallite_subFp0,& !< plastic def grad at start of crystallite inc crystallite_subFi0,& !< intermediate def grad at start of crystallite inc @@ -60,9 +59,8 @@ module constitutive crystallite_P, & !< 1st Piola-Kirchhoff stress per grain crystallite_Lp, & !< current plastic velocitiy grad (end of converged time step) crystallite_S, & !< current 2nd Piola-Kirchhoff stress vector (end of converged time step) - crystallite_partitionedF0 !< def grad at start of homog inc - real(pReal), dimension(:,:,:,:,:), allocatable, public :: & - crystallite_partitionedF !< def grad to be reached at end of homog inc + crystallite_partitionedF0, & !< def grad at start of homog inc + crystallite_F !< def grad to be reached at end of homog inc type :: tTensorContainer real(pReal), dimension(:,:,:), allocatable :: data @@ -179,6 +177,14 @@ module constitutive module subroutine constitutive_mech_forward end subroutine constitutive_mech_forward + module subroutine mech_restore(ip,el,includeL) + integer, intent(in) :: & + ip, & + el + logical, intent(in) :: & + includeL + end subroutine mech_restore + ! == cleaned:end =================================================================================== module function crystallite_stress(dt,co,ip,el) result(converged_) @@ -392,8 +398,7 @@ module constitutive crystallite_restartRead, & constitutive_initializeRestorationPoints, & constitutive_windForward, & - crystallite_restore, & - PLASTICITY_UNDEFINED_ID, & + PLASTICITY_UNDEFINED_ID, & PLASTICITY_NONE_ID, & PLASTICITY_ISOTROPIC_ID, & PLASTICITY_PHENOPOWERLAW_ID, & @@ -734,20 +739,21 @@ subroutine constitutive_allocateState(state, & sizeDotState, & sizeDeltaState + state%sizeState = sizeState state%sizeDotState = sizeDotState state%sizeDeltaState = sizeDeltaState state%offsetDeltaState = sizeState-sizeDeltaState ! deltaState occupies latter part of state by definition - allocate(state%atol (sizeState), source=0.0_pReal) - allocate(state%state0 (sizeState,Nconstituents), source=0.0_pReal) + allocate(state%atol (sizeState), source=0.0_pReal) + allocate(state%state0 (sizeState,Nconstituents), source=0.0_pReal) allocate(state%partitionedState0(sizeState,Nconstituents), source=0.0_pReal) - allocate(state%subState0 (sizeState,Nconstituents), source=0.0_pReal) - allocate(state%state (sizeState,Nconstituents), source=0.0_pReal) + allocate(state%subState0 (sizeState,Nconstituents), source=0.0_pReal) + allocate(state%state (sizeState,Nconstituents), source=0.0_pReal) - allocate(state%dotState (sizeDotState,Nconstituents), source=0.0_pReal) + allocate(state%dotState (sizeDotState,Nconstituents), source=0.0_pReal) - allocate(state%deltaState(sizeDeltaState,Nconstituents), source=0.0_pReal) + allocate(state%deltaState (sizeDeltaState,Nconstituents), source=0.0_pReal) end subroutine constitutive_allocateState @@ -756,22 +762,27 @@ end subroutine constitutive_allocateState !-------------------------------------------------------------------------------------------------- !> @brief Restore data after homog cutback. !-------------------------------------------------------------------------------------------------- -subroutine constitutive_restore(ip,el) +subroutine constitutive_restore(ip,el,includeL) + logical, intent(in) :: includeL integer, intent(in) :: & ip, & !< integration point number el !< element number + integer :: & co, & !< constituent number - s + so + do co = 1,homogenization_Nconstituents(material_homogenizationAt(el)) - do s = 1, phase_Nsources(material_phaseAt(co,el)) - sourceState(material_phaseAt(co,el))%p(s)%state( :,material_phasememberAt(co,ip,el)) = & - sourceState(material_phaseAt(co,el))%p(s)%partitionedState0(:,material_phasememberAt(co,ip,el)) + do so = 1, phase_Nsources(material_phaseAt(co,el)) + sourceState(material_phaseAt(co,el))%p(so)%state( :,material_phasememberAt(co,ip,el)) = & + sourceState(material_phaseAt(co,el))%p(so)%partitionedState0(:,material_phasememberAt(co,ip,el)) enddo enddo + call mech_restore(ip,el,includeL) + end subroutine constitutive_restore @@ -783,7 +794,7 @@ subroutine constitutive_forward integer :: i, j - crystallite_F0 = crystallite_partitionedF + crystallite_F0 = crystallite_F crystallite_Lp0 = crystallite_Lp crystallite_S0 = crystallite_S @@ -830,12 +841,13 @@ subroutine crystallite_init Nconstituents, & ph, & me, & - co, & !< counter in integration point component loop - ip, & !< counter in integration point loop - el, & !< counter in element loop + co, & !< counter in integration point component loop + ip, & !< counter in integration point loop + el, & !< counter in element loop cMax, & !< maximum number of integration point components iMax, & !< maximum number of integration points eMax !< maximum number of elements + class(tNode), pointer :: & num_crystallite, & @@ -854,23 +866,21 @@ subroutine crystallite_init iMax = discretization_nIPs eMax = discretization_Nelems - allocate(crystallite_partitionedF(3,3,cMax,iMax,eMax),source=0.0_pReal) + allocate(crystallite_F(3,3,cMax,iMax,eMax),source=0.0_pReal) allocate(crystallite_S0, & crystallite_F0,crystallite_Lp0, & crystallite_partitionedS0, & crystallite_partitionedF0,& - crystallite_partitionedLp0, & + crystallite_partitionedLp0, & crystallite_S,crystallite_P, & crystallite_Fe,crystallite_Lp, & - crystallite_subF, & crystallite_subFp0,crystallite_subFi0, & - source = crystallite_partitionedF) + source = crystallite_F) allocate(crystallite_subdt(cMax,iMax,eMax),source=0.0_pReal) allocate(crystallite_orientation(cMax,iMax,eMax)) - num_crystallite => config_numerics%get('crystallite',defaultVal=emptyDict) num%subStepMinCryst = num_crystallite%get_asFloat ('subStepMin', defaultVal=1.0e-3_pReal) @@ -933,8 +943,8 @@ subroutine crystallite_init flush(IO_STDOUT) !$OMP PARALLEL DO PRIVATE(ph,me) - do el = 1, size(material_phaseMemberAt,3) - do ip = 1, size(material_phaseMemberAt,2); do co = 1, homogenization_Nconstituents(material_homogenizationAt(el)) + do el = 1, size(material_phaseMemberAt,3); do ip = 1, size(material_phaseMemberAt,2) + do co = 1, homogenization_Nconstituents(material_homogenizationAt(el)) ph = material_phaseAt(co,el) me = material_phaseMemberAt(co,ip,el) @@ -953,12 +963,12 @@ subroutine crystallite_init constitutive_mech_partitionedFi0(ph)%data(1:3,1:3,me) = constitutive_mech_Fi0(ph)%data(1:3,1:3,me) constitutive_mech_partitionedFp0(ph)%data(1:3,1:3,me) = constitutive_mech_Fp0(ph)%data(1:3,1:3,me) - enddo; enddo - enddo + enddo + enddo; enddo !$OMP END PARALLEL DO crystallite_partitionedF0 = crystallite_F0 - crystallite_partitionedF = crystallite_F0 + crystallite_F = crystallite_F0 !$OMP PARALLEL DO PRIVATE(ph,me) @@ -978,9 +988,6 @@ subroutine crystallite_init end subroutine crystallite_init - - - !-------------------------------------------------------------------------------------------------- !> @brief Backup data for homog cutback. !-------------------------------------------------------------------------------------------------- @@ -991,7 +998,7 @@ subroutine constitutive_initializeRestorationPoints(ip,el) el !< element number integer :: & co, & !< constituent number - s,ph, me + so,ph, me do co = 1,homogenization_Nconstituents(material_homogenizationAt(el)) ph = material_phaseAt(co,el) @@ -1002,9 +1009,9 @@ subroutine constitutive_initializeRestorationPoints(ip,el) call mech_initializeRestorationPoints(ph,me) - do s = 1, phase_Nsources(material_phaseAt(co,el)) - sourceState(material_phaseAt(co,el))%p(s)%partitionedState0(:,material_phasememberAt(co,ip,el)) = & - sourceState(material_phaseAt(co,el))%p(s)%state0( :,material_phasememberAt(co,ip,el)) + do so = 1, phase_Nsources(material_phaseAt(co,el)) + sourceState(material_phaseAt(co,el))%p(so)%partitionedState0(:,material_phasememberAt(co,ip,el)) = & + sourceState(material_phaseAt(co,el))%p(so)%state0( :,material_phasememberAt(co,ip,el)) enddo enddo @@ -1019,57 +1026,28 @@ subroutine constitutive_windForward(ip,el) integer, intent(in) :: & ip, & !< integration point number el !< element number + integer :: & co, & !< constituent number - s, ph, me + so, ph, me + + do co = 1,homogenization_Nconstituents(material_homogenizationAt(el)) ph = material_phaseAt(co,el) me = material_phaseMemberAt(co,ip,el) - crystallite_partitionedF0 (1:3,1:3,co,ip,el) = crystallite_partitionedF(1:3,1:3,co,ip,el) - crystallite_partitionedLp0(1:3,1:3,co,ip,el) = crystallite_Lp (1:3,1:3,co,ip,el) - crystallite_partitionedS0 (1:3,1:3,co,ip,el) = crystallite_S (1:3,1:3,co,ip,el) + crystallite_partitionedF0 (1:3,1:3,co,ip,el) = crystallite_F (1:3,1:3,co,ip,el) + crystallite_partitionedLp0(1:3,1:3,co,ip,el) = crystallite_Lp(1:3,1:3,co,ip,el) + crystallite_partitionedS0 (1:3,1:3,co,ip,el) = crystallite_S (1:3,1:3,co,ip,el) call constitutive_mech_windForward(ph,me) - do s = 1, phase_Nsources(material_phaseAt(co,el)) - sourceState(ph)%p(s)%partitionedState0(:,me) = sourceState(ph)%p(s)%state(:,me) + do so = 1, phase_Nsources(material_phaseAt(co,el)) + sourceState(ph)%p(so)%partitionedState0(:,me) = sourceState(ph)%p(so)%state(:,me) enddo enddo end subroutine constitutive_windForward -!-------------------------------------------------------------------------------------------------- -!> @brief Restore data after homog cutback. -!-------------------------------------------------------------------------------------------------- -subroutine crystallite_restore(ip,el,includeL) - - integer, intent(in) :: & - ip, & !< integration point number - el !< element number - logical, intent(in) :: & - includeL !< protect agains fake cutback - integer :: & - co, p, m !< constituent number - - do co = 1,homogenization_Nconstituents(material_homogenizationAt(el)) - p = material_phaseAt(co,el) - m = material_phaseMemberAt(co,ip,el) - if (includeL) then - crystallite_Lp(1:3,1:3,co,ip,el) = crystallite_partitionedLp0(1:3,1:3,co,ip,el) - constitutive_mech_Li(p)%data(1:3,1:3,m) = constitutive_mech_partitionedLi0(p)%data(1:3,1:3,m) - endif ! maybe protecting everything from overwriting makes more sense - - constitutive_mech_Fp(p)%data(1:3,1:3,m) = constitutive_mech_partitionedFp0(p)%data(1:3,1:3,m) - constitutive_mech_Fi(p)%data(1:3,1:3,m) = constitutive_mech_partitionedFi0(p)%data(1:3,1:3,m) - crystallite_S (1:3,1:3,co,ip,el) = crystallite_partitionedS0 (1:3,1:3,co,ip,el) - - plasticState (material_phaseAt(co,el))%state( :,material_phasememberAt(co,ip,el)) = & - plasticState (material_phaseAt(co,el))%partitionedState0(:,material_phasememberAt(co,ip,el)) - enddo - -end subroutine crystallite_restore - - !-------------------------------------------------------------------------------------------------- !> @brief Calculate tangent (dPdF). !-------------------------------------------------------------------------------------------------- @@ -1080,13 +1058,13 @@ function crystallite_stressTangent(co,ip,el) result(dPdF) co, & !< counter in constituent loop ip, & !< counter in integration point loop el !< counter in element loop + integer :: & o, & p, ph, me - real(pReal), dimension(3,3) :: devNull, & invSubFp0,invSubFi0,invFp,invFi, & - temp_33_1, temp_33_2, temp_33_3, temp_33_4 + temp_33_1, temp_33_2, temp_33_3 real(pReal), dimension(3,3,3,3) :: dSdFe, & dSdF, & dSdFi, & @@ -1102,6 +1080,7 @@ function crystallite_stressTangent(co,ip,el) result(dPdF) real(pReal), dimension(9,9):: temp_99 logical :: error + ph = material_phaseAt(co,el) me = material_phaseMemberAt(co,ip,el) @@ -1149,8 +1128,8 @@ function crystallite_stressTangent(co,ip,el) result(dPdF) !-------------------------------------------------------------------------------------------------- ! calculate dSdF temp_33_1 = transpose(matmul(invFp,invFi)) - temp_33_2 = matmul(crystallite_subF(1:3,1:3,co,ip,el),invSubFp0) - temp_33_3 = matmul(matmul(crystallite_subF(1:3,1:3,co,ip,el),invFp), invSubFi0) + temp_33_2 = matmul(crystallite_F(1:3,1:3,co,ip,el),invSubFp0) + temp_33_3 = matmul(matmul(crystallite_F(1:3,1:3,co,ip,el),invFp), invSubFi0) 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) @@ -1180,21 +1159,20 @@ function crystallite_stressTangent(co,ip,el) result(dPdF) !-------------------------------------------------------------------------------------------------- ! assemble dPdF temp_33_1 = matmul(crystallite_S(1:3,1:3,co,ip,el),transpose(invFp)) - temp_33_2 = matmul(invFp,temp_33_1) - temp_33_3 = matmul(crystallite_subF(1:3,1:3,co,ip,el),invFp) - temp_33_4 = matmul(temp_33_3,crystallite_S(1:3,1:3,co,ip,el)) + temp_33_2 = matmul(crystallite_F(1:3,1:3,co,ip,el),invFp) + temp_33_3 = matmul(temp_33_2,crystallite_S(1:3,1:3,co,ip,el)) dPdF = 0.0_pReal do p=1,3 - dPdF(p,1:3,p,1:3) = transpose(temp_33_2) + dPdF(p,1:3,p,1:3) = transpose(matmul(invFp,temp_33_1)) enddo do o=1,3; do p=1,3 dPdF(1:3,1:3,p,o) = dPdF(1:3,1:3,p,o) & - + matmul(matmul(crystallite_subF(1:3,1:3,co,ip,el), & + + matmul(matmul(crystallite_F(1:3,1:3,co,ip,el), & 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_2,dSdF(1:3,1:3,p,o)), & transpose(invFp)) & - + matmul(temp_33_4,transpose(dFpinvdF(1:3,1:3,p,o))) + + matmul(temp_33_3,transpose(dFpinvdF(1:3,1:3,p,o))) enddo; enddo end function crystallite_stressTangent @@ -1237,7 +1215,7 @@ function crystallite_push33ToRef(co,ip,el, tensor33) T = matmul(material_orientation0(co,ip,el)%asMatrix(), & ! ToDo: initial orientation correct? - transpose(math_inv33(crystallite_subF(1:3,1:3,co,ip,el)))) + transpose(math_inv33(crystallite_F(1:3,1:3,co,ip,el)))) crystallite_push33ToRef = matmul(transpose(T),matmul(tensor33,T)) end function crystallite_push33ToRef @@ -1247,8 +1225,9 @@ end function crystallite_push33ToRef !> @brief integrate stress, state with adaptive 1st order explicit Euler method !> using Fixed Point Iteration to adapt the stepsize !-------------------------------------------------------------------------------------------------- -function integrateSourceState(co,ip,el) result(broken) +function integrateSourceState(dt,co,ip,el) result(broken) + real(pReal), intent(in) :: dt integer, intent(in) :: & el, & !< element index in element loop ip, & !< integration point index in ip loop @@ -1281,8 +1260,7 @@ function integrateSourceState(co,ip,el) result(broken) do so = 1, phase_Nsources(ph) size_so(so) = sourceState(ph)%p(so)%sizeDotState sourceState(ph)%p(so)%state(1:size_so(so),me) = sourceState(ph)%p(so)%subState0(1:size_so(so),me) & - + sourceState(ph)%p(so)%dotState (1:size_so(so),me) & - * crystallite_subdt(co,ip,el) + + sourceState(ph)%p(so)%dotState (1:size_so(so),me) * dt source_dotState(1:size_so(so),2,so) = 0.0_pReal enddo @@ -1304,8 +1282,8 @@ function integrateSourceState(co,ip,el) result(broken) sourceState(ph)%p(so)%dotState(:,me) = sourceState(ph)%p(so)%dotState(:,me) * zeta & + source_dotState(1:size_so(so),1,so)* (1.0_pReal - zeta) r(1:size_so(so)) = sourceState(ph)%p(so)%state (1:size_so(so),me) & - - sourceState(ph)%p(so)%subState0(1:size_so(so),me) & - - sourceState(ph)%p(so)%dotState (1:size_so(so),me) * crystallite_subdt(co,ip,el) + - sourceState(ph)%p(so)%subState0(1:size_so(so),me) & + - sourceState(ph)%p(so)%dotState (1:size_so(so),me) * dt sourceState(ph)%p(so)%state(1:size_so(so),me) = sourceState(ph)%p(so)%state(1:size_so(so),me) & - r(1:size_so(so)) converged_ = converged_ .and. converged(r(1:size_so(so)), & @@ -1371,7 +1349,7 @@ end function converged !-------------------------------------------------------------------------------------------------- subroutine crystallite_restartWrite - integer :: i + integer :: ph integer(HID_T) :: fileHandle, groupHandle character(len=pStringLen) :: fileName, datasetName @@ -1380,27 +1358,27 @@ subroutine crystallite_restartWrite write(fileName,'(a,i0,a)') trim(getSolverJobName())//'_',worldrank,'.hdf5' fileHandle = HDF5_openFile(fileName,'a') - call HDF5_write(fileHandle,crystallite_partitionedF,'F') + call HDF5_write(fileHandle,crystallite_F,'F') call HDF5_write(fileHandle,crystallite_Lp, 'L_p') call HDF5_write(fileHandle,crystallite_S, 'S') groupHandle = HDF5_addGroup(fileHandle,'phase') - do i = 1,size(material_name_phase) - write(datasetName,'(i0,a)') i,'_omega' - call HDF5_write(groupHandle,plasticState(i)%state,datasetName) - write(datasetName,'(i0,a)') i,'_F_i' - call HDF5_write(groupHandle,constitutive_mech_Fi(i)%data,datasetName) - write(datasetName,'(i0,a)') i,'_L_i' - call HDF5_write(groupHandle,constitutive_mech_Li(i)%data,datasetName) - write(datasetName,'(i0,a)') i,'_F_p' - call HDF5_write(groupHandle,constitutive_mech_Fp(i)%data,datasetName) + do ph = 1,size(material_name_phase) + write(datasetName,'(i0,a)') ph,'_omega' + call HDF5_write(groupHandle,plasticState(ph)%state,datasetName) + write(datasetName,'(i0,a)') ph,'_F_i' + call HDF5_write(groupHandle,constitutive_mech_Fi(ph)%data,datasetName) + write(datasetName,'(i0,a)') ph,'_L_i' + call HDF5_write(groupHandle,constitutive_mech_Li(ph)%data,datasetName) + write(datasetName,'(i0,a)') ph,'_F_p' + call HDF5_write(groupHandle,constitutive_mech_Fp(ph)%data,datasetName) enddo call HDF5_closeGroup(groupHandle) groupHandle = HDF5_addGroup(fileHandle,'homogenization') - do i = 1, size(material_name_homogenization) - write(datasetName,'(i0,a)') i,'_omega' - call HDF5_write(groupHandle,homogState(i)%state,datasetName) + do ph = 1, size(material_name_homogenization) + write(datasetName,'(i0,a)') ph,'_omega' + call HDF5_write(groupHandle,homogState(ph)%state,datasetName) enddo call HDF5_closeGroup(groupHandle) @@ -1415,7 +1393,7 @@ end subroutine crystallite_restartWrite !-------------------------------------------------------------------------------------------------- subroutine crystallite_restartRead - integer :: i + integer :: ph integer(HID_T) :: fileHandle, groupHandle character(len=pStringLen) :: fileName, datasetName @@ -1429,22 +1407,22 @@ subroutine crystallite_restartRead call HDF5_read(fileHandle,crystallite_S0, 'S') groupHandle = HDF5_openGroup(fileHandle,'phase') - do i = 1,size(material_name_phase) - write(datasetName,'(i0,a)') i,'_omega' - call HDF5_read(groupHandle,plasticState(i)%state0,datasetName) - write(datasetName,'(i0,a)') i,'_F_i' - call HDF5_read(groupHandle,constitutive_mech_Fi0(i)%data,datasetName) - write(datasetName,'(i0,a)') i,'_L_i' - call HDF5_read(groupHandle,constitutive_mech_Li0(i)%data,datasetName) - write(datasetName,'(i0,a)') i,'_F_p' - call HDF5_read(groupHandle,constitutive_mech_Fp0(i)%data,datasetName) + do ph = 1,size(material_name_phase) + write(datasetName,'(i0,a)') ph,'_omega' + call HDF5_read(groupHandle,plasticState(ph)%state0,datasetName) + write(datasetName,'(i0,a)') ph,'_F_i' + call HDF5_read(groupHandle,constitutive_mech_Fi0(ph)%data,datasetName) + write(datasetName,'(i0,a)') ph,'_L_i' + call HDF5_read(groupHandle,constitutive_mech_Li0(ph)%data,datasetName) + write(datasetName,'(i0,a)') ph,'_F_p' + call HDF5_read(groupHandle,constitutive_mech_Fp0(ph)%data,datasetName) enddo call HDF5_closeGroup(groupHandle) groupHandle = HDF5_openGroup(fileHandle,'homogenization') - do i = 1,size(material_name_homogenization) - write(datasetName,'(i0,a)') i,'_omega' - call HDF5_read(groupHandle,homogState(i)%state0,datasetName) + do ph = 1,size(material_name_homogenization) + write(datasetName,'(i0,a)') ph,'_omega' + call HDF5_read(groupHandle,homogState(ph)%state0,datasetName) enddo call HDF5_closeGroup(groupHandle) diff --git a/src/constitutive_mech.f90 b/src/constitutive_mech.f90 index de6f2ae9f..c48c59ec9 100644 --- a/src/constitutive_mech.f90 +++ b/src/constitutive_mech.f90 @@ -800,7 +800,7 @@ function integrateStress(F,Delta_t,co,ip,el) result(broken) broken = .true. - call constitutive_plastic_dependentState(crystallite_partitionedF(1:3,1:3,co,ip,el),co,ip,el) + call constitutive_plastic_dependentState(crystallite_F(1:3,1:3,co,ip,el),co,ip,el) ph = material_phaseAt(co,el) me = material_phaseMemberAt(co,ip,el) @@ -959,19 +959,21 @@ function integrateStateFPI(F_0,F,Delta_t,co,ip,el) result(broken) el, & !< element index in element loop ip, & !< integration point index in ip loop co !< grain index in grain loop + logical :: & + broken + integer :: & NiterationState, & !< number of iterations in state loop ph, & me, & - size_pl + sizeDotState real(pReal) :: & zeta real(pReal), dimension(constitutive_plasticity_maxSizeDotState) :: & r ! state residuum real(pReal), dimension(constitutive_plasticity_maxSizeDotState,2) :: & - plastic_dotState - logical :: & - broken + dotState + ph = material_phaseAt(co,el) me = material_phaseMemberAt(co,ip,el) @@ -979,15 +981,15 @@ function integrateStateFPI(F_0,F,Delta_t,co,ip,el) result(broken) broken = mech_collectDotState(Delta_t, co,ip,el,ph,me) if(broken) return - size_pl = plasticState(ph)%sizeDotState - plasticState(ph)%state(1:size_pl,me) = plasticState(ph)%subState0(1:size_pl,me) & - + plasticState(ph)%dotState (1:size_pl,me) * Delta_t - plastic_dotState(1:size_pl,2) = 0.0_pReal + sizeDotState = plasticState(ph)%sizeDotState + plasticState(ph)%state(1:sizeDotState,me) = plasticState(ph)%subState0(1:sizeDotState,me) & + + plasticState(ph)%dotState (1:sizeDotState,me) * Delta_t + dotState(1:sizeDotState,2) = 0.0_pReal iteration: do NiterationState = 1, num%nState - if(nIterationState > 1) plastic_dotState(1:size_pl,2) = plastic_dotState(1:size_pl,1) - plastic_dotState(1:size_pl,1) = plasticState(ph)%dotState(:,me) + if(nIterationState > 1) dotState(1:sizeDotState,2) = dotState(1:sizeDotState,1) + dotState(1:sizeDotState,1) = plasticState(ph)%dotState(:,me) broken = integrateStress(F,Delta_t,co,ip,el) if(broken) exit iteration @@ -995,16 +997,16 @@ function integrateStateFPI(F_0,F,Delta_t,co,ip,el) result(broken) broken = mech_collectDotState(Delta_t, co,ip,el,ph,me) if(broken) exit iteration - zeta = damper(plasticState(ph)%dotState(:,me),plastic_dotState(1:size_pl,1),& - plastic_dotState(1:size_pl,2)) + zeta = damper(plasticState(ph)%dotState(:,me),dotState(1:sizeDotState,1),& + dotState(1:sizeDotState,2)) plasticState(ph)%dotState(:,me) = plasticState(ph)%dotState(:,me) * zeta & - + plastic_dotState(1:size_pl,1) * (1.0_pReal - zeta) - r(1:size_pl) = plasticState(ph)%state (1:size_pl,me) & - - plasticState(ph)%subState0(1:size_pl,me) & - - plasticState(ph)%dotState (1:size_pl,me) * Delta_t - plasticState(ph)%state(1:size_pl,me) = plasticState(ph)%state(1:size_pl,me) & - - r(1:size_pl) - if (converged(r(1:size_pl),plasticState(ph)%state(1:size_pl,me),plasticState(ph)%atol(1:size_pl))) then + + dotState(1:sizeDotState,1) * (1.0_pReal - zeta) + r(1:sizeDotState) = plasticState(ph)%state (1:sizeDotState,me) & + - plasticState(ph)%subState0(1:sizeDotState,me) & + - plasticState(ph)%dotState (1:sizeDotState,me) * Delta_t + plasticState(ph)%state(1:sizeDotState,me) = plasticState(ph)%state(1:sizeDotState,me) & + - r(1:sizeDotState) + if (converged(r(1:sizeDotState),plasticState(ph)%state(1:sizeDotState,me),plasticState(ph)%atol(1:sizeDotState))) then broken = constitutive_deltaState(crystallite_S(1:3,1:3,co,ip,el), & constitutive_mech_Fi(ph)%data(1:3,1:3,me),co,ip,el,ph,me) exit iteration @@ -1012,6 +1014,7 @@ function integrateStateFPI(F_0,F,Delta_t,co,ip,el) result(broken) enddo iteration + contains !-------------------------------------------------------------------------------------------------- @@ -1048,12 +1051,14 @@ function integrateStateEuler(F_0,F,Delta_t,co,ip,el) result(broken) el, & !< element index in element loop ip, & !< integration point index in ip loop co !< grain index in grain loop + logical :: & + broken + integer :: & ph, & me, & sizeDotState - logical :: & - broken + ph = material_phaseAt(co,el) me = material_phaseMemberAt(co,ip,el) @@ -1085,13 +1090,13 @@ function integrateStateAdaptiveEuler(F_0,F,Delta_t,co,ip,el) result(broken) el, & !< element index in element loop ip, & !< integration point index in ip loop co !< grain index in grain loop + logical :: & + broken + integer :: & ph, & me, & sizeDotState - logical :: & - broken - real(pReal), dimension(constitutive_plasticity_maxSizeDotState) :: residuum_plastic @@ -1105,7 +1110,7 @@ function integrateStateAdaptiveEuler(F_0,F,Delta_t,co,ip,el) result(broken) residuum_plastic(1:sizeDotState) = - plasticState(ph)%dotstate(1:sizeDotState,me) * 0.5_pReal * Delta_t plasticState(ph)%state(1:sizeDotState,me) = plasticState(ph)%subState0(1:sizeDotState,me) & - + plasticState(ph)%dotstate(1:sizeDotState,me) * Delta_t + + plasticState(ph)%dotstate(1:sizeDotState,me) * Delta_t broken = constitutive_deltaState(crystallite_S(1:3,1:3,co,ip,el), & constitutive_mech_Fi(ph)%data(1:3,1:3,me),co,ip,el,ph,me) @@ -1145,6 +1150,7 @@ function integrateStateRK4(F_0,F,Delta_t,co,ip,el) result(broken) real(pReal), dimension(4), parameter :: & B = [1.0_pReal/6.0_pReal, 1.0_pReal/3.0_pReal, 1.0_pReal/3.0_pReal, 1.0_pReal/6.0_pReal] + broken = integrateStateRK(F_0,F,Delta_t,co,ip,el,A,B,C) end function integrateStateRK4 @@ -1178,6 +1184,7 @@ function integrateStateRKCK45(F_0,F,Delta_t,co,ip,el) result(broken) [2825.0_pReal/27648.0_pReal, .0_pReal, 18575.0_pReal/48384.0_pReal,& 13525.0_pReal/55296.0_pReal, 277.0_pReal/14336.0_pReal, 1._pReal/4._pReal] + broken = integrateStateRK(F_0,F,Delta_t,co,ip,el,A,B,C,DB) end function integrateStateRKCK45 @@ -1215,18 +1222,18 @@ function integrateStateRK(F_0,F,Delta_t,co,ip,el,A,B,C,DB) result(broken) broken = mech_collectDotState(Delta_t,co,ip,el,ph,me) if(broken) return + sizeDotState = plasticState(ph)%sizeDotState + do stage = 1, size(A,1) - sizeDotState = plasticState(ph)%sizeDotState + plastic_RKdotState(1:sizeDotState,stage) = plasticState(ph)%dotState(:,me) plasticState(ph)%dotState(:,me) = A(1,stage) * plastic_RKdotState(1:sizeDotState,1) do n = 2, stage - sizeDotState = plasticState(ph)%sizeDotState plasticState(ph)%dotState(:,me) = plasticState(ph)%dotState(:,me) & - + A(n,stage) * plastic_RKdotState(1:sizeDotState,n) + + A(n,stage) * plastic_RKdotState(1:sizeDotState,n) enddo - sizeDotState = plasticState(ph)%sizeDotState plasticState(ph)%state(1:sizeDotState,me) = plasticState(ph)%subState0(1:sizeDotState,me) & + plasticState(ph)%dotState (1:sizeDotState,me) * Delta_t @@ -1239,7 +1246,6 @@ function integrateStateRK(F_0,F,Delta_t,co,ip,el,A,B,C,DB) result(broken) enddo if(broken) return - sizeDotState = plasticState(ph)%sizeDotState plastic_RKdotState(1:sizeDotState,size(B)) = plasticState (ph)%dotState(:,me) plasticState(ph)%dotState(:,me) = matmul(plastic_RKdotState(1:sizeDotState,1:size(B)),B) @@ -1282,7 +1288,7 @@ subroutine crystallite_results(group,ph) select case (output_constituent(ph)%label(ou)) case('F') - selected_tensors = select_tensors(crystallite_partitionedF,ph) + selected_tensors = select_tensors(crystallite_F,ph) call results_writeDataset(group//'/mechanics/',selected_tensors,output_constituent(ph)%label(ou),& 'deformation gradient','1') case('F_e') @@ -1482,25 +1488,24 @@ module function crystallite_stress(dt,co,ip,el) result(converged_) formerSubStep integer :: & NiterationCrystallite, & ! number of iterations in crystallite loop - s, ph, me + so, ph, me logical :: todo real(pReal) :: subFrac,subStep real(pReal), dimension(3,3) :: & subLp0, & !< plastic velocity grad at start of crystallite inc subLi0, & !< intermediate velocity grad at start of crystallite inc - subF0 + subF0, & + subF ph = material_phaseAt(co,el) me = material_phaseMemberAt(co,ip,el) subLi0 = constitutive_mech_partitionedLi0(ph)%data(1:3,1:3,me) subLp0 = crystallite_partitionedLp0(1:3,1:3,co,ip,el) - plasticState (material_phaseAt(co,el))%subState0( :,material_phaseMemberAt(co,ip,el)) = & - plasticState (material_phaseAt(co,el))%partitionedState0(:,material_phaseMemberAt(co,ip,el)) - do s = 1, phase_Nsources(material_phaseAt(co,el)) - sourceState(material_phaseAt(co,el))%p(s)%subState0( :,material_phaseMemberAt(co,ip,el)) = & - sourceState(material_phaseAt(co,el))%p(s)%partitionedState0(:,material_phaseMemberAt(co,ip,el)) + plasticState(ph)%subState0(:,me) = plasticState(ph)%partitionedState0(:,me) + do so = 1, phase_Nsources(ph) + sourceState(ph)%p(so)%subState0(:,me) = sourceState(ph)%p(so)%partitionedState0(:,me) enddo crystallite_subFp0(1:3,1:3,co,ip,el) = constitutive_mech_partitionedFp0(ph)%data(1:3,1:3,me) crystallite_subFi0(1:3,1:3,co,ip,el) = constitutive_mech_partitionedFi0(ph)%data(1:3,1:3,me) @@ -1525,16 +1530,14 @@ module function crystallite_stress(dt,co,ip,el) result(converged_) todo = subStep > 0.0_pReal ! still time left to integrate on? if (todo) then - subF0 = crystallite_subF(1:3,1:3,co,ip,el) + subF0 = subF subLp0 = crystallite_Lp (1:3,1:3,co,ip,el) subLi0 = constitutive_mech_Li(ph)%data(1:3,1:3,me) crystallite_subFp0(1:3,1:3,co,ip,el) = constitutive_mech_Fp(ph)%data(1:3,1:3,me) crystallite_subFi0(1:3,1:3,co,ip,el) = constitutive_mech_Fi(ph)%data(1:3,1:3,me) - plasticState( material_phaseAt(co,el))%subState0(:,material_phaseMemberAt(co,ip,el)) & - = plasticState(material_phaseAt(co,el))%state( :,material_phaseMemberAt(co,ip,el)) - do s = 1, phase_Nsources(material_phaseAt(co,el)) - sourceState( material_phaseAt(co,el))%p(s)%subState0(:,material_phaseMemberAt(co,ip,el)) & - = sourceState(material_phaseAt(co,el))%p(s)%state( :,material_phaseMemberAt(co,ip,el)) + plasticState(ph)%subState0(:,me) = plasticState(ph)%state(:,me) + do so = 1, phase_Nsources(ph) + sourceState(ph)%p(so)%subState0(:,me) = sourceState(ph)%p(so)%state(:,me) enddo endif !-------------------------------------------------------------------------------------------------- @@ -1548,11 +1551,9 @@ module function crystallite_stress(dt,co,ip,el) result(converged_) crystallite_Lp (1:3,1:3,co,ip,el) = subLp0 constitutive_mech_Li(ph)%data(1:3,1:3,me) = subLi0 endif - plasticState (material_phaseAt(co,el))%state( :,material_phaseMemberAt(co,ip,el)) & - = plasticState(material_phaseAt(co,el))%subState0(:,material_phaseMemberAt(co,ip,el)) - do s = 1, phase_Nsources(material_phaseAt(co,el)) - sourceState( material_phaseAt(co,el))%p(s)%state( :,material_phaseMemberAt(co,ip,el)) & - = sourceState(material_phaseAt(co,el))%p(s)%subState0(:,material_phaseMemberAt(co,ip,el)) + plasticState(ph)%state(:,me) = plasticState(ph)%subState0(:,me) + do so = 1, phase_Nsources(ph) + sourceState(ph)%p(so)%state(:,me) = sourceState(ph)%p(so)%subState0(:,me) enddo todo = subStep > num%subStepMinCryst ! still on track or already done (beyond repair) @@ -1561,21 +1562,50 @@ module function crystallite_stress(dt,co,ip,el) result(converged_) !-------------------------------------------------------------------------------------------------- ! prepare for integration if (todo) then - crystallite_subF(1:3,1:3,co,ip,el) = subF0 & - + subStep *( crystallite_partitionedF (1:3,1:3,co,ip,el) & - -crystallite_partitionedF0(1:3,1:3,co,ip,el)) - crystallite_Fe(1:3,1:3,co,ip,el) = matmul(crystallite_subF(1:3,1:3,co,ip,el), & - math_inv33(matmul(constitutive_mech_Fi(ph)%data(1:3,1:3,me), & - constitutive_mech_Fp(ph)%data(1:3,1:3,me)))) + subF = subF0 & + + subStep * (crystallite_F(1:3,1:3,co,ip,el) - crystallite_partitionedF0(1:3,1:3,co,ip,el)) + crystallite_Fe(1:3,1:3,co,ip,el) = matmul(subF,math_inv33(matmul(constitutive_mech_Fi(ph)%data(1:3,1:3,me), & + constitutive_mech_Fp(ph)%data(1:3,1:3,me)))) crystallite_subdt(co,ip,el) = subStep * dt - converged_ = .not. integrateState(subF0,crystallite_subF(1:3,1:3,co,ip,el),& - crystallite_subdt(co,ip,el),co,ip,el) - converged_ = converged_ .and. .not. integrateSourceState(co,ip,el) + converged_ = .not. integrateState(subF0,subF,subStep * dt,co,ip,el) + converged_ = converged_ .and. .not. integrateSourceState(subStep * dt,co,ip,el) endif enddo cutbackLooping end function crystallite_stress + +!-------------------------------------------------------------------------------------------------- +!> @brief Restore data after homog cutback. +!-------------------------------------------------------------------------------------------------- +module subroutine mech_restore(ip,el,includeL) + + integer, intent(in) :: & + ip, & !< integration point number + el !< element number + logical, intent(in) :: & + includeL !< protect agains fake cutback + integer :: & + co, p, m !< constituent number + + do co = 1,homogenization_Nconstituents(material_homogenizationAt(el)) + p = material_phaseAt(co,el) + m = material_phaseMemberAt(co,ip,el) + if (includeL) then + crystallite_Lp(1:3,1:3,co,ip,el) = crystallite_partitionedLp0(1:3,1:3,co,ip,el) + constitutive_mech_Li(p)%data(1:3,1:3,m) = constitutive_mech_partitionedLi0(p)%data(1:3,1:3,m) + endif ! maybe protecting everything from overwriting makes more sense + + constitutive_mech_Fp(p)%data(1:3,1:3,m) = constitutive_mech_partitionedFp0(p)%data(1:3,1:3,m) + constitutive_mech_Fi(p)%data(1:3,1:3,m) = constitutive_mech_partitionedFi0(p)%data(1:3,1:3,m) + crystallite_S (1:3,1:3,co,ip,el) = crystallite_partitionedS0 (1:3,1:3,co,ip,el) + + plasticState (material_phaseAt(co,el))%state( :,material_phasememberAt(co,ip,el)) = & + plasticState (material_phaseAt(co,el))%partitionedState0(:,material_phasememberAt(co,ip,el)) + enddo + +end subroutine mech_restore + end submodule constitutive_mech diff --git a/src/homogenization.f90 b/src/homogenization.f90 index ebf5fd50d..52553b57b 100644 --- a/src/homogenization.f90 +++ b/src/homogenization.f90 @@ -70,29 +70,22 @@ module homogenization end subroutine mech_homogenize module subroutine mech_results(group_base,h) - character(len=*), intent(in) :: group_base integer, intent(in) :: h - end subroutine mech_results -! -------- ToDo --------------------------------------------------------- - module function mech_RGC_updateState(P,F,F0,avgF,dt,dPdF,ip,el) - logical, dimension(2) :: mech_RGC_updateState - real(pReal), dimension(:,:,:), intent(in) :: & - P,& !< partitioned stresses - F,& !< partitioned deformation gradients - F0 !< partitioned initial deformation gradients - real(pReal), dimension(:,:,:,:,:), intent(in) :: dPdF !< partitioned stiffnesses - real(pReal), dimension(3,3), intent(in) :: avgF !< average F - real(pReal), intent(in) :: dt !< time increment - integer, intent(in) :: & - ip, & !< integration point number - el !< element number - end function mech_RGC_updateState + module function mech_updateState(subdt,subF,ip,el) result(doneAndHappy) + real(pReal), intent(in) :: & + subdt !< current time step + real(pReal), intent(in), dimension(3,3) :: & + subF + integer, intent(in) :: & + ip, & !< integration point + el !< element number + logical, dimension(2) :: doneAndHappy + end function mech_updateState end interface -! ----------------------------------------------------------------------- public :: & homogenization_init, & @@ -148,11 +141,10 @@ subroutine materialpoint_stressAndItsTangent(dt,FEsolving_execIP,FEsolving_execE real(pReal), intent(in) :: dt !< time increment integer, dimension(2), intent(in) :: FEsolving_execElem, FEsolving_execIP integer :: & - NiterationHomog, & NiterationMPstate, & ip, & !< integration point number el, & !< element number - myNgrains, co, ce, ho + myNgrains, co, ce, ho, me real(pReal) :: & subFrac, & subStep @@ -162,12 +154,12 @@ subroutine materialpoint_stressAndItsTangent(dt,FEsolving_execIP,FEsolving_execE doneAndHappy -!$OMP PARALLEL DO PRIVATE(ce,ho,myNgrains,NiterationMPstate,NiterationHomog,subFrac,converged,subStep,doneAndHappy) + !$OMP PARALLEL DO PRIVATE(ce,me,ho,myNgrains,NiterationMPstate,subFrac,converged,subStep,doneAndHappy) do el = FEsolving_execElem(1),FEsolving_execElem(2) ho = material_homogenizationAt(el) myNgrains = homogenization_Nconstituents(ho) do ip = FEsolving_execIP(1),FEsolving_execIP(2) - + me = material_homogenizationMemberAt(ip,el) !-------------------------------------------------------------------------------------------------- ! initialize restoration points call constitutive_initializeRestorationPoints(ip,el) @@ -177,15 +169,10 @@ subroutine materialpoint_stressAndItsTangent(dt,FEsolving_execIP,FEsolving_execE subStep = 1.0_pReal/num%subStepSizeHomog ! ... larger then the requested calculation if (homogState(ho)%sizeState > 0) & - homogState(ho)%subState0(:,material_homogenizationMemberAt(ip,el)) = & - homogState(ho)%State0( :,material_homogenizationMemberAt(ip,el)) - + homogState(ho)%subState0(:,me) = homogState(ho)%State0(:,me) if (damageState(ho)%sizeState > 0) & - damageState(ho)%subState0(:,material_homogenizationMemberAt(ip,el)) = & - damageState(ho)%State0( :,material_homogenizationMemberAt(ip,el)) + damageState(ho)%subState0(:,me) = damageState(ho)%State0(:,me) - - NiterationHomog = 0 cutBackLooping: do while (.not. terminallyIll .and. subStep > num%subStepMinHomog) if (converged) then @@ -198,33 +185,26 @@ subroutine materialpoint_stressAndItsTangent(dt,FEsolving_execIP,FEsolving_execE call constitutive_windForward(ip,el) if(homogState(ho)%sizeState > 0) & - homogState(ho)%subState0(:,material_homogenizationMemberAt(ip,el)) = & - homogState(ho)%State (:,material_homogenizationMemberAt(ip,el)) + homogState(ho)%subState0(:,me) = homogState(ho)%State(:,me) if(damageState(ho)%sizeState > 0) & - damageState(ho)%subState0(:,material_homogenizationMemberAt(ip,el)) = & - damageState(ho)%State (:,material_homogenizationMemberAt(ip,el)) + damageState(ho)%subState0(:,me) = damageState(ho)%State(:,me) endif steppingNeeded - else - if ( (myNgrains == 1 .and. subStep <= 1.0 ) .or. & ! single grain already tried internal subStepping in crystallite + elseif ( (myNgrains == 1 .and. subStep <= 1.0 ) .or. & ! single grain already tried internal subStepping in crystallite num%subStepSizeHomog * subStep <= num%subStepMinHomog ) then ! would require too small subStep ! cutback makes no sense - if (.not. terminallyIll) & ! so first signals terminally ill... - print*, ' Integration point ', ip,' at element ', el, ' terminally ill' - terminallyIll = .true. ! ...and kills all others - else ! cutback makes sense - subStep = num%subStepSizeHomog * subStep ! crystallite had severe trouble, so do a significant cutback + if (.not. terminallyIll) & ! so first signals terminally ill... + print*, ' Integration point ', ip,' at element ', el, ' terminally ill' + terminallyIll = .true. ! ...and kills all others + else ! cutback makes sense + subStep = num%subStepSizeHomog * subStep ! crystallite had severe trouble, so do a significant cutback - call crystallite_restore(ip,el,subStep < 1.0_pReal) - call constitutive_restore(ip,el) + call constitutive_restore(ip,el,subStep < 1.0_pReal) - if(homogState(ho)%sizeState > 0) & - homogState(ho)%State( :,material_homogenizationMemberAt(ip,el)) = & - homogState(ho)%subState0(:,material_homogenizationMemberAt(ip,el)) - if(damageState(ho)%sizeState > 0) & - damageState(ho)%State( :,material_homogenizationMemberAt(ip,el)) = & - damageState(ho)%subState0(:,material_homogenizationMemberAt(ip,el)) - endif + if(homogState(ho)%sizeState > 0) & + homogState(ho)%State(:,me) = homogState(ho)%subState0(:,me) + if(damageState(ho)%sizeState > 0) & + damageState(ho)%State(:,me) = damageState(ho)%subState0(:,me) endif if (subStep > num%subStepMinHomog) doneAndHappy = [.false.,.true.] @@ -253,18 +233,16 @@ subroutine materialpoint_stressAndItsTangent(dt,FEsolving_execIP,FEsolving_execE doneAndHappy = [.true.,.false.] else ce = (el-1)*discretization_nIPs + ip - doneAndHappy = updateState(dt*subStep, & - homogenization_F0(1:3,1:3,ce) & - + (homogenization_F(1:3,1:3,ce)-homogenization_F0(1:3,1:3,ce)) & + doneAndHappy = mech_updateState(dt*subStep, & + homogenization_F0(1:3,1:3,ce) & + + (homogenization_F(1:3,1:3,ce)-homogenization_F0(1:3,1:3,ce)) & *(subStep+subFrac), & - ip,el) + ip,el) converged = all(doneAndHappy) endif endif enddo convergenceLooping - NiterationHomog = NiterationHomog + 1 - enddo cutBackLooping enddo enddo @@ -290,74 +268,35 @@ subroutine materialpoint_stressAndItsTangent(dt,FEsolving_execIP,FEsolving_execE end subroutine materialpoint_stressAndItsTangent -!-------------------------------------------------------------------------------------------------- -!> @brief update the internal state of the homogenization scheme and tell whether "done" and -!> "happy" with result -!-------------------------------------------------------------------------------------------------- -function updateState(subdt,subF,ip,el) - - real(pReal), intent(in) :: & - subdt !< current time step - real(pReal), intent(in), dimension(3,3) :: & - subF - integer, intent(in) :: & - ip, & !< integration point - el !< element number - integer :: c - logical, dimension(2) :: updateState - real(pReal) :: dPdFs(3,3,3,3,homogenization_Nconstituents(material_homogenizationAt(el))) - - updateState = .true. - chosenHomogenization: select case(homogenization_type(material_homogenizationAt(el))) - case (HOMOGENIZATION_RGC_ID) chosenHomogenization - do c=1,homogenization_Nconstituents(material_homogenizationAt(el)) - dPdFs(:,:,:,:,c) = crystallite_stressTangent(c,ip,el) - enddo - updateState = & - updateState .and. & - mech_RGC_updateState(crystallite_P(1:3,1:3,1:homogenization_Nconstituents(material_homogenizationAt(el)),ip,el), & - crystallite_partitionedF(1:3,1:3,1:homogenization_Nconstituents(material_homogenizationAt(el)),ip,el), & - crystallite_partitionedF0(1:3,1:3,1:homogenization_Nconstituents(material_homogenizationAt(el)),ip,el),& - subF,& - subdt, & - dPdFs, & - ip, & - el) - end select chosenHomogenization - -end function updateState - - !-------------------------------------------------------------------------------------------------- !> @brief writes homogenization results to HDF5 output file !-------------------------------------------------------------------------------------------------- subroutine homogenization_results - use material, only: & - material_homogenization_type => homogenization_type - integer :: p + integer :: ho character(len=:), allocatable :: group_base,group + call results_closeGroup(results_addGroup('current/homogenization/')) - do p=1,size(material_name_homogenization) - group_base = 'current/homogenization/'//trim(material_name_homogenization(p)) + do ho=1,size(material_name_homogenization) + group_base = 'current/homogenization/'//trim(material_name_homogenization(ho)) call results_closeGroup(results_addGroup(group_base)) - call mech_results(group_base,p) + call mech_results(group_base,ho) group = trim(group_base)//'/damage' call results_closeGroup(results_addGroup(group)) - select case(damage_type(p)) + select case(damage_type(ho)) case(DAMAGE_NONLOCAL_ID) - call damage_nonlocal_results(p,group) + call damage_nonlocal_results(ho,group) end select group = trim(group_base)//'/thermal' call results_closeGroup(results_addGroup(group)) - select case(thermal_type(p)) + select case(thermal_type(ho)) case(THERMAL_CONDUCTION_ID) - call thermal_conduction_results(p,group) + call thermal_conduction_results(ho,group) end select enddo @@ -373,6 +312,7 @@ subroutine homogenization_forward integer :: ho + do ho = 1, size(material_name_homogenization) homogState (ho)%state0 = homogState (ho)%state damageState(ho)%state0 = damageState(ho)%state diff --git a/src/homogenization_mech.f90 b/src/homogenization_mech.f90 index e4499e9b7..641e960fd 100644 --- a/src/homogenization_mech.f90 +++ b/src/homogenization_mech.f90 @@ -52,6 +52,21 @@ submodule(homogenization) homogenization_mech end subroutine mech_RGC_averageStressAndItsTangent + module function mech_RGC_updateState(P,F,F0,avgF,dt,dPdF,ip,el) result(doneAndHappy) + logical, dimension(2) :: doneAndHappy + real(pReal), dimension(:,:,:), intent(in) :: & + P,& !< partitioned stresses + F,& !< partitioned deformation gradients + F0 !< partitioned initial deformation gradients + real(pReal), dimension(:,:,:,:,:), intent(in) :: dPdF !< partitioned stiffnesses + real(pReal), dimension(3,3), intent(in) :: avgF !< average F + real(pReal), intent(in) :: dt !< time increment + integer, intent(in) :: & + ip, & !< integration point number + el !< element number + end function mech_RGC_updateState + + module subroutine mech_RGC_results(instance,group) integer, intent(in) :: instance !< homogenization instance character(len=*), intent(in) :: group !< group name in HDF5 file @@ -101,16 +116,16 @@ module subroutine mech_partition(subF,ip,el) chosenHomogenization: select case(homogenization_type(material_homogenizationAt(el))) case (HOMOGENIZATION_NONE_ID) chosenHomogenization - crystallite_partitionedF(1:3,1:3,1,ip,el) = subF + crystallite_F(1:3,1:3,1,ip,el) = subF case (HOMOGENIZATION_ISOSTRAIN_ID) chosenHomogenization call mech_isostrain_partitionDeformation(& - crystallite_partitionedF(1:3,1:3,1:homogenization_Nconstituents(material_homogenizationAt(el)),ip,el), & + crystallite_F(1:3,1:3,1:homogenization_Nconstituents(material_homogenizationAt(el)),ip,el), & subF) case (HOMOGENIZATION_RGC_ID) chosenHomogenization call mech_RGC_partitionDeformation(& - crystallite_partitionedF(1:3,1:3,1:homogenization_Nconstituents(material_homogenizationAt(el)),ip,el), & + crystallite_F(1:3,1:3,1:homogenization_Nconstituents(material_homogenizationAt(el)),ip,el), & subF,& ip, & el) @@ -166,6 +181,45 @@ module subroutine mech_homogenize(ip,el) end subroutine mech_homogenize +!-------------------------------------------------------------------------------------------------- +!> @brief update the internal state of the homogenization scheme and tell whether "done" and +!> "happy" with result +!-------------------------------------------------------------------------------------------------- +module function mech_updateState(subdt,subF,ip,el) result(doneAndHappy) + + real(pReal), intent(in) :: & + subdt !< current time step + real(pReal), intent(in), dimension(3,3) :: & + subF + integer, intent(in) :: & + ip, & !< integration point + el !< element number + logical, dimension(2) :: doneAndHappy + + integer :: co + real(pReal) :: dPdFs(3,3,3,3,homogenization_Nconstituents(material_homogenizationAt(el))) + + + if (homogenization_type(material_homogenizationAt(el)) == HOMOGENIZATION_RGC_ID) then + do co = 1, homogenization_Nconstituents(material_homogenizationAt(el)) + dPdFs(:,:,:,:,co) = crystallite_stressTangent(co,ip,el) + enddo + doneAndHappy = & + mech_RGC_updateState(crystallite_P(1:3,1:3,1:homogenization_Nconstituents(material_homogenizationAt(el)),ip,el), & + crystallite_F(1:3,1:3,1:homogenization_Nconstituents(material_homogenizationAt(el)),ip,el), & + crystallite_partitionedF0(1:3,1:3,1:homogenization_Nconstituents(material_homogenizationAt(el)),ip,el),& + subF,& + subdt, & + dPdFs, & + ip, & + el) + else + doneAndHappy = .true. + endif + +end function mech_updateState + + !-------------------------------------------------------------------------------------------------- !> @brief Write results to file. !-------------------------------------------------------------------------------------------------- diff --git a/src/homogenization_mech_RGC.f90 b/src/homogenization_mech_RGC.f90 index a89008e96..04ec73845 100644 --- a/src/homogenization_mech_RGC.f90 +++ b/src/homogenization_mech_RGC.f90 @@ -8,6 +8,7 @@ !-------------------------------------------------------------------------------------------------- submodule(homogenization:homogenization_mech) homogenization_mech_RGC use rotations + use lattice type :: tParameters integer, dimension(:), allocatable :: & @@ -242,7 +243,18 @@ end subroutine mech_RGC_partitionDeformation !> @brief update the internal state of the homogenization scheme and tell whether "done" and ! "happy" with result !-------------------------------------------------------------------------------------------------- -module procedure mech_RGC_updateState +module function mech_RGC_updateState(P,F,F0,avgF,dt,dPdF,ip,el) result(doneAndHappy) + logical, dimension(2) :: doneAndHappy + real(pReal), dimension(:,:,:), intent(in) :: & + P,& !< partitioned stresses + F,& !< partitioned deformation gradients + F0 !< partitioned initial deformation gradients + real(pReal), dimension(:,:,:,:,:), intent(in) :: dPdF !< partitioned stiffnesses + real(pReal), dimension(3,3), intent(in) :: avgF !< average F + real(pReal), intent(in) :: dt !< time increment + integer, intent(in) :: & + ip, & !< integration point number + el !< element number integer, dimension(4) :: intFaceN,intFaceP,faceID integer, dimension(3) :: nGDim,iGr3N,iGr3P @@ -256,7 +268,7 @@ module procedure mech_RGC_updateState real(pReal), dimension(:), allocatable :: resid,relax,p_relax,p_resid,drelax zeroTimeStep: if(dEq0(dt)) then - mech_RGC_updateState = .true. ! pretend everything is fine and return + doneAndHappy = .true. ! pretend everything is fine and return return endif zeroTimeStep @@ -327,12 +339,12 @@ module procedure mech_RGC_updateState stresMax = maxval(abs(P)) ! get the maximum of first Piola-Kirchhoff (material) stress residMax = maxval(abs(tract)) ! get the maximum of the residual - mech_RGC_updateState = .false. + doneAndHappy = .false. !-------------------------------------------------------------------------------------------------- ! If convergence reached => done and happy if (residMax < num%rtol*stresMax .or. residMax < num%atol) then - mech_RGC_updateState = .true. + doneAndHappy = .true. !-------------------------------------------------------------------------------------------------- ! compute/update the state for postResult, i.e., all energy densities computed by time-integration @@ -354,7 +366,7 @@ module procedure mech_RGC_updateState !-------------------------------------------------------------------------------------------------- ! if residual blows-up => done but unhappy elseif (residMax > num%relMax*stresMax .or. residMax > num%absMax) then ! try to restart when residual blows up exceeding maximum bound - mech_RGC_updateState = [.true.,.false.] ! with direct cut-back + doneAndHappy = [.true.,.false.] ! with direct cut-back return endif @@ -484,7 +496,7 @@ module procedure mech_RGC_updateState enddo; enddo stt%relaxationVector(:,of) = relax + drelax ! Updateing the state variable for the next iteration if (any(abs(drelax) > num%maxdRelax)) then ! Forcing cutback when the incremental change of relaxation vector becomes too large - mech_RGC_updateState = [.true.,.false.] + doneAndHappy = [.true.,.false.] !$OMP CRITICAL (write2out) print'(a,i3,a,i3,a)',' RGC_updateState: ip ',ip,' | el ',el,' enforces cutback' print'(a,e15.8)',' due to large relaxation change = ',maxval(abs(drelax)) @@ -513,8 +525,10 @@ module procedure mech_RGC_updateState real(pReal), dimension (3) :: nVect,surfCorr real(pReal), dimension (2) :: Gmoduli integer :: iGrain,iGNghb,iFace,i,j,k,l - real(pReal) :: muGrain,muGNghb,nDefNorm,bgGrain,bgGNghb - real(pReal), parameter :: nDefToler = 1.0e-10_pReal + real(pReal) :: muGrain,muGNghb,nDefNorm + real(pReal), parameter :: & + nDefToler = 1.0e-10_pReal, & + b = 2.5e-10_pReal ! Length of Burgers vector nGDim = param(instance)%N_constituents rPen = 0.0_pReal @@ -532,9 +546,7 @@ module procedure mech_RGC_updateState !----------------------------------------------------------------------------------------------- ! computing the mismatch and penalty stress tensor of all grains grainLoop: do iGrain = 1,product(prm%N_constituents) - Gmoduli = equivalentModuli(iGrain,ip,el) - muGrain = Gmoduli(1) ! collecting the equivalent shear modulus of grain - bgGrain = Gmoduli(2) ! and the lengthh of Burgers vector + muGrain = equivalentMu(iGrain,ip,el) iGrain3 = grain1to3(iGrain,prm%N_constituents) ! get the grain ID in local 3-dimensional index (x,y,z)-position interfaceLoop: do iFace = 1,6 @@ -546,9 +558,7 @@ module procedure mech_RGC_updateState where(iGNghb3 < 1) iGNghb3 = nGDim where(iGNghb3 >nGDim) iGNghb3 = 1 iGNghb = grain3to1(iGNghb3,prm%N_constituents) ! get the ID of the neighboring grain - Gmoduli = equivalentModuli(iGNghb,ip,el) ! collect the shear modulus and Burgers vector of the neighbor - muGNghb = Gmoduli(1) - bgGNghb = Gmoduli(2) + muGNghb = equivalentMu(iGNghb,ip,el) gDef = 0.5_pReal*(fDef(1:3,1:3,iGNghb) - fDef(1:3,1:3,iGrain)) ! difference/jump in deformation gradeint across the neighbor !------------------------------------------------------------------------------------------- @@ -568,7 +578,7 @@ module procedure mech_RGC_updateState !------------------------------------------------------------------------------------------- ! compute the stress penalty of all interfaces do i = 1,3; do j = 1,3; do k = 1,3; do l = 1,3 - rPen(i,j,iGrain) = rPen(i,j,iGrain) + 0.5_pReal*(muGrain*bgGrain + muGNghb*bgGNghb)*prm%xi_alpha & + rPen(i,j,iGrain) = rPen(i,j,iGrain) + 0.5_pReal*(muGrain*b + muGNghb*b)*prm%xi_alpha & *surfCorr(abs(intFace(1)))/prm%D_alpha(abs(intFace(1))) & *cosh(prm%c_alpha*nDefNorm) & *0.5_pReal*nVect(l)*nDef(i,k)/nDefNorm*math_LeviCivita(k,l,j) & @@ -655,44 +665,26 @@ module procedure mech_RGC_updateState end function surfaceCorrection - !-------------------------------------------------------------------------------------------------- + !------------------------------------------------------------------------------------------------- !> @brief compute the equivalent shear and bulk moduli from the elasticity tensor - !-------------------------------------------------------------------------------------------------- - function equivalentModuli(grainID,ip,el) - - real(pReal), dimension(2) :: equivalentModuli + !------------------------------------------------------------------------------------------------- + real(pReal) function equivalentMu(grainID,ip,el) integer, intent(in) :: & grainID,& ip, & !< integration point number el !< element number - real(pReal), dimension(6,6) :: elasTens - real(pReal) :: & - cEquiv_11, & - cEquiv_12, & - cEquiv_44 - - elasTens = constitutive_homogenizedC(grainID,ip,el) - - !---------------------------------------------------------------------------------------------- - ! compute the equivalent shear modulus after Turterltaub and Suiker, JMPS (2005) - cEquiv_11 = (elasTens(1,1) + elasTens(2,2) + elasTens(3,3))/3.0_pReal - cEquiv_12 = (elasTens(1,2) + elasTens(2,3) + elasTens(3,1) + & - elasTens(1,3) + elasTens(2,1) + elasTens(3,2))/6.0_pReal - cEquiv_44 = (elasTens(4,4) + elasTens(5,5) + elasTens(6,6))/3.0_pReal - equivalentModuli(1) = 0.2_pReal*(cEquiv_11 - cEquiv_12) + 0.6_pReal*cEquiv_44 - - !---------------------------------------------------------------------------------------------- - ! obtain the length of Burgers vector (could be model dependend) - equivalentModuli(2) = 2.5e-10_pReal - - end function equivalentModuli - !-------------------------------------------------------------------------------------------------- + equivalentMu = lattice_equivalent_mu(constitutive_homogenizedC(grainID,ip,el),'voigt') + + end function equivalentMu + + + !------------------------------------------------------------------------------------------------- !> @brief calculating the grain deformation gradient (the same with ! homogenization_RGC_partitionDeformation, but used only for perturbation scheme) - !-------------------------------------------------------------------------------------------------- + !------------------------------------------------------------------------------------------------- subroutine grainDeformation(F, avgF, instance, of) real(pReal), dimension(:,:,:), intent(out) :: F !< partitioned F per grain @@ -707,7 +699,7 @@ module procedure mech_RGC_updateState integer, dimension(3) :: iGrain3 integer :: iGrain,iFace,i,j - !------------------------------------------------------------------------------------------------- + !----------------------------------------------------------------------------------------------- ! compute the deformation gradient of individual grains due to relaxations associate(prm => param(instance)) @@ -729,7 +721,7 @@ module procedure mech_RGC_updateState end subroutine grainDeformation -end procedure mech_RGC_updateState +end function mech_RGC_updateState !-------------------------------------------------------------------------------------------------- diff --git a/src/lattice.f90 b/src/lattice.f90 index 676232efe..6af135e4e 100644 --- a/src/lattice.f90 +++ b/src/lattice.f90 @@ -421,6 +421,8 @@ module lattice lattice_BCT_ID, & lattice_HEX_ID, & lattice_ORT_ID, & + lattice_equivalent_nu, & + lattice_equivalent_mu, & lattice_applyLatticeSymmetry33, & lattice_SchmidMatrix_slip, & lattice_SchmidMatrix_twin, & @@ -508,8 +510,8 @@ subroutine lattice_init lattice_C66(1:6,1:6,p) = applyLatticeSymmetryC66(lattice_C66(1:6,1:6,p),phase%get_asString('lattice')) - lattice_mu(p) = equivalent_mu(lattice_C66(1:6,1:6,p),'voigt') - lattice_nu(p) = equivalent_nu(lattice_C66(1:6,1:6,p),'voigt') + lattice_nu(p) = lattice_equivalent_nu(lattice_C66(1:6,1:6,p),'voigt') + lattice_mu(p) = lattice_equivalent_mu(lattice_C66(1:6,1:6,p),'voigt') lattice_C66(1:6,1:6,p) = math_sym3333to66(math_Voigt66to3333(lattice_C66(1:6,1:6,p))) ! Literature data is in Voigt notation do i = 1, 6 @@ -2188,15 +2190,16 @@ end function getlabels !> @brief Equivalent Poisson's ratio (ν) !> @details https://doi.org/10.1143/JPSJ.20.635 !-------------------------------------------------------------------------------------------------- -function equivalent_nu(C,assumption) result(nu) +function lattice_equivalent_nu(C,assumption) result(nu) real(pReal), dimension(6,6), intent(in) :: C !< Stiffness tensor (Voigt notation) character(len=*), intent(in) :: assumption !< Assumption ('Voigt' = isostrain, 'Reuss' = isostress) - real(pReal) :: K, mu, nu + logical :: error real(pReal), dimension(6,6) :: S + if (IO_lc(assumption) == 'voigt') then K = (C(1,1)+C(2,2)+C(3,3) +2.0_pReal*(C(1,2)+C(2,3)+C(1,3))) & / 9.0_pReal @@ -2210,25 +2213,26 @@ function equivalent_nu(C,assumption) result(nu) K = 0.0_pReal endif - mu = equivalent_mu(C,assumption) + mu = lattice_equivalent_mu(C,assumption) nu = (1.5_pReal*K -mu)/(3.0_pReal*K+mu) -end function equivalent_nu +end function lattice_equivalent_nu !-------------------------------------------------------------------------------------------------- !> @brief Equivalent shear modulus (μ) !> @details https://doi.org/10.1143/JPSJ.20.635 !-------------------------------------------------------------------------------------------------- -function equivalent_mu(C,assumption) result(mu) +function lattice_equivalent_mu(C,assumption) result(mu) real(pReal), dimension(6,6), intent(in) :: C !< Stiffness tensor (Voigt notation) character(len=*), intent(in) :: assumption !< Assumption ('Voigt' = isostrain, 'Reuss' = isostress) - real(pReal) :: mu + logical :: error real(pReal), dimension(6,6) :: S + if (IO_lc(assumption) == 'voigt') then mu = (1.0_pReal*(C(1,1)+C(2,2)+C(3,3)) -1.0_pReal*(C(1,2)+C(2,3)+C(1,3)) +3.0_pReal*(C(4,4)+C(5,5)+C(6,6))) & / 15.0_pReal @@ -2242,7 +2246,7 @@ function equivalent_mu(C,assumption) result(mu) mu = 0.0_pReal endif -end function equivalent_mu +end function lattice_equivalent_mu !-------------------------------------------------------------------------------------------------- @@ -2266,14 +2270,14 @@ subroutine selfTest call random_number(C) C(1,1) = C(1,1) + 1.0_pReal C = applyLatticeSymmetryC66(C,'aP') - if(dNeq(C(6,6),equivalent_mu(C,'voigt'),1.0e-12_pReal)) error stop 'equivalent_mu/voigt' - if(dNeq(C(6,6),equivalent_mu(C,'voigt'),1.0e-12_pReal)) error stop 'equivalent_mu/reuss' + if(dNeq(C(6,6),lattice_equivalent_mu(C,'voigt'),1.0e-12_pReal)) error stop 'equivalent_mu/voigt' + if(dNeq(C(6,6),lattice_equivalent_mu(C,'voigt'),1.0e-12_pReal)) error stop 'equivalent_mu/reuss' lambda = C(1,2) - if(dNeq(lambda*0.5_pReal/(lambda+equivalent_mu(C,'voigt')),equivalent_nu(C,'voigt'),1.0e-12_pReal)) & - error stop 'equivalent_nu/voigt' - if(dNeq(lambda*0.5_pReal/(lambda+equivalent_mu(C,'reuss')),equivalent_nu(C,'reuss'),1.0e-12_pReal)) & - error stop 'equivalent_nu/reuss' + if(dNeq(lambda*0.5_pReal/(lambda+lattice_equivalent_mu(C,'voigt')), & + lattice_equivalent_nu(C,'voigt'),1.0e-12_pReal)) error stop 'equivalent_nu/voigt' + if(dNeq(lambda*0.5_pReal/(lambda+lattice_equivalent_mu(C,'reuss')), & + lattice_equivalent_nu(C,'reuss'),1.0e-12_pReal)) error stop 'equivalent_nu/reuss' end subroutine selfTest diff --git a/src/math.f90 b/src/math.f90 index 8005b5406..6b89a9923 100644 --- a/src/math.f90 +++ b/src/math.f90 @@ -279,9 +279,12 @@ real(pReal) pure function math_LeviCivita(i,j,k) integer, intent(in) :: i,j,k - 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 + integer :: o + + + if (any([(all(cshift([i,j,k],o) == [1,2,3]),o=0,2)])) then math_LeviCivita = +1.0_pReal - 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 + elseif (any([(all(cshift([i,j,k],o) == [3,2,1]),o=0,2)])) then math_LeviCivita = -1.0_pReal else math_LeviCivita = 0.0_pReal diff --git a/src/prec.f90 b/src/prec.f90 index 95b1116cd..4d73462c4 100644 --- a/src/prec.f90 +++ b/src/prec.f90 @@ -108,8 +108,10 @@ logical elemental pure function dEq(a,b,tol) real(pReal), intent(in) :: a,b real(pReal), intent(in), optional :: tol + real(pReal) :: eps + if (present(tol)) then eps = tol else @@ -132,11 +134,8 @@ logical elemental pure function dNeq(a,b,tol) real(pReal), intent(in) :: a,b real(pReal), intent(in), optional :: tol - if (present(tol)) then - dNeq = .not. dEq(a,b,tol) - else - dNeq = .not. dEq(a,b) - endif + + dNeq = .not. dEq(a,b,tol) end function dNeq @@ -151,8 +150,10 @@ logical elemental pure function dEq0(a,tol) real(pReal), intent(in) :: a real(pReal), intent(in), optional :: tol + real(pReal) :: eps + if (present(tol)) then eps = tol else @@ -175,11 +176,8 @@ logical elemental pure function dNeq0(a,tol) real(pReal), intent(in) :: a real(pReal), intent(in), optional :: tol - if (present(tol)) then - dNeq0 = .not. dEq0(a,tol) - else - dNeq0 = .not. dEq0(a) - endif + + dNeq0 = .not. dEq0(a,tol) end function dNeq0 @@ -195,8 +193,10 @@ logical elemental pure function cEq(a,b,tol) complex(pReal), intent(in) :: a,b real(pReal), intent(in), optional :: tol + real(pReal) :: eps + if (present(tol)) then eps = tol else @@ -220,11 +220,8 @@ logical elemental pure function cNeq(a,b,tol) complex(pReal), intent(in) :: a,b real(pReal), intent(in), optional :: tol - if (present(tol)) then - cNeq = .not. cEq(a,b,tol) - else - cNeq = .not. cEq(a,b) - endif + + cNeq = .not. cEq(a,b,tol) end function cNeq @@ -238,6 +235,7 @@ pure function prec_bytesToC_FLOAT(bytes) real(C_FLOAT), dimension(size(bytes,kind=pI64)/(storage_size(0._C_FLOAT,pI64)/8_pI64)) :: & prec_bytesToC_FLOAT + prec_bytesToC_FLOAT = transfer(bytes,prec_bytesToC_FLOAT,size(prec_bytesToC_FLOAT)) end function prec_bytesToC_FLOAT @@ -252,6 +250,7 @@ pure function prec_bytesToC_DOUBLE(bytes) real(C_DOUBLE), dimension(size(bytes,kind=pI64)/(storage_size(0._C_DOUBLE,pI64)/8_pI64)) :: & prec_bytesToC_DOUBLE + prec_bytesToC_DOUBLE = transfer(bytes,prec_bytesToC_DOUBLE,size(prec_bytesToC_DOUBLE)) end function prec_bytesToC_DOUBLE @@ -266,6 +265,7 @@ pure function prec_bytesToC_INT32_T(bytes) integer(C_INT32_T), dimension(size(bytes,kind=pI64)/(storage_size(0_C_INT32_T,pI64)/8_pI64)) :: & prec_bytesToC_INT32_T + prec_bytesToC_INT32_T = transfer(bytes,prec_bytesToC_INT32_T,size(prec_bytesToC_INT32_T)) end function prec_bytesToC_INT32_T @@ -280,6 +280,7 @@ pure function prec_bytesToC_INT64_T(bytes) integer(C_INT64_T), dimension(size(bytes,kind=pI64)/(storage_size(0_C_INT64_T,pI64)/8_pI64)) :: & prec_bytesToC_INT64_T + prec_bytesToC_INT64_T = transfer(bytes,prec_bytesToC_INT64_T,size(prec_bytesToC_INT64_T)) end function prec_bytesToC_INT64_T @@ -295,6 +296,7 @@ subroutine selfTest integer(pInt), dimension(1) :: i real(pReal), dimension(2) :: r + realloc_lhs_test = [1,2] if (any(realloc_lhs_test/=[1,2])) error stop 'LHS allocation'