diff --git a/python/damask/grid_filters.py b/python/damask/grid_filters.py index 664198630..69e7dd6b1 100644 --- a/python/damask/grid_filters.py +++ b/python/damask/grid_filters.py @@ -97,6 +97,8 @@ def cell_coord0(grid,size,origin=np.zeros(3)): number of grid points. size : numpy.ndarray physical size of the periodic field. + origin : numpy.ndarray, optional + physical origin of the periodic field. Default is [0.0,0.0,0.0]. """ start = origin + size/grid*.5 @@ -149,6 +151,36 @@ def cell_displacement_avg(size,F): 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][::-1],size)) +def cell_displacement(size,F): + """ + Cell center displacement field from deformation gradient field. + + Parameters + ---------- + size : numpy.ndarray + physical size of the periodic field. + F : numpy.ndarray + deformation gradient field. + + """ + return cell_displacement_avg(size,F) + cell_displacement_fluct(size,F) + +def cell_coord(size,F,origin=np.zeros(3)): + """ + Cell center positions. + + Parameters + ---------- + size : numpy.ndarray + physical size of the periodic field. + F : numpy.ndarray + deformation gradient field. + origin : numpy.ndarray, optional + physical origin of the periodic field. Default is [0.0,0.0,0.0]. + + """ + return cell_coord0(F.shape[:3][::-1],size,origin) + cell_displacement(size,F) + def cell_coord0_2_DNA(coord0,ordered=True): """ Return grid 'DNA', i.e. grid, size, and origin from array of cell positions. @@ -196,6 +228,8 @@ def node_coord0(grid,size,origin=np.zeros(3)): number of grid points. size : numpy.ndarray physical size of the periodic field. + origin : numpy.ndarray, optional + physical origin of the periodic field. Default is [0.0,0.0,0.0]. """ x, y, z = np.meshgrid(np.linspace(origin[2],size[2]+origin[2],1+grid[2]), @@ -234,9 +268,38 @@ def node_displacement_avg(size,F): 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][::-1],size)) +def node_displacement(size,F): + """ + Nodal displacement field from deformation gradient field. + + Parameters + ---------- + size : numpy.ndarray + physical size of the periodic field. + F : numpy.ndarray + deformation gradient field. + + """ + return node_displacement_avg(size,F) + node_displacement_fluct(size,F) + +def node_coord(size,F,origin=np.zeros(3)): + """ + Nodal positions. + + Parameters + ---------- + size : numpy.ndarray + physical size of the periodic field. + F : numpy.ndarray + deformation gradient field. + origin : numpy.ndarray, optional + physical origin of the periodic field. Default is [0.0,0.0,0.0]. + + """ + return node_coord0(F.shape[:3][::-1],size,origin) + node_displacement(size,F) def cell_2_node(cell_data): - """Interpolate cell data to nodal data.""" + """Interpolate periodic cell 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 @@ -244,7 +307,7 @@ 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 nodal data to cell data.""" + """Interpolate periodic nodal data to cell 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 diff --git a/python/tests/test_grid_filters.py b/python/tests/test_grid_filters.py index b23fad549..c8442eee4 100644 --- a/python/tests/test_grid_filters.py +++ b/python/tests/test_grid_filters.py @@ -35,6 +35,13 @@ class TestGridFilters: _grid,_size,_origin = eval('grid_filters.{}_coord0_2_DNA(coord0.reshape((-1,3)))'.format(mode)) assert np.allclose(grid,_grid) and np.allclose(size,_size) and np.allclose(origin,_origin) + def test_displacement_fluct_equivalence(self): + size = np.random.random(3) + grid = np.random.randint(8,32,(3)) + F = np.random.random(tuple(grid)+(3,3)) + assert np.allclose(grid_filters.node_displacement_fluct(size,F), + grid_filters.cell_2_node(grid_filters.cell_displacement_fluct(size,F))) + @pytest.mark.parametrize('mode',[('cell'),('node')]) def test_displacement_avg_vanishes(self,mode):