From 7b3d1204fab4277ee2a9b24872bc7af4757a9ea0 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Fri, 3 Jul 2020 07:29:31 +0200 Subject: [PATCH 01/73] easier to use --- python/damask/_result.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/python/damask/_result.py b/python/damask/_result.py index 6c3e751f1..205b3a0f8 100644 --- a/python/damask/_result.py +++ b/python/damask/_result.py @@ -466,6 +466,11 @@ class Result: return f[self.get_dataset_location('orientation')[0]].attrs['Lattice'].astype('str') # np.bytes_ to string + def enable_user_function(self,func): + globals()[func.__name__]=func + print(f'Function {func.__name__} enabled in add_calculation.') + + def read_dataset(self,path,c=0,plain=False): """ Dataset for all points/cells. From 50d7842dbef3a6adebac3e613743404b11bfc875 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Fri, 31 Jul 2020 16:50:01 +0200 Subject: [PATCH 02/73] more tests --- python/damask/_result.py | 3 ++- python/tests/test_Result.py | 34 +++++++++++++++++++++++++++------- 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/python/damask/_result.py b/python/damask/_result.py index 152e648a5..45a0c2056 100644 --- a/python/damask/_result.py +++ b/python/damask/_result.py @@ -509,7 +509,7 @@ class Result: else: return dataset - + @property def cell_coordinates(self): """Return initial coordinates of the cell centers.""" if self.structured: @@ -518,6 +518,7 @@ class Result: with h5py.File(self.fname,'r') as f: return f['geometry/x_c'][()] + @property def node_coordinates(self): """Return initial coordinates of the cell centers.""" if self.structured: diff --git a/python/tests/test_Result.py b/python/tests/test_Result.py index 20c27649b..c6dbfb5bd 100644 --- a/python/tests/test_Result.py +++ b/python/tests/test_Result.py @@ -10,13 +10,14 @@ import h5py import damask from damask import Result from damask import mechanics +from damask import grid_filters @pytest.fixture def default(tmp_path,reference_dir): """Small Result file in temp location for modification.""" fname = '12grains6x7x8_tensionY.hdf5' - shutil.copy(os.path.join(reference_dir,fname),tmp_path) - f = Result(os.path.join(tmp_path,fname)) + shutil.copy(reference_dir/fname,tmp_path) + f = Result(tmp_path/fname) f.pick('times',20.0) return f @@ -24,13 +25,13 @@ def default(tmp_path,reference_dir): def single_phase(tmp_path,reference_dir): """Single phase Result file in temp location for modification.""" fname = '6grains6x7x8_single_phase_tensionY.hdf5' - shutil.copy(os.path.join(reference_dir,fname),tmp_path) - return Result(os.path.join(tmp_path,fname)) + shutil.copy(reference_dir/fname,tmp_path) + return Result(tmp_path/fname) @pytest.fixture def reference_dir(reference_dir_base): """Directory containing reference results.""" - return os.path.join(reference_dir_base,'Result') + return reference_dir_base/'Result' class TestResult: @@ -98,8 +99,17 @@ class TestResult: in_file = default.read_dataset(loc['|Fe|'],0) assert np.allclose(in_memory,in_file) - def test_add_calculation(self,default): - default.add_calculation('x','2.0*np.abs(#F#)-1.0','-','my notes') + @pytest.mark.parametrize('mode',['direct','function']) + def test_add_calculation(self,default,mode): + def my_func(field): + return 2.0*np.abs(field)-1.0 + + if mode == 'direct': + default.add_calculation('x','2.0*np.abs(#F#)-1.0','-','my notes') + else: + default.enable_user_function(my_func) + default.add_calculation('x','my_func(#F#)','-','my notes') + loc = {'F': default.get_dataset_location('F'), 'x': default.get_dataset_location('x')} in_memory = 2.0*np.abs(default.read_dataset(loc['F'],0))-1.0 @@ -312,6 +322,16 @@ class TestResult: with pytest.raises(PermissionError): default.rename('P','another_new_name') + @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') + 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') + assert np.allclose(a,b) + @pytest.mark.parametrize('output',['F',[],['F','P']]) def test_vtk(self,tmp_path,default,output): os.chdir(tmp_path) From a9f53f482267c60584f32f45c509cf2523131a1c Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Fri, 31 Jul 2020 17:04:14 +0200 Subject: [PATCH 03/73] non-vectorized formulas can be implemented in a user functionc --- python/damask/_result.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/python/damask/_result.py b/python/damask/_result.py index 45a0c2056..bf3ee67b9 100644 --- a/python/damask/_result.py +++ b/python/damask/_result.py @@ -567,7 +567,7 @@ class Result: 'Creator': inspect.stack()[0][3][1:] } } - def add_calculation(self,label,formula,unit='n/a',description=None,vectorized=True): + def add_calculation(self,label,formula,unit='n/a',description=None): """ Add result of a general formula. @@ -581,13 +581,8 @@ class Result: Physical unit of the result. description : str, optional Human-readable description of the result. - vectorized : bool, optional - Indicate whether the formula can be used in vectorized form. Defaults to ‘True’. """ - if not vectorized: - raise NotImplementedError - dataset_mapping = {d:d for d in set(re.findall(r'#(.*?)#',formula))} # datasets used in the formula args = {'formula':formula,'label':label,'unit':unit,'description':description} self._add_generic_pointwise(self._add_calculation,dataset_mapping,args) From 72ea9a5cec90e9388e67eaf8bdd3229c201fc505 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Fri, 31 Jul 2020 17:04:14 +0200 Subject: [PATCH 04/73] non-vectorized formulas can be implemented in a user function --- python/tests/test_Geom.py | 10 +++++----- python/tests/test_Orientation.py | 2 +- python/tests/test_Result.py | 11 +++++++---- python/tests/test_Rotation.py | 2 +- python/tests/test_Table.py | 25 +++++++++++++++++-------- 5 files changed, 31 insertions(+), 19 deletions(-) diff --git a/python/tests/test_Geom.py b/python/tests/test_Geom.py index 28c9d14b0..480c74788 100644 --- a/python/tests/test_Geom.py +++ b/python/tests/test_Geom.py @@ -26,7 +26,7 @@ def default(): @pytest.fixture def reference_dir(reference_dir_base): """Directory containing reference results.""" - return os.path.join(reference_dir_base,'Geom') + return reference_dir_base/'Geom' class TestGeom: @@ -87,7 +87,7 @@ class TestGeom: modified = copy.deepcopy(default) modified.mirror(directions,reflect) tag = f'directions={"-".join(directions)}_reflect={reflect}' - reference = os.path.join(reference_dir,f'mirror_{tag}.geom') + reference = reference_dir/f'mirror_{tag}.geom' if update: modified.to_file(reference) assert geom_equal(modified,Geom.from_file(reference)) @@ -96,7 +96,7 @@ class TestGeom: modified = copy.deepcopy(default) modified.clean(stencil) tag = f'stencil={stencil}' - reference = os.path.join(reference_dir,f'clean_{tag}.geom') + reference = reference_dir/f'clean_{tag}.geom' if update: modified.to_file(reference) assert geom_equal(modified,Geom.from_file(reference)) @@ -113,7 +113,7 @@ class TestGeom: modified = copy.deepcopy(default) modified.scale(grid) tag = f'grid={util.srepr(grid,"-")}' - reference = os.path.join(reference_dir,f'scale_{tag}.geom') + reference = reference_dir/f'scale_{tag}.geom' if update: modified.to_file(reference) assert geom_equal(modified,Geom.from_file(reference)) @@ -152,7 +152,7 @@ class TestGeom: modified = copy.deepcopy(default) modified.rotate(Rotation.from_Eulers(Eulers,degrees=True)) tag = f'Eulers={util.srepr(Eulers,"-")}' - reference = os.path.join(reference_dir,f'rotate_{tag}.geom') + reference = reference_dir/f'rotate_{tag}.geom' if update: modified.to_file(reference) assert geom_equal(modified,Geom.from_file(reference)) diff --git a/python/tests/test_Orientation.py b/python/tests/test_Orientation.py index 84414a343..4987f1f1f 100644 --- a/python/tests/test_Orientation.py +++ b/python/tests/test_Orientation.py @@ -33,7 +33,7 @@ def inverse_pole(orientation,axis,proper=False,SST=True): @pytest.fixture def reference_dir(reference_dir_base): """Directory containing reference results.""" - return os.path.join(reference_dir_base,'Rotation') + return reference_dir_base/'Rotation' class TestOrientation: diff --git a/python/tests/test_Result.py b/python/tests/test_Result.py index c6dbfb5bd..53bcdda9d 100644 --- a/python/tests/test_Result.py +++ b/python/tests/test_Result.py @@ -1,6 +1,7 @@ import time import shutil import os +import sys from datetime import datetime import pytest @@ -100,14 +101,16 @@ class TestResult: assert np.allclose(in_memory,in_file) @pytest.mark.parametrize('mode',['direct','function']) - def test_add_calculation(self,default,mode): - def my_func(field): - return 2.0*np.abs(field)-1.0 + def test_add_calculation(self,default,tmp_path,mode): if mode == 'direct': default.add_calculation('x','2.0*np.abs(#F#)-1.0','-','my notes') else: - default.enable_user_function(my_func) + with open(tmp_path/'f.py','w') as f: + f.write("import numpy as np\ndef my_func(field):\n return 2.0*np.abs(field)-1.0\n") + sys.path.insert(0,str(tmp_path)) + import f + default.enable_user_function(f.my_func) default.add_calculation('x','my_func(#F#)','-','my notes') loc = {'F': default.get_dataset_location('F'), diff --git a/python/tests/test_Rotation.py b/python/tests/test_Rotation.py index 49f57f67f..8b26a7472 100644 --- a/python/tests/test_Rotation.py +++ b/python/tests/test_Rotation.py @@ -6,7 +6,7 @@ import numpy as np from damask import Rotation from damask import _rotation -n = 1100 +n = 1000 atol=1.e-4 @pytest.fixture diff --git a/python/tests/test_Table.py b/python/tests/test_Table.py index ac7444808..2f7c14bae 100644 --- a/python/tests/test_Table.py +++ b/python/tests/test_Table.py @@ -15,7 +15,7 @@ def default(): @pytest.fixture def reference_dir(reference_dir_base): """Directory containing reference results.""" - return os.path.join(reference_dir_base,'Table') + return reference_dir_base/'Table' class TestTable: @@ -35,9 +35,13 @@ class TestTable: d = default.get('5_F') assert np.allclose(d,1.0) and d.shape[1:] == (1,) - def test_write_read_str(self,default,tmpdir): - default.to_ASCII(str(tmpdir.join('default.txt'))) - new = Table.from_ASCII(str(tmpdir.join('default.txt'))) + @pytest.mark.parametrize('mode',['str','path']) + def test_write_read(self,default,tmpdir,mode): + default.to_ASCII(tmpdir/'default.txt') + if mode == 'path': + new = Table.from_ASCII(tmpdir/'default.txt') + elif mode == 'str': + new = Table.from_ASCII(str(tmpdir/'default.txt')) assert all(default.data==new.data) and default.shapes == new.shapes def test_write_read_file(self,default,tmpdir): @@ -54,20 +58,25 @@ class TestTable: new = Table.from_ASCII(f) assert all(default.data==new.data) and default.shapes == new.shapes - def test_read_ang_str(self,reference_dir): - new = Table.from_ang(os.path.join(reference_dir,'simple.ang')) + + @pytest.mark.parametrize('mode',['str','path']) + def test_read_ang(self,reference_dir,mode): + if mode == 'path': + new = Table.from_ang(reference_dir/'simple.ang') + elif mode == 'str': + new = Table.from_ang(str(reference_dir/'simple.ang')) assert new.data.shape == (4,10) and \ new.labels == ['eu', 'pos', 'IQ', 'CI', 'ID', 'intensity', 'fit'] def test_read_ang_file(self,reference_dir): - f = open(os.path.join(reference_dir,'simple.ang')) + f = open(reference_dir/'simple.ang') new = Table.from_ang(f) assert new.data.shape == (4,10) and \ new.labels == ['eu', 'pos', 'IQ', 'CI', 'ID', 'intensity', 'fit'] @pytest.mark.parametrize('fname',['datatype-mix.txt','whitespace-mix.txt']) def test_read_strange(self,reference_dir,fname): - with open(os.path.join(reference_dir,fname)) as f: + with open(reference_dir/fname) as f: Table.from_ASCII(f) def test_set(self,default): From 3f2e63977d622c1358f31b5fe823ad6dfbc37ab0 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Fri, 31 Jul 2020 19:46:44 +0200 Subject: [PATCH 05/73] not needed anymore --- python/tests/test_Geom.py | 1 - python/tests/test_Table.py | 2 -- 2 files changed, 3 deletions(-) diff --git a/python/tests/test_Geom.py b/python/tests/test_Geom.py index 480c74788..155178322 100644 --- a/python/tests/test_Geom.py +++ b/python/tests/test_Geom.py @@ -1,5 +1,4 @@ import copy -import os import pytest import numpy as np diff --git a/python/tests/test_Table.py b/python/tests/test_Table.py index 2f7c14bae..f23d2f842 100644 --- a/python/tests/test_Table.py +++ b/python/tests/test_Table.py @@ -1,5 +1,3 @@ -import os - import pytest import numpy as np From ae20f5ffe67f8d348b47a757b1e511eaa24c797f Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Mon, 3 Aug 2020 18:19:38 +0200 Subject: [PATCH 06/73] attempt to fix parallel writing on MacOS should resolve TypeError: cannot pickle 'vtkmodules.vtkIOXML.vtkXMLRectilinearGridWriter' object error --- python/damask/_vtk.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/python/damask/_vtk.py b/python/damask/_vtk.py index 51175fdd7..00aa2f4e9 100644 --- a/python/damask/_vtk.py +++ b/python/damask/_vtk.py @@ -190,9 +190,13 @@ class VTK: writer.SetCompressorTypeToZLib() writer.SetDataModeToBinary() writer.SetInputData(self.geom) + if parallel: - mp_writer = mp.Process(target=self._write,args=(writer,)) - mp_writer.start() + try: + mp_writer = mp.Process(target=self._write,args=(writer,)) + mp_writer.start() + except TypeError: + writer.Write() else: writer.Write() From f557c076896f3e2a5ba511ad3371003b9779e87a Mon Sep 17 00:00:00 2001 From: Test User Date: Mon, 3 Aug 2020 20:52:08 +0200 Subject: [PATCH 07/73] [skip ci] updated version information after successful test of v2.0.3-2948-gb93078d9 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index f5754c664..2279ff194 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v2.0.3-2945-gb7e03364 +v2.0.3-2948-gb93078d9 From 84551c9d1e24451b23066378eba4360da50a8449 Mon Sep 17 00:00:00 2001 From: Philip Eisenlohr Date: Tue, 4 Aug 2020 12:52:04 -0400 Subject: [PATCH 08/73] integrated former imageData functionality as "shade" method --- python/damask/_colormap.py | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/python/damask/_colormap.py b/python/damask/_colormap.py index 73e7d0936..8a31ceb3c 100644 --- a/python/damask/_colormap.py +++ b/python/damask/_colormap.py @@ -9,6 +9,8 @@ if os.name == 'posix' and 'DISPLAY' not in os.environ: import matplotlib.pyplot as plt from matplotlib import cm +from PIL import Image + import damask from . import Table @@ -161,6 +163,42 @@ class Colormap(mpl.colors.ListedColormap): print(' '+', '.join(cat[1])) + def shade(self,field,bounds=None,gap=None): + """ + Generate PIL image of 2D field using colormap. + + Parameters + ---------- + field : numpy 2D array + Data to be shaded. + bounds : array, optional + Lower and upper bound of value range. + gap : scalar, optional + Transparent value. NaN will always be rendered transparent. + + Returns + ------- + PIL.Image + RGBA image of shaded data. + + """ + N = len(self.colors) + mask = np.logical_not(np.isnan(field) if gap is None else \ + np.logical_or (np.isnan(field), field == gap)) # mask gap and NaN (if gap present) + + if bounds is None: + bounds = [field[mask].min(), + field[mask].max()] + hi,lo = max(bounds),min(bounds) + delta,avg = hi-lo,0.5*(hi+lo) + + if delta * 1e8 <= avg: # delta around numerical noise + hi,lo = hi+0.5*avg,lo-0.5*avg # extend range to have actual data centered within + + return Image.fromarray((np.dstack((self.colors[(np.clip((field-lo)/(hi-lo),0.0,1.0)*(N-1)).astype(np.uint8),:3], + mask.astype(float)))*255).astype(np.uint8), 'RGBA') + + def show(self,aspect=10,vertical=False): """Show colormap as matplotlib figure.""" fig = plt.figure(figsize=(5/aspect,5) if vertical else (5,5/aspect)) From e07c00a59262e884cfa75526064e9be282030589 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Tue, 4 Aug 2020 20:14:04 +0200 Subject: [PATCH 09/73] polishing + simple test autoscaling seems to be broken --- python/damask/_colormap.py | 20 ++++++++++---------- python/tests/reference/Colormap/shade.png | Bin 0 -> 143 bytes python/tests/test_Colormap.py | 12 ++++++++++++ 3 files changed, 22 insertions(+), 10 deletions(-) create mode 100644 python/tests/reference/Colormap/shade.png diff --git a/python/damask/_colormap.py b/python/damask/_colormap.py index 8a31ceb3c..8bcb076d4 100644 --- a/python/damask/_colormap.py +++ b/python/damask/_colormap.py @@ -8,7 +8,6 @@ if os.name == 'posix' and 'DISPLAY' not in os.environ: mpl.use('Agg') import matplotlib.pyplot as plt from matplotlib import cm - from PIL import Image import damask @@ -169,11 +168,11 @@ class Colormap(mpl.colors.ListedColormap): Parameters ---------- - field : numpy 2D array + field : np.array of shape(:,:) Data to be shaded. - bounds : array, optional + bounds : iterable of len(2), optional Lower and upper bound of value range. - gap : scalar, optional + gap : field.dtype, optional Transparent value. NaN will always be rendered transparent. Returns @@ -184,16 +183,17 @@ class Colormap(mpl.colors.ListedColormap): """ N = len(self.colors) mask = np.logical_not(np.isnan(field) if gap is None else \ - np.logical_or (np.isnan(field), field == gap)) # mask gap and NaN (if gap present) + np.logical_or (np.isnan(field), field == gap)) # mask gap and NaN (if gap present) if bounds is None: - bounds = [field[mask].min(), - field[mask].max()] - hi,lo = max(bounds),min(bounds) + hi,lo = field[mask].min(),field[mask].max() + else: + hi,lo = bounds[::-1] + delta,avg = hi-lo,0.5*(hi+lo) - if delta * 1e8 <= avg: # delta around numerical noise - hi,lo = hi+0.5*avg,lo-0.5*avg # extend range to have actual data centered within + if delta * 1e8 <= avg: # delta around numerical noise + hi,lo = hi+0.5*avg,lo-0.5*avg # extend range to have actual data centered within return Image.fromarray((np.dstack((self.colors[(np.clip((field-lo)/(hi-lo),0.0,1.0)*(N-1)).astype(np.uint8),:3], mask.astype(float)))*255).astype(np.uint8), 'RGBA') diff --git a/python/tests/reference/Colormap/shade.png b/python/tests/reference/Colormap/shade.png new file mode 100644 index 0000000000000000000000000000000000000000..a9e5eacea012a542f6f2ce8996be96d34f917f7a GIT binary patch literal 143 zcmeAS@N?(olHy`uVBq!ia0vp^+(695!3HFgJ}hYlQemDhjv*CudQVw%H5dpu9GreM zg2O2!$u8&Iqrd)3TRSoqT7TVfcH`$qOOs{QKgp~pT=>jIi*@6%6~E5J8*V9kzTYC| orbwt@_LA=%rc7Wo@1_JJA19Zn_gU_y9H0#hp00i_>zopr0366ORsaA1 literal 0 HcmV?d00001 diff --git a/python/tests/test_Colormap.py b/python/tests/test_Colormap.py index fbe65e2bd..8eebf63ee 100644 --- a/python/tests/test_Colormap.py +++ b/python/tests/test_Colormap.py @@ -4,6 +4,8 @@ import time import numpy as np import pytest +from PIL import Image +from PIL import ImageChops import damask from damask import Colormap @@ -129,6 +131,16 @@ class TestColormap: c += c assert (np.allclose(c.colors[:len(c.colors)//2],c.colors[len(c.colors)//2:])) + def test_shade(self,reference_dir,update): + data = np.add(*np.indices((10, 11))) + img_current = Colormap.from_predefined('orientation').shade(data) + if update: + img_current.save(reference_dir/'shade.png') + else: + img_reference = Image.open(reference_dir/'shade.png') + diff = ImageChops.difference(img_reference.convert('RGB'),img_current.convert('RGB')) + assert not diff.getbbox() + def test_list(self): Colormap.list_predefined() From e73ffd6da9e715a7fd37465702055ea14b94501c Mon Sep 17 00:00:00 2001 From: Philip Eisenlohr Date: Tue, 4 Aug 2020 20:29:27 +0200 Subject: [PATCH 10/73] fixed and condensed lo,hi range assignment --- python/damask/_colormap.py | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/python/damask/_colormap.py b/python/damask/_colormap.py index 8bcb076d4..6d6fb437b 100644 --- a/python/damask/_colormap.py +++ b/python/damask/_colormap.py @@ -171,7 +171,7 @@ class Colormap(mpl.colors.ListedColormap): field : np.array of shape(:,:) Data to be shaded. bounds : iterable of len(2), optional - Lower and upper bound of value range. + Colormap value range (low,high). gap : field.dtype, optional Transparent value. NaN will always be rendered transparent. @@ -183,16 +183,14 @@ class Colormap(mpl.colors.ListedColormap): """ N = len(self.colors) mask = np.logical_not(np.isnan(field) if gap is None else \ - np.logical_or (np.isnan(field), field == gap)) # mask gap and NaN (if gap present) + np.logical_or (np.isnan(field), field == gap)) # mask NaN (and gap if present) + + lo,hi = (field[mask].min(),field[mask].max()) if bounds is None else \ + (min(bounds[:2]),max(bounds[:2])) - if bounds is None: - hi,lo = field[mask].min(),field[mask].max() - else: - hi,lo = bounds[::-1] - delta,avg = hi-lo,0.5*(hi+lo) - if delta * 1e8 <= avg: # delta around numerical noise + if delta * 1e8 <= avg: # delta is similar to numerical noise hi,lo = hi+0.5*avg,lo-0.5*avg # extend range to have actual data centered within return Image.fromarray((np.dstack((self.colors[(np.clip((field-lo)/(hi-lo),0.0,1.0)*(N-1)).astype(np.uint8),:3], From 7d49606597e76fc56944cf5bf36f5000577845a2 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Tue, 4 Aug 2020 20:34:40 +0200 Subject: [PATCH 11/73] restored correct bound calculation test different bounds options --- python/damask/_colormap.py | 2 +- python/tests/reference/Colormap/shade.png | Bin 143 -> 0 bytes python/tests/reference/Colormap/shade_None.png | Bin 0 -> 146 bytes python/tests/reference/Colormap/shade_[2, 10].png | Bin 0 -> 136 bytes python/tests/test_Colormap.py | 9 +++++---- 5 files changed, 6 insertions(+), 5 deletions(-) delete mode 100644 python/tests/reference/Colormap/shade.png create mode 100644 python/tests/reference/Colormap/shade_None.png create mode 100644 python/tests/reference/Colormap/shade_[2, 10].png diff --git a/python/damask/_colormap.py b/python/damask/_colormap.py index 8bcb076d4..5c0ca11d3 100644 --- a/python/damask/_colormap.py +++ b/python/damask/_colormap.py @@ -186,7 +186,7 @@ class Colormap(mpl.colors.ListedColormap): np.logical_or (np.isnan(field), field == gap)) # mask gap and NaN (if gap present) if bounds is None: - hi,lo = field[mask].min(),field[mask].max() + hi,lo = field[mask].max(),field[mask].min() else: hi,lo = bounds[::-1] diff --git a/python/tests/reference/Colormap/shade.png b/python/tests/reference/Colormap/shade.png deleted file mode 100644 index a9e5eacea012a542f6f2ce8996be96d34f917f7a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 143 zcmeAS@N?(olHy`uVBq!ia0vp^+(695!3HFgJ}hYlQemDhjv*CudQVw%H5dpu9GreM zg2O2!$u8&Iqrd)3TRSoqT7TVfcH`$qOOs{QKgp~pT=>jIi*@6%6~E5J8*V9kzTYC| orbwt@_LA=%rc7Wo@1_JJA19Zn_gU_y9H0#hp00i_>zopr0366ORsaA1 diff --git a/python/tests/reference/Colormap/shade_None.png b/python/tests/reference/Colormap/shade_None.png new file mode 100644 index 0000000000000000000000000000000000000000..2289910ae27a5d96cd99cf2400367fd8afa9a311 GIT binary patch literal 146 zcmeAS@N?(olHy`uVBq!ia0vp^+(695!3HFgJ}hYlQjwl6jv*CudQTnXZE)alJ*fWo z`wGz+2hwkbCU0SVW^=pp&HZIhCRg08RN8STQt%8%8@qF(Q-pb%+O^(OM|K4+-jH`@ uR)qN~AlFj-TJKK1HPWx+BFy`i|6pvLX89&|fmz9*vXDv2;edFxsq+4aDKW>ecpX&CfSZLuTj;U@d lOq`YqYV`(WwsT literal 0 HcmV?d00001 diff --git a/python/tests/test_Colormap.py b/python/tests/test_Colormap.py index 8eebf63ee..b3309f12b 100644 --- a/python/tests/test_Colormap.py +++ b/python/tests/test_Colormap.py @@ -131,13 +131,14 @@ class TestColormap: c += c assert (np.allclose(c.colors[:len(c.colors)//2],c.colors[len(c.colors)//2:])) - def test_shade(self,reference_dir,update): + @pytest.mark.parametrize('bounds',[None,[2,10]]) + def test_shade(self,reference_dir,update,bounds): data = np.add(*np.indices((10, 11))) - img_current = Colormap.from_predefined('orientation').shade(data) + img_current = Colormap.from_predefined('orientation').shade(data,bounds=bounds) if update: - img_current.save(reference_dir/'shade.png') + img_current.save(reference_dir/f'shade_{bounds}.png') else: - img_reference = Image.open(reference_dir/'shade.png') + img_reference = Image.open(reference_dir/f'shade_{bounds}.png') diff = ImageChops.difference(img_reference.convert('RGB'),img_current.convert('RGB')) assert not diff.getbbox() From 0aaba487d7a27cb9623b0e7dd1e141bef72509f2 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Wed, 5 Aug 2020 06:20:05 +0200 Subject: [PATCH 12/73] required packages --- python/setup.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/python/setup.py b/python/setup.py index 798d8e4bf..360918b38 100644 --- a/python/setup.py +++ b/python/setup.py @@ -20,6 +20,8 @@ setuptools.setup( "scipy", "h5py", "vtk", + "matplotlib", + "PIL", ], classifiers = [ "Intended Audience :: Science/Research", From e4103564a982f6dd781b029506e4f1c4198805d1 Mon Sep 17 00:00:00 2001 From: Philip Eisenlohr Date: Wed, 5 Aug 2020 10:08:48 -0400 Subject: [PATCH 13/73] 16bit color index; proper rounding of index values --- python/damask/_colormap.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/python/damask/_colormap.py b/python/damask/_colormap.py index 6d6fb437b..0da9a564e 100644 --- a/python/damask/_colormap.py +++ b/python/damask/_colormap.py @@ -168,7 +168,7 @@ class Colormap(mpl.colors.ListedColormap): Parameters ---------- - field : np.array of shape(:,:) + field : numpy.array of shape(:,:) Data to be shaded. bounds : iterable of len(2), optional Colormap value range (low,high). @@ -193,8 +193,14 @@ class Colormap(mpl.colors.ListedColormap): if delta * 1e8 <= avg: # delta is similar to numerical noise hi,lo = hi+0.5*avg,lo-0.5*avg # extend range to have actual data centered within - return Image.fromarray((np.dstack((self.colors[(np.clip((field-lo)/(hi-lo),0.0,1.0)*(N-1)).astype(np.uint8),:3], - mask.astype(float)))*255).astype(np.uint8), 'RGBA') + return Image.fromarray( + (np.dstack(( + self.colors[(np.round(np.clip((field-lo)/(hi-lo),0.0,1.0))*(N-1)).astype(np.uint16),:3], + mask.astype(float) + ) + )*255 + ).astype(np.uint8), + mode='RGBA') def show(self,aspect=10,vertical=False): From ce00371f52f61a13589c29e73b42646e77933fb7 Mon Sep 17 00:00:00 2001 From: Philip Eisenlohr Date: Wed, 5 Aug 2020 10:44:10 -0400 Subject: [PATCH 14/73] fixed rounding bug and updated reference images --- python/damask/_colormap.py | 2 +- python/tests/reference/Colormap/shade_None.png | Bin 146 -> 147 bytes .../tests/reference/Colormap/shade_[2, 10].png | Bin 136 -> 138 bytes 3 files changed, 1 insertion(+), 1 deletion(-) diff --git a/python/damask/_colormap.py b/python/damask/_colormap.py index 0da9a564e..99332821d 100644 --- a/python/damask/_colormap.py +++ b/python/damask/_colormap.py @@ -195,7 +195,7 @@ class Colormap(mpl.colors.ListedColormap): return Image.fromarray( (np.dstack(( - self.colors[(np.round(np.clip((field-lo)/(hi-lo),0.0,1.0))*(N-1)).astype(np.uint16),:3], + self.colors[(np.round(np.clip((field-lo)/(hi-lo),0.0,1.0)*(N-1))).astype(np.uint16),:3], mask.astype(float) ) )*255 diff --git a/python/tests/reference/Colormap/shade_None.png b/python/tests/reference/Colormap/shade_None.png index 2289910ae27a5d96cd99cf2400367fd8afa9a311..1fe460cb0f557e34144f5db2599c1ada23cebc50 100644 GIT binary patch delta 118 zcmV-+0Ez#S0h0lcByUI8lxMV#=15(jrD148rQdZ Y0D@{c?6U0%$N&HU07*qoM6N<$f)OM#?EnA( delta 117 zcmV-*0E+*U0g?fbByL$rL_t(|oQ=xC4S+xhMZqWi_ox+^z-QT2W3&b4JllEf-=^e~ zc-?s-xZGJ0%m{`DLxDnAH)bZ*jmpHjQKPVK%$is?swUQrITzNAxh||5>t0wlj;Htm Xg_b$&U7$vN00000NkvXXu0mjfu1Phy diff --git a/python/tests/reference/Colormap/shade_[2, 10].png b/python/tests/reference/Colormap/shade_[2, 10].png index 25c1cebb8d5fcef42d67da42ebcaaf627e508efa..3fb795d83c44555fec0b8a62614990129b4f2054 100644 GIT binary patch delta 109 zcmV-z0FwWR0g3^TBxX@bL_t(|oQ=%E4TCTg1;OF>U!(2F5kw-%At?Y3P{7;sXqWHk zhr6Q>|JLlSS^F^O(_?#?`^WZss}$nG34}@^R0^R|2$e#p6hfu&I)@NWGg+e$JT%Wr P00000NkvXXu0mjf>a{S2 delta 107 zcmV-x0F?iV0f+&RBxFxXL_t(|oQ=w{4TC@w1u*mXpYb?A0wfX&L{Ew^z;o^4?BnD0 z^vT_tqc!W;>Z~cFXa#T_2T3{Bsha(g>ACs5C;Q5h{&PX@p86`~WNXqXjbDb5Q^Q N002ovPDHLkV1kD(Fq{AY From 5f759eae435bf2fba8a2d468c765831466d6896b Mon Sep 17 00:00:00 2001 From: Test User Date: Thu, 6 Aug 2020 05:41:54 +0200 Subject: [PATCH 15/73] [skip ci] updated version information after successful test of v2.0.3-2957-gce00371f --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 2279ff194..55ad31923 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v2.0.3-2948-gb93078d9 +v2.0.3-2957-gce00371f From f379a5f0f164c16faaf3f786d385cc57d67a6285 Mon Sep 17 00:00:00 2001 From: Test User Date: Thu, 6 Aug 2020 08:17:02 +0200 Subject: [PATCH 16/73] [skip ci] updated version information after successful test of v2.0.3-2964-g7824a61f --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 2279ff194..4509da1c9 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v2.0.3-2948-gb93078d9 +v2.0.3-2964-g7824a61f From 0ad189ea9d4b7a2967a04ec7561c393c2c64a4c0 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 8 Aug 2020 18:18:32 +0200 Subject: [PATCH 17/73] not needed anymore --- processing/legacy/imageData.py | 184 ------------------------------ processing/legacy/imageDataRGB.py | 134 ---------------------- 2 files changed, 318 deletions(-) delete mode 100755 processing/legacy/imageData.py delete mode 100755 processing/legacy/imageDataRGB.py diff --git a/processing/legacy/imageData.py b/processing/legacy/imageData.py deleted file mode 100755 index 51547d4eb..000000000 --- a/processing/legacy/imageData.py +++ /dev/null @@ -1,184 +0,0 @@ -#!/usr/bin/env python3 - -import os -import sys -from optparse import OptionParser - -import numpy as np -from PIL import Image - -import damask - - -scriptName = os.path.splitext(os.path.basename(__file__))[0] -scriptID = ' '.join([scriptName,damask.version]) - - -# -------------------------------------------------------------------- -# MAIN -# -------------------------------------------------------------------- - -parser = OptionParser(option_class=damask.extendableOption, usage='%prog options [file[s]]', description = """ -Generate PNG image from data in given column (or 2D data of overall table). - -""", version = scriptID) - -parser.add_option('-l','--label', - dest = 'label', - type = 'string', metavar = 'string', - help = 'column containing data [all]') -parser.add_option('-r','--range', - dest = 'range', - type = 'float', nargs = 2, metavar = 'float float', - help = 'data range (min max) [auto]') -parser.add_option('--gap', '--transparent', - dest = 'gap', - type = 'float', metavar = 'float', - help = 'value to treat as transparent [%default]') -parser.add_option('-d','--dimension', - dest = 'dimension', - type = 'int', nargs = 2, metavar = 'int int', - help = 'data dimension (width height) [native]') -parser.add_option('--color', - dest = 'color', - type = 'string', metavar = 'string', - help = 'color scheme [%default]') -parser.add_option('--invert', - dest = 'invert', - action = 'store_true', - help = 'invert color scheme') -parser.add_option('--abs', - dest = 'abs', - action = 'store_true', - help = 'magnitude of values') -parser.add_option('--log', - dest = 'log', - action = 'store_true', - help = 'log10 of values') -parser.add_option('--fliplr', - dest = 'flipLR', - action = 'store_true', - help = 'flip around vertical axis') -parser.add_option('--flipud', - dest = 'flipUD', - action = 'store_true', - help = 'flip around horizontal axis') -parser.add_option('--crop', - dest = 'crop', - type = 'int', nargs = 4, metavar = 'int int int int', - help = 'pixels cropped on left, right, top, bottom') -parser.add_option('-N','--pixelsize', - dest = 'pixelsize', - type = 'int', metavar = 'int', - help = 'pixel per data point') -parser.add_option('-x','--pixelsizex', - dest = 'pixelsizex', - type = 'int', metavar = 'int', - help = 'pixel per data point along x') -parser.add_option('-y','--pixelsizey', - dest = 'pixelsizey', - type = 'int', metavar = 'int', - help = 'pixel per data point along y') -parser.add_option('--show', - dest = 'show', - action = 'store_true', - help = 'show resulting image') - -parser.set_defaults(label = None, - range = [0.0,0.0], - gap = None, - dimension = [], - abs = False, - log = False, - flipLR = False, - flipUD = False, - color = "gray", - invert = False, - crop = [0,0,0,0], - pixelsize = 1, - pixelsizex = 1, - pixelsizey = 1, - show = False, - ) - -(options,filenames) = parser.parse_args() -if filenames == []: filenames = [None] - -if options.pixelsize > 1: (options.pixelsizex,options.pixelsizey) = [options.pixelsize]*2 - -# --- color palette --------------------------------------------------------------------------------- - -theMap = damask.Colormap(predefined = options.color) -if options.invert: theMap = theMap.invert() -theColors = np.uint8(np.array(theMap.export(format = 'list',steps = 256))*255) - -# --- loop over input files ------------------------------------------------------------------------- -for name in filenames: - try: - table = damask.ASCIItable(name = name, labeled = options.label is not None, readonly = True) - except IOError: - continue - damask.util.report(scriptName,name) - -# ------------------------------------------ read header ------------------------------------------ - - table.head_read() - -# ------------------------------------------ process data ------------------------------------------ - - missing_labels = table.data_readArray(options.label) - if len(missing_labels) > 0: - damask.util.croak('column {} not found.'.format(options.label)) - table.close(dismiss = True) # close ASCIItable and remove empty file - continue -# convert data to values between 0 and 1 and arrange according to given options - if options.dimension != []: table.data = table.data.reshape(options.dimension[1],options.dimension[0]) - if options.abs: table.data = np.abs(table.data) - if options.log: table.data = np.log10(table.data);options.range = np.log10(options.range) - if options.flipLR: table.data = np.fliplr(table.data) - if options.flipUD: table.data = np.flipud(table.data) - - mask = np.logical_or(table.data == options.gap, np.isnan(table.data))\ - if options.gap else np.logical_not(np.isnan(table.data)) # mask gap and NaN (if gap present) - if np.all(np.array(options.range) == 0.0): - options.range = [table.data[mask].min(), - table.data[mask].max()] - damask.util.croak('data range: {0} – {1}'.format(*options.range)) - - delta = max(options.range) - min(options.range) - avg = 0.5*(max(options.range) + min(options.range)) - - if delta * 1e8 <= avg: # delta around numerical noise - options.range = [min(options.range) - 0.5*avg, max(options.range) + 0.5*avg] # extend range to have actual data centered within - - table.data = (table.data - min(options.range)) / \ - (max(options.range) - min(options.range)) - - table.data = np.clip(table.data,0.0,1.0).\ - repeat(options.pixelsizex,axis = 1).\ - repeat(options.pixelsizey,axis = 0) - - mask = mask.\ - repeat(options.pixelsizex,axis = 1).\ - repeat(options.pixelsizey,axis = 0) - - (height,width) = table.data.shape - damask.util.croak('image dimension: {0} x {1}'.format(width,height)) - - im = Image.fromarray(np.dstack((theColors[np.array(255*table.data,dtype = np.uint8)], - 255*mask.astype(np.uint8))), 'RGBA').\ - crop(( options.crop[0], - options.crop[2], - width -options.crop[1], - height-options.crop[3])) - -# ------------------------------------------ output result ----------------------------------------- - - im.save(sys.stdout if not name else - os.path.splitext(name)[0]+ \ - ('' if options.label is None else '_'+options.label)+ \ - '.png', - format = "PNG") - - table.close() # close ASCII table - if options.show: im.show() diff --git a/processing/legacy/imageDataRGB.py b/processing/legacy/imageDataRGB.py deleted file mode 100755 index a34a48f4f..000000000 --- a/processing/legacy/imageDataRGB.py +++ /dev/null @@ -1,134 +0,0 @@ -#!/usr/bin/env python3 - -import os -import sys -from optparse import OptionParser - -import numpy as np -from PIL import Image - -import damask - - -scriptName = os.path.splitext(os.path.basename(__file__))[0] -scriptID = ' '.join([scriptName,damask.version]) - - -# -------------------------------------------------------------------- -# MAIN -# -------------------------------------------------------------------- - -parser = OptionParser(option_class=damask.extendableOption, usage='%prog options [file[s]]', description = """ -Generate PNG image from data in given column vector containing RGB tuples. - -""", version = scriptID) - -parser.add_option('-l','--label', - dest = 'label', - type = 'string', metavar = 'string', - help = 'column containing RGB triplet') -parser.add_option('-d','--dimension', - dest = 'dimension', - type = 'int', nargs = 2, metavar = 'int int', - help = 'data dimension (width height)') -parser.add_option('--fliplr', - dest = 'flipLR', - action = 'store_true', - help = 'flip around vertical axis') -parser.add_option('--flipud', - dest = 'flipUD', - action = 'store_true', - help = 'flip around horizontal axis') -parser.add_option('--crop', - dest = 'crop', - type = 'int', nargs = 4, metavar = ' '.join(['int']*4), - help = 'pixels cropped on left, right, top, bottom') -parser.add_option('-N','--pixelsize', - dest = 'pixelsize', - type = 'int', metavar = 'int', - help = 'pixels per data point') -parser.add_option('-x','--pixelsizex', - dest = 'pixelsizex', - type = 'int', metavar = 'int', - help = 'pixels per data point along x') -parser.add_option('-y','--pixelsizey', - dest = 'pixelsizey', - type = 'int', metavar = 'int', - help = 'pixels per data point along y') -parser.add_option('--show', - dest = 'show', - action = 'store_true', - help = 'show resulting image') - -parser.set_defaults(label = None, - dimension = [], - flipLR = False, - flipUD = False, - crop = [0,0,0,0], - pixelsize = 1, - pixelsizex = 1, - pixelsizey = 1, - show = False, - ) - -(options,filenames) = parser.parse_args() -if filenames == []: filenames = [None] - -if options.dimension == []: parser.error('dimension of data array missing') -if options.pixelsize > 1: (options.pixelsizex,options.pixelsizey) = [options.pixelsize]*2 - -# --- loop over input files ------------------------------------------------------------------------- -for name in filenames: - try: - table = damask.ASCIItable(name = name, labeled = options.label is not None, readonly = True) - except IOError: - continue - damask.util.report(scriptName,name) - -# ------------------------------------------ read header ------------------------------------------ - - table.head_read() - -# ------------------------------------------ process data ------------------------------------------ - - errors = [] - - missing_labels = table.data_readArray(options.label) - if len(missing_labels) > 0: - errors.append('column{} {} not found'.format('s' if len(missing_labels) > 1 else '', - ', '.join(missing_labels))) - if table.label_dimension(options.label) != 3: - errors.append('column {} does not have dimension'.format(options.label)) - - if errors != []: - damask.util.croak(errors) - table.close(dismiss = True) # close ASCII table file handles and delete output file - continue -# convert data to shape and arrange according to given options - if options.dimension != []: table.data = table.data.reshape(options.dimension[1],options.dimension[0],3) - if options.flipLR: table.data = np.fliplr(table.data) - if options.flipUD: table.data = np.flipud(table.data) - - table.data = table.data.repeat(options.pixelsizex,axis=1).\ - repeat(options.pixelsizey,axis=0) - - table.data *= 1. if np.any(table.data > 1.0) else 255.0 # ensure 8 bit data range - - (height,width,bands) = table.data.shape - damask.util.croak('image dimension: {0} x {1}'.format(width,height)) - - im = Image.fromarray(table.data.astype('uint8'), 'RGB').\ - crop(( options.crop[0], - options.crop[2], - width -options.crop[1], - height-options.crop[3])) - -# ------------------------------------------ output result ----------------------------------------- - - im.save(os.path.splitext(name)[0]+ \ - ('_'+options.label if options.label else '')+ \ - '.png' if name else sys.stdout, - format = "PNG") - - table.close() # close ASCII table - if options.show: im.show() From 0878302961846dfd059113100d3c8c0790e5a9a5 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 8 Aug 2020 18:19:04 +0200 Subject: [PATCH 18/73] WIP: making compatible with python3/vtk9 --- processing/post/vtk2ang.py | 130 ++++++++++++++++--------------------- 1 file changed, 56 insertions(+), 74 deletions(-) diff --git a/processing/post/vtk2ang.py b/processing/post/vtk2ang.py index eb94f7d8a..9ee19dac7 100755 --- a/processing/post/vtk2ang.py +++ b/processing/post/vtk2ang.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2.7 +#!/usr/bin/env python3 import os import sys @@ -11,13 +11,13 @@ import vtk import damask - + scriptName = os.path.splitext(os.path.basename(__file__))[0] scriptID = ' '.join([scriptName,damask.version]) # ----------------------------- def getHeader(filename,sizeFastIndex,sizeSlowIndex,stepsize): - """Returns header for ang file step size in micrometer""" + """Returns header for ang file step size in micrometer.""" return '\n'.join([ \ '# TEM_PIXperUM 1.000000', \ '# x-star 1.000000', \ @@ -53,7 +53,7 @@ def getHeader(filename,sizeFastIndex,sizeSlowIndex,stepsize): # ----------------------------- def positiveRadians(angle): - """Returns positive angle in radians from angle in degrees""" + """Returns positive angle in radians from angle in degrees.""" angle = math.radians(float(angle)) while angle < 0.0: angle += 2.0 * math.pi @@ -67,7 +67,7 @@ def getDataLine(angles,x,y,validData=True): Returns string of one line in ang file. Convention in ang file: y coordinate comes first and is fastest index - positions in micrometer + positions in micrometer. """ info = {True: (9999.9, 1.0, 0,99999,0.0), False: ( -1.0,-1.0,-1, -1,1.0)} @@ -75,18 +75,16 @@ def getDataLine(angles,x,y,validData=True): %(tuple(map(positiveRadians,angles))+(y*1e6,x*1e6)+info[validData]) - # -------------------------------------------------------------------- # MAIN FUNCTION STARTS HERE # -------------------------------------------------------------------- - parser = OptionParser(usage='%prog options [file[s]]', description = """ Builds a ang files from a vtk file. """, version = scriptID) -parser.add_option('--disp','--displacement',dest='dispLabel', +parser.add_option('--disp','--displacement',dest='dispLabel', metavar ='string', help='label of displacements [%default]') parser.add_option('--euler', dest='eulerLabel', nargs=3, @@ -110,11 +108,6 @@ parser.add_option('-s','--scale', dest='scale', type='float', parser.add_option('-r','--resolution', dest='resolution', type='float', metavar ='float', help='scaling factor for resolution [%default]') -parser.add_option('--hex','--hexagonal', dest='hexagonal', action='store_true', - help='use in plane hexagonal grid') -parser.add_option('--interpolation', dest='interpolation', type='int', - metavar='float', - help='number of points for linear interpolation [%default]') parser.add_option('--verbose', dest='verbose', action='store_true', help='verbose mode') parser.add_option('--visualize', dest='visualize', action='store_true', @@ -122,7 +115,6 @@ parser.add_option('--visualize', dest='visualize', action='store_true parser.set_defaults(dispLabel = 'displacement') parser.set_defaults(eulerLabel = ['1_1_eulerangles','1_2_eulerangles','1_3_eulerangles']) -parser.set_defaults(hexagonal = False) parser.set_defaults(normal = [0.0,0.0,-1.0]) parser.set_defaults(up = [0.0,1.0,0.0]) parser.set_defaults(Nslices = 1) @@ -130,7 +122,6 @@ parser.set_defaults(distance = 0.0) parser.set_defaults(scale = 1.0) parser.set_defaults(resolution = 1.0) parser.set_defaults(dispScaling = 1.0) -parser.set_defaults(interpolation = 1) parser.set_defaults(verbose = False) parser.set_defaults(visualize = False) (options,filenames) = parser.parse_args() @@ -153,35 +144,26 @@ if np.dot(np.array(options.normal),np.array(options.up)) > 1e-3: parser.error('normal vector and up vector have to be orthogonal') -# check for options that are not yet implemented - -if options.interpolation > 1: - parser.error('interpolation not yet supported') -if options.hexagonal: - parser.error('hexagonal grid not yet supported') - - - #--- ITERATE OVER FILES AND PROCESS THEM for filename in filenames: - + if options.verbose: sys.stdout.write("\nREADING VTK FILE\n") # Read the source file reader = vtk.vtkUnstructuredGridReader() reader.SetFileName(filename) reader.ReadAllScalarsOn() reader.ReadAllVectorsOn() - reader.Update() + reader.Update() undeformedMesh = reader.GetOutput() - + # Get euler angles from cell data - + if options.verbose: sys.stdout.write("\nGETTING EULER ANGLES\n") angles = {} - for i in range(reader.GetNumberOfScalarsInFile()): - scalarName = reader.GetScalarsNameInFile(i) + for i in range(undeformedMesh.GetPointData().GetNumberOfArrays()): + scalarName = undeformedMesh.GetPointData().GetArrayName(i) if scalarName in options.eulerLabel: angles[scalarName] = undeformedMesh.GetCellData().GetScalars(scalarName) if options.verbose: sys.stdout.write(" found scalar with name %s\n"%scalarName) @@ -189,14 +171,14 @@ for filename in filenames: for label in options.eulerLabel: if label not in angles.keys(): parser.error('Could not find scalar data with name %s'%label) - - + + # Get deformed mesh - + if options.verbose: sys.stdout.write("\nDEFORM MESH\n") warpVector = vtk.vtkWarpVector() undeformedMesh.GetPointData().SetActiveVectors(options.dispLabel) - warpVector.SetInput(undeformedMesh) + warpVector.SetInputData(undeformedMesh) warpVector.Update() deformedMesh = warpVector.GetOutput() box = deformedMesh.GetBounds() # bounding box in mesh system @@ -208,24 +190,24 @@ for filename in filenames: # Get cell centers of deformed mesh (position of ips) - + if options.verbose: sys.stdout.write("\nGETTING CELL CENTERS OF DEFORMED MESH\n") cellCenter = vtk.vtkCellCenters() cellCenter.SetVertexCells(0) # do not generate vertex cells, just points - cellCenter.SetInput(deformedMesh) + cellCenter.SetInputData(deformedMesh) cellCenter.Update() meshIPs = cellCenter.GetOutput() # Get outer surface of deformed mesh - + if options.verbose: sys.stdout.write("\nGETTING OUTER SURFACE OF DEFORMED MESH\n") surfaceFilter = vtk.vtkDataSetSurfaceFilter() - surfaceFilter.SetInput(deformedMesh) + surfaceFilter.SetInputData(deformedMesh) surfaceFilter.Update() surface = surfaceFilter.GetOutput() - - + + # Get coordinate system for ang files # z-vector is normal to slices # x-vector corresponds to the up-direction @@ -249,10 +231,10 @@ for filename in filenames: if options.verbose: sys.stdout.write("\nGETTING BOUNDING BOX IN ROTATED SYSTEM\n") rotatedbox = [[np.inf,-np.inf] for i in range(3)] # bounding box in rotated TSL system - for n in range(8): # loop over eight vertices of mesh bounding box - vert = np.array([box[0+(n/1)%2], - box[2+(n/2)%2], - box[4+(n/4)%2]]) # vertex in mesh system + for n in range(8): # loop over eight vertices of mesh bounding box + vert = np.array([box[0+(n//1)%2], + box[2+(n//2)%2], + box[4+(n//4)%2]]) # vertex in mesh system rotatedvert = np.dot(R,vert) # vertex in rotated system for i in range(3): rotatedbox[i][0] = min(rotatedbox[i][0],rotatedvert[i]) @@ -274,7 +256,7 @@ for filename in filenames: for i in range(2): Npoints.extend([int(math.ceil(extent[i] / options.resolution))]) correction.extend([float(Npoints[i]) * options.resolution - extent[i]]) - if options.distance > 0.0: + if options.distance > 0.0: Npoints.extend([int(math.ceil(extent[2] / options.distance))]) correction.extend([float(Npoints[2]) * options.distance - extent[2]]) else: @@ -282,8 +264,8 @@ for filename in filenames: correction.extend([0.0]) options.distance = extent[2] / float(options.Nslices) for i in range(3): - rotatedbox[i][0] = rotatedbox[i][0] - 0.5 * correction[i] - rotatedbox[i][1] = rotatedbox[i][1] + 0.5 * correction[i] + rotatedbox[i][0] -= 0.5 * correction[i] + rotatedbox[i][1] += 0.5 * correction[i] extent[i] = rotatedbox[i][1] - rotatedbox[i][0] NpointsPerSlice = Npoints[0] * Npoints[1] totalNpoints = NpointsPerSlice * Npoints[2] @@ -301,20 +283,20 @@ for filename in filenames: if options.verbose: sys.stdout.write("\nGENERATING POINTS FOR POINT GRID") points = vtk.vtkPoints() for k in range(Npoints[2]): - for j in range(Npoints[0]): + for j in range(Npoints[0]): for i in range(Npoints[1]): # y is fastest index rotatedpoint = np.array([rotatedbox[0][0] + (float(j) + 0.5) * options.resolution, - rotatedbox[1][0] + (float(i) + 0.5) * options.resolution, - rotatedbox[2][0] + (float(k) + 0.5) * options.distance ]) # point in rotated system + rotatedbox[1][0] + (float(i) + 0.5) * options.resolution, + rotatedbox[2][0] + (float(k) + 0.5) * options.distance ]) # point in rotated system point = np.dot(R.T,rotatedpoint) # point in mesh system points.InsertNextPoint(list(point)) - if options.verbose: + if options.verbose: sys.stdout.write("\rGENERATING POINTS FOR POINT GRID %d%%" %(100*(Npoints[1]*(k*Npoints[0]+j)+i+1)/totalNpoints)) sys.stdout.flush() - if options.verbose: + if options.verbose: sys.stdout.write("\n number of slices: %i\n"%Npoints[2]) sys.stdout.write(" slice spacing: %.8f\n"%options.distance) - if Npoints[2] > 1: + if Npoints[2] > 1: sys.stdout.write(" number of points per slice: %i = %i rows * %i points in row\n"%(NpointsPerSlice,Npoints[0],Npoints[1])) sys.stdout.write(" grid resolution: %.8f\n"%options.resolution) @@ -324,7 +306,7 @@ for filename in filenames: vertex = vtk.vtkVertex() vertex.GetPointIds().SetId(0,i) # each vertex consists of exactly one (index 0) point with ID "i" vertices.InsertNextCell(vertex) - if options.verbose: + if options.verbose: sys.stdout.write("\rGENERATING VERTICES FOR POINT GRID %d%%" %(100*(i+1)/totalNpoints)) sys.stdout.flush() @@ -357,34 +339,34 @@ for filename in filenames: if enclosedPoints.IsInside(i): NenclosedPoints += 1 # here one could use faster(?) "FindClosestPoint" if only first nearest neighbor required - kdTree.FindClosestNPoints(options.interpolation,pointgrid.GetPoint(i),ids) - for j in range(ids.GetNumberOfIds()): + kdTree.FindClosestNPoints(1,pointgrid.GetPoint(i),ids) + for j in range(ids.GetNumberOfIds()): gridToMesh[-1].extend([ids.GetId(j)]) - if options.verbose: + if options.verbose: sys.stdout.write("\rBUILDING MAPPING OF GRID POINTS %d%%" %(100*(i+1)/totalNpoints)) sys.stdout.flush() if options.verbose: sys.stdout.write("\n Number of points inside mesh geometry %i\n"%NenclosedPoints) sys.stdout.write(" Number of points outside mesh geometry %i\n"%(totalNpoints - NenclosedPoints)) - + # ITERATE OVER SLICES AND CREATE ANG FILE - - if options.verbose: + + if options.verbose: sys.stdout.write("\nWRITING OUT ANG FILES\n") sys.stdout.write(" scaling all length with %f\n"%options.scale) x0,y0,z0 = np.dot(R,pointgrid.GetPoint(0)) # first point on slice defines origin for sliceN in range(Npoints[2]): - + # Open file and write header - + angfilename = eval('"'+eval("'%%s_slice%%0%ii.ang'%(math.log10(Npoints[2])+1)")+'"%(os.path.splitext(filename)[0],sliceN+1)') with open(angfilename,'w') as angfile: if options.verbose: sys.stdout.write(" %s\n"%angfilename) angfile.write(getHeader(filename,Npoints[1],Npoints[0],options.resolution*options.scale)) for i in range(sliceN*NpointsPerSlice,(sliceN+1)*NpointsPerSlice): # Iterate over points on slice - + # Get euler angles of closest IDs @@ -397,26 +379,26 @@ for filename in filenames: phi[-1].extend([angles[options.eulerLabel[k]].GetValue(IP)]) else: phi = [[720,720,720]] # fake angles - - + + # Interpolate Euler angle # NOT YET IMPLEMENTED, simply take the nearest neighbors values interpolatedPhi = phi[0] - - + + # write data to ang file x,y,z = np.dot(R,pointgrid.GetPoint(i)) # point in rotated TSL system - x -= x0 # first point on slice defines origin - y -= y0 # first point on slice defines origin + x -= x0 # first point on slice defines origin + y -= y0 # first point on slice defines origin x *= options.scale y *= options.scale angfile.write(getDataLine(interpolatedPhi,x,y,enclosedPoints.IsInside(i))) - + # Visualize slices - + if options.visualize: meshMapper = vtk.vtkDataSetMapper() meshMapper.SetInput(surface) @@ -426,11 +408,11 @@ for filename in filenames: meshActor.GetProperty().SetOpacity(0.2) meshActor.GetProperty().SetColor(1.0,1.0,0) meshActor.GetProperty().BackfaceCullingOn() - + boxpoints = vtk.vtkPoints() for n in range(8): P = [rotatedbox[0][(n/1)%2], - rotatedbox[1][(n/2)%2], + rotatedbox[1][(n/2)%2], rotatedbox[2][(n/4)%2]] boxpoints.InsertNextPoint(list(np.dot(R.T,np.array(P)))) box = vtk.vtkHexahedron() @@ -469,7 +451,7 @@ for filename in filenames: renderer.AddActor(boxActor) renderer.AddActor(gridActor) renderer.SetBackground(1,1,1) - + renderWindow.Render() renderWindowInteractor.SetInteractorStyle(vtk.vtkInteractorStyleTrackballCamera()) renderWindowInteractor.Start() From e4ad2ab82e90527f610464a5f8afacd650ba436c Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 8 Aug 2020 18:19:48 +0200 Subject: [PATCH 19/73] test is broken, consider the script to be broken. just keep the executable until the next cleanup in PRIVATE is done --- processing/pre/geom_addPrimitive.py | 62 +---------------------------- 1 file changed, 1 insertion(+), 61 deletions(-) diff --git a/processing/pre/geom_addPrimitive.py b/processing/pre/geom_addPrimitive.py index c04fcf565..318810a01 100755 --- a/processing/pre/geom_addPrimitive.py +++ b/processing/pre/geom_addPrimitive.py @@ -1,12 +1,8 @@ #!/usr/bin/env python3 import os -import sys -from io import StringIO from optparse import OptionParser -import numpy as np - import damask @@ -76,60 +72,4 @@ parser.set_defaults(center = (.0,.0,.0), inside = True, ) -(options, filenames) = parser.parse_args() - -if options.dimension is None: - parser.error('no dimension specified.') -if [options.angleaxis,options.quaternion].count(None) == 0: - parser.error('more than one rotation specified.') - -if options.angleaxis is not None: - rotation = damask.Rotation.from_axis_angle(np.array(options.angleaxis),options.degrees,normalise=True) -elif options.quaternion is not None: - rotation = damask.Rotation.from_quaternion(options.quaternion) -else: - rotation = damask.Rotation() - - -if filenames == []: filenames = [None] - -for name in filenames: - damask.util.report(scriptName,name) - - geom = damask.Geom.from_file(StringIO(''.join(sys.stdin.read())) if name is None else name) - grid = geom.get_grid() - size = geom.get_size() - - # scale to box of size [1.0,1.0,1.0] - if options.realspace: - center = (np.array(options.center) - geom.get_origin())/size - r = np.array(options.dimension)/size/2.0 - else: - center = (np.array(options.center) + 0.5)/grid - r = np.array(options.dimension)/grid/2.0 - - if np.any(center<0.0) or np.any(center>=1.0): print('error') - - offset = np.ones(3)*0.5 if options.periodic else center - mask = np.full(grid,False) - # High exponents can cause underflow & overflow - okay here, just compare to 1, so +infinity and 0 are fine - np.seterr(over='ignore', under='ignore') - - e = 2.0**np.array(options.exponent) - for x in range(grid[0]): - for y in range(grid[1]): - for z in range(grid[2]): - coords = np.array([x+0.5,y+0.5,z+0.5])/grid - mask[x,y,z] = np.sum(np.abs((rotation*(coords-offset))/r)**e) < 1 - - if options.periodic: - shift = ((offset-center)*grid).astype(int) - mask = np.roll(mask,shift,(0,1,2)) - - if options.inside: mask = np.logical_not(mask) - fill = np.nanmax(geom.microstructure)+1 if options.fill is None else options.fill - - damask.util.croak(geom.update(np.where(mask,geom.microstructure,fill))) - geom.add_comments(scriptID + ' ' + ' '.join(sys.argv[1:])) - - geom.to_file(sys.stdout if name is None else name,pack=False) +print('This script is broken and does nothing') From 0bfe5903ad394edda386d80b224fde4b0bfc822d Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 8 Aug 2020 18:21:17 +0200 Subject: [PATCH 20/73] standard layout - standard libraries - space - external libraries - space - damask library --- processing/pre/mentat_pbcOnBoxMesh.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/processing/pre/mentat_pbcOnBoxMesh.py b/processing/pre/mentat_pbcOnBoxMesh.py index adf0b1aff..3677a5efa 100755 --- a/processing/pre/mentat_pbcOnBoxMesh.py +++ b/processing/pre/mentat_pbcOnBoxMesh.py @@ -1,9 +1,14 @@ #!/usr/bin/env python3 -# -*- coding: UTF-8 no BOM -*- -import sys,os,re,time,tempfile -import numpy as np +import sys +import os +import re +import time +import tempfile from optparse import OptionParser + +import numpy as np + import damask sys.path.append(str(damask.solver.Marc().library_path)) From ba4625c2a4a688f124b8d96389100bae95029f3b Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 8 Aug 2020 18:22:34 +0200 Subject: [PATCH 21/73] return not needed --- processing/pre/mentat_spectralBox.py | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/processing/pre/mentat_spectralBox.py b/processing/pre/mentat_spectralBox.py index e6d138952..b0694ec4a 100755 --- a/processing/pre/mentat_spectralBox.py +++ b/processing/pre/mentat_spectralBox.py @@ -20,7 +20,6 @@ def outMentat(cmd,locals): py_mentat.py_send(cmd) else: py_mentat.py_send(cmd) - return #------------------------------------------------------------------------------------------------- def outFile(cmd,locals,dest): @@ -31,7 +30,6 @@ def outFile(cmd,locals,dest): dest.write(cmd+'\n') else: dest.write(cmd+'\n') - return #------------------------------------------------------------------------------------------------- def output(cmds,locals,dest): @@ -43,8 +41,6 @@ def output(cmds,locals,dest): outMentat(str(cmd),locals) else: outFile(str(cmd),locals,dest) - return - #------------------------------------------------------------------------------------------------- @@ -105,7 +101,7 @@ def mesh(r,d): #------------------------------------------------------------------------------------------------- def material(): - cmds = [\ + return [\ "*new_mater standard", "*mater_option general:state:solid", "*mater_option structural:type:hypo_elast", @@ -119,12 +115,10 @@ def material(): "all_existing", ] - return cmds - #------------------------------------------------------------------------------------------------- def geometry(): - cmds = [\ + return [\ "*geometry_type mech_three_solid", # "*geometry_option red_integ_capacity:on", "*add_geometry_elements", @@ -134,8 +128,6 @@ def geometry(): "all_existing", ] - return cmds - #------------------------------------------------------------------------------------------------- def initial_conditions(homogenization,microstructures): From 56eb57d253f6dcfecc78537bdd38822ae6404cce Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 8 Aug 2020 18:24:17 +0200 Subject: [PATCH 22/73] homogenization will be removed soon, stop reporting it --- python/damask/_geom.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/python/damask/_geom.py b/python/damask/_geom.py index 59da5e117..7ee923ad8 100644 --- a/python/damask/_geom.py +++ b/python/damask/_geom.py @@ -46,7 +46,6 @@ class Geom: f'grid a b c: {util.srepr(self.get_grid ()," x ")}', f'size x y z: {util.srepr(self.get_size ()," x ")}', f'origin x y z: {util.srepr(self.get_origin()," ")}', - f'homogenization: {self.get_homogenization()}', f'# microstructures: {self.N_microstructure}', f'max microstructure: {np.nanmax(self.microstructure)}', ]) @@ -100,8 +99,6 @@ class Geom: message[-1] = util.delete(message[-1]) message.append(util.emph(f'origin x y z: {util.srepr(self.get_origin()," ")}')) - message.append(f'homogenization: {self.get_homogenization()}') - message.append(f'# microstructures: {unique_old}') if unique_old != self.N_microstructure: message[-1] = util.delete(message[-1]) From 5fcff876f9f8ab4b5baa59013f3f38c2a3ef92c2 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 8 Aug 2020 18:41:47 +0200 Subject: [PATCH 23/73] replace selectively useful for vicinity_offset and add_primitive --- python/damask/_geom.py | 24 ++++++++++++++++-------- python/tests/test_Geom.py | 10 ++++++++++ 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/python/damask/_geom.py b/python/damask/_geom.py index 7ee923ad8..144a80b70 100644 --- a/python/damask/_geom.py +++ b/python/damask/_geom.py @@ -6,7 +6,7 @@ from functools import partial import numpy as np from scipy import ndimage,spatial -import damask +from . import environment from . import VTK from . import util from . import grid_filters @@ -143,20 +143,28 @@ class Geom: """ Replace the existing microstructure representation. + The complete microstructure is replaced (indcluding grid definition), + unless a masked array is provided in which case the grid dimensions + need to match and masked entries are not replaced. + Parameters ---------- - microstructure : numpy.ndarray - microstructure array (3D). + microstructure : numpy.ndarray or numpy.ma.core.MaskedArray of shape (:,:,:) + Microstructure indices. """ if microstructure is not None: - if len(microstructure.shape) != 3: - raise ValueError(f'Invalid microstructure shape {microstructure.shape}') - elif microstructure.dtype not in np.sctypes['float'] + np.sctypes['int']: - raise TypeError(f'Invalid microstructue data type {microstructure.dtype}') + if isinstance(microstructure,np.ma.core.MaskedArray): + self.microstructure = np.where(microstructure.mask, + self.microstructure,microstructure.data) else: self.microstructure = np.copy(microstructure) + if len(self.microstructure.shape) != 3: + raise ValueError(f'Invalid microstructure shape {microstructure.shape}') + elif self.microstructure.dtype not in np.sctypes['float'] + np.sctypes['int']: + raise TypeError(f'Invalid microstructue data type {microstructure.dtype}') + def set_size(self,size): """ @@ -359,7 +367,7 @@ class Geom: seeds_p = seeds coords = grid_filters.cell_coord0(grid,size).reshape(-1,3) - pool = multiprocessing.Pool(processes = int(damask.environment.options['DAMASK_NUM_THREADS'])) + pool = multiprocessing.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]) pool.close() pool.join() diff --git a/python/tests/test_Geom.py b/python/tests/test_Geom.py index 155178322..f5ffbd6bf 100644 --- a/python/tests/test_Geom.py +++ b/python/tests/test_Geom.py @@ -40,6 +40,16 @@ class TestGeom: print(modified) assert geom_equal(modified,default) + @pytest.mark.parametrize('masked',[True,False]) + def test_set_microstructure(self,default,masked): + old = default.get_microstructure() + new = np.random.randint(200,size=default.grid) + default.set_microstructure(np.ma.MaskedArray(new,np.full_like(new,masked))) + if masked: + assert np.all(default.microstructure==old) + else: + assert np.all(default.microstructure==new) + def test_write_read_str(self,default,tmpdir): default.to_file(str(tmpdir.join('default.geom'))) From a0e0f28e51db223110cb87d0ebdb99c95804b341 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 8 Aug 2020 19:42:34 +0200 Subject: [PATCH 24/73] migrating shell scripts to library --- processing/pre/geom_vicinityOffset.py | 32 ++------- python/damask/_geom.py | 97 ++++++++++++++++++++------- python/tests/test_Geom.py | 41 ++++++++++- 3 files changed, 117 insertions(+), 53 deletions(-) diff --git a/processing/pre/geom_vicinityOffset.py b/processing/pre/geom_vicinityOffset.py index e30779d31..650e0093a 100755 --- a/processing/pre/geom_vicinityOffset.py +++ b/processing/pre/geom_vicinityOffset.py @@ -5,7 +5,6 @@ import sys from io import StringIO from optparse import OptionParser -from scipy import ndimage import numpy as np import damask @@ -15,18 +14,6 @@ scriptName = os.path.splitext(os.path.basename(__file__))[0] scriptID = ' '.join([scriptName,damask.version]) -def taintedNeighborhood(stencil,trigger=[],size=1): - - me = stencil[stencil.shape[0]//2] - if len(trigger) == 0: - return np.any(stencil != me) - if me in trigger: - trigger = set(trigger) - trigger.remove(me) - trigger = list(trigger) - return np.any(np.in1d(stencil,np.array(trigger))) - - #-------------------------------------------------------------------------------------------------- # MAIN #-------------------------------------------------------------------------------------------------- @@ -67,19 +54,12 @@ options.trigger = np.array(options.trigger, dtype=int) if filenames == []: filenames = [None] for name in filenames: - damask.util.report(scriptName,name) + damask.util.report(scriptName,name) - geom = damask.Geom.from_file(StringIO(''.join(sys.stdin.read())) if name is None else name) + geom = damask.Geom.from_file(StringIO(''.join(sys.stdin.read())) if name is None else name) - offset = np.nanmax(geom.microstructure) if options.offset is None else options.offset + damask.util.croak(geom.vicinity_offset(options.vicinity,options.offset,options.trigger, + True if options.mode is 'wrap' else False)) + geom.add_comments(scriptID + ' ' + ' '.join(sys.argv[1:])) - damask.util.croak(geom.update(np.where(ndimage.filters.generic_filter( - geom.microstructure, - taintedNeighborhood, - size=1+2*options.vicinity,mode=options.mode, - extra_arguments=(), - extra_keywords={"trigger":options.trigger,"size":1+2*options.vicinity}), - geom.microstructure + offset,geom.microstructure))) - geom.add_comments(scriptID + ' ' + ' '.join(sys.argv[1:])) - - geom.to_file(sys.stdout if name is None else name,pack=False) + geom.to_file(sys.stdout if name is None else name,pack=False) diff --git a/python/damask/_geom.py b/python/damask/_geom.py index 144a80b70..4416be401 100644 --- a/python/damask/_geom.py +++ b/python/damask/_geom.py @@ -278,7 +278,7 @@ class Geom: Parameters ---------- fname : str or file handle - geometry file to read. + Geometry file to read. """ try: @@ -345,15 +345,15 @@ class Geom: Parameters ---------- grid : numpy.ndarray of shape (3) - number of grid points in x,y,z direction. + Number of grid points in x,y,z direction. size : list or numpy.ndarray of shape (3) - physical size of the microstructure in meter. + Physical size of the microstructure in meter. seeds : numpy.ndarray of shape (:,3) - position of the seed points in meter. All points need to lay within the box. + Position of the seed points in meter. All points need to lay within the box. weights : numpy.ndarray of shape (seeds.shape[0]) - weights of the seeds. Setting all weights to 1.0 gives a standard Voronoi tessellation. + Weights of the seeds. Setting all weights to 1.0 gives a standard Voronoi tessellation. periodic : Boolean, optional - perform a periodic tessellation. Defaults to True. + Perform a periodic tessellation. Defaults to True. """ if periodic: @@ -391,13 +391,13 @@ class Geom: Parameters ---------- grid : numpy.ndarray of shape (3) - number of grid points in x,y,z direction. + Number of grid points in x,y,z direction. size : list or numpy.ndarray of shape (3) - physical size of the microstructure in meter. + Physical size of the microstructure in meter. seeds : numpy.ndarray of shape (:,3) - position of the seed points in meter. All points need to lay within the box. + Position of the seed points in meter. All points need to lay within the box. periodic : Boolean, optional - perform a periodic tessellation. Defaults to True. + Perform a periodic tessellation. Defaults to True. """ coords = grid_filters.cell_coord0(grid,size).reshape(-1,3) @@ -415,9 +415,9 @@ class Geom: Parameters ---------- fname : str or file handle - geometry file to write. + Geometry file to write. pack : bool, optional - compress geometry with 'x of y' and 'a to b'. + Compress geometry with 'x of y' and 'a to b'. """ header = self.get_header() @@ -481,7 +481,7 @@ class Geom: Parameters ---------- fname : str, optional - vtk file to write. If no file is given, a string is returned. + Vtk file to write. If no file is given, a string is returned. """ v = VTK.from_rectilinearGrid(self.grid,self.size,self.origin) @@ -508,9 +508,9 @@ class Geom: Parameters ---------- directions : iterable containing str - direction(s) along which the microstructure is mirrored. Valid entries are 'x', 'y', 'z'. + Direction(s) along which the microstructure is mirrored. Valid entries are 'x', 'y', 'z'. reflect : bool, optional - reflect (include) outermost layers. + Reflect (include) outermost layers. """ valid = {'x','y','z'} @@ -540,7 +540,7 @@ class Geom: Parameters ---------- grid : numpy.ndarray of shape (3) - number of grid points in x,y,z direction. + Number of grid points in x,y,z direction. """ #ToDo: self.add_comments('geom.py:scale v{}'.format(version) @@ -563,7 +563,7 @@ class Geom: Parameters ---------- stencil : int, optional - size of smoothing stencil. + Size of smoothing stencil. """ def mostFrequent(arr): @@ -596,9 +596,9 @@ class Geom: Parameters ---------- R : damask.Rotation - rotation to apply to the microstructure. + Rotation to apply to the microstructure. fill : int or float, optional - microstructure index to fill the corners. Defaults to microstructure.max() + 1. + Microstructure index to fill the corners. Defaults to microstructure.max() + 1. """ if fill is None: fill = np.nanmax(self.microstructure) + 1 @@ -631,11 +631,11 @@ class Geom: Parameters ---------- grid : numpy.ndarray of shape (3) - number of grid points in x,y,z direction. + Number of grid points in x,y,z direction. offset : numpy.ndarray of shape (3) - offset (measured in grid points) from old to new microstructue[0,0,0]. + Offset (measured in grid points) from old to new microstructure[0,0,0]. fill : int or float, optional - microstructure index to fill the corners. Defaults to microstructure.max() + 1. + Microstructure index to fill the corners. Defaults to microstructure.max() + 1. """ if fill is None: fill = np.nanmax(self.microstructure) + 1 @@ -658,14 +658,14 @@ class Geom: def substitute(self,from_microstructure,to_microstructure): """ - Substitude microstructure indices. + Substitute microstructure indices. Parameters ---------- from_microstructure : iterable of ints - microstructure indices to be substituted. + Microstructure indices to be substituted. to_microstructure : iterable of ints - new microstructure indices. + New microstructure indices. """ substituted = self.get_microstructure() @@ -674,3 +674,50 @@ class Geom: #ToDo: self.add_comments('geom.py:substitute v{}'.format(version) return self.update(substituted) + + + def vicinity_offset(self,vicinity=1,offset=None,trigger=[],periodic=True): + """ + Offset microstructure index of points in the vicinity of xxx. + + 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 + + Parameters + ---------- + vicinity : int, optional + Voxel distance checked for presence of other microstructure. + Defaults to 1. + offset : int, optional + Offset (positive or negative) to tag microstructure indices, + defaults to microstructure.max() + 1. + trigger : list of ints, optional + List of microstructure indices triggering a change. + Defaults to [], meaning that different neigboors trigger a change. + periodic : Boolean, optional + Assume geometry to be periodic. Defaults to True. + + """ + def tainted_neighborhood(stencil,trigger): + + me = stencil[stencil.shape[0]//2] + if len(trigger) == 0: + return np.any(stencil != me) + if me in trigger: + trigger = set(trigger) + trigger.remove(me) + trigger = list(trigger) + return np.any(np.in1d(stencil,np.array(trigger))) + + offset_ = np.nanmax(self.microstructure) if offset is None else offset + mask = ndimage.filters.generic_filter(self.microstructure, + tainted_neighborhood, + size=1+2*vicinity, + mode=('wrap' if periodic else 'nearest'), + extra_keywords={'trigger':trigger}) + microstructure = np.ma.MaskedArray(self.microstructure + offset_, np.logical_not(mask)) + + #ToDo: self.add_comments('geom.py:vicinity_offset v{}'.format(version) + return self.update(microstructure) + diff --git a/python/tests/test_Geom.py b/python/tests/test_Geom.py index f5ffbd6bf..1cb29e0b0 100644 --- a/python/tests/test_Geom.py +++ b/python/tests/test_Geom.py @@ -77,9 +77,19 @@ class TestGeom: with pytest.raises(ValueError): default.update(default.microstructure[1:,1:,1:],size=np.ones(2)) - def test_invalid_microstructure(self,default): + def test_invalid_origin(self,default): with pytest.raises(ValueError): - default.update(default.microstructure[1]) + default.update(default.microstructure[1:,1:,1:],origin=np.ones(4)) + + def test_invalid_microstructure_size(self,default): + microstructure=np.ones((3,3)) + with pytest.raises(ValueError): + default.update(microstructure) + + def test_invalid_microstructure_type(self,default): + microstructure=np.random.randint(1,300,(3,4,5))==1 + with pytest.raises(TypeError): + default.update(microstructure) def test_invalid_homogenization(self,default): with pytest.raises(TypeError): @@ -171,7 +181,34 @@ class TestGeom: modified.canvas(modified.grid + grid_add) e = default.grid assert np.all(modified.microstructure[:e[0],:e[1],:e[2]] == default.microstructure) + + @pytest.mark.parametrize('trigger',[[1],[]]) + def test_vicinity_offset(self,trigger): + offset = np.random.randint(2,4) + vicinity = np.random.randint(2,4) + + g=np.random.randint(28,40,(3)) + m=np.ones(g,'i') + x=(g*np.random.permutation(np.array([.5,1,1]))).astype('i') + m[slice(0,x[0]),slice(0,x[1]),slice(0,x[2])]=2 + m2=copy.deepcopy(m) + for i in [0,1,2]: + m2[(np.roll(m,+vicinity,i)-m)!=0] +=offset + m2[(np.roll(m,-vicinity,i)-m)!=0] +=offset + if len(trigger) > 0: + m2[m==1]=1 + + geom = Geom(m,np.random.rand(3)) + geom.vicinity_offset(vicinity,offset,trigger=trigger) + + assert np.all(m2==geom.microstructure) + @pytest.mark.parametrize('periodic',[True,False]) + def test_vicinity_offset_invariant(self,default,periodic): + old = default.get_microstructure() + default.vicinity_offset(trigger=[old.max()+1,old.min()-1]) + assert np.all(old==default.microstructure) + @pytest.mark.parametrize('periodic',[True,False]) def test_tessellation_approaches(self,periodic): grid = np.random.randint(10,20,3) From 2db8ba13fc81dbd3c27aecc2d9c28a6569f90ed6 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 8 Aug 2020 19:44:08 +0200 Subject: [PATCH 25/73] better reporting: show small values --- src/grid/grid_damage_spectral.f90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/grid/grid_damage_spectral.f90 b/src/grid/grid_damage_spectral.f90 index 339a11a4a..65ca9b1dd 100644 --- a/src/grid/grid_damage_spectral.f90 +++ b/src/grid/grid_damage_spectral.f90 @@ -210,8 +210,8 @@ function grid_damage_spectral_solution(timeinc,timeinc_old) result(solution) call VecMax(solution_vec,devNull,phi_max,ierr); CHKERRQ(ierr) if (solution%converged) & write(6,'(/,a)') ' ... nonlocal damage converged .....................................' - write(6,'(/,a,f8.6,2x,f8.6,2x,f8.6,/)',advance='no') ' Minimum|Maximum|Delta Damage = ',& - phi_min, phi_max, stagNorm + write(6,'(/,a,f8.6,2x,f8.6,2x,e11.4,/)',advance='no') ' Minimum|Maximum|Delta Damage = ',& + phi_min, phi_max, stagNorm write(6,'(/,a)') ' ===========================================================================' flush(6) From 55a620b3783ce81ee71c3e759ad08a6f4b519147 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 8 Aug 2020 20:14:30 +0200 Subject: [PATCH 26/73] migrating to library --- python/damask/_geom.py | 56 ++++++++++++++++++++++++++++++++++++++- python/tests/test_Geom.py | 15 +++++++++++ 2 files changed, 70 insertions(+), 1 deletion(-) diff --git a/python/damask/_geom.py b/python/damask/_geom.py index 4416be401..0aed3a113 100644 --- a/python/damask/_geom.py +++ b/python/damask/_geom.py @@ -7,6 +7,7 @@ import numpy as np from scipy import ndimage,spatial from . import environment +from . import Rotation from . import VTK from . import util from . import grid_filters @@ -501,6 +502,58 @@ class Geom: return ''.join(f.readlines()) + def add_primitive(self,dimension,center,exponent, + fill=None,R=Rotation(),inverse=False,periodic=True): + """ + Inserts a primitive geometric object at a given position. + + Parameters + ---------- + dimension : numpy.ndarray of shape(3) + Dimension (diameter/side length) of the primitive. If given as + integers, grid point locations (cell centers) are addressed. + If given as floats, coordinates are addressed. + center : numpy.ndarray of shape(3) + Center of the primitive. If given as integers, grid point + locations (cell centers) are addressed. + If given as floats, coordinates are addressed. + exponent : numpy.ndarray of shape(3) or float + Exponents for the three axis. + 0 gives octahedron (|x|^(2^0) + |y|^(2^0) + |z|^(2^0) < 1) + 1 gives a sphere (|x|^(2^1) + |y|^(2^1) + |z|^(2^1) < 1) + fill : integer, optional + Fill value for primitive. Defaults to microstructure.max() + 1. + R : damask.Rotation, optional + Rotation of primitive. Defaults to no rotation. + inverse : Boolean, optional + Retain original microstructure within primitive and fill + outside. Defaults to False. + periodic : Boolean, optional + Repeat primitive over boundaries. Defaults to False. + + """ + # normalized 'radius' and center + r = np.array(dimension)/self.grid/2.0 if np.array(dimension).dtype in np.sctypes['int'] else \ + np.array(dimension)/self.size/2.0 + c = (np.array(center) + .5)/self.grid if np.array(center).dtype in np.sctypes['int'] else \ + (np.array(center) - self.origin)/self.size + + coords = grid_filters.cell_coord0(self.grid,np.ones(3)) \ + - (np.ones(3)*0.5 if periodic else c) # center if periodic + coords_rot = R.broadcast_to(tuple(self.grid))@coords + + with np.errstate(over='ignore',under='ignore'): + mask = np.where(np.sum(np.abs(coords_rot/r)**(2.0**exponent),axis=-1) < 1,True,False) + + if periodic: # translate back to center + mask = np.roll(mask,((c-np.ones(3)*.5)*self.grid).astype(int),(0,1,2)) + + fill_ = np.full_like(self.microstructure,np.nanmax(self.microstructure)+1 if fill is None else fill) + ms = np.ma.MaskedArray(fill_,np.logical_not(mask) if inverse else mask) + + return self.update(ms) + + def mirror(self,directions,reflect=False): """ Mirror microstructure along given directions. @@ -508,7 +561,8 @@ class Geom: Parameters ---------- directions : iterable containing str - Direction(s) along which the microstructure is mirrored. Valid entries are 'x', 'y', 'z'. + Direction(s) along which the microstructure is mirrored. + Valid entries are 'x', 'y', 'z'. reflect : bool, optional Reflect (include) outermost layers. diff --git a/python/tests/test_Geom.py b/python/tests/test_Geom.py index 1cb29e0b0..04fb323c1 100644 --- a/python/tests/test_Geom.py +++ b/python/tests/test_Geom.py @@ -182,6 +182,21 @@ class TestGeom: e = default.grid assert np.all(modified.microstructure[:e[0],:e[1],:e[2]] == default.microstructure) + @pytest.mark.parametrize('center',[np.random.random(3)*.5, + np.random.randint(4,10,(3))]) + @pytest.mark.parametrize('diameter',[np.random.random(3)*.5, + np.random.randint(4,10,(3))]) + def test_add_primitive(self,diameter,center): + """Same volume fraction for periodic microstructures and different center.""" + 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) + G_2 = Geom(np.ones(g,'i'),s,o) + G_1.add_primitive(diameter,center,1) + G_2.add_primitive(diameter,center,1) + assert np.count_nonzero(G_1.microstructure!=2) == np.count_nonzero(G_2.microstructure!=2) + @pytest.mark.parametrize('trigger',[[1],[]]) def test_vicinity_offset(self,trigger): offset = np.random.randint(2,4) From 6a5471d2432e1458d89744c15a082306aa190dff Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 8 Aug 2020 20:24:36 +0200 Subject: [PATCH 27/73] have microstructure with 'to' and 'of' --- .../tests/reference/Geom/clean_stencil=1.geom | 40 +-- .../tests/reference/Geom/clean_stencil=2.geom | 40 +-- .../tests/reference/Geom/clean_stencil=3.geom | 40 +-- .../tests/reference/Geom/clean_stencil=4.geom | 40 +-- .../mirror_directions=x-y-z_reflect=True.geom | 160 +++++------ .../mirror_directions=x_reflect=False.geom | 40 +-- .../mirror_directions=y-z_reflect=False.geom | 96 +++---- ...mirror_directions=z-x-y_reflect=False.geom | 96 +++---- .../Geom/rotate_Eulers=0.0-32.0-240.0.geom | 42 +-- .../Geom/rotate_Eulers=32.0-68.0-21.0.geom | 88 +++--- .../reference/Geom/scale_grid=10-10-10.geom | 200 +++++++------- .../reference/Geom/scale_grid=10-11-10.geom | 220 +++++++-------- .../reference/Geom/scale_grid=10-13-10.geom | 260 +++++++++--------- .../reference/Geom/scale_grid=10-20-2.geom | 80 +++--- .../reference/Geom/scale_grid=5-4-20.geom | 160 +++++------ .../reference/Geom/scale_grid=8-10-12.geom | 240 ++++++++-------- python/tests/test_Geom.py | 2 +- 17 files changed, 922 insertions(+), 922 deletions(-) diff --git a/python/tests/reference/Geom/clean_stencil=1.geom b/python/tests/reference/Geom/clean_stencil=1.geom index 2fe5314fe..3e6f6fe9c 100644 --- a/python/tests/reference/Geom/clean_stencil=1.geom +++ b/python/tests/reference/Geom/clean_stencil=1.geom @@ -3,23 +3,23 @@ grid a 8 b 5 c 4 size x 8e-06 y 5e-06 z 4e-06 origin x 0.0 y 0.0 z 0.0 homogenization 1 - 1 1 2 22 2 2 1 21 - 1 1 6 26 2 2 5 25 - 1 1 10 30 2 2 9 29 - 1 1 14 34 2 2 13 33 - 1 1 18 38 2 2 17 37 - 1 1 3 23 2 2 2 22 - 1 1 7 27 2 2 6 26 - 1 1 11 31 2 2 10 30 - 1 1 15 35 2 2 14 34 - 1 1 19 39 2 2 18 38 - 1 1 4 24 2 2 3 23 - 1 1 8 28 2 2 7 27 - 1 1 12 32 2 2 11 31 - 1 1 16 36 2 2 15 35 - 1 1 20 40 2 2 19 39 - 1 1 5 25 2 2 4 24 - 1 1 9 29 2 2 8 28 - 1 1 13 33 2 2 12 32 - 1 1 17 37 2 2 16 36 - 1 1 21 41 2 2 20 40 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 2 3 4 5 6 7 8 9 +10 11 12 13 14 15 16 17 +18 19 20 21 22 23 24 25 +26 27 28 29 30 31 32 33 +34 35 36 37 38 39 40 41 + 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 + 1 2 3 4 5 6 7 8 + 9 10 11 12 13 14 15 16 +17 18 19 20 21 22 23 24 +25 26 27 28 29 30 31 32 +33 34 35 36 37 38 39 40 diff --git a/python/tests/reference/Geom/clean_stencil=2.geom b/python/tests/reference/Geom/clean_stencil=2.geom index f074fea56..14c1fa5e2 100644 --- a/python/tests/reference/Geom/clean_stencil=2.geom +++ b/python/tests/reference/Geom/clean_stencil=2.geom @@ -3,23 +3,23 @@ grid a 8 b 5 c 4 size x 8e-06 y 5e-06 z 4e-06 origin x 0.0 y 0.0 z 0.0 homogenization 1 - 1 1 1 2 2 2 1 1 - 1 1 1 2 2 2 2 1 - 1 1 1 6 2 2 2 5 - 1 1 1 10 2 2 2 9 - 1 1 1 14 2 2 2 13 - 1 1 1 2 2 2 2 1 - 1 1 1 2 2 2 2 1 - 1 1 1 6 2 2 2 5 - 1 1 1 10 2 2 2 9 - 1 1 1 14 2 2 2 13 - 1 1 1 3 2 2 2 2 - 1 1 1 3 2 2 2 2 - 1 1 1 7 2 2 2 6 - 1 1 1 11 2 2 2 10 - 1 1 1 15 2 2 2 14 - 1 1 1 4 2 2 2 3 - 1 1 1 4 2 2 2 3 - 1 1 1 8 2 2 2 7 - 1 1 1 12 2 2 2 11 - 1 1 1 16 2 2 2 15 +1 1 1 1 1 1 1 1 +1 1 1 1 1 1 1 1 +1 1 1 1 1 1 1 1 +1 1 1 1 1 1 1 1 +1 1 1 1 1 1 1 1 +1 1 1 1 1 1 1 1 +1 1 1 1 1 1 1 1 +1 1 1 1 1 1 1 1 +1 1 1 1 1 1 1 1 +1 1 1 1 1 1 1 1 +2 2 2 2 2 2 2 2 +2 2 2 2 2 2 2 2 +2 2 2 2 2 2 2 2 +2 2 2 2 2 2 2 2 +2 2 2 2 2 2 2 2 +1 2 2 2 2 2 2 2 +2 2 2 2 2 2 2 2 +2 2 2 2 2 2 2 2 +2 2 2 2 2 2 2 2 +2 2 2 2 2 2 2 2 diff --git a/python/tests/reference/Geom/clean_stencil=3.geom b/python/tests/reference/Geom/clean_stencil=3.geom index 63e1dce5a..3aea8ffa5 100644 --- a/python/tests/reference/Geom/clean_stencil=3.geom +++ b/python/tests/reference/Geom/clean_stencil=3.geom @@ -3,23 +3,23 @@ grid a 8 b 5 c 4 size x 8e-06 y 5e-06 z 4e-06 origin x 0.0 y 0.0 z 0.0 homogenization 1 - 1 1 1 2 2 2 2 21 - 1 1 1 2 2 2 2 21 - 1 1 1 2 2 2 2 25 - 1 1 1 2 2 2 2 29 - 1 1 1 2 2 2 2 37 - 1 1 1 2 2 2 2 21 - 1 1 1 2 2 2 2 21 - 1 1 1 2 2 2 2 25 - 1 1 1 2 2 2 2 29 - 1 1 1 2 2 2 2 37 - 1 1 1 2 2 2 2 22 - 1 1 1 2 2 2 2 22 - 1 1 1 2 2 2 2 26 - 1 1 1 2 2 2 2 30 - 1 1 1 2 2 2 2 38 - 1 1 1 2 2 2 2 24 - 1 1 1 2 2 2 2 24 - 1 1 1 2 2 2 2 28 - 1 1 1 2 2 2 2 32 - 1 1 1 2 2 2 2 40 +1 1 1 1 1 1 1 1 +1 1 1 1 1 1 1 1 +1 1 1 1 1 1 1 1 +1 1 1 1 1 1 1 1 +1 1 1 1 1 1 1 1 +2 2 1 1 1 1 1 1 +2 2 1 1 1 1 1 1 +1 1 1 1 1 1 1 1 +1 1 1 1 1 1 1 1 +1 1 1 1 1 1 1 1 +2 2 2 2 2 2 2 2 +2 2 2 2 2 2 2 2 +2 2 2 2 2 2 2 2 +2 2 2 2 2 2 2 2 +2 2 2 2 2 2 2 2 +2 2 2 2 2 2 2 2 +2 2 2 2 2 2 2 2 +2 2 2 2 2 2 2 2 +2 2 2 2 2 2 2 2 +2 2 2 2 2 2 2 2 diff --git a/python/tests/reference/Geom/clean_stencil=4.geom b/python/tests/reference/Geom/clean_stencil=4.geom index eef322d3f..595e04b23 100644 --- a/python/tests/reference/Geom/clean_stencil=4.geom +++ b/python/tests/reference/Geom/clean_stencil=4.geom @@ -3,23 +3,23 @@ grid a 8 b 5 c 4 size x 8e-06 y 5e-06 z 4e-06 origin x 0.0 y 0.0 z 0.0 homogenization 1 -1 1 1 2 2 2 2 2 -1 1 1 2 2 2 2 2 -1 1 1 2 2 2 2 2 -1 1 1 1 2 2 2 2 -1 1 1 1 2 2 2 2 -1 1 1 2 2 2 2 2 -1 1 1 2 2 2 2 2 -1 1 1 2 2 2 2 2 -1 1 1 1 2 2 2 2 -1 1 1 1 2 2 2 2 -1 1 1 2 2 2 2 2 -1 1 1 2 2 2 2 2 -1 1 1 2 2 2 2 2 -1 1 1 1 2 2 2 2 -1 1 1 1 2 2 2 2 -1 1 1 1 2 2 2 2 -1 1 1 1 2 2 2 2 -1 1 1 1 2 2 2 2 -1 1 1 1 2 2 2 2 -1 1 1 1 2 2 2 2 +1 1 1 1 1 1 1 1 +1 1 1 1 1 1 1 1 +1 1 1 1 1 1 1 1 +1 1 1 1 1 1 1 1 +1 1 1 1 1 1 1 1 +1 1 1 1 1 1 1 1 +1 1 1 1 1 1 1 1 +1 1 1 1 1 1 1 1 +1 1 1 1 1 1 1 1 +1 1 1 1 1 1 1 1 +2 2 2 2 1 1 1 1 +2 2 2 2 1 1 1 1 +2 2 2 2 1 1 1 1 +1 1 1 1 1 1 1 1 +1 1 1 1 1 1 1 1 +2 2 2 2 2 2 2 2 +2 2 2 2 2 2 2 2 +2 2 2 2 2 2 2 2 +2 2 2 2 2 2 2 2 +2 2 2 2 2 2 2 2 diff --git a/python/tests/reference/Geom/mirror_directions=x-y-z_reflect=True.geom b/python/tests/reference/Geom/mirror_directions=x-y-z_reflect=True.geom index 77ff709d7..851d4fb1c 100644 --- a/python/tests/reference/Geom/mirror_directions=x-y-z_reflect=True.geom +++ b/python/tests/reference/Geom/mirror_directions=x-y-z_reflect=True.geom @@ -3,83 +3,83 @@ grid a 16 b 10 c 8 size x 1.6e-05 y 1e-05 z 8e-06 origin x 0.0 y 0.0 z 0.0 homogenization 1 - 1 1 2 22 2 2 1 21 21 1 2 2 22 2 1 1 - 1 1 6 26 2 2 5 25 25 5 2 2 26 6 1 1 - 1 1 10 30 2 2 9 29 29 9 2 2 30 10 1 1 - 1 1 14 34 2 2 13 33 33 13 2 2 34 14 1 1 - 1 1 18 38 2 2 17 37 37 17 2 2 38 18 1 1 - 1 1 18 38 2 2 17 37 37 17 2 2 38 18 1 1 - 1 1 14 34 2 2 13 33 33 13 2 2 34 14 1 1 - 1 1 10 30 2 2 9 29 29 9 2 2 30 10 1 1 - 1 1 6 26 2 2 5 25 25 5 2 2 26 6 1 1 - 1 1 2 22 2 2 1 21 21 1 2 2 22 2 1 1 - 1 1 3 23 2 2 2 22 22 2 2 2 23 3 1 1 - 1 1 7 27 2 2 6 26 26 6 2 2 27 7 1 1 - 1 1 11 31 2 2 10 30 30 10 2 2 31 11 1 1 - 1 1 15 35 2 2 14 34 34 14 2 2 35 15 1 1 - 1 1 19 39 2 2 18 38 38 18 2 2 39 19 1 1 - 1 1 19 39 2 2 18 38 38 18 2 2 39 19 1 1 - 1 1 15 35 2 2 14 34 34 14 2 2 35 15 1 1 - 1 1 11 31 2 2 10 30 30 10 2 2 31 11 1 1 - 1 1 7 27 2 2 6 26 26 6 2 2 27 7 1 1 - 1 1 3 23 2 2 2 22 22 2 2 2 23 3 1 1 - 1 1 4 24 2 2 3 23 23 3 2 2 24 4 1 1 - 1 1 8 28 2 2 7 27 27 7 2 2 28 8 1 1 - 1 1 12 32 2 2 11 31 31 11 2 2 32 12 1 1 - 1 1 16 36 2 2 15 35 35 15 2 2 36 16 1 1 - 1 1 20 40 2 2 19 39 39 19 2 2 40 20 1 1 - 1 1 20 40 2 2 19 39 39 19 2 2 40 20 1 1 - 1 1 16 36 2 2 15 35 35 15 2 2 36 16 1 1 - 1 1 12 32 2 2 11 31 31 11 2 2 32 12 1 1 - 1 1 8 28 2 2 7 27 27 7 2 2 28 8 1 1 - 1 1 4 24 2 2 3 23 23 3 2 2 24 4 1 1 - 1 1 5 25 2 2 4 24 24 4 2 2 25 5 1 1 - 1 1 9 29 2 2 8 28 28 8 2 2 29 9 1 1 - 1 1 13 33 2 2 12 32 32 12 2 2 33 13 1 1 - 1 1 17 37 2 2 16 36 36 16 2 2 37 17 1 1 - 1 1 21 41 2 2 20 40 40 20 2 2 41 21 1 1 - 1 1 21 41 2 2 20 40 40 20 2 2 41 21 1 1 - 1 1 17 37 2 2 16 36 36 16 2 2 37 17 1 1 - 1 1 13 33 2 2 12 32 32 12 2 2 33 13 1 1 - 1 1 9 29 2 2 8 28 28 8 2 2 29 9 1 1 - 1 1 5 25 2 2 4 24 24 4 2 2 25 5 1 1 - 1 1 5 25 2 2 4 24 24 4 2 2 25 5 1 1 - 1 1 9 29 2 2 8 28 28 8 2 2 29 9 1 1 - 1 1 13 33 2 2 12 32 32 12 2 2 33 13 1 1 - 1 1 17 37 2 2 16 36 36 16 2 2 37 17 1 1 - 1 1 21 41 2 2 20 40 40 20 2 2 41 21 1 1 - 1 1 21 41 2 2 20 40 40 20 2 2 41 21 1 1 - 1 1 17 37 2 2 16 36 36 16 2 2 37 17 1 1 - 1 1 13 33 2 2 12 32 32 12 2 2 33 13 1 1 - 1 1 9 29 2 2 8 28 28 8 2 2 29 9 1 1 - 1 1 5 25 2 2 4 24 24 4 2 2 25 5 1 1 - 1 1 4 24 2 2 3 23 23 3 2 2 24 4 1 1 - 1 1 8 28 2 2 7 27 27 7 2 2 28 8 1 1 - 1 1 12 32 2 2 11 31 31 11 2 2 32 12 1 1 - 1 1 16 36 2 2 15 35 35 15 2 2 36 16 1 1 - 1 1 20 40 2 2 19 39 39 19 2 2 40 20 1 1 - 1 1 20 40 2 2 19 39 39 19 2 2 40 20 1 1 - 1 1 16 36 2 2 15 35 35 15 2 2 36 16 1 1 - 1 1 12 32 2 2 11 31 31 11 2 2 32 12 1 1 - 1 1 8 28 2 2 7 27 27 7 2 2 28 8 1 1 - 1 1 4 24 2 2 3 23 23 3 2 2 24 4 1 1 - 1 1 3 23 2 2 2 22 22 2 2 2 23 3 1 1 - 1 1 7 27 2 2 6 26 26 6 2 2 27 7 1 1 - 1 1 11 31 2 2 10 30 30 10 2 2 31 11 1 1 - 1 1 15 35 2 2 14 34 34 14 2 2 35 15 1 1 - 1 1 19 39 2 2 18 38 38 18 2 2 39 19 1 1 - 1 1 19 39 2 2 18 38 38 18 2 2 39 19 1 1 - 1 1 15 35 2 2 14 34 34 14 2 2 35 15 1 1 - 1 1 11 31 2 2 10 30 30 10 2 2 31 11 1 1 - 1 1 7 27 2 2 6 26 26 6 2 2 27 7 1 1 - 1 1 3 23 2 2 2 22 22 2 2 2 23 3 1 1 - 1 1 2 22 2 2 1 21 21 1 2 2 22 2 1 1 - 1 1 6 26 2 2 5 25 25 5 2 2 26 6 1 1 - 1 1 10 30 2 2 9 29 29 9 2 2 30 10 1 1 - 1 1 14 34 2 2 13 33 33 13 2 2 34 14 1 1 - 1 1 18 38 2 2 17 37 37 17 2 2 38 18 1 1 - 1 1 18 38 2 2 17 37 37 17 2 2 38 18 1 1 - 1 1 14 34 2 2 13 33 33 13 2 2 34 14 1 1 - 1 1 10 30 2 2 9 29 29 9 2 2 30 10 1 1 - 1 1 6 26 2 2 5 25 25 5 2 2 26 6 1 1 - 1 1 2 22 2 2 1 21 21 1 2 2 22 2 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 2 3 4 5 6 7 8 9 9 8 7 6 5 4 3 2 +10 11 12 13 14 15 16 17 17 16 15 14 13 12 11 10 +18 19 20 21 22 23 24 25 25 24 23 22 21 20 19 18 +26 27 28 29 30 31 32 33 33 32 31 30 29 28 27 26 +34 35 36 37 38 39 40 41 41 40 39 38 37 36 35 34 +34 35 36 37 38 39 40 41 41 40 39 38 37 36 35 34 +26 27 28 29 30 31 32 33 33 32 31 30 29 28 27 26 +18 19 20 21 22 23 24 25 25 24 23 22 21 20 19 18 +10 11 12 13 14 15 16 17 17 16 15 14 13 12 11 10 + 2 3 4 5 6 7 8 9 9 8 7 6 5 4 3 2 + 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 + 1 2 3 4 5 6 7 8 8 7 6 5 4 3 2 1 + 9 10 11 12 13 14 15 16 16 15 14 13 12 11 10 9 +17 18 19 20 21 22 23 24 24 23 22 21 20 19 18 17 +25 26 27 28 29 30 31 32 32 31 30 29 28 27 26 25 +33 34 35 36 37 38 39 40 40 39 38 37 36 35 34 33 +33 34 35 36 37 38 39 40 40 39 38 37 36 35 34 33 +25 26 27 28 29 30 31 32 32 31 30 29 28 27 26 25 +17 18 19 20 21 22 23 24 24 23 22 21 20 19 18 17 + 9 10 11 12 13 14 15 16 16 15 14 13 12 11 10 9 + 1 2 3 4 5 6 7 8 8 7 6 5 4 3 2 1 + 1 2 3 4 5 6 7 8 8 7 6 5 4 3 2 1 + 9 10 11 12 13 14 15 16 16 15 14 13 12 11 10 9 +17 18 19 20 21 22 23 24 24 23 22 21 20 19 18 17 +25 26 27 28 29 30 31 32 32 31 30 29 28 27 26 25 +33 34 35 36 37 38 39 40 40 39 38 37 36 35 34 33 +33 34 35 36 37 38 39 40 40 39 38 37 36 35 34 33 +25 26 27 28 29 30 31 32 32 31 30 29 28 27 26 25 +17 18 19 20 21 22 23 24 24 23 22 21 20 19 18 17 + 9 10 11 12 13 14 15 16 16 15 14 13 12 11 10 9 + 1 2 3 4 5 6 7 8 8 7 6 5 4 3 2 1 + 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 + 2 3 4 5 6 7 8 9 9 8 7 6 5 4 3 2 +10 11 12 13 14 15 16 17 17 16 15 14 13 12 11 10 +18 19 20 21 22 23 24 25 25 24 23 22 21 20 19 18 +26 27 28 29 30 31 32 33 33 32 31 30 29 28 27 26 +34 35 36 37 38 39 40 41 41 40 39 38 37 36 35 34 +34 35 36 37 38 39 40 41 41 40 39 38 37 36 35 34 +26 27 28 29 30 31 32 33 33 32 31 30 29 28 27 26 +18 19 20 21 22 23 24 25 25 24 23 22 21 20 19 18 +10 11 12 13 14 15 16 17 17 16 15 14 13 12 11 10 + 2 3 4 5 6 7 8 9 9 8 7 6 5 4 3 2 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 diff --git a/python/tests/reference/Geom/mirror_directions=x_reflect=False.geom b/python/tests/reference/Geom/mirror_directions=x_reflect=False.geom index afb3bb5f8..3a6558be1 100644 --- a/python/tests/reference/Geom/mirror_directions=x_reflect=False.geom +++ b/python/tests/reference/Geom/mirror_directions=x_reflect=False.geom @@ -3,23 +3,23 @@ grid a 14 b 5 c 4 size x 1.4e-05 y 5e-06 z 4e-06 origin x 0.0 y 0.0 z 0.0 homogenization 1 - 1 1 2 22 2 2 1 21 1 2 2 22 2 1 - 1 1 6 26 2 2 5 25 5 2 2 26 6 1 - 1 1 10 30 2 2 9 29 9 2 2 30 10 1 - 1 1 14 34 2 2 13 33 13 2 2 34 14 1 - 1 1 18 38 2 2 17 37 17 2 2 38 18 1 - 1 1 3 23 2 2 2 22 2 2 2 23 3 1 - 1 1 7 27 2 2 6 26 6 2 2 27 7 1 - 1 1 11 31 2 2 10 30 10 2 2 31 11 1 - 1 1 15 35 2 2 14 34 14 2 2 35 15 1 - 1 1 19 39 2 2 18 38 18 2 2 39 19 1 - 1 1 4 24 2 2 3 23 3 2 2 24 4 1 - 1 1 8 28 2 2 7 27 7 2 2 28 8 1 - 1 1 12 32 2 2 11 31 11 2 2 32 12 1 - 1 1 16 36 2 2 15 35 15 2 2 36 16 1 - 1 1 20 40 2 2 19 39 19 2 2 40 20 1 - 1 1 5 25 2 2 4 24 4 2 2 25 5 1 - 1 1 9 29 2 2 8 28 8 2 2 29 9 1 - 1 1 13 33 2 2 12 32 12 2 2 33 13 1 - 1 1 17 37 2 2 16 36 16 2 2 37 17 1 - 1 1 21 41 2 2 20 40 20 2 2 41 21 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 2 3 4 5 6 7 8 9 8 7 6 5 4 3 +10 11 12 13 14 15 16 17 16 15 14 13 12 11 +18 19 20 21 22 23 24 25 24 23 22 21 20 19 +26 27 28 29 30 31 32 33 32 31 30 29 28 27 +34 35 36 37 38 39 40 41 40 39 38 37 36 35 + 2 2 2 2 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 2 2 2 2 + 1 2 3 4 5 6 7 8 7 6 5 4 3 2 + 9 10 11 12 13 14 15 16 15 14 13 12 11 10 +17 18 19 20 21 22 23 24 23 22 21 20 19 18 +25 26 27 28 29 30 31 32 31 30 29 28 27 26 +33 34 35 36 37 38 39 40 39 38 37 36 35 34 diff --git a/python/tests/reference/Geom/mirror_directions=y-z_reflect=False.geom b/python/tests/reference/Geom/mirror_directions=y-z_reflect=False.geom index 37d8ae18e..6a451ba7a 100644 --- a/python/tests/reference/Geom/mirror_directions=y-z_reflect=False.geom +++ b/python/tests/reference/Geom/mirror_directions=y-z_reflect=False.geom @@ -3,51 +3,51 @@ grid a 8 b 8 c 6 size x 8e-06 y 8.000000000000001e-06 z 6e-06 origin x 0.0 y 0.0 z 0.0 homogenization 1 - 1 1 2 22 2 2 1 21 - 1 1 6 26 2 2 5 25 - 1 1 10 30 2 2 9 29 - 1 1 14 34 2 2 13 33 - 1 1 18 38 2 2 17 37 - 1 1 14 34 2 2 13 33 - 1 1 10 30 2 2 9 29 - 1 1 6 26 2 2 5 25 - 1 1 3 23 2 2 2 22 - 1 1 7 27 2 2 6 26 - 1 1 11 31 2 2 10 30 - 1 1 15 35 2 2 14 34 - 1 1 19 39 2 2 18 38 - 1 1 15 35 2 2 14 34 - 1 1 11 31 2 2 10 30 - 1 1 7 27 2 2 6 26 - 1 1 4 24 2 2 3 23 - 1 1 8 28 2 2 7 27 - 1 1 12 32 2 2 11 31 - 1 1 16 36 2 2 15 35 - 1 1 20 40 2 2 19 39 - 1 1 16 36 2 2 15 35 - 1 1 12 32 2 2 11 31 - 1 1 8 28 2 2 7 27 - 1 1 5 25 2 2 4 24 - 1 1 9 29 2 2 8 28 - 1 1 13 33 2 2 12 32 - 1 1 17 37 2 2 16 36 - 1 1 21 41 2 2 20 40 - 1 1 17 37 2 2 16 36 - 1 1 13 33 2 2 12 32 - 1 1 9 29 2 2 8 28 - 1 1 4 24 2 2 3 23 - 1 1 8 28 2 2 7 27 - 1 1 12 32 2 2 11 31 - 1 1 16 36 2 2 15 35 - 1 1 20 40 2 2 19 39 - 1 1 16 36 2 2 15 35 - 1 1 12 32 2 2 11 31 - 1 1 8 28 2 2 7 27 - 1 1 3 23 2 2 2 22 - 1 1 7 27 2 2 6 26 - 1 1 11 31 2 2 10 30 - 1 1 15 35 2 2 14 34 - 1 1 19 39 2 2 18 38 - 1 1 15 35 2 2 14 34 - 1 1 11 31 2 2 10 30 - 1 1 7 27 2 2 6 26 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 2 3 4 5 6 7 8 9 +10 11 12 13 14 15 16 17 +18 19 20 21 22 23 24 25 +26 27 28 29 30 31 32 33 +34 35 36 37 38 39 40 41 +26 27 28 29 30 31 32 33 +18 19 20 21 22 23 24 25 +10 11 12 13 14 15 16 17 + 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 + 1 2 3 4 5 6 7 8 + 9 10 11 12 13 14 15 16 +17 18 19 20 21 22 23 24 +25 26 27 28 29 30 31 32 +33 34 35 36 37 38 39 40 +25 26 27 28 29 30 31 32 +17 18 19 20 21 22 23 24 + 9 10 11 12 13 14 15 16 + 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 + 2 3 4 5 6 7 8 9 +10 11 12 13 14 15 16 17 +18 19 20 21 22 23 24 25 +26 27 28 29 30 31 32 33 +34 35 36 37 38 39 40 41 +26 27 28 29 30 31 32 33 +18 19 20 21 22 23 24 25 +10 11 12 13 14 15 16 17 diff --git a/python/tests/reference/Geom/mirror_directions=z-x-y_reflect=False.geom b/python/tests/reference/Geom/mirror_directions=z-x-y_reflect=False.geom index 5d7c23eb0..57d110425 100644 --- a/python/tests/reference/Geom/mirror_directions=z-x-y_reflect=False.geom +++ b/python/tests/reference/Geom/mirror_directions=z-x-y_reflect=False.geom @@ -3,51 +3,51 @@ grid a 14 b 8 c 6 size x 1.4e-05 y 8.000000000000001e-06 z 6e-06 origin x 0.0 y 0.0 z 0.0 homogenization 1 - 1 1 2 22 2 2 1 21 1 2 2 22 2 1 - 1 1 6 26 2 2 5 25 5 2 2 26 6 1 - 1 1 10 30 2 2 9 29 9 2 2 30 10 1 - 1 1 14 34 2 2 13 33 13 2 2 34 14 1 - 1 1 18 38 2 2 17 37 17 2 2 38 18 1 - 1 1 14 34 2 2 13 33 13 2 2 34 14 1 - 1 1 10 30 2 2 9 29 9 2 2 30 10 1 - 1 1 6 26 2 2 5 25 5 2 2 26 6 1 - 1 1 3 23 2 2 2 22 2 2 2 23 3 1 - 1 1 7 27 2 2 6 26 6 2 2 27 7 1 - 1 1 11 31 2 2 10 30 10 2 2 31 11 1 - 1 1 15 35 2 2 14 34 14 2 2 35 15 1 - 1 1 19 39 2 2 18 38 18 2 2 39 19 1 - 1 1 15 35 2 2 14 34 14 2 2 35 15 1 - 1 1 11 31 2 2 10 30 10 2 2 31 11 1 - 1 1 7 27 2 2 6 26 6 2 2 27 7 1 - 1 1 4 24 2 2 3 23 3 2 2 24 4 1 - 1 1 8 28 2 2 7 27 7 2 2 28 8 1 - 1 1 12 32 2 2 11 31 11 2 2 32 12 1 - 1 1 16 36 2 2 15 35 15 2 2 36 16 1 - 1 1 20 40 2 2 19 39 19 2 2 40 20 1 - 1 1 16 36 2 2 15 35 15 2 2 36 16 1 - 1 1 12 32 2 2 11 31 11 2 2 32 12 1 - 1 1 8 28 2 2 7 27 7 2 2 28 8 1 - 1 1 5 25 2 2 4 24 4 2 2 25 5 1 - 1 1 9 29 2 2 8 28 8 2 2 29 9 1 - 1 1 13 33 2 2 12 32 12 2 2 33 13 1 - 1 1 17 37 2 2 16 36 16 2 2 37 17 1 - 1 1 21 41 2 2 20 40 20 2 2 41 21 1 - 1 1 17 37 2 2 16 36 16 2 2 37 17 1 - 1 1 13 33 2 2 12 32 12 2 2 33 13 1 - 1 1 9 29 2 2 8 28 8 2 2 29 9 1 - 1 1 4 24 2 2 3 23 3 2 2 24 4 1 - 1 1 8 28 2 2 7 27 7 2 2 28 8 1 - 1 1 12 32 2 2 11 31 11 2 2 32 12 1 - 1 1 16 36 2 2 15 35 15 2 2 36 16 1 - 1 1 20 40 2 2 19 39 19 2 2 40 20 1 - 1 1 16 36 2 2 15 35 15 2 2 36 16 1 - 1 1 12 32 2 2 11 31 11 2 2 32 12 1 - 1 1 8 28 2 2 7 27 7 2 2 28 8 1 - 1 1 3 23 2 2 2 22 2 2 2 23 3 1 - 1 1 7 27 2 2 6 26 6 2 2 27 7 1 - 1 1 11 31 2 2 10 30 10 2 2 31 11 1 - 1 1 15 35 2 2 14 34 14 2 2 35 15 1 - 1 1 19 39 2 2 18 38 18 2 2 39 19 1 - 1 1 15 35 2 2 14 34 14 2 2 35 15 1 - 1 1 11 31 2 2 10 30 10 2 2 31 11 1 - 1 1 7 27 2 2 6 26 6 2 2 27 7 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 2 3 4 5 6 7 8 9 8 7 6 5 4 3 +10 11 12 13 14 15 16 17 16 15 14 13 12 11 +18 19 20 21 22 23 24 25 24 23 22 21 20 19 +26 27 28 29 30 31 32 33 32 31 30 29 28 27 +34 35 36 37 38 39 40 41 40 39 38 37 36 35 +26 27 28 29 30 31 32 33 32 31 30 29 28 27 +18 19 20 21 22 23 24 25 24 23 22 21 20 19 +10 11 12 13 14 15 16 17 16 15 14 13 12 11 + 2 2 2 2 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 2 2 2 2 + 1 2 3 4 5 6 7 8 7 6 5 4 3 2 + 9 10 11 12 13 14 15 16 15 14 13 12 11 10 +17 18 19 20 21 22 23 24 23 22 21 20 19 18 +25 26 27 28 29 30 31 32 31 30 29 28 27 26 +33 34 35 36 37 38 39 40 39 38 37 36 35 34 +25 26 27 28 29 30 31 32 31 30 29 28 27 26 +17 18 19 20 21 22 23 24 23 22 21 20 19 18 + 9 10 11 12 13 14 15 16 15 14 13 12 11 10 + 2 2 2 2 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 2 2 2 2 + 2 3 4 5 6 7 8 9 8 7 6 5 4 3 +10 11 12 13 14 15 16 17 16 15 14 13 12 11 +18 19 20 21 22 23 24 25 24 23 22 21 20 19 +26 27 28 29 30 31 32 33 32 31 30 29 28 27 +34 35 36 37 38 39 40 41 40 39 38 37 36 35 +26 27 28 29 30 31 32 33 32 31 30 29 28 27 +18 19 20 21 22 23 24 25 24 23 22 21 20 19 +10 11 12 13 14 15 16 17 16 15 14 13 12 11 diff --git a/python/tests/reference/Geom/rotate_Eulers=0.0-32.0-240.0.geom b/python/tests/reference/Geom/rotate_Eulers=0.0-32.0-240.0.geom index a3d1de0b4..f76d931ad 100644 --- a/python/tests/reference/Geom/rotate_Eulers=0.0-32.0-240.0.geom +++ b/python/tests/reference/Geom/rotate_Eulers=0.0-32.0-240.0.geom @@ -15,8 +15,8 @@ homogenization 1 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 -42 42 30 14 18 42 42 42 -42 42 29 13 17 42 42 42 +42 42 25 32 40 42 42 42 +42 42 1 1 1 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 @@ -25,32 +25,32 @@ homogenization 1 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 -42 42 31 15 19 42 42 42 -42 6 10 2 2 42 42 42 -42 1 2 2 2 2 42 42 +42 42 2 2 2 42 42 42 +42 16 24 31 31 42 42 42 +42 1 1 1 1 1 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 -42 42 32 16 20 42 42 42 -42 7 11 2 2 42 42 42 -42 7 11 2 2 42 42 42 -42 2 2 2 2 2 42 42 -42 42 2 2 31 35 42 42 -42 42 22 26 10 14 1 42 +42 42 24 31 39 42 42 42 +42 2 2 2 2 42 42 42 +42 2 2 2 2 42 42 42 +42 8 15 23 30 38 42 42 +42 42 14 22 21 29 42 42 +42 42 1 1 1 1 1 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 -42 4 2 2 2 2 42 42 -42 42 2 2 32 36 42 42 -42 42 24 28 12 16 1 42 -42 42 42 7 7 1 1 42 -42 42 42 7 7 1 1 42 +42 7 14 22 29 37 42 42 +42 42 2 2 2 2 42 42 +42 42 2 2 2 2 2 42 +42 42 42 12 12 19 27 42 +42 42 42 12 12 19 27 42 42 42 42 1 1 1 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 @@ -58,9 +58,9 @@ homogenization 1 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 -42 42 25 29 13 17 1 42 -42 42 42 8 8 1 1 42 -42 42 42 1 1 1 42 42 +42 42 4 12 19 27 34 42 +42 42 42 2 2 2 2 42 +42 42 42 3 11 18 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 @@ -69,8 +69,8 @@ homogenization 1 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 -42 42 42 1 1 1 42 42 -42 42 42 1 1 1 42 42 +42 42 42 2 10 17 42 42 +42 42 42 2 2 2 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 diff --git a/python/tests/reference/Geom/rotate_Eulers=32.0-68.0-21.0.geom b/python/tests/reference/Geom/rotate_Eulers=32.0-68.0-21.0.geom index e29cd4266..31ac1a15c 100644 --- a/python/tests/reference/Geom/rotate_Eulers=32.0-68.0-21.0.geom +++ b/python/tests/reference/Geom/rotate_Eulers=32.0-68.0-21.0.geom @@ -18,66 +18,66 @@ homogenization 1 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 -42 42 42 1 2 42 42 42 42 42 42 -42 42 42 42 42 42 42 42 42 42 42 -42 42 42 42 42 42 42 42 42 42 42 -42 42 42 42 42 42 42 42 42 42 42 -42 42 42 42 42 42 42 42 42 42 42 -42 42 42 42 42 42 42 42 42 42 42 -42 42 42 42 42 42 42 42 42 42 42 -42 42 42 42 42 42 42 42 42 42 42 -42 42 42 42 42 42 42 42 42 42 42 -42 42 42 42 1 42 42 42 42 42 42 -42 42 42 42 1 5 42 42 42 42 42 -42 42 42 1 7 4 42 42 42 42 42 -42 42 42 42 42 27 42 42 42 42 42 -42 42 42 42 42 42 2 42 42 42 42 -42 42 42 42 42 42 42 42 42 42 42 -42 42 42 42 42 42 42 42 42 42 42 -42 42 42 42 42 42 42 42 42 42 42 -42 42 42 42 42 42 42 42 42 42 42 -42 42 42 42 42 42 42 42 42 42 42 -42 42 42 42 42 42 42 42 42 42 42 42 42 42 1 1 42 42 42 42 42 42 -42 42 42 1 1 9 29 42 42 42 42 -42 42 1 1 11 8 28 2 42 42 42 -42 42 42 1 10 31 2 42 42 42 42 -42 42 42 42 30 2 2 2 42 42 42 -42 42 42 42 42 42 2 1 42 42 42 +42 42 42 42 42 42 42 42 42 42 42 +42 42 42 42 42 42 42 42 42 42 42 +42 42 42 42 42 42 42 42 42 42 42 +42 42 42 42 42 42 42 42 42 42 42 +42 42 42 42 42 42 42 42 42 42 42 +42 42 42 42 42 42 42 42 42 42 42 +42 42 42 42 42 42 42 42 42 42 42 +42 42 42 42 42 42 42 42 42 42 42 +42 42 42 42 2 42 42 42 42 42 42 +42 42 42 42 2 3 42 42 42 42 42 +42 42 42 11 12 2 42 42 42 42 42 +42 42 42 42 42 13 42 42 42 42 42 +42 42 42 42 42 42 6 42 42 42 42 +42 42 42 42 42 42 42 42 42 42 42 +42 42 42 42 42 42 42 42 42 42 42 +42 42 42 42 42 42 42 42 42 42 42 +42 42 42 42 42 42 42 42 42 42 42 +42 42 42 42 42 42 42 42 42 42 42 +42 42 42 42 42 42 42 42 42 42 42 +42 42 42 2 10 42 42 42 42 42 42 +42 42 42 2 2 11 12 42 42 42 42 +42 42 1 19 20 2 2 5 42 42 42 +42 42 42 1 1 21 2 42 42 42 42 +42 42 42 42 1 1 14 15 42 42 42 +42 42 42 42 42 42 1 1 42 42 42 42 42 42 42 42 42 42 1 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 -42 42 42 1 42 42 42 42 42 42 42 -42 42 42 1 1 42 42 42 42 42 42 -42 42 1 16 36 12 32 42 42 42 42 -42 42 42 15 35 2 2 2 42 42 42 -42 42 42 42 2 2 2 11 3 42 42 -42 42 42 42 42 42 10 6 42 42 42 -42 42 42 42 42 42 42 6 42 42 42 +42 42 42 2 42 42 42 42 42 42 42 +42 42 42 2 2 42 42 42 42 42 42 +42 42 35 2 2 2 2 42 42 42 42 +42 42 42 28 29 2 2 2 42 42 42 +42 42 42 42 22 23 2 2 2 42 42 +42 42 42 42 42 42 24 16 42 42 42 +42 42 42 42 42 42 42 16 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 -42 42 42 1 42 42 42 42 42 42 42 -42 42 42 1 17 42 42 42 42 42 42 -42 42 42 16 36 37 2 42 42 42 42 -42 42 42 42 39 2 2 12 42 42 42 -42 42 42 38 2 2 2 11 8 42 42 -42 42 42 42 2 2 14 30 42 42 42 -42 42 42 42 42 42 13 30 42 42 42 +42 42 42 34 42 42 42 42 42 42 42 +42 42 42 34 27 42 42 42 42 42 42 +42 42 42 2 2 28 21 42 42 42 42 +42 42 42 42 37 2 22 23 42 42 42 +42 42 42 1 30 31 2 2 15 42 42 +42 42 42 42 1 1 32 25 42 42 42 +42 42 42 42 42 42 1 25 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 -42 42 42 42 40 42 42 42 42 42 42 +42 42 42 42 2 42 42 42 42 42 42 42 42 42 42 42 2 42 42 42 42 42 -42 42 42 42 42 2 2 15 42 42 42 -42 42 42 42 42 2 18 42 42 42 42 -42 42 42 42 42 42 17 42 42 42 42 +42 42 42 42 42 39 2 2 42 42 42 +42 42 42 42 42 1 40 42 42 42 42 +42 42 42 42 42 42 1 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 @@ -86,7 +86,7 @@ homogenization 1 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 -42 42 42 42 42 42 2 20 42 42 42 +42 42 42 42 42 42 38 39 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 diff --git a/python/tests/reference/Geom/scale_grid=10-10-10.geom b/python/tests/reference/Geom/scale_grid=10-10-10.geom index 43587a615..41f78c670 100644 --- a/python/tests/reference/Geom/scale_grid=10-10-10.geom +++ b/python/tests/reference/Geom/scale_grid=10-10-10.geom @@ -3,103 +3,103 @@ grid a 10 b 10 c 10 size x 8e-06 y 5e-06 z 4e-06 origin x 0.0 y 0.0 z 0.0 homogenization 1 - 1 1 2 2 22 2 2 2 1 21 - 1 1 2 2 22 2 2 2 1 21 - 1 1 6 6 26 2 2 2 5 25 - 1 1 6 6 26 2 2 2 5 25 - 1 1 10 10 30 2 2 2 9 29 - 1 1 10 10 30 2 2 2 9 29 - 1 1 14 14 34 2 2 2 13 33 - 1 1 14 14 34 2 2 2 13 33 - 1 1 18 18 38 2 2 2 17 37 - 1 1 18 18 38 2 2 2 17 37 - 1 1 2 2 22 2 2 2 1 21 - 1 1 2 2 22 2 2 2 1 21 - 1 1 6 6 26 2 2 2 5 25 - 1 1 6 6 26 2 2 2 5 25 - 1 1 10 10 30 2 2 2 9 29 - 1 1 10 10 30 2 2 2 9 29 - 1 1 14 14 34 2 2 2 13 33 - 1 1 14 14 34 2 2 2 13 33 - 1 1 18 18 38 2 2 2 17 37 - 1 1 18 18 38 2 2 2 17 37 - 1 1 3 3 23 2 2 2 2 22 - 1 1 3 3 23 2 2 2 2 22 - 1 1 7 7 27 2 2 2 6 26 - 1 1 7 7 27 2 2 2 6 26 - 1 1 11 11 31 2 2 2 10 30 - 1 1 11 11 31 2 2 2 10 30 - 1 1 15 15 35 2 2 2 14 34 - 1 1 15 15 35 2 2 2 14 34 - 1 1 19 19 39 2 2 2 18 38 - 1 1 19 19 39 2 2 2 18 38 - 1 1 3 3 23 2 2 2 2 22 - 1 1 3 3 23 2 2 2 2 22 - 1 1 7 7 27 2 2 2 6 26 - 1 1 7 7 27 2 2 2 6 26 - 1 1 11 11 31 2 2 2 10 30 - 1 1 11 11 31 2 2 2 10 30 - 1 1 15 15 35 2 2 2 14 34 - 1 1 15 15 35 2 2 2 14 34 - 1 1 19 19 39 2 2 2 18 38 - 1 1 19 19 39 2 2 2 18 38 - 1 1 3 3 23 2 2 2 2 22 - 1 1 3 3 23 2 2 2 2 22 - 1 1 7 7 27 2 2 2 6 26 - 1 1 7 7 27 2 2 2 6 26 - 1 1 11 11 31 2 2 2 10 30 - 1 1 11 11 31 2 2 2 10 30 - 1 1 15 15 35 2 2 2 14 34 - 1 1 15 15 35 2 2 2 14 34 - 1 1 19 19 39 2 2 2 18 38 - 1 1 19 19 39 2 2 2 18 38 - 1 1 4 4 24 2 2 2 3 23 - 1 1 4 4 24 2 2 2 3 23 - 1 1 8 8 28 2 2 2 7 27 - 1 1 8 8 28 2 2 2 7 27 - 1 1 12 12 32 2 2 2 11 31 - 1 1 12 12 32 2 2 2 11 31 - 1 1 16 16 36 2 2 2 15 35 - 1 1 16 16 36 2 2 2 15 35 - 1 1 20 20 40 2 2 2 19 39 - 1 1 20 20 40 2 2 2 19 39 - 1 1 4 4 24 2 2 2 3 23 - 1 1 4 4 24 2 2 2 3 23 - 1 1 8 8 28 2 2 2 7 27 - 1 1 8 8 28 2 2 2 7 27 - 1 1 12 12 32 2 2 2 11 31 - 1 1 12 12 32 2 2 2 11 31 - 1 1 16 16 36 2 2 2 15 35 - 1 1 16 16 36 2 2 2 15 35 - 1 1 20 20 40 2 2 2 19 39 - 1 1 20 20 40 2 2 2 19 39 - 1 1 4 4 24 2 2 2 3 23 - 1 1 4 4 24 2 2 2 3 23 - 1 1 8 8 28 2 2 2 7 27 - 1 1 8 8 28 2 2 2 7 27 - 1 1 12 12 32 2 2 2 11 31 - 1 1 12 12 32 2 2 2 11 31 - 1 1 16 16 36 2 2 2 15 35 - 1 1 16 16 36 2 2 2 15 35 - 1 1 20 20 40 2 2 2 19 39 - 1 1 20 20 40 2 2 2 19 39 - 1 1 5 5 25 2 2 2 4 24 - 1 1 5 5 25 2 2 2 4 24 - 1 1 9 9 29 2 2 2 8 28 - 1 1 9 9 29 2 2 2 8 28 - 1 1 13 13 33 2 2 2 12 32 - 1 1 13 13 33 2 2 2 12 32 - 1 1 17 17 37 2 2 2 16 36 - 1 1 17 17 37 2 2 2 16 36 - 1 1 21 21 41 2 2 2 20 40 - 1 1 21 21 41 2 2 2 20 40 - 1 1 5 5 25 2 2 2 4 24 - 1 1 5 5 25 2 2 2 4 24 - 1 1 9 9 29 2 2 2 8 28 - 1 1 9 9 29 2 2 2 8 28 - 1 1 13 13 33 2 2 2 12 32 - 1 1 13 13 33 2 2 2 12 32 - 1 1 17 17 37 2 2 2 16 36 - 1 1 17 17 37 2 2 2 16 36 - 1 1 21 21 41 2 2 2 20 40 - 1 1 21 21 41 2 2 2 20 40 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 2 3 4 4 5 6 7 7 8 9 + 2 3 4 4 5 6 7 7 8 9 +10 11 12 12 13 14 15 15 16 17 +10 11 12 12 13 14 15 15 16 17 +18 19 20 20 21 22 23 23 24 25 +18 19 20 20 21 22 23 23 24 25 +26 27 28 28 29 30 31 31 32 33 +26 27 28 28 29 30 31 31 32 33 +34 35 36 36 37 38 39 39 40 41 +34 35 36 36 37 38 39 39 40 41 + 2 3 4 4 5 6 7 7 8 9 + 2 3 4 4 5 6 7 7 8 9 +10 11 12 12 13 14 15 15 16 17 +10 11 12 12 13 14 15 15 16 17 +18 19 20 20 21 22 23 23 24 25 +18 19 20 20 21 22 23 23 24 25 +26 27 28 28 29 30 31 31 32 33 +26 27 28 28 29 30 31 31 32 33 +34 35 36 36 37 38 39 39 40 41 +34 35 36 36 37 38 39 39 40 41 + 2 3 4 4 5 6 7 7 8 9 + 2 3 4 4 5 6 7 7 8 9 +10 11 12 12 13 14 15 15 16 17 +10 11 12 12 13 14 15 15 16 17 +18 19 20 20 21 22 23 23 24 25 +18 19 20 20 21 22 23 23 24 25 +26 27 28 28 29 30 31 31 32 33 +26 27 28 28 29 30 31 31 32 33 +34 35 36 36 37 38 39 39 40 41 +34 35 36 36 37 38 39 39 40 41 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 1 2 3 3 4 5 6 6 7 8 + 1 2 3 3 4 5 6 6 7 8 + 9 10 11 11 12 13 14 14 15 16 + 9 10 11 11 12 13 14 14 15 16 +17 18 19 19 20 21 22 22 23 24 +17 18 19 19 20 21 22 22 23 24 +25 26 27 27 28 29 30 30 31 32 +25 26 27 27 28 29 30 30 31 32 +33 34 35 35 36 37 38 38 39 40 +33 34 35 35 36 37 38 38 39 40 + 1 2 3 3 4 5 6 6 7 8 + 1 2 3 3 4 5 6 6 7 8 + 9 10 11 11 12 13 14 14 15 16 + 9 10 11 11 12 13 14 14 15 16 +17 18 19 19 20 21 22 22 23 24 +17 18 19 19 20 21 22 22 23 24 +25 26 27 27 28 29 30 30 31 32 +25 26 27 27 28 29 30 30 31 32 +33 34 35 35 36 37 38 38 39 40 +33 34 35 35 36 37 38 38 39 40 diff --git a/python/tests/reference/Geom/scale_grid=10-11-10.geom b/python/tests/reference/Geom/scale_grid=10-11-10.geom index e12fc64fc..fa0bf784c 100644 --- a/python/tests/reference/Geom/scale_grid=10-11-10.geom +++ b/python/tests/reference/Geom/scale_grid=10-11-10.geom @@ -3,113 +3,113 @@ grid a 10 b 11 c 10 size x 8e-06 y 5e-06 z 4e-06 origin x 0.0 y 0.0 z 0.0 homogenization 1 - 1 1 2 2 22 2 2 2 1 21 - 1 1 2 2 22 2 2 2 1 21 - 1 1 6 6 26 2 2 2 5 25 - 1 1 6 6 26 2 2 2 5 25 - 1 1 10 10 30 2 2 2 9 29 - 1 1 10 10 30 2 2 2 9 29 - 1 1 10 10 30 2 2 2 9 29 - 1 1 14 14 34 2 2 2 13 33 - 1 1 14 14 34 2 2 2 13 33 - 1 1 18 18 38 2 2 2 17 37 - 1 1 18 18 38 2 2 2 17 37 - 1 1 2 2 22 2 2 2 1 21 - 1 1 2 2 22 2 2 2 1 21 - 1 1 6 6 26 2 2 2 5 25 - 1 1 6 6 26 2 2 2 5 25 - 1 1 10 10 30 2 2 2 9 29 - 1 1 10 10 30 2 2 2 9 29 - 1 1 10 10 30 2 2 2 9 29 - 1 1 14 14 34 2 2 2 13 33 - 1 1 14 14 34 2 2 2 13 33 - 1 1 18 18 38 2 2 2 17 37 - 1 1 18 18 38 2 2 2 17 37 - 1 1 3 3 23 2 2 2 2 22 - 1 1 3 3 23 2 2 2 2 22 - 1 1 7 7 27 2 2 2 6 26 - 1 1 7 7 27 2 2 2 6 26 - 1 1 11 11 31 2 2 2 10 30 - 1 1 11 11 31 2 2 2 10 30 - 1 1 11 11 31 2 2 2 10 30 - 1 1 15 15 35 2 2 2 14 34 - 1 1 15 15 35 2 2 2 14 34 - 1 1 19 19 39 2 2 2 18 38 - 1 1 19 19 39 2 2 2 18 38 - 1 1 3 3 23 2 2 2 2 22 - 1 1 3 3 23 2 2 2 2 22 - 1 1 7 7 27 2 2 2 6 26 - 1 1 7 7 27 2 2 2 6 26 - 1 1 11 11 31 2 2 2 10 30 - 1 1 11 11 31 2 2 2 10 30 - 1 1 11 11 31 2 2 2 10 30 - 1 1 15 15 35 2 2 2 14 34 - 1 1 15 15 35 2 2 2 14 34 - 1 1 19 19 39 2 2 2 18 38 - 1 1 19 19 39 2 2 2 18 38 - 1 1 3 3 23 2 2 2 2 22 - 1 1 3 3 23 2 2 2 2 22 - 1 1 7 7 27 2 2 2 6 26 - 1 1 7 7 27 2 2 2 6 26 - 1 1 11 11 31 2 2 2 10 30 - 1 1 11 11 31 2 2 2 10 30 - 1 1 11 11 31 2 2 2 10 30 - 1 1 15 15 35 2 2 2 14 34 - 1 1 15 15 35 2 2 2 14 34 - 1 1 19 19 39 2 2 2 18 38 - 1 1 19 19 39 2 2 2 18 38 - 1 1 4 4 24 2 2 2 3 23 - 1 1 4 4 24 2 2 2 3 23 - 1 1 8 8 28 2 2 2 7 27 - 1 1 8 8 28 2 2 2 7 27 - 1 1 12 12 32 2 2 2 11 31 - 1 1 12 12 32 2 2 2 11 31 - 1 1 12 12 32 2 2 2 11 31 - 1 1 16 16 36 2 2 2 15 35 - 1 1 16 16 36 2 2 2 15 35 - 1 1 20 20 40 2 2 2 19 39 - 1 1 20 20 40 2 2 2 19 39 - 1 1 4 4 24 2 2 2 3 23 - 1 1 4 4 24 2 2 2 3 23 - 1 1 8 8 28 2 2 2 7 27 - 1 1 8 8 28 2 2 2 7 27 - 1 1 12 12 32 2 2 2 11 31 - 1 1 12 12 32 2 2 2 11 31 - 1 1 12 12 32 2 2 2 11 31 - 1 1 16 16 36 2 2 2 15 35 - 1 1 16 16 36 2 2 2 15 35 - 1 1 20 20 40 2 2 2 19 39 - 1 1 20 20 40 2 2 2 19 39 - 1 1 4 4 24 2 2 2 3 23 - 1 1 4 4 24 2 2 2 3 23 - 1 1 8 8 28 2 2 2 7 27 - 1 1 8 8 28 2 2 2 7 27 - 1 1 12 12 32 2 2 2 11 31 - 1 1 12 12 32 2 2 2 11 31 - 1 1 12 12 32 2 2 2 11 31 - 1 1 16 16 36 2 2 2 15 35 - 1 1 16 16 36 2 2 2 15 35 - 1 1 20 20 40 2 2 2 19 39 - 1 1 20 20 40 2 2 2 19 39 - 1 1 5 5 25 2 2 2 4 24 - 1 1 5 5 25 2 2 2 4 24 - 1 1 9 9 29 2 2 2 8 28 - 1 1 9 9 29 2 2 2 8 28 - 1 1 13 13 33 2 2 2 12 32 - 1 1 13 13 33 2 2 2 12 32 - 1 1 13 13 33 2 2 2 12 32 - 1 1 17 17 37 2 2 2 16 36 - 1 1 17 17 37 2 2 2 16 36 - 1 1 21 21 41 2 2 2 20 40 - 1 1 21 21 41 2 2 2 20 40 - 1 1 5 5 25 2 2 2 4 24 - 1 1 5 5 25 2 2 2 4 24 - 1 1 9 9 29 2 2 2 8 28 - 1 1 9 9 29 2 2 2 8 28 - 1 1 13 13 33 2 2 2 12 32 - 1 1 13 13 33 2 2 2 12 32 - 1 1 13 13 33 2 2 2 12 32 - 1 1 17 17 37 2 2 2 16 36 - 1 1 17 17 37 2 2 2 16 36 - 1 1 21 21 41 2 2 2 20 40 - 1 1 21 21 41 2 2 2 20 40 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 2 3 4 4 5 6 7 7 8 9 + 2 3 4 4 5 6 7 7 8 9 +10 11 12 12 13 14 15 15 16 17 +10 11 12 12 13 14 15 15 16 17 +18 19 20 20 21 22 23 23 24 25 +18 19 20 20 21 22 23 23 24 25 +18 19 20 20 21 22 23 23 24 25 +26 27 28 28 29 30 31 31 32 33 +26 27 28 28 29 30 31 31 32 33 +34 35 36 36 37 38 39 39 40 41 +34 35 36 36 37 38 39 39 40 41 + 2 3 4 4 5 6 7 7 8 9 + 2 3 4 4 5 6 7 7 8 9 +10 11 12 12 13 14 15 15 16 17 +10 11 12 12 13 14 15 15 16 17 +18 19 20 20 21 22 23 23 24 25 +18 19 20 20 21 22 23 23 24 25 +18 19 20 20 21 22 23 23 24 25 +26 27 28 28 29 30 31 31 32 33 +26 27 28 28 29 30 31 31 32 33 +34 35 36 36 37 38 39 39 40 41 +34 35 36 36 37 38 39 39 40 41 + 2 3 4 4 5 6 7 7 8 9 + 2 3 4 4 5 6 7 7 8 9 +10 11 12 12 13 14 15 15 16 17 +10 11 12 12 13 14 15 15 16 17 +18 19 20 20 21 22 23 23 24 25 +18 19 20 20 21 22 23 23 24 25 +18 19 20 20 21 22 23 23 24 25 +26 27 28 28 29 30 31 31 32 33 +26 27 28 28 29 30 31 31 32 33 +34 35 36 36 37 38 39 39 40 41 +34 35 36 36 37 38 39 39 40 41 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 1 2 3 3 4 5 6 6 7 8 + 1 2 3 3 4 5 6 6 7 8 + 9 10 11 11 12 13 14 14 15 16 + 9 10 11 11 12 13 14 14 15 16 +17 18 19 19 20 21 22 22 23 24 +17 18 19 19 20 21 22 22 23 24 +17 18 19 19 20 21 22 22 23 24 +25 26 27 27 28 29 30 30 31 32 +25 26 27 27 28 29 30 30 31 32 +33 34 35 35 36 37 38 38 39 40 +33 34 35 35 36 37 38 38 39 40 + 1 2 3 3 4 5 6 6 7 8 + 1 2 3 3 4 5 6 6 7 8 + 9 10 11 11 12 13 14 14 15 16 + 9 10 11 11 12 13 14 14 15 16 +17 18 19 19 20 21 22 22 23 24 +17 18 19 19 20 21 22 22 23 24 +17 18 19 19 20 21 22 22 23 24 +25 26 27 27 28 29 30 30 31 32 +25 26 27 27 28 29 30 30 31 32 +33 34 35 35 36 37 38 38 39 40 +33 34 35 35 36 37 38 38 39 40 diff --git a/python/tests/reference/Geom/scale_grid=10-13-10.geom b/python/tests/reference/Geom/scale_grid=10-13-10.geom index cbe4afc00..705d10ff3 100644 --- a/python/tests/reference/Geom/scale_grid=10-13-10.geom +++ b/python/tests/reference/Geom/scale_grid=10-13-10.geom @@ -3,133 +3,133 @@ grid a 10 b 13 c 10 size x 8e-06 y 5e-06 z 4e-06 origin x 0.0 y 0.0 z 0.0 homogenization 1 - 1 1 2 2 22 2 2 2 1 21 - 1 1 2 2 22 2 2 2 1 21 - 1 1 6 6 26 2 2 2 5 25 - 1 1 6 6 26 2 2 2 5 25 - 1 1 6 6 26 2 2 2 5 25 - 1 1 10 10 30 2 2 2 9 29 - 1 1 10 10 30 2 2 2 9 29 - 1 1 10 10 30 2 2 2 9 29 - 1 1 14 14 34 2 2 2 13 33 - 1 1 14 14 34 2 2 2 13 33 - 1 1 14 14 34 2 2 2 13 33 - 1 1 18 18 38 2 2 2 17 37 - 1 1 18 18 38 2 2 2 17 37 - 1 1 2 2 22 2 2 2 1 21 - 1 1 2 2 22 2 2 2 1 21 - 1 1 6 6 26 2 2 2 5 25 - 1 1 6 6 26 2 2 2 5 25 - 1 1 6 6 26 2 2 2 5 25 - 1 1 10 10 30 2 2 2 9 29 - 1 1 10 10 30 2 2 2 9 29 - 1 1 10 10 30 2 2 2 9 29 - 1 1 14 14 34 2 2 2 13 33 - 1 1 14 14 34 2 2 2 13 33 - 1 1 14 14 34 2 2 2 13 33 - 1 1 18 18 38 2 2 2 17 37 - 1 1 18 18 38 2 2 2 17 37 - 1 1 3 3 23 2 2 2 2 22 - 1 1 3 3 23 2 2 2 2 22 - 1 1 7 7 27 2 2 2 6 26 - 1 1 7 7 27 2 2 2 6 26 - 1 1 7 7 27 2 2 2 6 26 - 1 1 11 11 31 2 2 2 10 30 - 1 1 11 11 31 2 2 2 10 30 - 1 1 11 11 31 2 2 2 10 30 - 1 1 15 15 35 2 2 2 14 34 - 1 1 15 15 35 2 2 2 14 34 - 1 1 15 15 35 2 2 2 14 34 - 1 1 19 19 39 2 2 2 18 38 - 1 1 19 19 39 2 2 2 18 38 - 1 1 3 3 23 2 2 2 2 22 - 1 1 3 3 23 2 2 2 2 22 - 1 1 7 7 27 2 2 2 6 26 - 1 1 7 7 27 2 2 2 6 26 - 1 1 7 7 27 2 2 2 6 26 - 1 1 11 11 31 2 2 2 10 30 - 1 1 11 11 31 2 2 2 10 30 - 1 1 11 11 31 2 2 2 10 30 - 1 1 15 15 35 2 2 2 14 34 - 1 1 15 15 35 2 2 2 14 34 - 1 1 15 15 35 2 2 2 14 34 - 1 1 19 19 39 2 2 2 18 38 - 1 1 19 19 39 2 2 2 18 38 - 1 1 3 3 23 2 2 2 2 22 - 1 1 3 3 23 2 2 2 2 22 - 1 1 7 7 27 2 2 2 6 26 - 1 1 7 7 27 2 2 2 6 26 - 1 1 7 7 27 2 2 2 6 26 - 1 1 11 11 31 2 2 2 10 30 - 1 1 11 11 31 2 2 2 10 30 - 1 1 11 11 31 2 2 2 10 30 - 1 1 15 15 35 2 2 2 14 34 - 1 1 15 15 35 2 2 2 14 34 - 1 1 15 15 35 2 2 2 14 34 - 1 1 19 19 39 2 2 2 18 38 - 1 1 19 19 39 2 2 2 18 38 - 1 1 4 4 24 2 2 2 3 23 - 1 1 4 4 24 2 2 2 3 23 - 1 1 8 8 28 2 2 2 7 27 - 1 1 8 8 28 2 2 2 7 27 - 1 1 8 8 28 2 2 2 7 27 - 1 1 12 12 32 2 2 2 11 31 - 1 1 12 12 32 2 2 2 11 31 - 1 1 12 12 32 2 2 2 11 31 - 1 1 16 16 36 2 2 2 15 35 - 1 1 16 16 36 2 2 2 15 35 - 1 1 16 16 36 2 2 2 15 35 - 1 1 20 20 40 2 2 2 19 39 - 1 1 20 20 40 2 2 2 19 39 - 1 1 4 4 24 2 2 2 3 23 - 1 1 4 4 24 2 2 2 3 23 - 1 1 8 8 28 2 2 2 7 27 - 1 1 8 8 28 2 2 2 7 27 - 1 1 8 8 28 2 2 2 7 27 - 1 1 12 12 32 2 2 2 11 31 - 1 1 12 12 32 2 2 2 11 31 - 1 1 12 12 32 2 2 2 11 31 - 1 1 16 16 36 2 2 2 15 35 - 1 1 16 16 36 2 2 2 15 35 - 1 1 16 16 36 2 2 2 15 35 - 1 1 20 20 40 2 2 2 19 39 - 1 1 20 20 40 2 2 2 19 39 - 1 1 4 4 24 2 2 2 3 23 - 1 1 4 4 24 2 2 2 3 23 - 1 1 8 8 28 2 2 2 7 27 - 1 1 8 8 28 2 2 2 7 27 - 1 1 8 8 28 2 2 2 7 27 - 1 1 12 12 32 2 2 2 11 31 - 1 1 12 12 32 2 2 2 11 31 - 1 1 12 12 32 2 2 2 11 31 - 1 1 16 16 36 2 2 2 15 35 - 1 1 16 16 36 2 2 2 15 35 - 1 1 16 16 36 2 2 2 15 35 - 1 1 20 20 40 2 2 2 19 39 - 1 1 20 20 40 2 2 2 19 39 - 1 1 5 5 25 2 2 2 4 24 - 1 1 5 5 25 2 2 2 4 24 - 1 1 9 9 29 2 2 2 8 28 - 1 1 9 9 29 2 2 2 8 28 - 1 1 9 9 29 2 2 2 8 28 - 1 1 13 13 33 2 2 2 12 32 - 1 1 13 13 33 2 2 2 12 32 - 1 1 13 13 33 2 2 2 12 32 - 1 1 17 17 37 2 2 2 16 36 - 1 1 17 17 37 2 2 2 16 36 - 1 1 17 17 37 2 2 2 16 36 - 1 1 21 21 41 2 2 2 20 40 - 1 1 21 21 41 2 2 2 20 40 - 1 1 5 5 25 2 2 2 4 24 - 1 1 5 5 25 2 2 2 4 24 - 1 1 9 9 29 2 2 2 8 28 - 1 1 9 9 29 2 2 2 8 28 - 1 1 9 9 29 2 2 2 8 28 - 1 1 13 13 33 2 2 2 12 32 - 1 1 13 13 33 2 2 2 12 32 - 1 1 13 13 33 2 2 2 12 32 - 1 1 17 17 37 2 2 2 16 36 - 1 1 17 17 37 2 2 2 16 36 - 1 1 17 17 37 2 2 2 16 36 - 1 1 21 21 41 2 2 2 20 40 - 1 1 21 21 41 2 2 2 20 40 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 2 3 4 4 5 6 7 7 8 9 + 2 3 4 4 5 6 7 7 8 9 +10 11 12 12 13 14 15 15 16 17 +10 11 12 12 13 14 15 15 16 17 +10 11 12 12 13 14 15 15 16 17 +18 19 20 20 21 22 23 23 24 25 +18 19 20 20 21 22 23 23 24 25 +18 19 20 20 21 22 23 23 24 25 +26 27 28 28 29 30 31 31 32 33 +26 27 28 28 29 30 31 31 32 33 +26 27 28 28 29 30 31 31 32 33 +34 35 36 36 37 38 39 39 40 41 +34 35 36 36 37 38 39 39 40 41 + 2 3 4 4 5 6 7 7 8 9 + 2 3 4 4 5 6 7 7 8 9 +10 11 12 12 13 14 15 15 16 17 +10 11 12 12 13 14 15 15 16 17 +10 11 12 12 13 14 15 15 16 17 +18 19 20 20 21 22 23 23 24 25 +18 19 20 20 21 22 23 23 24 25 +18 19 20 20 21 22 23 23 24 25 +26 27 28 28 29 30 31 31 32 33 +26 27 28 28 29 30 31 31 32 33 +26 27 28 28 29 30 31 31 32 33 +34 35 36 36 37 38 39 39 40 41 +34 35 36 36 37 38 39 39 40 41 + 2 3 4 4 5 6 7 7 8 9 + 2 3 4 4 5 6 7 7 8 9 +10 11 12 12 13 14 15 15 16 17 +10 11 12 12 13 14 15 15 16 17 +10 11 12 12 13 14 15 15 16 17 +18 19 20 20 21 22 23 23 24 25 +18 19 20 20 21 22 23 23 24 25 +18 19 20 20 21 22 23 23 24 25 +26 27 28 28 29 30 31 31 32 33 +26 27 28 28 29 30 31 31 32 33 +26 27 28 28 29 30 31 31 32 33 +34 35 36 36 37 38 39 39 40 41 +34 35 36 36 37 38 39 39 40 41 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + 1 2 3 3 4 5 6 6 7 8 + 1 2 3 3 4 5 6 6 7 8 + 9 10 11 11 12 13 14 14 15 16 + 9 10 11 11 12 13 14 14 15 16 + 9 10 11 11 12 13 14 14 15 16 +17 18 19 19 20 21 22 22 23 24 +17 18 19 19 20 21 22 22 23 24 +17 18 19 19 20 21 22 22 23 24 +25 26 27 27 28 29 30 30 31 32 +25 26 27 27 28 29 30 30 31 32 +25 26 27 27 28 29 30 30 31 32 +33 34 35 35 36 37 38 38 39 40 +33 34 35 35 36 37 38 38 39 40 + 1 2 3 3 4 5 6 6 7 8 + 1 2 3 3 4 5 6 6 7 8 + 9 10 11 11 12 13 14 14 15 16 + 9 10 11 11 12 13 14 14 15 16 + 9 10 11 11 12 13 14 14 15 16 +17 18 19 19 20 21 22 22 23 24 +17 18 19 19 20 21 22 22 23 24 +17 18 19 19 20 21 22 22 23 24 +25 26 27 27 28 29 30 30 31 32 +25 26 27 27 28 29 30 30 31 32 +25 26 27 27 28 29 30 30 31 32 +33 34 35 35 36 37 38 38 39 40 +33 34 35 35 36 37 38 38 39 40 diff --git a/python/tests/reference/Geom/scale_grid=10-20-2.geom b/python/tests/reference/Geom/scale_grid=10-20-2.geom index 6b1888f17..3dcc4ff0c 100644 --- a/python/tests/reference/Geom/scale_grid=10-20-2.geom +++ b/python/tests/reference/Geom/scale_grid=10-20-2.geom @@ -3,43 +3,43 @@ grid a 10 b 20 c 2 size x 8e-06 y 5e-06 z 4e-06 origin x 0.0 y 0.0 z 0.0 homogenization 1 - 1 1 2 2 22 2 2 2 1 21 - 1 1 2 2 22 2 2 2 1 21 - 1 1 2 2 22 2 2 2 1 21 - 1 1 6 6 26 2 2 2 5 25 - 1 1 6 6 26 2 2 2 5 25 - 1 1 6 6 26 2 2 2 5 25 - 1 1 6 6 26 2 2 2 5 25 - 1 1 6 6 26 2 2 2 5 25 - 1 1 10 10 30 2 2 2 9 29 - 1 1 10 10 30 2 2 2 9 29 - 1 1 10 10 30 2 2 2 9 29 - 1 1 10 10 30 2 2 2 9 29 - 1 1 14 14 34 2 2 2 13 33 - 1 1 14 14 34 2 2 2 13 33 - 1 1 14 14 34 2 2 2 13 33 - 1 1 14 14 34 2 2 2 13 33 - 1 1 14 14 34 2 2 2 13 33 - 1 1 18 18 38 2 2 2 17 37 - 1 1 18 18 38 2 2 2 17 37 - 1 1 18 18 38 2 2 2 17 37 - 1 1 5 5 25 2 2 2 4 24 - 1 1 5 5 25 2 2 2 4 24 - 1 1 5 5 25 2 2 2 4 24 - 1 1 9 9 29 2 2 2 8 28 - 1 1 9 9 29 2 2 2 8 28 - 1 1 9 9 29 2 2 2 8 28 - 1 1 9 9 29 2 2 2 8 28 - 1 1 9 9 29 2 2 2 8 28 - 1 1 13 13 33 2 2 2 12 32 - 1 1 13 13 33 2 2 2 12 32 - 1 1 13 13 33 2 2 2 12 32 - 1 1 13 13 33 2 2 2 12 32 - 1 1 17 17 37 2 2 2 16 36 - 1 1 17 17 37 2 2 2 16 36 - 1 1 17 17 37 2 2 2 16 36 - 1 1 17 17 37 2 2 2 16 36 - 1 1 17 17 37 2 2 2 16 36 - 1 1 21 21 41 2 2 2 20 40 - 1 1 21 21 41 2 2 2 20 40 - 1 1 21 21 41 2 2 2 20 40 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + 1 2 3 3 4 5 6 6 7 8 + 1 2 3 3 4 5 6 6 7 8 + 1 2 3 3 4 5 6 6 7 8 + 9 10 11 11 12 13 14 14 15 16 + 9 10 11 11 12 13 14 14 15 16 + 9 10 11 11 12 13 14 14 15 16 + 9 10 11 11 12 13 14 14 15 16 + 9 10 11 11 12 13 14 14 15 16 +17 18 19 19 20 21 22 22 23 24 +17 18 19 19 20 21 22 22 23 24 +17 18 19 19 20 21 22 22 23 24 +17 18 19 19 20 21 22 22 23 24 +25 26 27 27 28 29 30 30 31 32 +25 26 27 27 28 29 30 30 31 32 +25 26 27 27 28 29 30 30 31 32 +25 26 27 27 28 29 30 30 31 32 +25 26 27 27 28 29 30 30 31 32 +33 34 35 35 36 37 38 38 39 40 +33 34 35 35 36 37 38 38 39 40 +33 34 35 35 36 37 38 38 39 40 diff --git a/python/tests/reference/Geom/scale_grid=5-4-20.geom b/python/tests/reference/Geom/scale_grid=5-4-20.geom index 043683f6a..16f243bd2 100644 --- a/python/tests/reference/Geom/scale_grid=5-4-20.geom +++ b/python/tests/reference/Geom/scale_grid=5-4-20.geom @@ -3,83 +3,83 @@ grid a 5 b 4 c 20 size x 8e-06 y 5e-06 z 4e-06 origin x 0.0 y 0.0 z 0.0 homogenization 1 - 1 2 2 2 21 - 1 6 2 2 25 - 1 14 2 2 33 - 1 18 2 2 37 - 1 2 2 2 21 - 1 6 2 2 25 - 1 14 2 2 33 - 1 18 2 2 37 - 1 2 2 2 21 - 1 6 2 2 25 - 1 14 2 2 33 - 1 18 2 2 37 - 1 2 2 2 21 - 1 6 2 2 25 - 1 14 2 2 33 - 1 18 2 2 37 - 1 3 2 2 22 - 1 7 2 2 26 - 1 15 2 2 34 - 1 19 2 2 38 - 1 3 2 2 22 - 1 7 2 2 26 - 1 15 2 2 34 - 1 19 2 2 38 - 1 3 2 2 22 - 1 7 2 2 26 - 1 15 2 2 34 - 1 19 2 2 38 - 1 3 2 2 22 - 1 7 2 2 26 - 1 15 2 2 34 - 1 19 2 2 38 - 1 3 2 2 22 - 1 7 2 2 26 - 1 15 2 2 34 - 1 19 2 2 38 - 1 3 2 2 22 - 1 7 2 2 26 - 1 15 2 2 34 - 1 19 2 2 38 - 1 4 2 2 23 - 1 8 2 2 27 - 1 16 2 2 35 - 1 20 2 2 39 - 1 4 2 2 23 - 1 8 2 2 27 - 1 16 2 2 35 - 1 20 2 2 39 - 1 4 2 2 23 - 1 8 2 2 27 - 1 16 2 2 35 - 1 20 2 2 39 - 1 4 2 2 23 - 1 8 2 2 27 - 1 16 2 2 35 - 1 20 2 2 39 - 1 4 2 2 23 - 1 8 2 2 27 - 1 16 2 2 35 - 1 20 2 2 39 - 1 4 2 2 23 - 1 8 2 2 27 - 1 16 2 2 35 - 1 20 2 2 39 - 1 5 2 2 24 - 1 9 2 2 28 - 1 17 2 2 36 - 1 21 2 2 40 - 1 5 2 2 24 - 1 9 2 2 28 - 1 17 2 2 36 - 1 21 2 2 40 - 1 5 2 2 24 - 1 9 2 2 28 - 1 17 2 2 36 - 1 21 2 2 40 - 1 5 2 2 24 - 1 9 2 2 28 - 1 17 2 2 36 - 1 21 2 2 40 + 1 1 1 1 1 + 1 1 1 1 1 + 1 1 1 1 1 + 1 1 1 1 1 + 1 1 1 1 1 + 1 1 1 1 1 + 1 1 1 1 1 + 1 1 1 1 1 + 1 1 1 1 1 + 1 1 1 1 1 + 1 1 1 1 1 + 1 1 1 1 1 + 1 1 1 1 1 + 1 1 1 1 1 + 1 1 1 1 1 + 1 1 1 1 1 + 2 4 6 7 9 +10 12 14 15 17 +26 28 30 31 33 +34 36 38 39 41 + 2 4 6 7 9 +10 12 14 15 17 +26 28 30 31 33 +34 36 38 39 41 + 2 4 6 7 9 +10 12 14 15 17 +26 28 30 31 33 +34 36 38 39 41 + 2 4 6 7 9 +10 12 14 15 17 +26 28 30 31 33 +34 36 38 39 41 + 2 4 6 7 9 +10 12 14 15 17 +26 28 30 31 33 +34 36 38 39 41 + 2 4 6 7 9 +10 12 14 15 17 +26 28 30 31 33 +34 36 38 39 41 + 2 2 2 2 2 + 2 2 2 2 2 + 2 2 2 2 2 + 2 2 2 2 2 + 2 2 2 2 2 + 2 2 2 2 2 + 2 2 2 2 2 + 2 2 2 2 2 + 2 2 2 2 2 + 2 2 2 2 2 + 2 2 2 2 2 + 2 2 2 2 2 + 2 2 2 2 2 + 2 2 2 2 2 + 2 2 2 2 2 + 2 2 2 2 2 + 2 2 2 2 2 + 2 2 2 2 2 + 2 2 2 2 2 + 2 2 2 2 2 + 2 2 2 2 2 + 2 2 2 2 2 + 2 2 2 2 2 + 2 2 2 2 2 + 1 3 5 6 8 + 9 11 13 14 16 +25 27 29 30 32 +33 35 37 38 40 + 1 3 5 6 8 + 9 11 13 14 16 +25 27 29 30 32 +33 35 37 38 40 + 1 3 5 6 8 + 9 11 13 14 16 +25 27 29 30 32 +33 35 37 38 40 + 1 3 5 6 8 + 9 11 13 14 16 +25 27 29 30 32 +33 35 37 38 40 diff --git a/python/tests/reference/Geom/scale_grid=8-10-12.geom b/python/tests/reference/Geom/scale_grid=8-10-12.geom index 5cfe66aba..439c1bee0 100644 --- a/python/tests/reference/Geom/scale_grid=8-10-12.geom +++ b/python/tests/reference/Geom/scale_grid=8-10-12.geom @@ -3,123 +3,123 @@ grid a 8 b 10 c 12 size x 8e-06 y 5e-06 z 4e-06 origin x 0.0 y 0.0 z 0.0 homogenization 1 - 1 1 2 22 2 2 1 21 - 1 1 2 22 2 2 1 21 - 1 1 6 26 2 2 5 25 - 1 1 6 26 2 2 5 25 - 1 1 10 30 2 2 9 29 - 1 1 10 30 2 2 9 29 - 1 1 14 34 2 2 13 33 - 1 1 14 34 2 2 13 33 - 1 1 18 38 2 2 17 37 - 1 1 18 38 2 2 17 37 - 1 1 2 22 2 2 1 21 - 1 1 2 22 2 2 1 21 - 1 1 6 26 2 2 5 25 - 1 1 6 26 2 2 5 25 - 1 1 10 30 2 2 9 29 - 1 1 10 30 2 2 9 29 - 1 1 14 34 2 2 13 33 - 1 1 14 34 2 2 13 33 - 1 1 18 38 2 2 17 37 - 1 1 18 38 2 2 17 37 - 1 1 3 23 2 2 2 22 - 1 1 3 23 2 2 2 22 - 1 1 7 27 2 2 6 26 - 1 1 7 27 2 2 6 26 - 1 1 11 31 2 2 10 30 - 1 1 11 31 2 2 10 30 - 1 1 15 35 2 2 14 34 - 1 1 15 35 2 2 14 34 - 1 1 19 39 2 2 18 38 - 1 1 19 39 2 2 18 38 - 1 1 3 23 2 2 2 22 - 1 1 3 23 2 2 2 22 - 1 1 7 27 2 2 6 26 - 1 1 7 27 2 2 6 26 - 1 1 11 31 2 2 10 30 - 1 1 11 31 2 2 10 30 - 1 1 15 35 2 2 14 34 - 1 1 15 35 2 2 14 34 - 1 1 19 39 2 2 18 38 - 1 1 19 39 2 2 18 38 - 1 1 3 23 2 2 2 22 - 1 1 3 23 2 2 2 22 - 1 1 7 27 2 2 6 26 - 1 1 7 27 2 2 6 26 - 1 1 11 31 2 2 10 30 - 1 1 11 31 2 2 10 30 - 1 1 15 35 2 2 14 34 - 1 1 15 35 2 2 14 34 - 1 1 19 39 2 2 18 38 - 1 1 19 39 2 2 18 38 - 1 1 3 23 2 2 2 22 - 1 1 3 23 2 2 2 22 - 1 1 7 27 2 2 6 26 - 1 1 7 27 2 2 6 26 - 1 1 11 31 2 2 10 30 - 1 1 11 31 2 2 10 30 - 1 1 15 35 2 2 14 34 - 1 1 15 35 2 2 14 34 - 1 1 19 39 2 2 18 38 - 1 1 19 39 2 2 18 38 - 1 1 4 24 2 2 3 23 - 1 1 4 24 2 2 3 23 - 1 1 8 28 2 2 7 27 - 1 1 8 28 2 2 7 27 - 1 1 12 32 2 2 11 31 - 1 1 12 32 2 2 11 31 - 1 1 16 36 2 2 15 35 - 1 1 16 36 2 2 15 35 - 1 1 20 40 2 2 19 39 - 1 1 20 40 2 2 19 39 - 1 1 4 24 2 2 3 23 - 1 1 4 24 2 2 3 23 - 1 1 8 28 2 2 7 27 - 1 1 8 28 2 2 7 27 - 1 1 12 32 2 2 11 31 - 1 1 12 32 2 2 11 31 - 1 1 16 36 2 2 15 35 - 1 1 16 36 2 2 15 35 - 1 1 20 40 2 2 19 39 - 1 1 20 40 2 2 19 39 - 1 1 4 24 2 2 3 23 - 1 1 4 24 2 2 3 23 - 1 1 8 28 2 2 7 27 - 1 1 8 28 2 2 7 27 - 1 1 12 32 2 2 11 31 - 1 1 12 32 2 2 11 31 - 1 1 16 36 2 2 15 35 - 1 1 16 36 2 2 15 35 - 1 1 20 40 2 2 19 39 - 1 1 20 40 2 2 19 39 - 1 1 4 24 2 2 3 23 - 1 1 4 24 2 2 3 23 - 1 1 8 28 2 2 7 27 - 1 1 8 28 2 2 7 27 - 1 1 12 32 2 2 11 31 - 1 1 12 32 2 2 11 31 - 1 1 16 36 2 2 15 35 - 1 1 16 36 2 2 15 35 - 1 1 20 40 2 2 19 39 - 1 1 20 40 2 2 19 39 - 1 1 5 25 2 2 4 24 - 1 1 5 25 2 2 4 24 - 1 1 9 29 2 2 8 28 - 1 1 9 29 2 2 8 28 - 1 1 13 33 2 2 12 32 - 1 1 13 33 2 2 12 32 - 1 1 17 37 2 2 16 36 - 1 1 17 37 2 2 16 36 - 1 1 21 41 2 2 20 40 - 1 1 21 41 2 2 20 40 - 1 1 5 25 2 2 4 24 - 1 1 5 25 2 2 4 24 - 1 1 9 29 2 2 8 28 - 1 1 9 29 2 2 8 28 - 1 1 13 33 2 2 12 32 - 1 1 13 33 2 2 12 32 - 1 1 17 37 2 2 16 36 - 1 1 17 37 2 2 16 36 - 1 1 21 41 2 2 20 40 - 1 1 21 41 2 2 20 40 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 + 2 3 4 5 6 7 8 9 + 2 3 4 5 6 7 8 9 +10 11 12 13 14 15 16 17 +10 11 12 13 14 15 16 17 +18 19 20 21 22 23 24 25 +18 19 20 21 22 23 24 25 +26 27 28 29 30 31 32 33 +26 27 28 29 30 31 32 33 +34 35 36 37 38 39 40 41 +34 35 36 37 38 39 40 41 + 2 3 4 5 6 7 8 9 + 2 3 4 5 6 7 8 9 +10 11 12 13 14 15 16 17 +10 11 12 13 14 15 16 17 +18 19 20 21 22 23 24 25 +18 19 20 21 22 23 24 25 +26 27 28 29 30 31 32 33 +26 27 28 29 30 31 32 33 +34 35 36 37 38 39 40 41 +34 35 36 37 38 39 40 41 + 2 3 4 5 6 7 8 9 + 2 3 4 5 6 7 8 9 +10 11 12 13 14 15 16 17 +10 11 12 13 14 15 16 17 +18 19 20 21 22 23 24 25 +18 19 20 21 22 23 24 25 +26 27 28 29 30 31 32 33 +26 27 28 29 30 31 32 33 +34 35 36 37 38 39 40 41 +34 35 36 37 38 39 40 41 + 2 3 4 5 6 7 8 9 + 2 3 4 5 6 7 8 9 +10 11 12 13 14 15 16 17 +10 11 12 13 14 15 16 17 +18 19 20 21 22 23 24 25 +18 19 20 21 22 23 24 25 +26 27 28 29 30 31 32 33 +26 27 28 29 30 31 32 33 +34 35 36 37 38 39 40 41 +34 35 36 37 38 39 40 41 + 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 + 1 2 3 4 5 6 7 8 + 1 2 3 4 5 6 7 8 + 9 10 11 12 13 14 15 16 + 9 10 11 12 13 14 15 16 +17 18 19 20 21 22 23 24 +17 18 19 20 21 22 23 24 +25 26 27 28 29 30 31 32 +25 26 27 28 29 30 31 32 +33 34 35 36 37 38 39 40 +33 34 35 36 37 38 39 40 + 1 2 3 4 5 6 7 8 + 1 2 3 4 5 6 7 8 + 9 10 11 12 13 14 15 16 + 9 10 11 12 13 14 15 16 +17 18 19 20 21 22 23 24 +17 18 19 20 21 22 23 24 +25 26 27 28 29 30 31 32 +25 26 27 28 29 30 31 32 +33 34 35 36 37 38 39 40 +33 34 35 36 37 38 39 40 diff --git a/python/tests/test_Geom.py b/python/tests/test_Geom.py index 04fb323c1..01e655823 100644 --- a/python/tests/test_Geom.py +++ b/python/tests/test_Geom.py @@ -19,7 +19,7 @@ def default(): x=np.concatenate((np.ones(40,dtype=int), np.arange(2,42), np.ones(40,dtype=int)*2, - np.arange(1,41))).reshape(8,5,4) + np.arange(1,41))).reshape(8,5,4,order='F') return Geom(x,[8e-6,5e-6,4e-6]) @pytest.fixture From 0c6ce390b5c5edbd575e110c159900c8056b7fd7 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 8 Aug 2020 20:35:50 +0200 Subject: [PATCH 28/73] simple IO tests can be improved ... --- python/tests/test_Geom.py | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/python/tests/test_Geom.py b/python/tests/test_Geom.py index 01e655823..95d1a8f98 100644 --- a/python/tests/test_Geom.py +++ b/python/tests/test_Geom.py @@ -44,12 +44,12 @@ class TestGeom: def test_set_microstructure(self,default,masked): old = default.get_microstructure() new = np.random.randint(200,size=default.grid) - default.set_microstructure(np.ma.MaskedArray(new,np.full_like(new,masked))) + default.set_microstructure(np.ma.MaskedArray(new,np.full_like(new,masked))) if masked: assert np.all(default.microstructure==old) else: assert np.all(default.microstructure==new) - + def test_write_read_str(self,default,tmpdir): default.to_file(str(tmpdir.join('default.geom'))) @@ -63,6 +63,16 @@ class TestGeom: new = Geom.from_file(f) assert geom_equal(new,default) + def test_write_show(self,default,tmpdir): + with open(tmpdir.join('str.geom'),'w') as f: + f.write(default.show()) + with open(tmpdir.join('str.geom')) as f: + new = Geom.from_file(f) + assert geom_equal(new,default) + + def test_export_vtk(self,default,tmpdir): + default.to_vtk(str(tmpdir.join('default'))) + @pytest.mark.parametrize('pack',[True,False]) def test_pack(self,default,tmpdir,pack): default.to_file(tmpdir.join('default.geom'),pack=pack) @@ -181,7 +191,7 @@ class TestGeom: modified.canvas(modified.grid + grid_add) e = default.grid assert np.all(modified.microstructure[:e[0],:e[1],:e[2]] == default.microstructure) - + @pytest.mark.parametrize('center',[np.random.random(3)*.5, np.random.randint(4,10,(3))]) @pytest.mark.parametrize('diameter',[np.random.random(3)*.5, @@ -201,7 +211,7 @@ class TestGeom: def test_vicinity_offset(self,trigger): offset = np.random.randint(2,4) vicinity = np.random.randint(2,4) - + g=np.random.randint(28,40,(3)) m=np.ones(g,'i') x=(g*np.random.permutation(np.array([.5,1,1]))).astype('i') @@ -212,18 +222,18 @@ class TestGeom: m2[(np.roll(m,-vicinity,i)-m)!=0] +=offset if len(trigger) > 0: m2[m==1]=1 - + geom = Geom(m,np.random.rand(3)) geom.vicinity_offset(vicinity,offset,trigger=trigger) - + assert np.all(m2==geom.microstructure) @pytest.mark.parametrize('periodic',[True,False]) def test_vicinity_offset_invariant(self,default,periodic): old = default.get_microstructure() - default.vicinity_offset(trigger=[old.max()+1,old.min()-1]) + default.vicinity_offset(trigger=[old.max()+1,old.min()-1]) assert np.all(old==default.microstructure) - + @pytest.mark.parametrize('periodic',[True,False]) def test_tessellation_approaches(self,periodic): grid = np.random.randint(10,20,3) From 309c53dc97e5fb9da4d883c5d1affbb67cfa383a Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 8 Aug 2020 20:46:46 +0200 Subject: [PATCH 29/73] now a library function --- PRIVATE | 2 +- processing/pre/geom_addPrimitive.py | 75 --------------------------- processing/pre/geom_vicinityOffset.py | 65 ----------------------- 3 files changed, 1 insertion(+), 141 deletions(-) delete mode 100755 processing/pre/geom_addPrimitive.py delete mode 100755 processing/pre/geom_vicinityOffset.py diff --git a/PRIVATE b/PRIVATE index 3fc9d58a3..a52584687 160000 --- a/PRIVATE +++ b/PRIVATE @@ -1 +1 @@ -Subproject commit 3fc9d58a35614fd8ffa1179e634431eb457d0150 +Subproject commit a52584687a93b9f007cf019861fce68eb31451ab diff --git a/processing/pre/geom_addPrimitive.py b/processing/pre/geom_addPrimitive.py deleted file mode 100755 index 318810a01..000000000 --- a/processing/pre/geom_addPrimitive.py +++ /dev/null @@ -1,75 +0,0 @@ -#!/usr/bin/env python3 - -import os -from optparse import OptionParser - -import damask - - -scriptName = os.path.splitext(os.path.basename(__file__))[0] -scriptID = ' '.join([scriptName,damask.version]) - - -#-------------------------------------------------------------------------------------------------- -# MAIN -#-------------------------------------------------------------------------------------------------- - -parser = OptionParser(option_class=damask.extendableOption, usage='%prog options [geomfile(s)]', description = """ -Inserts a primitive geometric object at a given position. -These objects can be boxes, cylinders, or ellipsoids. - -""", version = scriptID) - -parser.add_option('-c', '--center', - dest='center', - type='float', nargs = 3, metavar=' '.join(['float']*3), - help='a,b,c origin of primitive %default') -parser.add_option('-d', '--dimension', - dest='dimension', - type='float', nargs = 3, metavar=' '.join(['float']*3), - help='a,b,c extension of hexahedral box') -parser.add_option('-e', '--exponent', - dest='exponent', - type='float', nargs = 3, metavar=' '.join(['float']*3), - help='i,j,k exponents for axes: '+ - '0 gives octahedron (|x|^(2^0) + |y|^(2^0) + |z|^(2^0) < 1), '+ - '1 gives a sphere (|x|^(2^1) + |y|^(2^1) + |z|^(2^1) < 1), '+ - 'large values produce boxes, negative turn concave.') -parser.add_option('-f', '--fill', - dest='fill', - type='float', metavar = 'int', - help='microstructure index to fill primitive, defaults to max microstructure index + 1') -parser.add_option('-q', '--quaternion', - dest='quaternion', - type='float', nargs = 4, metavar=' '.join(['float']*4), - help = 'rotation of primitive as quaternion') -parser.add_option('-a', '--angleaxis', - dest='angleaxis', - type=float, nargs = 4, metavar=' '.join(['float']*4), - help = 'axis and angle to rotate primitive') -parser.add_option( '--degrees', - dest='degrees', - action='store_true', - help = 'angle is given in degrees') -parser.add_option( '--nonperiodic', - dest='periodic', - action='store_false', - help = 'wrap around edges') -parser.add_option( '--realspace', - dest='realspace', - action='store_true', - help = '-c and -d span [origin,origin+size] instead of [0,grid] coordinates') -parser.add_option( '--invert', - dest='inside', - action='store_false', - help = 'invert the volume filled by the primitive (inside/outside)') - -parser.set_defaults(center = (.0,.0,.0), - degrees = False, - exponent = (20,20,20), # box shape by default - periodic = True, - realspace = False, - inside = True, - ) - -print('This script is broken and does nothing') diff --git a/processing/pre/geom_vicinityOffset.py b/processing/pre/geom_vicinityOffset.py deleted file mode 100755 index 650e0093a..000000000 --- a/processing/pre/geom_vicinityOffset.py +++ /dev/null @@ -1,65 +0,0 @@ -#!/usr/bin/env python3 - -import os -import sys -from io import StringIO -from optparse import OptionParser - -import numpy as np - -import damask - - -scriptName = os.path.splitext(os.path.basename(__file__))[0] -scriptID = ' '.join([scriptName,damask.version]) - - -#-------------------------------------------------------------------------------------------------- -# MAIN -#-------------------------------------------------------------------------------------------------- - -parser = OptionParser(option_class=damask.extendableOption, usage='%prog options [geomfile(s)]', description = """ -Offset microstructure index for points which see a microstructure different from themselves -(or listed as triggers) within a given (cubic) vicinity, i.e. within the region close to a grain/phase boundary. - -""", version = scriptID) - -parser.add_option('-v', '--vicinity', - dest = 'vicinity', - type = 'int', metavar = 'int', - help = 'voxel distance checked for presence of other microstructure [%default]') -parser.add_option('-o', '--offset', - dest='offset', - type = 'int', metavar = 'int', - help='offset (positive or negative) to tag microstructure indices, defaults to max microstructure index') -parser.add_option('-t', '--trigger', - dest = 'trigger', - action = 'extend', metavar = '', - help = 'list of microstructure indices triggering a change') -parser.add_option('-n', '--nonperiodic', - dest = 'mode', - action = 'store_const', const = 'nearest', - help = 'assume geometry to be non-periodic') - -parser.set_defaults(vicinity = 1, - trigger = [], - mode = 'wrap', - ) - -(options, filenames) = parser.parse_args() - -options.trigger = np.array(options.trigger, dtype=int) - - -if filenames == []: filenames = [None] - -for name in filenames: - damask.util.report(scriptName,name) - - geom = damask.Geom.from_file(StringIO(''.join(sys.stdin.read())) if name is None else name) - - damask.util.croak(geom.vicinity_offset(options.vicinity,options.offset,options.trigger, - True if options.mode is 'wrap' else False)) - geom.add_comments(scriptID + ' ' + ' '.join(sys.argv[1:])) - - geom.to_file(sys.stdout if name is None else name,pack=False) From ff7eed4477c4c4496a5a6ac75d42eaf1af8506e0 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 8 Aug 2020 20:56:17 +0200 Subject: [PATCH 30/73] (unified) type hints --- python/damask/_colormap.py | 2 +- python/damask/_geom.py | 14 +++++++------- python/damask/_rotation.py | 10 +++++----- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/python/damask/_colormap.py b/python/damask/_colormap.py index 99332821d..ec4000018 100644 --- a/python/damask/_colormap.py +++ b/python/damask/_colormap.py @@ -51,7 +51,7 @@ class Colormap(mpl.colors.ListedColormap): Color definition for minimum value. high : numpy.ndarray of shape (3) Color definition for maximum value. - N : integer, optional + N : int, optional The number of color quantization levels. Defaults to 256. name : str, optional The name of the colormap. Defaults to `DAMASK colormap`. diff --git a/python/damask/_geom.py b/python/damask/_geom.py index 0aed3a113..3fec15fdd 100644 --- a/python/damask/_geom.py +++ b/python/damask/_geom.py @@ -28,7 +28,7 @@ class Geom: physical size of the microstructure in meter. origin : list or numpy.ndarray, optional physical origin of the microstructure in meter. - homogenization : integer, optional + homogenization : int, optional homogenization index. comments : list of str, optional comments lines. @@ -210,7 +210,7 @@ class Geom: Parameters ---------- - homogenization : integer + homogenization : int homogenization index """ @@ -345,7 +345,7 @@ class Geom: Parameters ---------- - grid : numpy.ndarray of shape (3) + grid : int numpy.ndarray of shape (3) Number of grid points in x,y,z direction. size : list or numpy.ndarray of shape (3) Physical size of the microstructure in meter. @@ -391,7 +391,7 @@ class Geom: Parameters ---------- - grid : numpy.ndarray of shape (3) + grid : int numpy.ndarray of shape (3) Number of grid points in x,y,z direction. size : list or numpy.ndarray of shape (3) Physical size of the microstructure in meter. @@ -509,11 +509,11 @@ class Geom: Parameters ---------- - dimension : numpy.ndarray of shape(3) + 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. If given as floats, coordinates are addressed. - center : numpy.ndarray of shape(3) + center : int or float numpy.ndarray of shape(3) Center of the primitive. If given as integers, grid point locations (cell centers) are addressed. If given as floats, coordinates are addressed. @@ -521,7 +521,7 @@ class Geom: Exponents for the three axis. 0 gives octahedron (|x|^(2^0) + |y|^(2^0) + |z|^(2^0) < 1) 1 gives a sphere (|x|^(2^1) + |y|^(2^1) + |z|^(2^1) < 1) - fill : integer, optional + fill : int, optional Fill value for primitive. Defaults to microstructure.max() + 1. R : damask.Rotation, optional Rotation of primitive. Defaults to no rotation. diff --git a/python/damask/_rotation.py b/python/damask/_rotation.py index 4c01bd430..9ee7fd5cc 100644 --- a/python/damask/_rotation.py +++ b/python/damask/_rotation.py @@ -357,7 +357,7 @@ class Rotation: accept_homomorph : boolean, optional Allow homomorphic variants, i.e. q_0 < 0 (negative real hemisphere). Defaults to False. - P : integer ∈ {-1,1}, optional + P : int ∈ {-1,1}, optional Convention used. Defaults to -1. """ @@ -422,7 +422,7 @@ class Rotation: Angle ω is given in degrees. Defaults to False. normalize: boolean, optional Allow |n| ≠ 1. Defaults to False. - P : integer ∈ {-1,1}, optional + P : int ∈ {-1,1}, optional Convention used. Defaults to -1. """ @@ -505,7 +505,7 @@ class Rotation: (n_1, n_2, n_3, tan(ω/2)), |n| = 1 and ω ∈ [0,π]. normalize : boolean, optional Allow |n| ≠ 1. Defaults to False. - P : integer ∈ {-1,1}, optional + P : int ∈ {-1,1}, optional Convention used. Defaults to -1. """ @@ -534,7 +534,7 @@ class Rotation: ---------- h : numpy.ndarray of shape (...,3) Homochoric vector: (h_1, h_2, h_3), |h| < (3/4*π)^(1/3). - P : integer ∈ {-1,1}, optional + P : int ∈ {-1,1}, optional Convention used. Defaults to -1. """ @@ -561,7 +561,7 @@ class Rotation: ---------- c : numpy.ndarray of shape (...,3) Cubochoric vector: (c_1, c_2, c_3), max(c_i) < 1/2*π^(2/3). - P : integer ∈ {-1,1}, optional + P : int ∈ {-1,1}, optional Convention used. Defaults to -1. """ From 2ef20df89f97432baea7dd1b26a8747a5d79a7c6 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 8 Aug 2020 22:34:19 +0200 Subject: [PATCH 31/73] same functionality is available in geom class is anyway just a call no scipy.ndimage --- processing/post/averageDown.py | 98 ---------------------------------- processing/post/blowUp.py | 72 ------------------------- 2 files changed, 170 deletions(-) delete mode 100755 processing/post/averageDown.py delete mode 100755 processing/post/blowUp.py diff --git a/processing/post/averageDown.py b/processing/post/averageDown.py deleted file mode 100755 index 341cc748d..000000000 --- a/processing/post/averageDown.py +++ /dev/null @@ -1,98 +0,0 @@ -#!/usr/bin/env python3 - -import os -import sys -from io import StringIO -from optparse import OptionParser - -import numpy as np -import scipy.ndimage - -import damask - - -scriptName = os.path.splitext(os.path.basename(__file__))[0] -scriptID = ' '.join([scriptName,damask.version]) - - -# -------------------------------------------------------------------- -# MAIN -# -------------------------------------------------------------------- - -parser = OptionParser(option_class=damask.extendableOption, usage='%prog options [ASCIItable(s)]', description = """ -Average each data block of size 'packing' into single values thus reducing the former grid to grid/packing. - -""", version = scriptID) - -parser.add_option('-c','--coordinates', - dest = 'pos', - type = 'string', metavar = 'string', - help = 'column label of coordinates [%default]') -parser.add_option('-p','--packing', - dest = 'packing', - type = 'int', nargs = 3, metavar = 'int int int', - help = 'size of packed group [%default]') -parser.add_option('--shift', - dest = 'shift', - type = 'int', nargs = 3, metavar = 'int int int', - help = 'shift vector of packing stencil [%default]') -parser.add_option('-g', '--grid', - dest = 'grid', - type = 'int', nargs = 3, metavar = 'int int int', - help = 'grid in x,y,z (optional)') -parser.add_option('-s', '--size', - dest = 'size', - type = 'float', nargs = 3, metavar = 'float float float', - help = 'size in x,y,z (optional)') -parser.set_defaults(pos = 'pos', - packing = (2,2,2), - shift = (0,0,0), - ) - -(options,filenames) = parser.parse_args() -if filenames == []: filenames = [None] - -packing = np.array(options.packing,dtype = int) -shift = np.array(options.shift, dtype = int) - -prefix = 'averagedDown{}x{}x{}_'.format(*packing) -if any(shift != 0): prefix += 'shift{:+}{:+}{:+}_'.format(*shift) - - -for name in filenames: - damask.util.report(scriptName,name) - - table = damask.Table.from_ASCII(StringIO(''.join(sys.stdin.read())) if name is None else name) - - if (options.grid is None or options.size is None): - grid,size,origin = damask.grid_filters.cell_coord0_gridSizeOrigin(table.get(options.pos)) - else: - grid = np.array(options.grid,'i') - size = np.array(options.size,'d') - - packing = np.where(grid == 1,1,packing) # reset packing to 1 where grid==1 - shift = np.where(grid == 1,0,shift) # reset shift to 0 where grid==1 - packedGrid = np.maximum(np.ones(3,'i'),grid//packing) - - data = table.data.values.reshape(tuple(grid)+(-1,),order = 'F') - averagedDown = scipy.ndimage.filters.uniform_filter( \ - np.roll( - np.roll( - np.roll(data, - -shift[0],axis = 0), - -shift[1],axis = 1), - -shift[2],axis = 2), - size = list(packing) + [1], - mode = 'wrap', - origin = list(-(packing//2)) + [0])\ - [::packing[0],::packing[1],::packing[2],:].reshape((packedGrid.prod(),-1),order = 'F') - - - table = damask.Table(averagedDown,table.shapes,table.comments) - - coords = damask.grid_filters.cell_coord0(packedGrid,size,shift/packedGrid*size+origin) - table.set(options.pos, coords.reshape(-1,3,order='F')) - - - outname = os.path.join(os.path.dirname(name),prefix+os.path.basename(name)) - table.to_ASCII(sys.stdout if name is None else outname) diff --git a/processing/post/blowUp.py b/processing/post/blowUp.py deleted file mode 100755 index 23c6b2ef2..000000000 --- a/processing/post/blowUp.py +++ /dev/null @@ -1,72 +0,0 @@ -#!/usr/bin/env python3 - -import os -import sys -from io import StringIO -from optparse import OptionParser - -from scipy import ndimage -import numpy as np - -import damask - - -scriptName = os.path.splitext(os.path.basename(__file__))[0] -scriptID = ' '.join([scriptName,damask.version]) - - -# -------------------------------------------------------------------- -# MAIN -# -------------------------------------------------------------------- - -parser = OptionParser(option_class=damask.extendableOption, usage='%prog options [ASCIItable(s)]', description = """ -Blows up each value to a surrounding data block of size 'packing' thus increasing the former resolution -to resolution*packing. - -""", version = scriptID) - -parser.add_option('-c','--coordinates', - dest = 'pos', metavar = 'string', - help = 'column label of coordinates [%default]') -parser.add_option('-p','--packing', - dest = 'packing', type = 'int', nargs = 3, metavar = 'int int int', - help = 'dimension of packed group [%default]') -parser.add_option('-g','--grid', - dest = 'resolution', type = 'int', nargs = 3, metavar = 'int int int', - help = 'grid in x,y,z (optional)') -parser.add_option('-s','--size', - dest = 'dimension', type = 'float', nargs = 3, metavar = 'int int int', - help = 'size in x,y,z (optional)') -parser.set_defaults(pos = 'pos', - packing = (2,2,2), - grid = (0,0,0), - size = (0.0,0.0,0.0), - ) - -(options,filenames) = parser.parse_args() -if filenames == []: filenames = [None] - -options.packing = np.array(options.packing) -prefix = 'blowUp{}x{}x{}_'.format(*options.packing) - - -for name in filenames: - damask.util.report(scriptName,name) - - table = damask.Table.from_ASCII(StringIO(''.join(sys.stdin.read())) if name is None else name) - grid,size,origin = damask.grid_filters.cell_coord0_gridSizeOrigin(table.get(options.pos)) - - packing = np.array(options.packing,'i') - outSize = grid*packing - - data = table.data.values.reshape(tuple(grid)+(-1,),order='F') - blownUp = ndimage.interpolation.zoom(data,tuple(packing)+(1,),order=0,mode='nearest').reshape(outSize.prod(),-1,order='F') - - table = damask.Table(blownUp,table.shapes,table.comments) - - coords = damask.grid_filters.cell_coord0(outSize,size,origin) - table.set(options.pos,coords.reshape(-1,3,order='F')) - table.set('elem',np.arange(1,outSize.prod()+1)) - - outname = os.path.join(os.path.dirname(name),prefix+os.path.basename(name)) - table.to_ASCII(sys.stdout if name is None else outname) From 7499b57f1795a191d1c3d30a9c9f82178eda474c Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 9 Aug 2020 05:59:58 +0200 Subject: [PATCH 32/73] test does not exist anymore --- .gitlab-ci.yml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index a37313dc6..a88b330bd 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -141,13 +141,6 @@ Pre_General: - release ################################################################################################### -Post_AverageDown: - stage: postprocessing - script: averageDown/test.py - except: - - master - - release - Post_ASCIItable: stage: postprocessing script: ASCIItable/test.py From 28bc1fae50f5362662b52d7444fa3b576d7e4bba Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 9 Aug 2020 06:17:14 +0200 Subject: [PATCH 33/73] don't repeat code --- src/system_routines.f90 | 102 ++++++++++++++++++++++------------------ 1 file changed, 55 insertions(+), 47 deletions(-) diff --git a/src/system_routines.f90 b/src/system_routines.f90 index 6dc1318e4..913fe82c8 100644 --- a/src/system_routines.f90 +++ b/src/system_routines.f90 @@ -95,14 +95,8 @@ contains logical function isDirectory(path) character(len=*), intent(in) :: path - character(kind=C_CHAR), dimension(pPathLen) :: strFixedLength ! C string as array - integer :: i - - strFixedLength = repeat(C_NULL_CHAR,len(strFixedLength)) - do i=1,len(path) ! copy array components - strFixedLength(i)=path(i:i) - enddo - isDirectory=merge(.True.,.False.,isDirectory_C(strFixedLength) /= 0_C_INT) + + isDirectory=merge(.True.,.False.,isDirectory_C(f_c_string(path)) /= 0_C_INT) end function isDirectory @@ -112,26 +106,15 @@ end function isDirectory !-------------------------------------------------------------------------------------------------- function getCWD() - character(kind=C_CHAR), dimension(pPathLen) :: charArray ! C string is an array + character(kind=C_CHAR), dimension(pPathLen) :: getCWD_Cstring character(len=:), allocatable :: getCWD integer(C_INT) :: stat - integer :: i - call getCurrentWorkDir_C(charArray,stat) + call getCurrentWorkDir_C(getCWD_Cstring,stat) - if (stat /= 0_C_INT) then - getCWD = 'Error occured when getting currend working directory' - else - allocate(character(len=pPathLen)::getCWD) - arrayToString: do i=1,len(getCWD) - if (charArray(i) /= C_NULL_CHAR) then - getCWD(i:i)=charArray(i) - else - getCWD = getCWD(:i-1) - exit - endif - enddo arrayToString - endif + getCWD = merge(c_f_string(getCWD_Cstring), & + 'Error occured when getting currend working directory', & + stat == 0_C_INT) end function getCWD @@ -141,26 +124,15 @@ end function getCWD !-------------------------------------------------------------------------------------------------- function getHostName() - character(kind=C_CHAR), dimension(pPathLen) :: charArray ! C string is an array + character(kind=C_CHAR), dimension(pPathLen) :: getHostName_Cstring character(len=:), allocatable :: getHostName integer(C_INT) :: stat - integer :: i - call getHostName_C(charArray,stat) + call getHostName_C(getHostName_Cstring,stat) - if (stat /= 0_C_INT) then - getHostName = 'Error occured when getting host name' - else - allocate(character(len=pPathLen)::getHostName) - arrayToString: do i=1,len(getHostName) - if (charArray(i) /= C_NULL_CHAR) then - getHostName(i:i)=charArray(i) - else - getHostName = getHostName(:i-1) - exit - endif - enddo arrayToString - endif + getHostName = merge(c_f_string(getHostName_Cstring), & + 'Error occured when getting host name', & + stat == 0_C_INT) end function getHostName @@ -171,16 +143,52 @@ end function getHostName logical function setCWD(path) character(len=*), intent(in) :: path - character(kind=C_CHAR), dimension(pPathLen) :: strFixedLength ! C string is an array - integer :: i - strFixedLength = repeat(C_NULL_CHAR,len(strFixedLength)) - do i=1,len(path) ! copy array components - strFixedLength(i)=path(i:i) - enddo - setCWD=merge(.True.,.False.,chdir_C(strFixedLength) /= 0_C_INT) + setCWD=merge(.True.,.False.,chdir_C(f_c_string(path)) /= 0_C_INT) end function setCWD + +!-------------------------------------------------------------------------------------------------- +!> @brief convert C string to Fortran string +!> @details: C string is NULL terminated and, hence, longer by one than the Fortran string +!-------------------------------------------------------------------------------------------------- +pure function c_f_string(c_string) result(f_string) + + character(kind=C_CHAR), dimension(:), intent(in) :: c_string + character(len=:), allocatable :: f_string + integer :: i + + allocate(character(len=size(c_string))::f_string) + arrayToString: do i=1,len(f_string) + if (c_string(i) /= C_NULL_CHAR) then + f_string(i:i)=c_string(i) + else + f_string = f_string(:i-1) + exit + endif + enddo arrayToString + +end function c_f_string + + +!-------------------------------------------------------------------------------------------------- +!> @brief convert Fortran string to C string +!> @details: C string is NULL terminated and, hence, longer by one than the Fortran string +!-------------------------------------------------------------------------------------------------- +pure function f_c_string(f_string) result(c_string) + + character(len=*), intent(in) :: f_string + character(kind=C_CHAR), dimension(len(f_string)+1) :: c_string + integer :: i + + do i=1,len(f_string) + c_string(i)=f_string(i:i) + enddo + c_string(i) = C_NULL_CHAR + +end function f_c_string + + end module system_routines From 93adee25813ececdee369a0142cf5bf14f1d61a6 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 9 Aug 2020 06:27:29 +0200 Subject: [PATCH 34/73] no need to have fixed string here --- src/HDF5_utilities.f90 | 51 +++++++++++++++++++++--------------------- 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/src/HDF5_utilities.f90 b/src/HDF5_utilities.f90 index a0c3b4e81..f099b0542 100644 --- a/src/HDF5_utilities.f90 +++ b/src/HDF5_utilities.f90 @@ -246,7 +246,8 @@ end function HDF5_openGroup subroutine HDF5_closeGroup(group_id) integer(HID_T), intent(in) :: group_id - integer :: hdferr + + integer :: hdferr call h5gclose_f(group_id, hdferr) if (hdferr < 0) call IO_error(1,ext_msg = 'HDF5_closeGroup: h5gclose_f (el is ID)', el = int(group_id)) @@ -262,8 +263,8 @@ logical function HDF5_objectExists(loc_id,path) integer(HID_T), intent(in) :: loc_id character(len=*), intent(in), optional :: path - integer :: hdferr - character(len=pStringLen) :: p + integer :: hdferr + character(len=:), allocatable :: p if (present(path)) then p = trim(path) @@ -291,10 +292,10 @@ subroutine HDF5_addAttribute_str(loc_id,attrLabel,attrValue,path) character(len=*), intent(in) :: attrLabel, attrValue character(len=*), intent(in), optional :: path - integer :: hdferr - integer(HID_T) :: attr_id, space_id, type_id - logical :: attrExists - character(len=pStringLen) :: p + integer(HID_T) :: attr_id, space_id, type_id + logical :: attrExists + integer :: hdferr + character(len=:), allocatable :: p if (present(path)) then p = trim(path) @@ -333,15 +334,15 @@ end subroutine HDF5_addAttribute_str !-------------------------------------------------------------------------------------------------- subroutine HDF5_addAttribute_int(loc_id,attrLabel,attrValue,path) - integer(HID_T), intent(in) :: loc_id - character(len=*), intent(in) :: attrLabel - integer, intent(in) :: attrValue - character(len=*), intent(in), optional :: path + integer(HID_T), intent(in) :: loc_id + character(len=*), intent(in) :: attrLabel + integer, intent(in) :: attrValue + character(len=*), intent(in), optional :: path - integer :: hdferr - integer(HID_T) :: attr_id, space_id - logical :: attrExists - character(len=pStringLen) :: p + integer(HID_T) :: attr_id, space_id + integer :: hdferr + logical :: attrExists + character(len=:), allocatable :: p if (present(path)) then p = trim(path) @@ -379,10 +380,10 @@ subroutine HDF5_addAttribute_real(loc_id,attrLabel,attrValue,path) real(pReal), intent(in) :: attrValue character(len=*), intent(in), optional :: path - integer :: hdferr - integer(HID_T) :: attr_id, space_id - logical :: attrExists - character(len=pStringLen) :: p + integer(HID_T) :: attr_id, space_id + integer :: hdferr + logical :: attrExists + character(len=:), allocatable :: p if (present(path)) then p = trim(path) @@ -420,11 +421,11 @@ subroutine HDF5_addAttribute_int_array(loc_id,attrLabel,attrValue,path) integer, intent(in), dimension(:) :: attrValue character(len=*), intent(in), optional :: path - integer :: hdferr - integer(HID_T) :: attr_id, space_id integer(HSIZE_T),dimension(1) :: array_size + integer(HID_T) :: attr_id, space_id + integer :: hdferr logical :: attrExists - character(len=pStringLen) :: p + character(len=:), allocatable :: p if (present(path)) then p = trim(path) @@ -464,11 +465,11 @@ subroutine HDF5_addAttribute_real_array(loc_id,attrLabel,attrValue,path) real(pReal), intent(in), dimension(:) :: attrValue character(len=*), intent(in), optional :: path - integer :: hdferr - integer(HID_T) :: attr_id, space_id integer(HSIZE_T),dimension(1) :: array_size + integer(HID_T) :: attr_id, space_id + integer :: hdferr logical :: attrExists - character(len=pStringLen) :: p + character(len=:), allocatable :: p if (present(path)) then p = trim(path) From 68bf21c9005b372a9057c6c05a803fe4f17de703 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 9 Aug 2020 06:37:50 +0200 Subject: [PATCH 35/73] can use string of dynamic length --- src/IO.f90 | 10 +++++----- src/grid/DAMASK_grid.f90 | 2 +- src/grid/grid_mech_FEM.f90 | 2 +- src/grid/grid_mech_spectral_basic.f90 | 2 +- src/grid/grid_mech_spectral_polarisation.f90 | 2 +- src/mesh/DAMASK_mesh.f90 | 2 +- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/IO.f90 b/src/IO.f90 index 0092fd1e2..aca887a22 100644 --- a/src/IO.f90 +++ b/src/IO.f90 @@ -413,9 +413,9 @@ subroutine IO_error(error_ID,el,ip,g,instance,ext_msg) integer, optional, intent(in) :: el,ip,g,instance character(len=*), optional, intent(in) :: ext_msg - external :: quit - character(len=pStringLen) :: msg - character(len=pStringLen) :: formatString + external :: quit + character(len=:), allocatable :: msg + character(len=pStringLen) :: formatString select case (error_ID) @@ -661,8 +661,8 @@ subroutine IO_warning(warning_ID,el,ip,g,ext_msg) integer, optional, intent(in) :: el,ip,g character(len=*), optional, intent(in) :: ext_msg - character(len=pStringLen) :: msg - character(len=pStringLen) :: formatString + character(len=:), allocatable :: msg + character(len=pStringLen) :: formatString select case (warning_ID) case (1) diff --git a/src/grid/DAMASK_grid.f90 b/src/grid/DAMASK_grid.f90 index af1eb1353..7c0f87078 100644 --- a/src/grid/DAMASK_grid.f90 +++ b/src/grid/DAMASK_grid.f90 @@ -36,7 +36,7 @@ program DAMASK_grid N_t = 0, & !< # of time indicators found in load case file N_n = 0, & !< # of increment specifiers found in load case file N_def = 0 !< # of rate of deformation specifiers found in load case file - character(len=pStringLen) :: & + character(len=:), allocatable :: & line !-------------------------------------------------------------------------------------------------- diff --git a/src/grid/grid_mech_FEM.f90 b/src/grid/grid_mech_FEM.f90 index 13382a444..43dbca00e 100644 --- a/src/grid/grid_mech_FEM.f90 +++ b/src/grid/grid_mech_FEM.f90 @@ -71,7 +71,7 @@ module grid_mech_FEM F_aim_lastInc = math_I3, & !< previous average deformation gradient P_av = 0.0_pReal !< average 1st Piola--Kirchhoff stress - character(len=pStringLen), private :: incInfo !< time and increment information + character(len=:), allocatable, private :: incInfo !< time and increment information real(pReal), private, dimension(3,3,3,3) :: & C_volAvg = 0.0_pReal, & !< current volume average stiffness diff --git a/src/grid/grid_mech_spectral_basic.f90 b/src/grid/grid_mech_spectral_basic.f90 index 7300d9b39..ccbeb3c42 100644 --- a/src/grid/grid_mech_spectral_basic.f90 +++ b/src/grid/grid_mech_spectral_basic.f90 @@ -66,7 +66,7 @@ module grid_mech_spectral_basic F_aim_lastInc = math_I3, & !< previous average deformation gradient P_av = 0.0_pReal !< average 1st Piola--Kirchhoff stress - character(len=pStringLen) :: incInfo !< time and increment information + character(len=:), allocatable :: incInfo !< time and increment information real(pReal), private, dimension(3,3,3,3) :: & C_volAvg = 0.0_pReal, & !< current volume average stiffness C_volAvgLastInc = 0.0_pReal, & !< previous volume average stiffness diff --git a/src/grid/grid_mech_spectral_polarisation.f90 b/src/grid/grid_mech_spectral_polarisation.f90 index cad0751cd..347a2a832 100644 --- a/src/grid/grid_mech_spectral_polarisation.f90 +++ b/src/grid/grid_mech_spectral_polarisation.f90 @@ -74,7 +74,7 @@ module grid_mech_spectral_polarisation F_av = 0.0_pReal, & !< average incompatible def grad field P_av = 0.0_pReal !< average 1st Piola--Kirchhoff stress - character(len=pStringLen) :: incInfo !< time and increment information + character(len=:), allocatable :: incInfo !< time and increment information real(pReal), dimension(3,3,3,3) :: & C_volAvg = 0.0_pReal, & !< current volume average stiffness C_volAvgLastInc = 0.0_pReal, & !< previous volume average stiffness diff --git a/src/mesh/DAMASK_mesh.f90 b/src/mesh/DAMASK_mesh.f90 index 5cb7d5120..b6cb4b2d1 100644 --- a/src/mesh/DAMASK_mesh.f90 +++ b/src/mesh/DAMASK_mesh.f90 @@ -27,7 +27,7 @@ program DAMASK_mesh integer, allocatable, dimension(:) :: chunkPos ! this is longer than needed for geometry parsing integer :: & N_def = 0 !< # of rate of deformation specifiers found in load case file - character(len=pStringLen) :: & + character(len=:), allocatable :: & line !-------------------------------------------------------------------------------------------------- From e6f1b17149aa67d80c4ebc0b0f22c55e7694f07a Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 9 Aug 2020 08:53:10 +0200 Subject: [PATCH 36/73] Gfortran 8 failed with At line 115 of file DAMASK/src/system_routines.f90 Fortran runtime error: Unequal character lengths (93/52) in MERGE intrinsic not sure whether this is a false alarm or not ... --- src/system_routines.f90 | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/system_routines.f90 b/src/system_routines.f90 index 913fe82c8..9a2442163 100644 --- a/src/system_routines.f90 +++ b/src/system_routines.f90 @@ -112,9 +112,11 @@ function getCWD() call getCurrentWorkDir_C(getCWD_Cstring,stat) - getCWD = merge(c_f_string(getCWD_Cstring), & - 'Error occured when getting currend working directory', & - stat == 0_C_INT) + if(stat == 0) then + getCWD = c_f_string(getCWD_Cstring) + else + getCWD = 'Error occured when getting currend working directory' + endif end function getCWD @@ -130,9 +132,11 @@ function getHostName() call getHostName_C(getHostName_Cstring,stat) - getHostName = merge(c_f_string(getHostName_Cstring), & - 'Error occured when getting host name', & - stat == 0_C_INT) + if(stat == 0) then + getHostName = c_f_string(getHostName_Cstring) + else + getHostName = 'Error occured when getting host name' + endif end function getHostName From 4bf3b926097bf85deb521242c043332d5e449235 Mon Sep 17 00:00:00 2001 From: Philip Eisenlohr Date: Sun, 9 Aug 2020 22:40:04 +0200 Subject: [PATCH 37/73] polishing vtk2ang.py --- processing/post/vtk2ang.py | 74 ++++++++++++++++++-------------------- 1 file changed, 35 insertions(+), 39 deletions(-) diff --git a/processing/post/vtk2ang.py b/processing/post/vtk2ang.py index 9ee19dac7..7991251fb 100755 --- a/processing/post/vtk2ang.py +++ b/processing/post/vtk2ang.py @@ -18,47 +18,43 @@ scriptID = ' '.join([scriptName,damask.version]) # ----------------------------- def getHeader(filename,sizeFastIndex,sizeSlowIndex,stepsize): """Returns header for ang file step size in micrometer.""" - return '\n'.join([ \ - '# TEM_PIXperUM 1.000000', \ - '# x-star 1.000000', \ - '# y-star 1.000000', \ - '# z-star 1.000000', \ - '# WorkingDistance 18.000000', \ - '#', \ - '# Phase 1', \ - '# MaterialName XX', \ - '# Formula XX', \ - '# Info', \ - '# Symmetry 43', \ - '# LatticeConstants 2.870 2.870 2.870 90.000 90.000 90.000', \ - '# NumberFamilies 1', \ - '# hklFamilies 1 1 0 1 0.000000 1', \ - '# Categories 0 0 0 0 0 ', \ - '#', \ - '# GRID: SqrGrid', \ - '# XSTEP: ' + str(stepsize*1e6), \ - '# YSTEP: ' + str(stepsize*1e6), \ - '# NCOLS_ODD: ' + str(sizeFastIndex), \ - '# NCOLS_EVEN: ' + str(sizeFastIndex), \ - '# NROWS: ' + str(sizeSlowIndex), \ - '#', \ - '# OPERATOR: ' + string.replace('$Id$','\n','\\n'), \ - '#', \ - '# SAMPLEID: %s'%filename, \ - '#', \ - '# SCANID: ', \ - '#', \ + return '\n'.join([ + '# TEM_PIXperUM 1.000000', + '# x-star 1.000000', + '# y-star 1.000000', + '# z-star 1.000000', + '# WorkingDistance 18.000000', + '#', + '# Phase 1', + '# MaterialName XX', + '# Formula XX', + '# Info', + '# Symmetry 43', + '# LatticeConstants 2.870 2.870 2.870 90.000 90.000 90.000', + '# NumberFamilies 1', + '# hklFamilies 1 1 0 1 0.000000 1', + '# Categories 0 0 0 0 0 ', + '#', + '# GRID: SqrGrid', + '# XSTEP: ' + str(stepsize*1e6), + '# YSTEP: ' + str(stepsize*1e6), + '# NCOLS_ODD: ' + str(sizeFastIndex), + '# NCOLS_EVEN: ' + str(sizeFastIndex), + '# NROWS: ' + str(sizeSlowIndex), + '#', + '# OPERATOR: ' + string.replace('$Id$','\n','\\n'), + '#', + '# SAMPLEID: {}'.format(filename), + '#', + '# SCANID: ', + '#', ]) + '\n' # ----------------------------- def positiveRadians(angle): """Returns positive angle in radians from angle in degrees.""" - angle = math.radians(float(angle)) - while angle < 0.0: - angle += 2.0 * math.pi - - return angle + return math.radians(float(angle)) % (2.*math.pi) # ----------------------------- @@ -230,11 +226,11 @@ for filename in filenames: # Get bounding box in rotated system (x,y,z) if options.verbose: sys.stdout.write("\nGETTING BOUNDING BOX IN ROTATED SYSTEM\n") - rotatedbox = [[np.inf,-np.inf] for i in range(3)] # bounding box in rotated TSL system - for n in range(8): # loop over eight vertices of mesh bounding box + rotatedbox = [[np.inf,-np.inf] for i in range(3)] # bounding box in rotated TSL system + for n in range(8): # loop over eight vertices of mesh bounding box vert = np.array([box[0+(n//1)%2], - box[2+(n//2)%2], - box[4+(n//4)%2]]) # vertex in mesh system + box[2+(n//2)%2], + box[4+(n//4)%2]]) # vertex in mesh system rotatedvert = np.dot(R,vert) # vertex in rotated system for i in range(3): rotatedbox[i][0] = min(rotatedbox[i][0],rotatedvert[i]) From 752d6f773bb1ff8d4724fb5c2b85fbaa27611435 Mon Sep 17 00:00:00 2001 From: Philip Eisenlohr Date: Sun, 9 Aug 2020 23:14:32 +0200 Subject: [PATCH 38/73] corrected add_primitive test --- python/tests/test_Geom.py | 49 ++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 26 deletions(-) diff --git a/python/tests/test_Geom.py b/python/tests/test_Geom.py index 95d1a8f98..4061c3ecf 100644 --- a/python/tests/test_Geom.py +++ b/python/tests/test_Geom.py @@ -45,10 +45,7 @@ class TestGeom: old = default.get_microstructure() new = np.random.randint(200,size=default.grid) default.set_microstructure(np.ma.MaskedArray(new,np.full_like(new,masked))) - if masked: - assert np.all(default.microstructure==old) - else: - assert np.all(default.microstructure==new) + assert np.all(default.microstructure==(old if masked else new)) def test_write_read_str(self,default,tmpdir): @@ -192,36 +189,36 @@ class TestGeom: e = default.grid assert np.all(modified.microstructure[:e[0],:e[1],:e[2]] == default.microstructure) - @pytest.mark.parametrize('center',[np.random.random(3)*.5, - np.random.randint(4,10,(3))]) - @pytest.mark.parametrize('diameter',[np.random.random(3)*.5, - np.random.randint(4,10,(3))]) - def test_add_primitive(self,diameter,center): - """Same volume fraction for periodic microstructures and different center.""" - 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) - G_2 = Geom(np.ones(g,'i'),s,o) - G_1.add_primitive(diameter,center,1) - G_2.add_primitive(diameter,center,1) - assert np.count_nonzero(G_1.microstructure!=2) == np.count_nonzero(G_2.microstructure!=2) + @pytest.mark.parametrize('center1,center2',[(np.random.random(3)*.5,np.random.random(3)), + (np.random.randint(4,8,(3)),np.random.randint(9,12,(3)))]) + @pytest.mark.parametrize('diameter',[np.random.random(3)*.5, + np.random.randint(4,10,(3))]) + def test_add_primitive(self,diameter,center1,center2): + """Same volume fraction for periodic microstructures and different center.""" + 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) + G_2 = Geom(np.ones(g,'i'),s,o) + G_1.add_primitive(diameter,center1,1) + G_2.add_primitive(diameter,center2,1) + assert np.count_nonzero(G_1.microstructure!=2) == np.count_nonzero(G_2.microstructure!=2) @pytest.mark.parametrize('trigger',[[1],[]]) def test_vicinity_offset(self,trigger): offset = np.random.randint(2,4) vicinity = np.random.randint(2,4) - g=np.random.randint(28,40,(3)) - m=np.ones(g,'i') - x=(g*np.random.permutation(np.array([.5,1,1]))).astype('i') - m[slice(0,x[0]),slice(0,x[1]),slice(0,x[2])]=2 - m2=copy.deepcopy(m) + g = np.random.randint(28,40,(3)) + m = np.ones(g,'i') + x = (g*np.random.permutation(np.array([.5,1,1]))).astype('i') + m[slice(0,x[0]),slice(0,x[1]),slice(0,x[2])] = 2 + m2 = copy.deepcopy(m) for i in [0,1,2]: - m2[(np.roll(m,+vicinity,i)-m)!=0] +=offset - m2[(np.roll(m,-vicinity,i)-m)!=0] +=offset + m2[(np.roll(m,+vicinity,i)-m)!=0] += offset + m2[(np.roll(m,-vicinity,i)-m)!=0] += offset if len(trigger) > 0: - m2[m==1]=1 + m2[m==1] = 1 geom = Geom(m,np.random.rand(3)) geom.vicinity_offset(vicinity,offset,trigger=trigger) From fdb0bcf8afe2f2029d01bf8e53df7da8d40bc669 Mon Sep 17 00:00:00 2001 From: Test User Date: Mon, 10 Aug 2020 06:20:56 +0200 Subject: [PATCH 39/73] [skip ci] updated version information after successful test of v2.0.3-2992-g4b45c37e --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 55ad31923..16d400581 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v2.0.3-2957-gce00371f +v2.0.3-2992-g4b45c37e From c1358294f7908a4e3ba81c9da16ceee12a740a46 Mon Sep 17 00:00:00 2001 From: Philip Eisenlohr Date: Wed, 12 Aug 2020 15:14:00 -0400 Subject: [PATCH 40/73] Corrected Kirchoff --> Kirchhoff --- src/constitutive_thermal.f90 | 26 +++++++++++++------------- src/crystallite.f90 | 8 ++++---- src/homogenization.f90 | 12 ++++++------ 3 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/constitutive_thermal.f90 b/src/constitutive_thermal.f90 index 3b3398ce2..96d4c03ee 100644 --- a/src/constitutive_thermal.f90 +++ b/src/constitutive_thermal.f90 @@ -1,5 +1,5 @@ !---------------------------------------------------------------------------------------------------- -!> @brief internal microstructure state for all thermal sources and kinematics constitutive models +!> @brief internal microstructure state for all thermal sources and kinematics constitutive models !---------------------------------------------------------------------------------------------------- submodule(constitutive) constitutive_thermal @@ -7,7 +7,7 @@ submodule(constitutive) constitutive_thermal module subroutine source_thermal_dissipation_init end subroutine source_thermal_dissipation_init - + module subroutine source_thermal_externalheat_init end subroutine source_thermal_externalheat_init @@ -19,7 +19,7 @@ submodule(constitutive) constitutive_thermal integer, intent(in) :: & phase !< phase ID of element real(pReal), intent(in), dimension(3,3) :: & - Tstar !< 2nd Piola Kirchoff stress tensor for a given element + Tstar !< 2nd Piola Kirchhoff stress tensor for a given element real(pReal), intent(in), dimension(3,3) :: & Lp !< plastic velocuty gradient for a given element real(pReal), intent(out) :: & @@ -48,7 +48,7 @@ module subroutine thermal_init ! initialize source mechanisms if (any(phase_source == SOURCE_thermal_dissipation_ID)) call source_thermal_dissipation_init if (any(phase_source == SOURCE_thermal_externalheat_ID)) call source_thermal_externalheat_init - + !-------------------------------------------------------------------------------------------------- !initialize kinematic mechanisms if (any(phase_kinematics == KINEMATICS_thermal_expansion_ID)) call kinematics_thermal_expansion_init @@ -66,7 +66,7 @@ module subroutine constitutive_thermal_getRateAndItsTangents(TDot, dTDot_dT, T, real(pReal), intent(in) :: & T real(pReal), intent(in), dimension(:,:,:,:,:) :: & - S, & !< current 2nd Piola Kirchoff stress + S, & !< current 2nd Piola Kirchhoff stress Lp !< plastic velocity gradient real(pReal), intent(inout) :: & TDot, & @@ -82,34 +82,34 @@ module subroutine constitutive_thermal_getRateAndItsTangents(TDot, dTDot_dT, T, grain, & source, & constituent - + homog = material_homogenizationAt(el) instance = thermal_typeInstance(homog) - + do grain = 1, homogenization_Ngrains(homog) phase = material_phaseAt(grain,el) constituent = material_phasememberAt(grain,ip,el) do source = 1, phase_Nsources(phase) - select case(phase_source(source,phase)) + select case(phase_source(source,phase)) case (SOURCE_thermal_dissipation_ID) call source_thermal_dissipation_getRateAndItsTangent(my_Tdot, my_dTdot_dT, & S(1:3,1:3,grain,ip,el), & - Lp(1:3,1:3,grain,ip,el), & + Lp(1:3,1:3,grain,ip,el), & phase) - + case (SOURCE_thermal_externalheat_ID) call source_thermal_externalheat_getRateAndItsTangent(my_Tdot, my_dTdot_dT, & phase, constituent) - + case default my_Tdot = 0.0_pReal my_dTdot_dT = 0.0_pReal end select Tdot = Tdot + my_Tdot dTdot_dT = dTdot_dT + my_dTdot_dT - enddo + enddo enddo - + end subroutine constitutive_thermal_getRateAndItsTangents diff --git a/src/crystallite.f90 b/src/crystallite.f90 index f33f392a2..ee825d4ea 100644 --- a/src/crystallite.f90 +++ b/src/crystallite.f90 @@ -82,7 +82,7 @@ module crystallite iJacoLpresiduum, & !< frequency of Jacobian update of residuum in Lp nState, & !< state loop limit nStress !< stress loop limit - character(len=:), allocatable :: & + character(len=:), allocatable :: & integrator !< integration scheme real(pReal) :: & subStepMinCryst, & !< minimum (relative) size of sub-step allowed during cutback @@ -140,7 +140,7 @@ subroutine crystallite_init iMax, & !< maximum number of integration points eMax, & !< maximum number of elements myNcomponents !< number of components at current IP - + class(tNode), pointer :: & num_crystallite, & debug_crystallite ! pointer to debug options for crystallite @@ -715,11 +715,11 @@ subroutine crystallite_results case('p') selected_tensors = select_tensors(crystallite_P,p) call results_writeDataset(group,selected_tensors,'P',& - 'First Piola-Kirchoff stress','Pa') + 'First Piola-Kirchhoff stress','Pa') case('s') selected_tensors = select_tensors(crystallite_S,p) call results_writeDataset(group,selected_tensors,'S',& - 'Second Piola-Kirchoff stress','Pa') + 'Second Piola-Kirchhoff stress','Pa') case('orientation') select case(lattice_structure(p)) case(lattice_ISO_ID) diff --git a/src/homogenization.f90 b/src/homogenization.f90 index 17b044ad5..d54e1f390 100644 --- a/src/homogenization.f90 +++ b/src/homogenization.f90 @@ -152,12 +152,12 @@ subroutine homogenization_init debug_homogenization debug_homogenization => debug_root%get('homogenization', defaultVal=emptyList) - debugHomog%basic = debug_homogenization%contains('basic') - debugHomog%extensive = debug_homogenization%contains('extensive') + debugHomog%basic = debug_homogenization%contains('basic') + debugHomog%extensive = debug_homogenization%contains('extensive') debugHomog%selective = debug_homogenization%contains('selective') - debugHomog%element = debug_root%get_asInt('element',defaultVal = 1) - debugHomog%ip = debug_root%get_asInt('integrationpoint',defaultVal = 1) - debugHomog%grain = debug_root%get_asInt('grain',defaultVal = 1) + debugHomog%element = debug_root%get_asInt('element',defaultVal = 1) + debugHomog%ip = debug_root%get_asInt('integrationpoint',defaultVal = 1) + debugHomog%grain = debug_root%get_asInt('grain',defaultVal = 1) if (debugHomog%grain < 1 & .or. debugHomog%grain > homogenization_Ngrains(material_homogenizationAt(debugHomog%element))) & @@ -618,7 +618,7 @@ subroutine homogenization_results ! 'deformation gradient','1') !temp = reshape(materialpoint_P,[3,3,discretization_nIP*discretization_nElem]) !call results_writeDataset(group,temp,'P',& - ! '1st Piola-Kirchoff stress','Pa') + ! '1st Piola-Kirchhoff stress','Pa') group = trim(group_base)//'/mech' call results_closeGroup(results_addGroup(group)) From 95092f3c5f7b4da3a91ac345ffba792bb6313eb8 Mon Sep 17 00:00:00 2001 From: Test User Date: Thu, 13 Aug 2020 10:15:34 +0200 Subject: [PATCH 41/73] [skip ci] updated version information after successful test of v2.0.3-2995-gd00974b5 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 16d400581..b7a86ed59 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v2.0.3-2992-g4b45c37e +v2.0.3-2995-gd00974b5 From 7754a1ea56d231e0b4ac5513a59fbc4a03f83d8b Mon Sep 17 00:00:00 2001 From: Sharan Roongta Date: Sat, 15 Aug 2020 16:02:10 +0200 Subject: [PATCH 42/73] Restructuring for material.yaml --- PRIVATE | 2 +- .../Polycrystal/material.config | 126 ---- .../SpectralMethod/Polycrystal/material.yaml | 123 ++++ src/CPFEM.f90 | 5 +- src/CPFEM2.f90 | 5 +- src/DAMASK_marc.f90 | 3 +- src/HDF5_utilities.f90 | 2 +- src/IO.f90 | 10 +- src/YAML_parse.f90 | 50 +- src/YAML_types.f90 | 130 +++- src/commercialFEM_fileList.f90 | 5 +- src/config.f90 | 331 +++------ src/constitutive.f90 | 238 ++++++- src/constitutive_damage.f90 | 90 ++- src/constitutive_plastic.f90 | 134 ++-- ...=> constitutive_plastic_disloTungsten.f90} | 176 ++--- src/constitutive_plastic_dislotwin.f90 | 276 ++++---- src/constitutive_plastic_isotropic.f90 | 83 ++- src/constitutive_plastic_kinehardening.f90 | 123 ++-- src/constitutive_plastic_none.f90 | 38 +- src/constitutive_plastic_nonlocal.f90 | 365 +++++----- src/constitutive_plastic_phenopowerlaw.f90 | 156 ++-- src/constitutive_thermal.f90 | 31 +- src/crystallite.f90 | 70 +- src/damage_local.f90 | 26 +- src/damage_none.f90 | 4 +- src/damage_nonlocal.f90 | 25 +- src/debug.f90 | 50 -- src/grid/DAMASK_grid.f90 | 1 - src/grid/discretization_grid.f90 | 3 +- src/grid/grid_damage_spectral.f90 | 2 +- src/grid/grid_mech_FEM.f90 | 3 +- src/grid/grid_mech_spectral_basic.f90 | 2 - src/grid/grid_mech_spectral_polarisation.f90 | 2 - src/grid/grid_thermal_spectral.f90 | 2 +- src/grid/spectral_utilities.f90 | 2 - src/homogenization.f90 | 7 +- src/homogenization_mech_RGC.f90 | 56 +- src/homogenization_mech_isostrain.f90 | 24 +- src/homogenization_mech_none.f90 | 2 +- src/kinematics_cleavage_opening.f90 | 83 ++- src/kinematics_slipplane_opening.f90 | 101 +-- src/kinematics_thermal_expansion.f90 | 69 +- src/lattice.f90 | 64 +- src/marc/discretization_marc.f90 | 3 +- src/material.f90 | 670 +++++------------- src/math.f90 | 5 +- src/mesh/DAMASK_mesh.f90 | 2 +- src/mesh/FEM_utilities.f90 | 3 +- src/mesh/discretization_mesh.f90 | 3 +- src/mesh/mesh_mech_FEM.f90 | 3 +- src/numerics.f90 | 82 --- src/results.f90 | 2 +- src/rotations.f90 | 2 +- src/source_damage_anisoBrittle.f90 | 125 ++-- src/source_damage_anisoDuctile.f90 | 99 +-- src/source_damage_isoBrittle.f90 | 88 ++- src/source_damage_isoDuctile.f90 | 88 ++- src/source_thermal_dissipation.f90 | 58 +- src/source_thermal_externalheat.f90 | 66 +- src/thermal_adiabatic.f90 | 30 +- src/thermal_conduction.f90 | 24 +- src/thermal_isothermal.f90 | 4 +- 63 files changed, 2291 insertions(+), 2166 deletions(-) delete mode 100644 examples/SpectralMethod/Polycrystal/material.config create mode 100644 examples/SpectralMethod/Polycrystal/material.yaml rename src/{constitutive_plastic_disloUCLA.f90 => constitutive_plastic_disloTungsten.f90} (81%) delete mode 100644 src/debug.f90 delete mode 100644 src/numerics.f90 diff --git a/PRIVATE b/PRIVATE index a52584687..a16d1e45a 160000 --- a/PRIVATE +++ b/PRIVATE @@ -1 +1 @@ -Subproject commit a52584687a93b9f007cf019861fce68eb31451ab +Subproject commit a16d1e45a2ed925e12244b0879b9d7e5a58d973b diff --git a/examples/SpectralMethod/Polycrystal/material.config b/examples/SpectralMethod/Polycrystal/material.config deleted file mode 100644 index ca2824301..000000000 --- a/examples/SpectralMethod/Polycrystal/material.config +++ /dev/null @@ -1,126 +0,0 @@ -#-------------------# - -#-------------------# - -[SX] -mech none - -#-------------------# - -#-------------------# -[Aluminum_phenopowerlaw] -elasticity hooke -plasticity phenopowerlaw - -(output) resistance_slip -(output) orientation # quaternion -(output) F # deformation gradient tensor -(output) Fe # elastic deformation gradient tensor -(output) Fp # plastic deformation gradient tensor -(output) P # first Piola-Kichhoff stress tensor -(output) Lp # plastic velocity gradient tensor - - -lattice_structure fcc -Nslip 12 # per family - -c11 106.75e9 -c12 60.41e9 -c44 28.34e9 - -gdot0_slip 0.001 -n_slip 20 -tau0_slip 31e6 # per family -tausat_slip 63e6 # per family -a_slip 2.25 -h0_slipslip 75e6 -interaction_slipslip 1 1 1.4 1.4 1.4 1.4 - -#-------------------# - -#-------------------# -[Grain01] -(constituent) phase 1 texture 01 fraction 1.0 -[Grain02] -(constituent) phase 1 texture 02 fraction 1.0 -[Grain03] -(constituent) phase 1 texture 03 fraction 1.0 -[Grain04] -(constituent) phase 1 texture 04 fraction 1.0 -[Grain05] -(constituent) phase 1 texture 05 fraction 1.0 -[Grain06] -(constituent) phase 1 texture 06 fraction 1.0 -[Grain07] -(constituent) phase 1 texture 07 fraction 1.0 -[Grain08] -(constituent) phase 1 texture 08 fraction 1.0 -[Grain09] -(constituent) phase 1 texture 09 fraction 1.0 -[Grain10] -(constituent) phase 1 texture 10 fraction 1.0 -[Grain11] -(constituent) phase 1 texture 11 fraction 1.0 -[Grain12] -(constituent) phase 1 texture 12 fraction 1.0 -[Grain13] -(constituent) phase 1 texture 13 fraction 1.0 -[Grain14] -(constituent) phase 1 texture 14 fraction 1.0 -[Grain15] -(constituent) phase 1 texture 15 fraction 1.0 -[Grain16] -(constituent) phase 1 texture 16 fraction 1.0 -[Grain17] -(constituent) phase 1 texture 17 fraction 1.0 -[Grain18] -(constituent) phase 1 texture 18 fraction 1.0 -[Grain19] -(constituent) phase 1 texture 19 fraction 1.0 -[Grain20] -(constituent) phase 1 texture 20 fraction 1.0 - - -#-------------------# - -#-------------------# -[Grain01] -(gauss) phi1 0.0 Phi 0.0 phi2 0.0 -[Grain02] -(gauss) phi1 257.468172 Phi 53.250534 phi2 157.331503 -[Grain03] -(gauss) phi1 216.994815 Phi 94.418518 phi2 251.147231 -[Grain04] -(gauss) phi1 196.157946 Phi 55.870978 phi2 21.68117 -[Grain05] -(gauss) phi1 152.515728 Phi 139.769395 phi2 240.036018 -[Grain06] -(gauss) phi1 232.521881 Phi 73.749222 phi2 241.429633 -[Grain07] -(gauss) phi1 157.531396 Phi 135.503513 phi2 75.737722 -[Grain08] -(gauss) phi1 321.03828 Phi 27.209843 phi2 46.413467 -[Grain09] -(gauss) phi1 346.918594 Phi 87.495569 phi2 113.554206 -[Grain10] -(gauss) phi1 138.038947 Phi 99.827132 phi2 130.935878 -[Grain11] -(gauss) phi1 285.021014 Phi 118.092004 phi2 205.270837 -[Grain12] -(gauss) phi1 190.402171 Phi 56.738068 phi2 157.896545 -[Grain13] -(gauss) phi1 204.496042 Phi 95.031265 phi2 355.814582 -[Grain14] -(gauss) phi1 333.21479 Phi 82.133355 phi2 36.736132 -[Grain15] -(gauss) phi1 25.572981 Phi 164.242648 phi2 75.195632 -[Grain16] -(gauss) phi1 31.366548 Phi 76.392403 phi2 58.071426 -[Grain17] -(gauss) phi1 7.278623 Phi 77.044663 phi2 235.118997 -[Grain18] -(gauss) phi1 299.743144 Phi 76.475096 phi2 91.184977 -[Grain19] -(gauss) phi1 280.13643 Phi 27.439718 phi2 167.871878 -[Grain20] -(gauss) phi1 313.204373 Phi 68.676053 phi2 87.993213 diff --git a/examples/SpectralMethod/Polycrystal/material.yaml b/examples/SpectralMethod/Polycrystal/material.yaml new file mode 100644 index 000000000..16c6042a6 --- /dev/null +++ b/examples/SpectralMethod/Polycrystal/material.yaml @@ -0,0 +1,123 @@ +homogenization: + SX: + mech: {type: none} +microstructure: +- constituents: + - fraction: 1.0 + orientation: [1.0, 0.0, 0.0, 0.0] + phase: Aluminum + homogenization: SX +- constituents: + - fraction: 1.0 + orientation: [0.7936696712125002, -0.28765777461664166, -0.3436487135089419, 0.4113964260949434] + phase: Aluminum + homogenization: SX +- constituents: + - fraction: 1.0 + orientation: [0.3986143167493579, -0.7014883552495493, 0.2154871765709027, 0.5500781677772945] + phase: Aluminum + homogenization: SX +- constituents: + - fraction: 1.0 + orientation: [0.28645844315788244, -0.022571491243423537, -0.467933059311115, -0.8357456192708106] + phase: Aluminum + homogenization: SX +- constituents: + - fraction: 1.0 + orientation: [0.33012772942625784, -0.6781865350268957, 0.6494525351030648, 0.09638521992649676] + phase: Aluminum + homogenization: SX +- constituents: + - fraction: 1.0 + orientation: [0.43596817439583935, -0.5982537129781701, 0.046599032277502436, 0.6707106499919265] + phase: Aluminum + homogenization: SX +- constituents: + - fraction: 1.0 + orientation: [0.169734823419553, -0.699615227367322, -0.6059581215838098, -0.33844257746495854] + phase: Aluminum + homogenization: SX +- constituents: + - fraction: 1.0 + orientation: [0.9698864809294915, 0.1729052643205874, -0.15948307917616958, 0.06315956884687175] + phase: Aluminum + homogenization: SX +- constituents: + - fraction: 1.0 + orientation: [0.46205660912967883, 0.3105054068891252, -0.617849551030653, 0.555294529545738] + phase: Aluminum + homogenization: SX +- constituents: + - fraction: 1.0 + orientation: [0.4512443497461787, -0.7636045534540555, -0.04739348426715133, -0.45939142396805815] + phase: Aluminum + homogenization: SX +- constituents: + - fraction: 1.0 + orientation: [0.2161856212656443, -0.6581450184826598, -0.5498086209601588, 0.4667112513346289] + phase: Aluminum + homogenization: SX +- constituents: + - fraction: 1.0 + orientation: [0.8753220715350803, -0.4561599367657419, -0.13298279533852678, -0.08969369719975541] + phase: Aluminum + homogenization: SX +- constituents: + - fraction: 1.0 + orientation: [0.11908260752431069, 0.18266024809834172, -0.7144822594012615, -0.664807992845101] + phase: Aluminum + homogenization: SX +- constituents: + - fraction: 1.0 + orientation: [0.751104669484278, 0.5585633382623958, -0.34579336397009175, 0.06538900566860861] + phase: Aluminum + homogenization: SX +- constituents: + - fraction: 1.0 + orientation: [0.08740438971703973, 0.8991264096610437, -0.4156704205935976, 0.10559485570696363] + phase: Aluminum + homogenization: SX +- constituents: + - fraction: 1.0 + orientation: [0.5584325870096193, 0.6016408353068798, -0.14280340445801173, 0.5529814994483859] + phase: Aluminum + homogenization: SX +- constituents: + - fraction: 1.0 + orientation: [0.4052725440888093, 0.25253073423599154, 0.5693263597910454, -0.669215876471182] + phase: Aluminum + homogenization: SX +- constituents: + - fraction: 1.0 + orientation: [0.7570164606888676, 0.15265448024694664, -0.5998021466848317, 0.20942796551297105] + phase: Aluminum + homogenization: SX +- constituents: + - fraction: 1.0 + orientation: [0.6987659297138081, -0.132172211261028, -0.19693254724422338, 0.6748883269678543] + phase: Aluminum + homogenization: SX +- constituents: + - fraction: 1.0 + orientation: [0.7729330445886478, 0.21682179052722322, -0.5207379472917645, 0.2905078484066341] + phase: Aluminum + homogenization: SX +phase: + Aluminum: + elasticity: {C_11: 106.75e9, C_12: 60.41e9, C_44: 28.34e9, type: hooke} + generic: + output: [F, P, Fe, Fp, Lp] + lattice: fcc + plasticity: + N_sl: [12] + a_sl: 2.25 + atol_xi: 1.0 + dot_gamma_0_sl: 0.001 + h_0_sl_sl: 75e6 + h_sl_sl: [1, 1, 1.4, 1.4, 1.4, 1.4] + n_sl: 20 + output: [xi_sl] + xi_0_sl: [31e6] + xi_inf_sl: [63e6] + type: phenopowerlaw + diff --git a/src/CPFEM.f90 b/src/CPFEM.f90 index f2b906b89..8d31ea078 100644 --- a/src/CPFEM.f90 +++ b/src/CPFEM.f90 @@ -5,7 +5,6 @@ !-------------------------------------------------------------------------------------------------- module CPFEM use prec - use debug use FEsolving use math use rotations @@ -19,7 +18,6 @@ module CPFEM use IO use discretization use DAMASK_interface - use numerics use HDF5_utilities use results use lattice @@ -79,8 +77,6 @@ subroutine CPFEM_initAll call DAMASK_interface_init call prec_init call IO_init - call numerics_init - call debug_init call config_init call math_init call rotations_init @@ -95,6 +91,7 @@ subroutine CPFEM_initAll call crystallite_init call homogenization_init call CPFEM_init + call config_deallocate end subroutine CPFEM_initAll diff --git a/src/CPFEM2.f90 b/src/CPFEM2.f90 index 027c6dfad..b26ad65fd 100644 --- a/src/CPFEM2.f90 +++ b/src/CPFEM2.f90 @@ -5,8 +5,6 @@ !-------------------------------------------------------------------------------------------------- module CPFEM2 use prec - use numerics - use debug use config use FEsolving use math @@ -47,8 +45,6 @@ subroutine CPFEM_initAll #ifdef Mesh call FEM_quadrature_init #endif - call numerics_init - call debug_init call config_init call math_init call rotations_init @@ -67,6 +63,7 @@ subroutine CPFEM_initAll call crystallite_init call homogenization_init call CPFEM_init + call config_deallocate end subroutine CPFEM_initAll diff --git a/src/DAMASK_marc.f90 b/src/DAMASK_marc.f90 index 8f170f05d..78203ffa2 100644 --- a/src/DAMASK_marc.f90 +++ b/src/DAMASK_marc.f90 @@ -175,10 +175,9 @@ subroutine hypela2(d,g,e,de,s,t,dt,ngens,m,nn,kcus,matus,ndi,nshear,disp, & jtype,lclass,ifr,ifu) use prec use DAMASK_interface - use numerics + use config use YAML_types use FEsolving - use debug use discretization_marc use homogenization use CPFEM diff --git a/src/HDF5_utilities.f90 b/src/HDF5_utilities.f90 index f099b0542..0ac32fd2e 100644 --- a/src/HDF5_utilities.f90 +++ b/src/HDF5_utilities.f90 @@ -13,7 +13,7 @@ module HDF5_utilities use prec use IO use rotations - use numerics + use config implicit none public diff --git a/src/IO.f90 b/src/IO.f90 index aca887a22..d4533f47c 100644 --- a/src/IO.f90 +++ b/src/IO.f90 @@ -392,9 +392,9 @@ logical function IO_stringAsBool(string) character(len=*), intent(in) :: string !< string for conversion to int value - if (trim(adjustl(string)) == 'True') then + if (trim(adjustl(string)) == 'True' .or. trim(adjustl(string)) == 'true') then IO_stringAsBool = .true. - elseif (trim(adjustl(string)) == 'False') then + elseif (trim(adjustl(string)) == 'False' .or. trim(adjustl(string)) == 'false') then IO_stringAsBool = .false. else IO_stringAsBool = .false. @@ -568,8 +568,6 @@ subroutine IO_error(error_ID,el,ip,g,instance,ext_msg) msg = 'Incorrect indent/Null value not allowed' case (702) msg = 'Invalid use of flow yaml' - case (703) - msg = 'Space expected after a list indicator - ' case (704) msg = 'Space expected after a colon for : pair' case (705) @@ -751,9 +749,9 @@ subroutine selfTest if(-3112019 /= IO_stringAsInt('-3112019')) call IO_error(0,ext_msg='IO_stringAsInt') if(3112019 /= IO_stringAsInt('+3112019 ')) call IO_error(0,ext_msg='IO_stringAsInt') - if(.not. IO_stringAsBool(' True')) call IO_error(0,ext_msg='IO_stringAsBool') + if(.not. IO_stringAsBool(' true')) call IO_error(0,ext_msg='IO_stringAsBool') if(.not. IO_stringAsBool(' True ')) call IO_error(0,ext_msg='IO_stringAsBool') - if( IO_stringAsBool(' False')) call IO_error(0,ext_msg='IO_stringAsBool') + if( IO_stringAsBool(' false')) call IO_error(0,ext_msg='IO_stringAsBool') if( IO_stringAsBool('False')) call IO_error(0,ext_msg='IO_stringAsBool') if(any([1,1,1] /= IO_stringPos('a'))) call IO_error(0,ext_msg='IO_stringPos') diff --git a/src/YAML_parse.f90 b/src/YAML_parse.f90 index 01e383b05..88f49c060 100644 --- a/src/YAML_parse.f90 +++ b/src/YAML_parse.f90 @@ -4,19 +4,18 @@ !> @brief Parser for YAML files !> @details module converts a YAML input file to an equivalent YAML flow style which is then parsed. !---------------------------------------------------------------------------------------------------- - module YAML_parse - use prec use IO use YAML_types implicit none - private - public :: YAML_init - public :: parse_flow,to_flow + public :: & + YAML_init, & + parse_flow, & + to_flow contains @@ -34,19 +33,22 @@ end subroutine YAML_init !> @brief reads the flow style string and stores it in the form of dictionaries, lists and scalars. !> @details A node type pointer can either point to a dictionary, list or scalar type entities. !-------------------------------------------------------------------------------------------------- -recursive function parse_flow(flow_string) result(node) +recursive function parse_flow(YAML_flow) result(node) - character(len=*), intent(inout) :: flow_string !< YAML file in flow style + character(len=*), intent(in) :: YAML_flow !< YAML file in flow style class (tNode), pointer :: node - class (tNode), pointer :: myVal - character(len=pStringLen) :: key - - integer :: e, & ! end position of dictionary or list - s, & ! start position of dictionary or list - d ! position of key: value separator (':') - - flow_string = trim(adjustl(flow_string(:))) + class (tNode), pointer :: & + myVal + character(len=:), allocatable :: & + flow_string, & + key + integer :: & + e, & ! end position of dictionary or list + s, & ! start position of dictionary or list + d ! position of key: value separator (':') + + flow_string = trim(adjustl(YAML_flow(:))) if (len_trim(flow_string) == 0) then node => emptyDict return @@ -166,7 +168,12 @@ logical function isListItem(line) character(len=*), intent(in) :: line - isListItem = index(adjustl(line),'-') == 1 + isListItem = .false. + if(len_trim(adjustl(line))> 2 .and. index(trim(adjustl(line)), '-') == 1) then + isListItem = scan(trim(adjustl(line)),' ') == 2 + else + isListItem = trim(adjustl(line)) == '-' + endif end function isListItem @@ -337,7 +344,7 @@ recursive subroutine lst(blck,flow,s_blck,s_flow,offset) integer, intent(inout) :: s_blck, & !< start position in blck s_flow, & !< start position in flow offset !< stores leading '- ' in nested lists - character(len=pStringLen) :: line + character(len=:), allocatable :: line integer :: e_blck,indent indent = indentDepth(blck(s_blck:),offset) @@ -373,8 +380,6 @@ recursive subroutine lst(blck,flow,s_blck,s_flow,offset) offset = 0 endif else ! list item in the same line - if(line(indentDepth(line)+2:indentDepth(line)+2) /= ' ') & - call IO_error(703,ext_msg=line) line = line(indentDepth(line)+3:) if(isScalar(line)) then call line_toFlow(flow,s_flow,line) @@ -419,7 +424,7 @@ recursive subroutine dct(blck,flow,s_blck,s_flow,offset) s_flow, & !< start position in flow offset - character(len=pStringLen) :: line + character(len=:), allocatable :: line integer :: e_blck,indent logical :: previous_isKey @@ -490,7 +495,7 @@ recursive subroutine decide(blck,flow,s_blck,s_flow,offset) s_flow, & !< start position in flow offset integer :: e_blck - character(len=pStringLen) :: line + character(len=:), allocatable :: line if(s_blck <= len(blck)) then e_blck = s_blck + index(blck(s_blck:),IO_EOL) - 2 @@ -564,8 +569,9 @@ subroutine selfTest() if (.not. isFlow(' [')) call IO_error(0,ext_msg='isFlow') if ( isListItem(' a')) call IO_error(0,ext_msg='isListItem') + if ( isListItem(' -b')) call IO_error(0,ext_msg='isListItem') if (.not. isListItem('- a ')) call IO_error(0,ext_msg='isListItem') - if (.not. isListItem(' -b')) call IO_error(0,ext_msg='isListItem') + if (.not. isListItem('- -a ')) call IO_error(0,ext_msg='isListItem') if ( isKeyValue(' a')) call IO_error(0,ext_msg='isKeyValue') if ( isKeyValue(' a: ')) call IO_error(0,ext_msg='isKeyValue') diff --git a/src/YAML_types.f90 b/src/YAML_types.f90 index ad3db9d47..9f82e622a 100644 --- a/src/YAML_types.f90 +++ b/src/YAML_types.f90 @@ -8,12 +8,10 @@ !-------------------------------------------------------------------------------------------------- module YAML_types - use IO use prec implicit none - private type, abstract, public :: tNode @@ -74,7 +72,7 @@ module YAML_types getKey => tNode_getKey_byIndex procedure :: & contains => tNode_contains - + generic :: & get => tNode_get_byIndex, & tNode_get_byKey @@ -181,6 +179,7 @@ module YAML_types public :: & YAML_types_init, & + output_asStrings, & !ToDo: Hack for GNU. Remove later assignment(=) contains @@ -210,9 +209,9 @@ subroutine selfTest s1 = '1' if(s1%asInt() /= 1) call IO_error(0,ext_msg='tScalar_asInt') if(dNeq(s1%asFloat(),1.0_pReal)) call IO_error(0,ext_msg='tScalar_asFloat') - s1 = 'True' + s1 = 'true' if(.not. s1%asBool()) call IO_error(0,ext_msg='tScalar_asBool') - if(s1%asString() /= 'True') call IO_error(0,ext_msg='tScalar_asString') + if(s1%asString() /= 'true') call IO_error(0,ext_msg='tScalar_asString') end select block @@ -259,7 +258,7 @@ subroutine selfTest allocate(tScalar::s2) s3 => s1%asScalar() s4 => s2%asScalar() - s3 = 'True' + s3 = 'true' s4 = 'False' call l1%append(s1) @@ -267,9 +266,9 @@ subroutine selfTest n => l1 if(any(l1%asBools() .neqv. [.true., .false.])) call IO_error(0,ext_msg='tList_asBools') - if(any(l1%asStrings() /= ['True ','False'])) call IO_error(0,ext_msg='tList_asStrings') + if(any(l1%asStrings() /= ['true ','False'])) call IO_error(0,ext_msg='tList_asStrings') if(n%get_asBool(2)) call IO_error(0,ext_msg='byIndex_asBool') - if(n%get_asString(1) /= 'True') call IO_error(0,ext_msg='byIndex_asString') + if(n%get_asString(1) /= 'true') call IO_error(0,ext_msg='byIndex_asString') end block end subroutine selfTest @@ -710,7 +709,6 @@ function tNode_get_byKey_asFloat(self,k,defaultVal) result(nodeAsFloat) else call IO_error(143,ext_msg=k) endif - end function tNode_get_byKey_asFloat @@ -764,7 +762,6 @@ function tNode_get_byKey_asBool(self,k,defaultVal) result(nodeAsBool) call IO_error(143,ext_msg=k) endif - end function tNode_get_byKey_asBool @@ -791,25 +788,37 @@ function tNode_get_byKey_asString(self,k,defaultVal) result(nodeAsString) call IO_error(143,ext_msg=k) endif - end function tNode_get_byKey_asString !-------------------------------------------------------------------------------------------------- !> @brief Access by key and convert to float array !-------------------------------------------------------------------------------------------------- -function tNode_get_byKey_asFloats(self,k) result(nodeAsFloats) +function tNode_get_byKey_asFloats(self,k,defaultVal,requiredSize) result(nodeAsFloats) + + class(tNode), intent(in), target :: self + character(len=*), intent(in) :: k + real(pReal), intent(in), dimension(:), optional :: defaultVal + integer, intent(in), optional :: requiredSize - class(tNode), intent(in), target :: self - character(len=*), intent(in) :: k real(pReal), dimension(:), allocatable :: nodeAsFloats class(tNode), pointer :: node type(tList), pointer :: list - node => self%get(k) - list => node%asList() - nodeAsFloats = list%asFloats() + if(self%contains(k)) then + node => self%get(k) + list => node%asList() + nodeAsFloats = list%asFloats() + elseif(present(defaultVal)) then + nodeAsFloats = defaultVal + else + call IO_error(143,ext_msg=k) + endif + + if(present(requiredSize)) then + if(requiredSize /= size(nodeAsFloats)) call IO_error(146,ext_msg=k) + endif end function tNode_get_byKey_asFloats @@ -817,18 +826,30 @@ end function tNode_get_byKey_asFloats !-------------------------------------------------------------------------------------------------- !> @brief Access by key and convert to int array !-------------------------------------------------------------------------------------------------- -function tNode_get_byKey_asInts(self,k) result(nodeAsInts) +function tNode_get_byKey_asInts(self,k,defaultVal,requiredSize) result(nodeAsInts) - class(tNode), intent(in), target :: self - character(len=*), intent(in) :: k + class(tNode), intent(in), target :: self + character(len=*), intent(in) :: k + integer, dimension(:), intent(in), optional :: defaultVal + integer, intent(in), optional :: requiredSize integer, dimension(:), allocatable :: nodeAsInts class(tNode), pointer :: node type(tList), pointer :: list - node => self%get(k) - list => node%asList() - nodeAsInts = list%asInts() + if(self%contains(k)) then + node => self%get(k) + list => node%asList() + nodeAsInts = list%asInts() + elseif(present(defaultVal)) then + nodeAsInts = defaultVal + else + call IO_error(143,ext_msg=k) + endif + + if(present(requiredSize)) then + if(requiredSize /= size(nodeAsInts)) call IO_error(146,ext_msg=k) + endif end function tNode_get_byKey_asInts @@ -836,18 +857,25 @@ end function tNode_get_byKey_asInts !-------------------------------------------------------------------------------------------------- !> @brief Access by key and convert to bool array !-------------------------------------------------------------------------------------------------- -function tNode_get_byKey_asBools(self,k) result(nodeAsBools) +function tNode_get_byKey_asBools(self,k,defaultVal) result(nodeAsBools) - class(tNode), intent(in), target :: self - character(len=*), intent(in) :: k - logical, dimension(:), allocatable :: nodeAsBools + class(tNode), intent(in), target :: self + character(len=*), intent(in) :: k + logical, dimension(:), intent(in), optional :: defaultVal + logical, dimension(:), allocatable :: nodeAsBools class(tNode), pointer :: node type(tList), pointer :: list - node => self%get(k) - list => node%asList() - nodeAsBools = list%asBools() + if(self%contains(k)) then + node => self%get(k) + list => node%asList() + nodeAsBools = list%asBools() + elseif(present(defaultVal)) then + nodeAsBools = defaultVal + else + call IO_error(143,ext_msg=k) + endif end function tNode_get_byKey_asBools @@ -855,22 +883,50 @@ end function tNode_get_byKey_asBools !-------------------------------------------------------------------------------------------------- !> @brief Access by key and convert to string array !-------------------------------------------------------------------------------------------------- -function tNode_get_byKey_asStrings(self,k) result(nodeAsStrings) +function tNode_get_byKey_asStrings(self,k,defaultVal) result(nodeAsStrings) - class(tNode), intent(in), target :: self - character(len=*), intent(in) :: k - character(len=:), allocatable, dimension(:) :: nodeAsStrings + class(tNode), intent(in), target :: self + character(len=*), intent(in) :: k + character(len=*), intent(in), dimension(:), optional :: defaultVal + character(len=:), allocatable, dimension(:) :: nodeAsStrings class(tNode), pointer :: node type(tList), pointer :: list - node => self%get(k) - list => node%asList() - nodeAsStrings = list%asStrings() + if(self%contains(k)) then + node => self%get(k) + list => node%asList() + nodeAsStrings = list%asStrings() + elseif(present(defaultVal)) then + nodeAsStrings = defaultVal + else + call IO_error(143,ext_msg=k) + endif end function tNode_get_byKey_asStrings +!-------------------------------------------------------------------------------------------------- +!> @brief Returns string output array (hack for GNU) +!-------------------------------------------------------------------------------------------------- +function output_asStrings(self) result(output) !ToDo: SR: Remove whenever GNU works + + class(tNode), pointer,intent(in) :: self + character(len=pStringLen), allocatable, dimension(:) :: output + + class(tNode), pointer :: output_list + integer :: o + + output_list => self%get('output',defaultVal=emptyList) + allocate(output(output_list%length)) + do o = 1, output_list%length + output(o) = output_list%get_asString(o) + enddo + + +end function output_asStrings + + !-------------------------------------------------------------------------------------------------- !> @brief Returns the index of a key in a dictionary !-------------------------------------------------------------------------------------------------- diff --git a/src/commercialFEM_fileList.f90 b/src/commercialFEM_fileList.f90 index e98631fe4..0e5066268 100644 --- a/src/commercialFEM_fileList.f90 +++ b/src/commercialFEM_fileList.f90 @@ -6,9 +6,6 @@ #include "IO.f90" #include "YAML_types.f90" #include "YAML_parse.f90" -#include "numerics.f90" -#include "debug.f90" -#include "list.f90" #include "future.f90" #include "config.f90" #include "LAPACK_interface.f90" @@ -33,7 +30,7 @@ #include "constitutive_plastic_phenopowerlaw.f90" #include "constitutive_plastic_kinehardening.f90" #include "constitutive_plastic_dislotwin.f90" -#include "constitutive_plastic_disloUCLA.f90" +#include "constitutive_plastic_disloTungsten.f90" #include "constitutive_plastic_nonlocal.f90" #include "constitutive_thermal.f90" #include "source_thermal_dissipation.f90" diff --git a/src/config.f90 b/src/config.f90 index 7cc40b7b2..c6c69ed48 100644 --- a/src/config.f90 +++ b/src/config.f90 @@ -1,35 +1,36 @@ !-------------------------------------------------------------------------------------------------- !> @author Martin Diehl, Max-Planck-Institut für Eisenforschung GmbH -!> @brief Reads in the material configuration from file -!> @details Reads the material configuration file, where solverJobName.materialConfig takes -!! precedence over material.config. Stores the raw strings and the positions of delimiters for the -!! parts 'homogenization', 'crystallite', 'phase', 'texture', and 'microstucture' +!> @brief Reads in the material, numerics & debug configuration from their respective file +!> @details Reads the material configuration file, where solverJobName.yaml takes +!! precedence over material.yaml. !-------------------------------------------------------------------------------------------------- module config use prec use DAMASK_interface use IO - use debug - use list use YAML_parse use YAML_types +#ifdef PETSc +#include + use petscsys +#endif +!$ use OMP_LIB + implicit none private - type(tPartitionedStringList), public, protected, allocatable, dimension(:) :: & - config_phase, & - config_microstructure, & - config_homogenization, & - config_texture, & - config_crystallite + class(tNode), pointer, public :: & + material_root, & + numerics_root, & + debug_root + + integer, protected, public :: & + worldrank = 0, & !< MPI worldrank (/=0 for MPI simulations only) + worldsize = 1 !< MPI worldsize (/=1 for MPI simulations only) + integer(4), protected, public :: & + DAMASK_NumThreadsInt = 0 !< value stored in environment variable DAMASK_NUM_THREADS, set to zero if no OpenMP directive - character(len=pStringLen), public, protected, allocatable, dimension(:) :: & - config_name_phase, & !< name of each phase - config_name_homogenization, & !< name of each homogenization - config_name_crystallite, & !< name of each crystallite setting - config_name_microstructure, & !< name of each microstructure - config_name_texture !< name of each texture public :: & config_init, & @@ -38,227 +39,117 @@ module config contains !-------------------------------------------------------------------------------------------------- -!> @brief reads material.config and stores its content per part +!> @brief calls subroutines that reads material, numerics and debug configuration files !-------------------------------------------------------------------------------------------------- subroutine config_init - integer :: i - logical :: verbose - - character(len=pStringLen) :: & - line, & - part - character(len=pStringLen), dimension(:), allocatable :: fileContent - class(tNode), pointer :: & - debug_material - logical :: fileExists - write(6,'(/,a)') ' <<<+- config init -+>>>'; flush(6) - - debug_material => debug_root%get('material',defaultVal=emptyList) - verbose = debug_material%contains('basic') - - inquire(file=trim(getSolverJobName())//'.materialConfig',exist=fileExists) - if(fileExists) then - write(6,'(/,a)') ' reading '//trim(getSolverJobName())//'.materialConfig'; flush(6) - fileContent = read_materialConfig(trim(getSolverJobName())//'.materialConfig') - else - inquire(file='material.config',exist=fileExists) - if(.not. fileExists) call IO_error(100,ext_msg='material.config') - write(6,'(/,a)') ' reading material.config'; flush(6) - fileContent = read_materialConfig('material.config') - endif - - do i = 1, size(fileContent) - line = trim(fileContent(i)) - part = IO_lc(IO_getTag(line,'<','>')) - select case (trim(part)) - - case (trim('phase')) - call parse_materialConfig(config_name_phase,config_phase,line,fileContent(i+1:)) - if (verbose) write(6,'(a)') ' Phase parsed'; flush(6) - - case (trim('microstructure')) - call parse_materialConfig(config_name_microstructure,config_microstructure,line,fileContent(i+1:)) - if (verbose) write(6,'(a)') ' Microstructure parsed'; flush(6) - - case (trim('crystallite')) - call parse_materialConfig(config_name_crystallite,config_crystallite,line,fileContent(i+1:)) - if (verbose) write(6,'(a)') ' Crystallite parsed'; flush(6) - deallocate(config_crystallite) - - case (trim('homogenization')) - call parse_materialConfig(config_name_homogenization,config_homogenization,line,fileContent(i+1:)) - if (verbose) write(6,'(a)') ' Homogenization parsed'; flush(6) - - case (trim('texture')) - call parse_materialConfig(config_name_texture,config_texture,line,fileContent(i+1:)) - if (verbose) write(6,'(a)') ' Texture parsed'; flush(6) - - end select - - enddo - - if (.not. allocated(config_homogenization) .or. size(config_homogenization) < 1) & - call IO_error(160,ext_msg='') - if (.not. allocated(config_microstructure) .or. size(config_microstructure) < 1) & - call IO_error(160,ext_msg='') - if (.not. allocated(config_phase) .or. size(config_phase) < 1) & - call IO_error(160,ext_msg='') - if (.not. allocated(config_texture) .or. size(config_texture) < 1) & - call IO_error(160,ext_msg='') - - -contains - - -!-------------------------------------------------------------------------------------------------- -!> @brief reads material.config -!! Recursion is triggered by "{path/to/inputfile}" in a line -!-------------------------------------------------------------------------------------------------- -recursive function read_materialConfig(fileName,cnt) result(fileContent) - - character(len=*), intent(in) :: fileName !< name of the material configuration file - integer, intent(in), optional :: cnt !< recursion counter - character(len=pStringLen), dimension(:), allocatable :: fileContent !< file content, separated per lines - character(len=pStringLen), dimension(:), allocatable :: includedContent - character(len=pStringLen) :: line - character(len=pStringLen), parameter :: dummy = 'https://damask.mpie.de' !< to fill up remaining array - character(len=:), allocatable :: rawData - integer :: & - startPos, endPos, & - myTotalLines, & !< # lines read from file without include statements - l,i - logical :: warned - if (present(cnt)) then - if (cnt>10) call IO_error(106,ext_msg=trim(fileName)) - endif - - rawData = IO_read(fileName) ! read data as stream - -!-------------------------------------------------------------------------------------------------- -! count lines to allocate string array - myTotalLines = 1 - do l=1, len(rawData) - if (rawData(l:l) == IO_EOL) myTotalLines = myTotalLines+1 - enddo - allocate(fileContent(myTotalLines)) - -!-------------------------------------------------------------------------------------------------- -! split raw data at end of line and handle includes - warned = .false. - startPos = 1 - l = 1 - do while (l <= myTotalLines) - endPos = merge(startPos + scan(rawData(startPos:),IO_EOL) - 2,len(rawData),l /= myTotalLines) - if (endPos - startPos > pStringLen -1) then - line = rawData(startPos:startPos+pStringLen-1) - if (.not. warned) then - call IO_warning(207,ext_msg=trim(fileName),el=l) - warned = .true. - endif - else - line = rawData(startPos:endpos) - endif - startPos = endPos + 2 ! jump to next line start - - recursion: if (scan(trim(adjustl(line)),'{') == 1 .and. scan(trim(line),'}') > 2) then - includedContent = read_materialConfig(trim(line(scan(line,'{')+1:scan(line,'}')-1)), & - merge(cnt,1,present(cnt))) ! to track recursion depth - fileContent = [ fileContent(1:l-1), includedContent, [(dummy,i=1,myTotalLines-l)] ] ! add content and grow array - myTotalLines = myTotalLines - 1 + size(includedContent) - l = l - 1 + size(includedContent) - else recursion - fileContent(l) = line - l = l + 1 - endif recursion - - enddo - -end function read_materialConfig - - -!-------------------------------------------------------------------------------------------------- -!> @brief parses the material.config file -!-------------------------------------------------------------------------------------------------- -subroutine parse_materialConfig(sectionNames,part,line, & - fileContent) - - character(len=pStringLen), allocatable, dimension(:), intent(out) :: sectionNames - type(tPartitionedStringList), allocatable, dimension(:), intent(inout) :: part - character(len=pStringLen), intent(inout) :: line - character(len=pStringLen), dimension(:), intent(in) :: fileContent - - integer, allocatable, dimension(:) :: partPosition !< position of [] tags + last line in section - integer :: i, j - logical :: echo - character(len=pStringLen) :: sectionName - - echo = .false. - - if (allocated(part)) call IO_error(161,ext_msg=trim(line)) - allocate(partPosition(0)) - - do i = 1, size(fileContent) - line = trim(fileContent(i)) - if (IO_getTag(line,'<','>') /= '') exit - nextSection: if (IO_getTag(line,'[',']') /= '') then - partPosition = [partPosition, i] - cycle - endif nextSection - if (size(partPosition) < 1) & - echo = (trim(IO_getTag(line,'/','/')) == 'echo') .or. echo - enddo - - allocate(sectionNames(size(partPosition))) - allocate(part(size(partPosition))) - - partPosition = [partPosition, i] ! needed when actually storing content - - do i = 1, size(partPosition) -1 - write(sectionName,'(i0,a,a)') i,'_',trim(IO_getTag(fileContent(partPosition(i)),'[',']')) - sectionNames(i) = sectionName - do j = partPosition(i) + 1, partPosition(i+1) -1 - call part(i)%add(trim(adjustl(fileContent(j)))) - enddo - if (echo) then - write(6,*) 'section',i, '"'//trim(sectionNames(i))//'"' - call part(i)%show() - endif - enddo - -end subroutine parse_materialConfig + call parse_material + call parse_numerics + call parse_debug + end subroutine config_init !-------------------------------------------------------------------------------------------------- -!> @brief deallocates the linked lists that store the content of the configuration files +!> @brief reads material.yaml !-------------------------------------------------------------------------------------------------- -subroutine config_deallocate(what) +subroutine parse_material - character(len=*), intent(in) :: what + logical :: fileExists + character(len=:), allocatable :: fname,flow - select case(trim(what)) + fname = getSolverJobName()//'.yaml' + inquire(file=fname,exist=fileExists) + if(.not. fileExists) then + fname = 'material.yaml' + inquire(file=fname,exist=fileExists) + if(.not. fileExists) call IO_error(100,ext_msg=fname) + endif - case('material.config/phase') - deallocate(config_phase) + write(6,'(/,a)') ' reading '//fname; flush(6) + flow = to_flow(IO_read(fname)) + material_root => parse_flow(flow) - case('material.config/microstructure') - deallocate(config_microstructure) +end subroutine parse_material - case('material.config/homogenization') - deallocate(config_homogenization) - case('material.config/texture') - deallocate(config_texture) - - case default - call IO_error(0,ext_msg='config_deallocate') +!-------------------------------------------------------------------------------------------------- +!> @brief reads in parameters from numerics.yaml and sets openMP related parameters. Also does +! a sanity check +!-------------------------------------------------------------------------------------------------- +subroutine parse_numerics - end select +!$ integer :: gotDAMASK_NUM_THREADS = 1 + integer :: ierr + character(len=:), allocatable :: & + numerics_inFlow + logical :: fexist +!$ character(len=6) DAMASK_NumThreadsString ! environment variable DAMASK_NUM_THREADS +#ifdef PETSc + call MPI_Comm_rank(PETSC_COMM_WORLD,worldrank,ierr);CHKERRQ(ierr) + call MPI_Comm_size(PETSC_COMM_WORLD,worldsize,ierr);CHKERRQ(ierr) +#endif + +!$ call GET_ENVIRONMENT_VARIABLE(NAME='DAMASK_NUM_THREADS',VALUE=DAMASK_NumThreadsString,STATUS=gotDAMASK_NUM_THREADS) ! get environment variable DAMASK_NUM_THREADS... +!$ if(gotDAMASK_NUM_THREADS /= 0) then ! could not get number of threads, set it to 1 +!$ call IO_warning(35,ext_msg='BEGIN:'//DAMASK_NumThreadsString//':END') +!$ DAMASK_NumThreadsInt = 1_4 +!$ else +!$ read(DAMASK_NumThreadsString,'(i6)') DAMASK_NumThreadsInt ! read as integer +!$ if (DAMASK_NumThreadsInt < 1_4) DAMASK_NumThreadsInt = 1_4 ! in case of string conversion fails, set it to one +!$ endif +!$ call omp_set_num_threads(DAMASK_NumThreadsInt) ! set number of threads for parallel execution + + numerics_root => emptyDict + inquire(file='numerics.yaml', exist=fexist) + + if (fexist) then + write(6,'(a,/)') ' using values from config.yaml file' + flush(6) + numerics_inFlow = to_flow(IO_read('numerics.yaml')) + numerics_root => parse_flow(numerics_inFlow) + endif + +!-------------------------------------------------------------------------------------------------- +! openMP parameter + !$ write(6,'(a24,1x,i8,/)') ' number of threads: ',DAMASK_NumThreadsInt + +end subroutine parse_numerics + + +!-------------------------------------------------------------------------------------------------- +!> @brief reads in parameters from debug.yaml +!-------------------------------------------------------------------------------------------------- +subroutine parse_debug + + character(len=:), allocatable :: debug_inFlow + logical :: fexist + +#ifdef DEBUG + write(6,'(a)') achar(27)//'[31m <<<+- DEBUG version -+>>>'//achar(27)//'[0m' +#endif + + debug_root => emptyDict + inquire(file='debug.yaml', exist=fexist) + fileExists: if (fexist) then + debug_inFlow = to_flow(IO_read('debug.yaml')) + debug_root => parse_flow(debug_inFlow) + endif fileExists + +end subroutine parse_debug + + +!-------------------------------------------------------------------------------------------------- +!> @brief deallocates material.yaml structure +!-------------------------------------------------------------------------------------------------- +subroutine config_deallocate + + deallocate(material_root) !ToDo: deallocation of numerics and debug (slightly different for optional files) + end subroutine config_deallocate end module config diff --git a/src/constitutive.f90 b/src/constitutive.f90 index feff4af86..4ecae8e01 100644 --- a/src/constitutive.f90 +++ b/src/constitutive.f90 @@ -7,8 +7,6 @@ module constitutive use prec use math use rotations - use debug - use numerics use IO use config use material @@ -21,6 +19,33 @@ module constitutive implicit none private + integer(kind(ELASTICITY_undefined_ID)), dimension(:), allocatable, protected :: & + phase_elasticity !< elasticity of each phase + + integer(kind(PLASTICITY_undefined_ID)), dimension(:), allocatable :: & !ToDo: old intel compiler complains about protected + phase_plasticity !< plasticity of each phase + + integer(kind(SOURCE_undefined_ID)), dimension(:,:), allocatable :: & ! ToDo: old intel compiler complains about protected + 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 + + integer, dimension(:), allocatable, public :: & ! ToDo: old intel compiler complains about protected + 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 + phase_localPlasticity !< flags phases with local constitutive law + + type(tPlasticState), allocatable, dimension(:), public :: & + plasticState + type(tSourceState), allocatable, dimension(:), public :: & + sourceState + + integer, public, protected :: & constitutive_plasticity_maxSizeDotState, & constitutive_source_maxSizeDotState @@ -37,6 +62,23 @@ module constitutive end subroutine thermal_init + 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 + 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 plastic_isotropic_dotState(Mp,instance,of) real(pReal), dimension(3,3), intent(in) :: & Mp !< Mandel stress @@ -71,7 +113,7 @@ module constitutive of end subroutine plastic_dislotwin_dotState - module subroutine plastic_disloUCLA_dotState(Mp,T,instance,of) + module subroutine plastic_disloTungsten_dotState(Mp,T,instance,of) real(pReal), dimension(3,3), intent(in) :: & Mp !< Mandel stress real(pReal), intent(in) :: & @@ -79,7 +121,7 @@ module constitutive integer, intent(in) :: & instance, & of - end subroutine plastic_disloUCLA_dotState + end subroutine plastic_disloTungsten_dotState module subroutine plastic_nonlocal_dotState(Mp, F, Fp, Temperature,timestep, & instance,of,ip,el) @@ -286,7 +328,6 @@ module constitutive end subroutine constitutive_plastic_LpAndItsTangents end interface constitutive_LpAndItsTangents - interface constitutive_dependentState @@ -326,11 +367,14 @@ module constitutive constitutive_SandItsTangents, & constitutive_collectDotState, & constitutive_deltaState, & - plastic_nonlocal_updateCompatibility, & constitutive_damage_getRateAndItsTangents, & constitutive_thermal_getRateAndItsTangents, & - constitutive_results - + constitutive_results, & + constitutive_allocateState, & + plastic_nonlocal_updateCompatibility, & + plastic_active, & + source_active, & + kinematics_active contains @@ -340,10 +384,15 @@ contains subroutine constitutive_init integer :: & - ph, & !< counter in phase loop - s !< counter in source loop + p, & !< counter in phase loop + s, & !< counter in source loop + stiffDegradationCtr class (tNode), pointer :: & - debug_constitutive + debug_constitutive, & + phases, & + phase, & + elastic, & + stiffDegradation debug_constitutive => debug_root%get('constitutive', defaultVal=emptyList) debugConstitutive%basic = debug_constitutive%contains('basic') @@ -353,7 +402,46 @@ subroutine constitutive_init debugConstitutive%ip = debug_root%get_asInt('integrationpoint',defaultVal = 1) debugConstitutive%grain = debug_root%get_asInt('grain',defaultVal = 1) +!------------------------------------------------------------------------------------------------- +! initialize elasticity (hooke) !ToDO: Maybe move to elastic submodule along with function homogenizedC? + phases => material_root%get('phase') + allocate(phase_elasticity(phases%length), source = ELASTICITY_undefined_ID) + allocate(phase_elasticityInstance(phases%length), source = 0) + allocate(phase_NstiffnessDegradations(phases%length),source=0) + do p = 1, phases%length + phase => phases%get(p) + elastic => phase%get('elasticity') + if(elastic%get_asString('type') == 'hooke') then + phase_elasticity(p) = ELASTICITY_HOOKE_ID + else + call IO_error(200,ext_msg=elastic%get_asString('type')) + endif + stiffDegradation => phase%get('stiffness_degradation',defaultVal=emptyList) ! check for stiffness degradation mechanisms + phase_NstiffnessDegradations(p) = 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) + stiffDegradation => phase%get('stiffness_degradation',defaultVal=emptyList) + do stiffDegradationCtr = 1, stiffDegradation%length + if(stiffDegradation%get_asString(stiffDegradationCtr) == 'damage') & + phase_stiffnessDegradation(stiffDegradationCtr,p) = STIFFNESS_DEGRADATION_damage_ID + enddo + enddo + endif + + do p = 1, phases%length + phase_elasticityInstance(p) = count(phase_elasticity(1:p) == phase_elasticity(p)) + enddo + + +!-------------------------------------------------------------------------------------------------- +! initialize constitutive laws call plastic_init call damage_init call thermal_init @@ -361,23 +449,87 @@ subroutine constitutive_init write(6,'(/,a)') ' <<<+- constitutive init -+>>>'; flush(6) constitutive_source_maxSizeDotState = 0 - PhaseLoop2:do ph = 1,material_Nphase + PhaseLoop2:do p = 1,phases%length !-------------------------------------------------------------------------------------------------- ! partition and initialize state - plasticState(ph)%partionedState0 = plasticState(ph)%state0 - plasticState(ph)%state = plasticState(ph)%partionedState0 - forall(s = 1:phase_Nsources(ph)) - sourceState(ph)%p(s)%partionedState0 = sourceState(ph)%p(s)%state0 - sourceState(ph)%p(s)%state = sourceState(ph)%p(s)%partionedState0 + plasticState(p)%partionedState0 = plasticState(p)%state0 + plasticState(p)%state = plasticState(p)%partionedState0 + forall(s = 1:phase_Nsources(p)) + sourceState(p)%p(s)%partionedState0 = sourceState(p)%p(s)%state0 + sourceState(p)%p(s)%state = sourceState(p)%p(s)%partionedState0 end forall constitutive_source_maxSizeDotState = max(constitutive_source_maxSizeDotState, & - maxval(sourceState(ph)%p%sizeDotState)) + maxval(sourceState(p)%p%sizeDotState)) enddo PhaseLoop2 constitutive_plasticity_maxSizeDotState = maxval(plasticState%sizeDotState) 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) + + character(len=*), intent(in) :: source_label !< name of source mechanism + integer, intent(in) :: src_length !< max. number of sources in system + logical, dimension(:,:), allocatable :: active_source + + class(tNode), pointer :: & + phases, & + phase, & + sources, & + src + integer :: p,s + + phases => material_root%get('phase') + allocate(active_source(src_length,phases%length), source = .false. ) + do p = 1, phases%length + phase => phases%get(p) + sources => phase%get('source',defaultVal=emptyList) + do s = 1, sources%length + src => sources%get(s) + if(src%get_asString('type') == source_label) active_source(s,p) = .true. + enddo + enddo + + +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) + + character(len=*), intent(in) :: kinematics_label !< name of kinematic mechanism + integer, intent(in) :: kinematics_length !< max. number of kinematics in system + logical, dimension(:,:), allocatable :: active_kinematics + + class(tNode), pointer :: & + phases, & + phase, & + kinematics, & + kinematics_type + integer :: p,k + + phases => material_root%get('phase') + allocate(active_kinematics(kinematics_length,phases%length), source = .false. ) + do p = 1, phases%length + phase => phases%get(p) + kinematics => phase%get('kinematics',defaultVal=emptyList) + do k = 1, kinematics%length + kinematics_type => kinematics%get(k) + if(kinematics_type%get_asString('type') == kinematics_label) active_kinematics(k,p) = .true. + enddo + enddo + + +end function kinematics_active + + !-------------------------------------------------------------------------------------------------- !> @brief returns the homogenize elasticity matrix !> ToDo: homogenizedC66 would be more consistent @@ -626,7 +778,7 @@ function constitutive_collectDotState(S, FArray, Fi, FpArray, subdt, ipc, ip, el plasticityType: select case (phase_plasticity(phase)) case (PLASTICITY_ISOTROPIC_ID) plasticityType - call plastic_isotropic_dotState (Mp,instance,of) + call plastic_isotropic_dotState(Mp,instance,of) case (PLASTICITY_PHENOPOWERLAW_ID) plasticityType call plastic_phenopowerlaw_dotState(Mp,instance,of) @@ -635,13 +787,13 @@ function constitutive_collectDotState(S, FArray, Fi, FpArray, subdt, ipc, ip, el call plastic_kinehardening_dotState(Mp,instance,of) case (PLASTICITY_DISLOTWIN_ID) plasticityType - call plastic_dislotwin_dotState (Mp,temperature(ho)%p(tme),instance,of) + call plastic_dislotwin_dotState(Mp,temperature(ho)%p(tme),instance,of) - case (PLASTICITY_DISLOUCLA_ID) plasticityType - call plastic_disloucla_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, & + 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))) @@ -651,13 +803,13 @@ function constitutive_collectDotState(S, FArray, Fi, FpArray, subdt, ipc, ip, el 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, ipc, ip, el) ! correct stress? case (SOURCE_damage_isoDuctile_ID) sourceType - call source_damage_isoDuctile_dotState ( ipc, ip, el) + call source_damage_isoDuctile_dotState(ipc, ip, el) case (SOURCE_damage_anisoDuctile_ID) sourceType - call source_damage_anisoDuctile_dotState ( ipc, ip, el) + call source_damage_anisoDuctile_dotState(ipc, ip, el) case (SOURCE_thermal_externalheat_ID) sourceType call source_thermal_externalheat_dotState(phase,of) @@ -749,6 +901,39 @@ function constitutive_deltaState(S, Fe, Fi, ipc, ip, el, phase, of) result(broke end function constitutive_deltaState +!-------------------------------------------------------------------------------------------------- +!> @brief Allocate the components of the state structure for a given phase +!-------------------------------------------------------------------------------------------------- +subroutine constitutive_allocateState(state, & + NipcMyPhase,sizeState,sizeDotState,sizeDeltaState) + + class(tState), intent(out) :: & + state + integer, intent(in) :: & + NipcMyPhase, & + sizeState, & + 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,NipcMyPhase), source=0.0_pReal) + allocate(state%partionedState0(sizeState,NipcMyPhase), source=0.0_pReal) + allocate(state%subState0 (sizeState,NipcMyPhase), source=0.0_pReal) + allocate(state%state (sizeState,NipcMyPhase), source=0.0_pReal) + + allocate(state%dotState (sizeDotState,NipcMyPhase), source=0.0_pReal) + + allocate(state%deltaState(sizeDeltaState,NipcMyPhase), source=0.0_pReal) + + +end subroutine constitutive_allocateState + + !-------------------------------------------------------------------------------------------------- !> @brief writes constitutive results to HDF5 output file !-------------------------------------------------------------------------------------------------- @@ -759,4 +944,5 @@ subroutine constitutive_results end subroutine constitutive_results + end module constitutive diff --git a/src/constitutive_damage.f90 b/src/constitutive_damage.f90 index 9e0c686b0..83b2c2384 100644 --- a/src/constitutive_damage.f90 +++ b/src/constitutive_damage.f90 @@ -5,23 +5,35 @@ submodule(constitutive) constitutive_damage interface - module subroutine source_damage_anisoBrittle_init - end subroutine source_damage_anisoBrittle_init + 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 - module subroutine source_damage_anisoDuctile_init - end subroutine source_damage_anisoDuctile_init + module function source_damage_anisoDuctile_init(source_length) result(mySources) + integer, intent(in) :: source_length + logical, dimension(:,:), allocatable :: mySources + end function source_damage_anisoDuctile_init - module subroutine source_damage_isoBrittle_init - end subroutine source_damage_isoBrittle_init + module function source_damage_isoBrittle_init(source_length) result(mySources) + integer, intent(in) :: source_length + logical, dimension(:,:), allocatable :: mySources + end function source_damage_isoBrittle_init - module subroutine source_damage_isoDuctile_init - end subroutine source_damage_isoDuctile_init + 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 - module subroutine kinematics_cleavage_opening_init - end subroutine kinematics_cleavage_opening_init + module function kinematics_cleavage_opening_init(kinematics_length) result(myKinematics) + integer, intent(in) :: kinematics_length + logical, dimension(:,:), allocatable :: myKinematics + end function kinematics_cleavage_opening_init - module subroutine kinematics_slipplane_opening_init - end subroutine kinematics_slipplane_opening_init + module function kinematics_slipplane_opening_init(kinematics_length) result(myKinematics) + integer, intent(in) :: kinematics_length + logical, dimension(:,:), allocatable :: myKinematics + end function kinematics_slipplane_opening_init module subroutine source_damage_anisobrittle_getRateAndItsTangent(localphiDot, dLocalphiDot_dPhi, phi, phase, constituent) @@ -97,16 +109,51 @@ contains !---------------------------------------------------------------------------------------------- module subroutine damage_init + integer :: & + ph !< counter in phase loop + class(tNode), pointer :: & + phases, & + phase, & + sources, & + kinematics + + phases => material_root%get('phase') + + allocate(sourceState (phases%length)) + allocate(phase_Nsources(phases%length),source = 0) ! same for kinematics + + do ph = 1,phases%length + phase => phases%get(ph) + sources => phase%get('source',defaultVal=emptyList) + phase_Nsources(ph) = sources%length + allocate(sourceState(ph)%p(phase_Nsources(ph))) + enddo + + allocate(phase_source(maxval(phase_Nsources),phases%length), source = SOURCE_undefined_ID) + ! initialize source mechanisms - if (any(phase_source == SOURCE_damage_isoBrittle_ID)) call source_damage_isoBrittle_init - if (any(phase_source == SOURCE_damage_isoDuctile_ID)) call source_damage_isoDuctile_init - if (any(phase_source == SOURCE_damage_anisoBrittle_ID)) call source_damage_anisoBrittle_init - if (any(phase_source == SOURCE_damage_anisoDuctile_ID)) call source_damage_anisoDuctile_init + if(maxval(phase_Nsources) /= 0) then + where(source_damage_isoBrittle_init (maxval(phase_Nsources))) phase_source = SOURCE_damage_isoBrittle_ID + where(source_damage_isoDuctile_init (maxval(phase_Nsources))) phase_source = SOURCE_damage_isoDuctile_ID + where(source_damage_anisoBrittle_init (maxval(phase_Nsources))) phase_source = SOURCE_damage_anisoBrittle_ID + where(source_damage_anisoDuctile_init (maxval(phase_Nsources))) phase_source = SOURCE_damage_anisoDuctile_ID + endif !-------------------------------------------------------------------------------------------------- ! initialize kinematic mechanisms - if (any(phase_kinematics == KINEMATICS_cleavage_opening_ID)) call kinematics_cleavage_opening_init - if (any(phase_kinematics == KINEMATICS_slipplane_opening_ID)) call kinematics_slipplane_opening_init + allocate(phase_Nkinematics(phases%length),source = 0) + do ph = 1,phases%length + phase => phases%get(ph) + kinematics => phase%get('kinematics',defaultVal=emptyList) + phase_Nkinematics(ph) = kinematics%length + enddo + + allocate(phase_kinematics(maxval(phase_Nkinematics),phases%length), source = KINEMATICS_undefined_ID) + + if(maxval(phase_Nkinematics) /= 0) then + where(kinematics_cleavage_opening_init(maxval(phase_Nkinematics))) phase_kinematics = KINEMATICS_cleavage_opening_ID + where(kinematics_slipplane_opening_init(maxval(phase_Nkinematics))) phase_kinematics = KINEMATICS_slipplane_opening_ID + endif end subroutine damage_init @@ -168,16 +215,17 @@ end subroutine constitutive_damage_getRateAndItsTangents !---------------------------------------------------------------------------------------------- -!< @brief writes damage sources resultsvto HDF5 output file +!< @brief writes damage sources results to HDF5 output file !---------------------------------------------------------------------------------------------- module subroutine damage_results integer :: p,i character(len=pStringLen) :: group - do p = 1, size(config_name_phase) + do p = 1, size(material_name_phase) + sourceLoop: do i = 1, phase_Nsources(p) - group = trim('current/constituent')//'/'//trim(config_name_phase(p)) + group = trim('current/constituent')//'/'//trim(material_name_phase(p)) group = trim(group)//'/sources' call results_closeGroup(results_addGroup(group)) diff --git a/src/constitutive_plastic.f90 b/src/constitutive_plastic.f90 index f7b1569d2..628a98d1a 100644 --- a/src/constitutive_plastic.f90 +++ b/src/constitutive_plastic.f90 @@ -5,26 +5,40 @@ submodule(constitutive) constitutive_plastic interface - module subroutine plastic_none_init - end subroutine plastic_none_init + module function plastic_none_init() result(myPlasticity) + logical, dimension(:), allocatable :: & + myPlasticity + end function plastic_none_init - module subroutine plastic_isotropic_init - end subroutine plastic_isotropic_init + module function plastic_isotropic_init() result(myPlasticity) + logical, dimension(:), allocatable :: & + myPlasticity + end function plastic_isotropic_init - module subroutine plastic_phenopowerlaw_init - end subroutine plastic_phenopowerlaw_init + module function plastic_phenopowerlaw_init() result(myPlasticity) + logical, dimension(:), allocatable :: & + myPlasticity + end function plastic_phenopowerlaw_init - module subroutine plastic_kinehardening_init - end subroutine plastic_kinehardening_init + module function plastic_kinehardening_init() result(myPlasticity) + logical, dimension(:), allocatable :: & + myPlasticity + end function plastic_kinehardening_init - module subroutine plastic_dislotwin_init - end subroutine plastic_dislotwin_init + module function plastic_dislotwin_init() result(myPlasticity) + logical, dimension(:), allocatable :: & + myPlasticity + end function plastic_dislotwin_init - module subroutine plastic_disloUCLA_init - end subroutine plastic_disloUCLA_init + module function plastic_disloTungsten_init() result(myPlasticity) + logical, dimension(:), allocatable :: & + myPlasticity + end function plastic_disloTungsten_init - module subroutine plastic_nonlocal_init - end subroutine plastic_nonlocal_init + module function plastic_nonlocal_init() result(myPlasticity) + logical, dimension(:), allocatable :: & + myPlasticity + end function plastic_nonlocal_init module subroutine plastic_isotropic_LpAndItsTangent(Lp,dLp_dMp,Mp,instance,of) @@ -80,7 +94,7 @@ submodule(constitutive) constitutive_plastic of end subroutine plastic_dislotwin_LpAndItsTangent - pure module subroutine plastic_disloUCLA_LpAndItsTangent(Lp,dLp_dMp,Mp,T,instance,of) + pure module subroutine plastic_disloTungsten_LpAndItsTangent(Lp,dLp_dMp,Mp,T,instance,of) real(pReal), dimension(3,3), intent(out) :: & Lp !< plastic velocity gradient real(pReal), dimension(3,3,3,3), intent(out) :: & @@ -93,7 +107,7 @@ submodule(constitutive) constitutive_plastic integer, intent(in) :: & instance, & of - end subroutine plastic_disloUCLA_LpAndItsTangent + end subroutine plastic_disloTungsten_LpAndItsTangent module subroutine plastic_nonlocal_LpAndItsTangent(Lp,dLp_dMp, & Mp,Temperature,instance,of,ip,el) @@ -122,11 +136,11 @@ submodule(constitutive) constitutive_plastic T end subroutine plastic_dislotwin_dependentState - module subroutine plastic_disloUCLA_dependentState(instance,of) + module subroutine plastic_disloTungsten_dependentState(instance,of) integer, intent(in) :: & instance, & of - end subroutine plastic_disloUCLA_dependentState + end subroutine plastic_disloTungsten_dependentState module subroutine plastic_nonlocal_dependentState(F, Fp, instance, of, ip, el) real(pReal), dimension(3,3), intent(in) :: & @@ -159,10 +173,10 @@ submodule(constitutive) constitutive_plastic character(len=*), intent(in) :: group end subroutine plastic_dislotwin_results - module subroutine plastic_disloUCLA_results(instance,group) + module subroutine plastic_disloTungsten_results(instance,group) integer, intent(in) :: instance character(len=*), intent(in) :: group - end subroutine plastic_disloUCLA_results + end subroutine plastic_disloTungsten_results module subroutine plastic_nonlocal_results(instance,group) integer, intent(in) :: instance @@ -181,21 +195,57 @@ contains !-------------------------------------------------------------------------------------------------- module subroutine plastic_init - if (any(phase_plasticity == PLASTICITY_NONE_ID)) call plastic_none_init - if (any(phase_plasticity == PLASTICITY_ISOTROPIC_ID)) call plastic_isotropic_init - if (any(phase_plasticity == PLASTICITY_PHENOPOWERLAW_ID)) call plastic_phenopowerlaw_init - if (any(phase_plasticity == PLASTICITY_KINEHARDENING_ID)) call plastic_kinehardening_init - if (any(phase_plasticity == PLASTICITY_DISLOTWIN_ID)) call plastic_dislotwin_init - if (any(phase_plasticity == PLASTICITY_DISLOUCLA_ID)) call plastic_disloucla_init - if (any(phase_plasticity == PLASTICITY_NONLOCAL_ID)) then - call plastic_nonlocal_init - else - call geometry_plastic_nonlocal_disable - endif + integer :: p + class(tNode), pointer :: phases + + phases => material_root%get('phase') + + allocate(plasticState(phases%length)) + allocate(phase_plasticity(phases%length),source = PLASTICITY_undefined_ID) + allocate(phase_plasticityInstance(phases%length),source = 0) + allocate(phase_localPlasticity(phases%length), source=.true.) + + where(plastic_none_init()) phase_plasticity = PLASTICITY_NONE_ID + where(plastic_isotropic_init()) phase_plasticity = PLASTICITY_ISOTROPIC_ID + where(plastic_phenopowerlaw_init()) phase_plasticity = PLASTICITY_PHENOPOWERLAW_ID + where(plastic_kinehardening_init()) phase_plasticity = PLASTICITY_KINEHARDENING_ID + where(plastic_dislotwin_init()) phase_plasticity = PLASTICITY_DISLOTWIN_ID + where(plastic_disloTungsten_init()) phase_plasticity = PLASTICITY_DISLOTUNGSTEN_ID + where(plastic_nonlocal_init()) phase_plasticity = PLASTICITY_NONLOCAL_ID + + do p = 1, phases%length + phase_plasticityInstance(p) = count(phase_plasticity(1:p) == phase_plasticity(p)) + enddo + end subroutine plastic_init +!-------------------------------------------------------------------------------------------------- +!> @brief checks if a plastic module is active or not +!-------------------------------------------------------------------------------------------------- +module function plastic_active(plastic_label) result(active_plastic) + + character(len=*), intent(in) :: plastic_label !< type of plasticity model + logical, dimension(:), allocatable :: active_plastic + + class(tNode), pointer :: & + phases, & + phase, & + pl + integer :: p + + phases => material_root%get('phase') + allocate(active_plastic(phases%length), source = .false. ) + do p = 1, phases%length + phase => phases%get(p) + pl => phase%get('plasticity') + if(pl%get_asString('type') == plastic_label) active_plastic(p) = .true. + enddo + +end function plastic_active + + !-------------------------------------------------------------------------------------------------- !> @brief calls microstructure function of the different plasticity constitutive models !-------------------------------------------------------------------------------------------------- @@ -222,8 +272,8 @@ module subroutine constitutive_plastic_dependentState(F, Fp, ipc, ip, el) plasticityType: select case (phase_plasticity(material_phaseAt(ipc,el))) case (PLASTICITY_DISLOTWIN_ID) plasticityType call plastic_dislotwin_dependentState(temperature(ho)%p(tme),instance,of) - case (PLASTICITY_DISLOUCLA_ID) plasticityType - call plastic_disloUCLA_dependentState(instance,of) + 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) end select plasticityType @@ -275,7 +325,7 @@ module subroutine constitutive_plastic_LpAndItsTangents(Lp, dLp_dS, dLp_dFi, & dLp_dMp = 0.0_pReal case (PLASTICITY_ISOTROPIC_ID) plasticityType - call plastic_isotropic_LpAndItsTangent (Lp,dLp_dMp,Mp,instance,of) + call plastic_isotropic_LpAndItsTangent(Lp,dLp_dMp,Mp,instance,of) case (PLASTICITY_PHENOPOWERLAW_ID) plasticityType call plastic_phenopowerlaw_LpAndItsTangent(Lp,dLp_dMp,Mp,instance,of) @@ -284,13 +334,13 @@ module subroutine constitutive_plastic_LpAndItsTangents(Lp, dLp_dS, dLp_dFi, & call plastic_kinehardening_LpAndItsTangent(Lp,dLp_dMp,Mp,instance,of) case (PLASTICITY_NONLOCAL_ID) plasticityType - call plastic_nonlocal_LpAndItsTangent (Lp,dLp_dMp,Mp, temperature(ho)%p(tme),instance,of,ip,el) + call plastic_nonlocal_LpAndItsTangent(Lp,dLp_dMp,Mp, temperature(ho)%p(tme),instance,of,ip,el) case (PLASTICITY_DISLOTWIN_ID) plasticityType - call plastic_dislotwin_LpAndItsTangent (Lp,dLp_dMp,Mp,temperature(ho)%p(tme),instance,of) + call plastic_dislotwin_LpAndItsTangent(Lp,dLp_dMp,Mp,temperature(ho)%p(tme),instance,of) - case (PLASTICITY_DISLOUCLA_ID) plasticityType - call plastic_disloucla_LpAndItsTangent (Lp,dLp_dMp,Mp,temperature(ho)%p(tme),instance,of) + case (PLASTICITY_DISLOTUNGSTEN_ID) plasticityType + call plastic_disloTungsten_LpAndItsTangent(Lp,dLp_dMp,Mp,temperature(ho)%p(tme),instance,of) end select plasticityType @@ -311,8 +361,8 @@ module subroutine plastic_results integer :: p character(len=pStringLen) :: group - plasticityLoop: do p=1,size(config_name_phase) - group = trim('current/constituent')//'/'//trim(config_name_phase(p)) + plasticityLoop: do p=1,size(material_name_phase) + group = trim('current/constituent')//'/'//trim(material_name_phase(p)) call results_closeGroup(results_addGroup(group)) group = trim(group)//'/plastic' @@ -332,8 +382,8 @@ module subroutine plastic_results case(PLASTICITY_DISLOTWIN_ID) call plastic_dislotwin_results(phase_plasticityInstance(p),group) - case(PLASTICITY_DISLOUCLA_ID) - call plastic_disloUCLA_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) diff --git a/src/constitutive_plastic_disloUCLA.f90 b/src/constitutive_plastic_disloTungsten.f90 similarity index 81% rename from src/constitutive_plastic_disloUCLA.f90 rename to src/constitutive_plastic_disloTungsten.f90 index 71f8f4a27..a5cb45654 100644 --- a/src/constitutive_plastic_disloUCLA.f90 +++ b/src/constitutive_plastic_disloTungsten.f90 @@ -5,7 +5,7 @@ !> @author Martin Diehl, Max-Planck-Institut für Eisenforschung GmbH !> @brief crystal plasticity model for bcc metals, especially Tungsten !-------------------------------------------------------------------------------------------------- -submodule(constitutive:constitutive_plastic) plastic_disloUCLA +submodule(constitutive:constitutive_plastic) plastic_disloTungsten real(pReal), parameter :: & kB = 1.38e-23_pReal !< Boltzmann constant in J/Kelvin @@ -20,8 +20,8 @@ submodule(constitutive:constitutive_plastic) plastic_disloUCLA b_sl, & !< magnitude of burgers vector [m] D_a, & i_sl, & !< Adj. parameter for distance between 2 forest dislocations - atomicVolume, & - tau_0, & + atomicVolume, & !< factor to calculate atomic volume + tau_0, & !< Peierls stress !* mobility law parameters delta_F, & !< activation energy for glide [J] v0, & !< dislocation velocity prefactor [m/s] @@ -46,26 +46,26 @@ submodule(constitutive:constitutive_plastic) plastic_disloUCLA dipoleFormation !< flag indicating consideration of dipole formation end type !< container type for internal constitutive parameters - type :: tDisloUCLAState + type :: tDisloTungstenState real(pReal), dimension(:,:), pointer :: & rho_mob, & rho_dip, & gamma_sl - end type tDisloUCLAState + end type tDisloTungstenState - type :: tDisloUCLAdependentState + type :: tDisloTungstendependentState real(pReal), dimension(:,:), allocatable :: & Lambda_sl, & threshold_stress - end type tDisloUCLAdependentState + end type tDisloTungstendependentState !-------------------------------------------------------------------------------------------------- ! containers for parameters and state type(tParameters), allocatable, dimension(:) :: param - type(tDisloUCLAState), allocatable, dimension(:) :: & + type(tDisloTungstenState), allocatable, dimension(:) :: & dotState, & state - type(tDisloUCLAdependentState), allocatable, dimension(:) :: dependentState + type(tDisloTungstendependentState), allocatable, dimension(:) :: dependentState contains @@ -74,8 +74,9 @@ contains !> @brief Perform module initialization. !> @details reads in material parameters, allocates arrays, and does sanity checks !-------------------------------------------------------------------------------------------------- -module subroutine plastic_disloUCLA_init +module function plastic_disloTungsten_init() result(myPlasticity) + logical, dimension(:), allocatable :: myPlasticity integer :: & Ninstance, & p, i, & @@ -90,43 +91,59 @@ module subroutine plastic_disloUCLA_init a !< non-Schmid coefficients character(len=pStringLen) :: & extmsg = '' + class(tNode), pointer :: & + phases, & + phase, & + pl - write(6,'(/,a)') ' <<<+- plastic_'//PLASTICITY_DISLOUCLA_LABEL//' init -+>>>' + write(6,'(/,a)') ' <<<+- plastic_disloTungsten init -+>>>' write(6,'(/,a)') ' Cereceda et al., International Journal of Plasticity 78:242–256, 2016' write(6,'(a)') ' https://dx.doi.org/10.1016/j.ijplas.2015.09.002' - Ninstance = count(phase_plasticity == PLASTICITY_DISLOUCLA_ID) + myPlasticity = plastic_active('disloTungsten') + + Ninstance = count(myPlasticity) write(6,'(a16,1x,i5,/)') '# instances:',Ninstance; flush(6) + if(Ninstance == 0) return allocate(param(Ninstance)) allocate(state(Ninstance)) allocate(dotState(Ninstance)) allocate(dependentState(Ninstance)) - do p = 1, size(phase_plasticity) - if (phase_plasticity(p) /= PLASTICITY_DISLOUCLA_ID) cycle - associate(prm => param(phase_plasticityInstance(p)), & - dot => dotState(phase_plasticityInstance(p)), & - stt => state(phase_plasticityInstance(p)), & - dst => dependentState(phase_plasticityInstance(p)), & - config => config_phase(p)) + phases => material_root%get('phase') + i = 0 + do p = 1, phases%length + phase => phases%get(p) - prm%output = config%getStrings('(output)',defaultVal=emptyStringArray) + if(.not. myPlasticity(p)) cycle + i = i + 1 + associate(prm => param(i), & + dot => dotState(i), & + stt => state(i), & + dst => dependentState(i)) + pl => phase%get('plasticity') + +#if defined (__GFORTRAN__) + prm%output = output_asStrings(pl) +#else + prm%output = pl%get_asStrings('output',defaultVal=emptyStringArray) +#endif ! This data is read in already in lattice prm%mu = lattice_mu(p) !-------------------------------------------------------------------------------------------------- ! slip related parameters - N_sl = config%getInts('nslip',defaultVal=emptyIntArray) + N_sl = pl%get_asInts('N_sl',defaultVal=emptyIntArray) prm%sum_N_sl = sum(abs(N_sl)) slipActive: if (prm%sum_N_sl > 0) then - prm%P_sl = lattice_SchmidMatrix_slip(N_sl,config%getString('lattice_structure'),& - config%getFloat('c/a',defaultVal=0.0_pReal)) + prm%P_sl = lattice_SchmidMatrix_slip(N_sl,phase%get_asString('lattice'),& + phase%get_asFloat('c/a',defaultVal=0.0_pReal)) - if(trim(config%getString('lattice_structure')) == 'bcc') then - a = config%getFloats('nonschmid_coefficients',defaultVal = emptyRealArray) + if(trim(phase%get_asString('lattice')) == 'bcc') then + a = pl%get_asFloats('nonSchmid_coefficients',defaultVal = emptyRealArray) prm%nonSchmid_pos = lattice_nonSchmidMatrix(N_sl,a,+1) prm%nonSchmid_neg = lattice_nonSchmidMatrix(N_sl,a,-1) else @@ -134,35 +151,36 @@ module subroutine plastic_disloUCLA_init prm%nonSchmid_neg = prm%P_sl endif - prm%h_sl_sl = lattice_interaction_SlipBySlip(N_sl,config%getFloats('interaction_slipslip'), & - config%getString('lattice_structure')) - prm%forestProjection = lattice_forestProjection_edge(N_sl,config%getString('lattice_structure'),& - config%getFloat('c/a',defaultVal=0.0_pReal)) + prm%h_sl_sl = lattice_interaction_SlipBySlip(N_sl,pl%get_asFloats('h_sl_sl'), & + phase%get_asString('lattice')) + prm%forestProjection = lattice_forestProjection_edge(N_sl,phase%get_asString('lattice'),& + phase%get_asFloat('c/a',defaultVal=0.0_pReal)) prm%forestProjection = transpose(prm%forestProjection) - rho_mob_0 = config%getFloats('rhoedge0', requiredSize=size(N_sl)) - rho_dip_0 = config%getFloats('rhoedgedip0', requiredSize=size(N_sl)) - prm%v0 = config%getFloats('v0', requiredSize=size(N_sl)) - prm%b_sl = config%getFloats('slipburgers', requiredSize=size(N_sl)) - prm%delta_F = config%getFloats('qedge', requiredSize=size(N_sl)) + rho_mob_0 = pl%get_asFloats('rho_mob_0', requiredSize=size(N_sl)) + rho_dip_0 = pl%get_asFloats('rho_dip_0', requiredSize=size(N_sl)) + prm%v0 = pl%get_asFloats('v_0', requiredSize=size(N_sl)) + prm%b_sl = pl%get_asFloats('b_sl', requiredSize=size(N_sl)) + prm%delta_F = pl%get_asFloats('Q_s', requiredSize=size(N_sl)) - prm%i_sl = config%getFloats('clambdaslip', requiredSize=size(N_sl)) - prm%tau_0 = config%getFloats('tau_peierls', requiredSize=size(N_sl)) - prm%p = config%getFloats('p_slip', requiredSize=size(N_sl), & + prm%i_sl = pl%get_asFloats('i_sl', requiredSize=size(N_sl)) + prm%tau_0 = pl%get_asFloats('tau_peierls', requiredSize=size(N_sl)) + prm%p = pl%get_asFloats('p_sl', requiredSize=size(N_sl), & defaultVal=[(1.0_pReal,i=1,size(N_sl))]) - prm%q = config%getFloats('q_slip', requiredSize=size(N_sl), & + prm%q = pl%get_asFloats('q_sl', requiredSize=size(N_sl), & defaultVal=[(1.0_pReal,i=1,size(N_sl))]) - prm%kink_height = config%getFloats('kink_height', requiredSize=size(N_sl)) - prm%w = config%getFloats('kink_width', requiredSize=size(N_sl)) - prm%omega = config%getFloats('omega', requiredSize=size(N_sl)) - prm%B = config%getFloats('friction_coeff', requiredSize=size(N_sl)) + prm%kink_height = pl%get_asFloats('h', requiredSize=size(N_sl)) + prm%w = pl%get_asFloats('w', requiredSize=size(N_sl)) + prm%omega = pl%get_asFloats('omega', requiredSize=size(N_sl)) + prm%B = pl%get_asFloats('B', requiredSize=size(N_sl)) - prm%D = config%getFloat('grainsize') - prm%D_0 = config%getFloat('d0') - prm%Q_cl = config%getFloat('qsd') - prm%atomicVolume = config%getFloat('catomicvolume') * prm%b_sl**3.0_pReal - prm%D_a = config%getFloat('cedgedipmindistance') * prm%b_sl - prm%dipoleformation = config%getFloat('dipoleformationfactor') > 0.0_pReal !should be on by default, ToDo: change to /key/-type key + prm%D = pl%get_asFloat('D') + prm%D_0 = pl%get_asFloat('D_0') + prm%Q_cl = pl%get_asFloat('Q_cl') + prm%atomicVolume = pl%get_asFloat('f_at') * prm%b_sl**3.0_pReal + prm%D_a = pl%get_asFloat('D_a') * prm%b_sl + + prm%dipoleformation = pl%get_asBool('dipole_formation_factor', defaultVal = .true.) ! expand: family => system rho_mob_0 = math_expand(rho_mob_0, N_sl) @@ -184,14 +202,14 @@ module subroutine plastic_disloUCLA_init ! sanity checks if ( prm%D_0 <= 0.0_pReal) extmsg = trim(extmsg)//' D_0' if ( prm%Q_cl <= 0.0_pReal) extmsg = trim(extmsg)//' Q_cl' - if (any(rho_mob_0 < 0.0_pReal)) extmsg = trim(extmsg)//' rhoedge0' - if (any(rho_dip_0 < 0.0_pReal)) extmsg = trim(extmsg)//' rhoedgedip0' - if (any(prm%v0 < 0.0_pReal)) extmsg = trim(extmsg)//' v0' + if (any(rho_mob_0 < 0.0_pReal)) extmsg = trim(extmsg)//' rho_mob_0' + if (any(rho_dip_0 < 0.0_pReal)) extmsg = trim(extmsg)//' rho_dip_0' + if (any(prm%v0 < 0.0_pReal)) extmsg = trim(extmsg)//' v_0' if (any(prm%b_sl <= 0.0_pReal)) extmsg = trim(extmsg)//' b_sl' - if (any(prm%delta_F <= 0.0_pReal)) extmsg = trim(extmsg)//' qedge' - if (any(prm%tau_0 < 0.0_pReal)) extmsg = trim(extmsg)//' tau_0' - if (any(prm%D_a <= 0.0_pReal)) extmsg = trim(extmsg)//' cedgedipmindistance or b_sl' - if (any(prm%atomicVolume <= 0.0_pReal)) extmsg = trim(extmsg)//' catomicvolume or b_sl' + if (any(prm%delta_F <= 0.0_pReal)) extmsg = trim(extmsg)//' Q_s' + if (any(prm%tau_0 < 0.0_pReal)) extmsg = trim(extmsg)//' tau_peierls' + if (any(prm%D_a <= 0.0_pReal)) extmsg = trim(extmsg)//' D_a or b_sl' + if (any(prm%atomicVolume <= 0.0_pReal)) extmsg = trim(extmsg)//' f_at or b_sl' else slipActive rho_mob_0= emptyRealArray; rho_dip_0 = emptyRealArray @@ -208,7 +226,7 @@ module subroutine plastic_disloUCLA_init sizeDotState = size(['rho_mob ','rho_dip ','gamma_sl']) * prm%sum_N_sl sizeState = sizeDotState - call material_allocateState(plasticState(p),NipcMyPhase,sizeState,sizeDotState,0) + call constitutive_allocateState(plasticState(p),NipcMyPhase,sizeState,sizeDotState,0) !-------------------------------------------------------------------------------------------------- ! state aliases and initialization @@ -217,7 +235,7 @@ module subroutine plastic_disloUCLA_init stt%rho_mob => plasticState(p)%state(startIndex:endIndex,:) stt%rho_mob = spread(rho_mob_0,2,NipcMyPhase) dot%rho_mob => plasticState(p)%dotState(startIndex:endIndex,:) - plasticState(p)%atol(startIndex:endIndex) = config%getFloat('atol_rho',defaultVal=1.0_pReal) + plasticState(p)%atol(startIndex:endIndex) = pl%get_asFloat('atol_rho',defaultVal=1.0_pReal) if (any(plasticState(p)%atol(startIndex:endIndex) < 0.0_pReal)) extmsg = trim(extmsg)//' atol_rho' startIndex = endIndex + 1 @@ -225,7 +243,7 @@ module subroutine plastic_disloUCLA_init stt%rho_dip => plasticState(p)%state(startIndex:endIndex,:) stt%rho_dip = spread(rho_dip_0,2,NipcMyPhase) dot%rho_dip => plasticState(p)%dotState(startIndex:endIndex,:) - plasticState(p)%atol(startIndex:endIndex) = config%getFloat('atol_rho',defaultVal=1.0_pReal) + plasticState(p)%atol(startIndex:endIndex) = pl%get_asFloat('atol_rho',defaultVal=1.0_pReal) startIndex = endIndex + 1 endIndex = endIndex + prm%sum_N_sl @@ -244,17 +262,17 @@ module subroutine plastic_disloUCLA_init !-------------------------------------------------------------------------------------------------- ! exit if any parameter is out of range - if (extmsg /= '') call IO_error(211,ext_msg=trim(extmsg)//'('//PLASTICITY_DISLOUCLA_LABEL//')') + if (extmsg /= '') call IO_error(211,ext_msg=trim(extmsg)//'(disloTungsten)') enddo -end subroutine plastic_disloUCLA_init +end function plastic_disloTungsten_init !-------------------------------------------------------------------------------------------------- !> @brief Calculate plastic velocity gradient and its tangent. !-------------------------------------------------------------------------------------------------- -pure module subroutine plastic_disloUCLA_LpAndItsTangent(Lp,dLp_dMp, & +pure module subroutine plastic_disloTungsten_LpAndItsTangent(Lp,dLp_dMp, & Mp,T,instance,of) real(pReal), dimension(3,3), intent(out) :: & Lp !< plastic velocity gradient @@ -291,13 +309,13 @@ pure module subroutine plastic_disloUCLA_LpAndItsTangent(Lp,dLp_dMp, & end associate -end subroutine plastic_disloUCLA_LpAndItsTangent +end subroutine plastic_disloTungsten_LpAndItsTangent !-------------------------------------------------------------------------------------------------- !> @brief Calculate the rate of change of microstructure. !-------------------------------------------------------------------------------------------------- -module subroutine plastic_disloUCLA_dotState(Mp,T,instance,of) +module subroutine plastic_disloTungsten_dotState(Mp,T,instance,of) real(pReal), dimension(3,3), intent(in) :: & Mp !< Mandel stress @@ -351,13 +369,13 @@ module subroutine plastic_disloUCLA_dotState(Mp,T,instance,of) end associate -end subroutine plastic_disloUCLA_dotState +end subroutine plastic_disloTungsten_dotState !-------------------------------------------------------------------------------------------------- !> @brief Calculate derived quantities from state. !-------------------------------------------------------------------------------------------------- -module subroutine plastic_disloUCLA_dependentState(instance,of) +module subroutine plastic_disloTungsten_dependentState(instance,of) integer, intent(in) :: & instance, & @@ -376,13 +394,13 @@ module subroutine plastic_disloUCLA_dependentState(instance,of) end associate -end subroutine plastic_disloUCLA_dependentState +end subroutine plastic_disloTungsten_dependentState !-------------------------------------------------------------------------------------------------- !> @brief Write results to HDF5 output file. !-------------------------------------------------------------------------------------------------- -module subroutine plastic_disloUCLA_results(instance,group) +module subroutine plastic_disloTungsten_results(instance,group) integer, intent(in) :: instance character(len=*), intent(in) :: group @@ -392,26 +410,26 @@ module subroutine plastic_disloUCLA_results(instance,group) associate(prm => param(instance), stt => state(instance), dst => dependentState(instance)) outputsLoop: do o = 1,size(prm%output) select case(trim(prm%output(o))) - case('edge_density') ! ToDo: should be rho_mob - if(prm%sum_N_sl>0) call results_writeDataset(group,stt%rho_mob,'rho_mob',& + case('rho_mob') + if(prm%sum_N_sl>0) call results_writeDataset(group,stt%rho_mob,trim(prm%output(o)), & 'mobile dislocation density','1/m²') - case('dipole_density') ! ToDo: should be rho_dip - if(prm%sum_N_sl>0) call results_writeDataset(group,stt%rho_dip,'rho_dip',& + case('rho_dip') + if(prm%sum_N_sl>0) call results_writeDataset(group,stt%rho_dip,trim(prm%output(o)), & 'dislocation dipole density''1/m²') - case('shear_rate_slip') ! should be gamma - if(prm%sum_N_sl>0) call results_writeDataset(group,stt%gamma_sl,'dot_gamma_sl',& ! this is not dot!! + case('gamma_sl') + if(prm%sum_N_sl>0) call results_writeDataset(group,stt%gamma_sl,trim(prm%output(o)), & 'plastic shear','1') - case('mfp_slip') !ToDo: should be Lambda - if(prm%sum_N_sl>0) call results_writeDataset(group,dst%Lambda_sl,'Lambda_sl',& + case('Lambda_sl') + if(prm%sum_N_sl>0) call results_writeDataset(group,dst%Lambda_sl,trim(prm%output(o)), & 'mean free path for slip','m') - case('threshold_stress_slip') !ToDo: should be tau_pass - if(prm%sum_N_sl>0) call results_writeDataset(group,dst%threshold_stress,'tau_pass',& + case('tau_pass') + if(prm%sum_N_sl>0) call results_writeDataset(group,dst%threshold_stress,trim(prm%output(o)), & 'threshold stress for slip','Pa') end select enddo outputsLoop end associate -end subroutine plastic_disloUCLA_results +end subroutine plastic_disloTungsten_results !-------------------------------------------------------------------------------------------------- @@ -529,4 +547,4 @@ pure subroutine kinetics(Mp,T,instance,of, & end subroutine kinetics -end submodule plastic_disloUCLA +end submodule plastic_disloTungsten diff --git a/src/constitutive_plastic_dislotwin.f90 b/src/constitutive_plastic_dislotwin.f90 index c9550ecd6..0f473b760 100644 --- a/src/constitutive_plastic_dislotwin.f90 +++ b/src/constitutive_plastic_dislotwin.f90 @@ -22,8 +22,8 @@ submodule(constitutive:constitutive_plastic) plastic_dislotwin D = 1.0_pReal, & !< grain size p_sb = 1.0_pReal, & !< p-exponent in shear band velocity q_sb = 1.0_pReal, & !< q-exponent in shear band velocity - CEdgeDipMinDistance = 1.0_pReal, & !< - i_tw = 1.0_pReal, & !< + CEdgeDipMinDistance = 1.0_pReal, & !< adjustment parameter to calculate minimum dipole distance + i_tw = 1.0_pReal, & !< adjustment parameter to calculate MFP for twinning tau_0 = 1.0_pReal, & !< strength due to elements in solid solution L_tw = 1.0_pReal, & !< Length of twin nuclei in Burgers vectors L_tr = 1.0_pReal, & !< Length of trans nuclei in Burgers vectors @@ -36,7 +36,7 @@ submodule(constitutive:constitutive_plastic) plastic_dislotwin SFE_0K = 1.0_pReal, & !< stacking fault energy at zero K dSFE_dT = 1.0_pReal, & !< temperature dependence of stacking fault energy gamma_fcc_hex = 1.0_pReal, & !< Free energy difference between austensite and martensite - i_tr = 1.0_pReal, & !< + i_tr = 1.0_pReal, & !< adjustment parameter to calculate MFP for transformation h = 1.0_pReal !< Stack height of hex nucleus real(pReal), allocatable, dimension(:) :: & b_sl, & !< absolute length of burgers vector [m] for each slip system @@ -56,11 +56,11 @@ submodule(constitutive:constitutive_plastic) plastic_dislotwin gamma_char, & !< characteristic shear for twins B !< drag coefficient real(pReal), allocatable, dimension(:,:) :: & - h_sl_sl, & !< - h_sl_tw, & !< - h_tw_tw, & !< - h_sl_tr, & !< - h_tr_tr, & !< + h_sl_sl, & !< components of slip-slip interaction matrix + h_sl_tw, & !< components of slip-twin interaction matrix + h_tw_tw, & !< components of twin-twin interaction matrix + h_sl_tr, & !< components of slip-trans interaction matrix + h_tr_tr, & !< components of trans-trans interaction matrix n0_sl, & !< slip system normal forestProjection, & C66 @@ -98,9 +98,9 @@ submodule(constitutive:constitutive_plastic) plastic_dislotwin Lambda_sl, & !< mean free path between 2 obstacles seen by a moving dislocation Lambda_tw, & !< mean free path between 2 obstacles seen by a growing twin Lambda_tr, & !< mean free path between 2 obstacles seen by a growing martensite - tau_pass, & - tau_hat_tw, & - tau_hat_tr, & + tau_pass, & !< threshold stress for slip + tau_hat_tw, & !< threshold stress for twinning + tau_hat_tr, & !< threshold stress for transformation V_tw, & !< volume of a new twin V_tr, & !< volume of a new martensite disc tau_r_tw, & !< stress to bring partials close together (twin) @@ -122,8 +122,9 @@ contains !> @brief Perform module initialization. !> @details reads in material parameters, allocates arrays, and does sanity checks !-------------------------------------------------------------------------------------------------- -module subroutine plastic_dislotwin_init +module function plastic_dislotwin_init() result(myPlasticity) + logical, dimension(:), allocatable :: myPlasticity integer :: & Ninstance, & p, i, & @@ -137,8 +138,12 @@ module subroutine plastic_dislotwin_init rho_dip_0 !< initial dipole dislocation density per slip system character(len=pStringLen) :: & extmsg = '' + class(tNode), pointer :: & + phases, & + phase, & + pl - write(6,'(/,a)') ' <<<+- constitutive_'//PLASTICITY_DISLOTWIN_LABEL//' init -+>>>' + write(6,'(/,a)') ' <<<+- constitutive_dislotwin init -+>>>' write(6,'(/,a)') ' Ma and Roters, Acta Materialia 52(12):3603–3612, 2004' write(6,'(a)') ' https://doi.org/10.1016/j.actamat.2004.04.012' @@ -149,23 +154,35 @@ module subroutine plastic_dislotwin_init write(6,'(/,a)') ' Wong et al., Acta Materialia 118:140–151, 2016' write(6,'(a,/)') ' https://doi.org/10.1016/j.actamat.2016.07.032' - Ninstance = count(phase_plasticity == PLASTICITY_DISLOTWIN_ID) + myPlasticity = plastic_active('dislotwin') + + Ninstance = count(myPlasticity) write(6,'(a16,1x,i5,/)') '# instances:',Ninstance; flush(6) + if(Ninstance == 0) return allocate(param(Ninstance)) allocate(state(Ninstance)) allocate(dotState(Ninstance)) allocate(dependentState(Ninstance)) - do p = 1, size(phase_plasticity) - if (phase_plasticity(p) /= PLASTICITY_DISLOTWIN_ID) cycle - associate(prm => param(phase_plasticityInstance(p)), & - dot => dotState(phase_plasticityInstance(p)), & - stt => state(phase_plasticityInstance(p)), & - dst => dependentState(phase_plasticityInstance(p)), & - config => config_phase(p)) + phases => material_root%get('phase') + i = 0 + do p = 1, phases%length + phase => phases%get(p) - prm%output = config%getStrings('(output)', defaultVal=emptyStringArray) + if(.not. myPlasticity(p)) cycle + i = i + 1 + associate(prm => param(i), & + dot => dotState(i), & + stt => state(i), & + dst => dependentState(i)) + pl => phase%get('plasticity') + +#if defined (__GFORTRAN__) + prm%output = output_asStrings(pl) +#else + prm%output = pl%get_asStrings('output',defaultVal=emptyStringArray) +#endif ! This data is read in already in lattice prm%mu = lattice_mu(p) @@ -174,49 +191,49 @@ module subroutine plastic_dislotwin_init !-------------------------------------------------------------------------------------------------- ! slip related parameters - N_sl = config%getInts('nslip',defaultVal=emptyIntArray) + N_sl = pl%get_asInts('N_sl',defaultVal=emptyIntArray) prm%sum_N_sl = sum(abs(N_sl)) slipActive: if (prm%sum_N_sl > 0) then - prm%P_sl = lattice_SchmidMatrix_slip(N_sl,config%getString('lattice_structure'),& - config%getFloat('c/a',defaultVal=0.0_pReal)) - prm%h_sl_sl = lattice_interaction_SlipBySlip(N_sl,config%getFloats('interaction_slipslip'), & - config%getString('lattice_structure')) - prm%forestProjection = lattice_forestProjection_edge(N_sl,config%getString('lattice_structure'),& - config%getFloat('c/a',defaultVal=0.0_pReal)) + prm%P_sl = lattice_SchmidMatrix_slip(N_sl,phase%get_asString('lattice'),& + phase%get_asFloat('c/a',defaultVal=0.0_pReal)) + prm%h_sl_sl = lattice_interaction_SlipBySlip(N_sl,pl%get_asFloats('h_sl_sl'), & + phase%get_asString('lattice')) + prm%forestProjection = lattice_forestProjection_edge(N_sl,phase%get_asString('lattice'),& + phase%get_asFloat('c/a',defaultVal=0.0_pReal)) prm%forestProjection = transpose(prm%forestProjection) - prm%n0_sl = lattice_slip_normal(N_sl,config%getString('lattice_structure'),& - config%getFloat('c/a',defaultVal=0.0_pReal)) + prm%n0_sl = lattice_slip_normal(N_sl,phase%get_asString('lattice'),& + phase%get_asFloat('c/a',defaultVal=0.0_pReal)) prm%fccTwinTransNucleation = merge(.true., .false., lattice_structure(p) == lattice_FCC_ID) & .and. (N_sl(1) == 12) if(prm%fccTwinTransNucleation) prm%fcc_twinNucleationSlipPair = lattice_FCC_TWINNUCLEATIONSLIPPAIR - rho_mob_0 = config%getFloats('rhoedge0', requiredSize=size(N_sl)) - rho_dip_0 = config%getFloats('rhoedgedip0',requiredSize=size(N_sl)) - prm%v0 = config%getFloats('v0', requiredSize=size(N_sl)) - prm%b_sl = config%getFloats('slipburgers',requiredSize=size(N_sl)) - prm%Delta_F = config%getFloats('qedge', requiredSize=size(N_sl)) - prm%CLambdaSlip = config%getFloats('clambdaslip',requiredSize=size(N_sl)) - prm%p = config%getFloats('p_slip', requiredSize=size(N_sl)) - prm%q = config%getFloats('q_slip', requiredSize=size(N_sl)) - prm%B = config%getFloats('b', requiredSize=size(N_sl), & + rho_mob_0 = pl%get_asFloats('rho_mob_0', requiredSize=size(N_sl)) + rho_dip_0 = pl%get_asFloats('rho_dip_0', requiredSize=size(N_sl)) + prm%v0 = pl%get_asFloats('v_0', requiredSize=size(N_sl)) + prm%b_sl = pl%get_asFloats('b_sl', requiredSize=size(N_sl)) + prm%Delta_F = pl%get_asFloats('Q_s', requiredSize=size(N_sl)) + prm%CLambdaSlip = pl%get_asFloats('i_sl', requiredSize=size(N_sl)) + prm%p = pl%get_asFloats('p_sl', requiredSize=size(N_sl)) + prm%q = pl%get_asFloats('q_sl', requiredSize=size(N_sl)) + prm%B = pl%get_asFloats('B', requiredSize=size(N_sl), & defaultVal=[(0.0_pReal, i=1,size(N_sl))]) - prm%tau_0 = config%getFloat('solidsolutionstrength') - prm%CEdgeDipMinDistance = config%getFloat('cedgedipmindistance') - prm%D0 = config%getFloat('d0') - prm%Qsd = config%getFloat('qsd') - prm%ExtendedDislocations = config%keyExists('/extend_dislocations/') + prm%tau_0 = pl%get_asFloat('tau_0') + prm%CEdgeDipMinDistance = pl%get_asFloat('D_a') + prm%D0 = pl%get_asFloat('D_0') + prm%Qsd = pl%get_asFloat('Q_cl') + prm%ExtendedDislocations = pl%get_asBool('extend_dislocations',defaultVal = .false.) if (prm%ExtendedDislocations) then - prm%SFE_0K = config%getFloat('sfe_0k') - prm%dSFE_dT = config%getFloat('dsfe_dt') + prm%SFE_0K = pl%get_asFloat('Gamma_sf_0K') + prm%dSFE_dT = pl%get_asFloat('dGamma_sf_dT') endif - prm%dipoleformation = .not. config%keyExists('/nodipoleformation/') + prm%dipoleformation = .not. pl%get_asBool('no_dipole_formation',defaultVal = .false.) ! multiplication factor according to crystal structure (nearest neighbors bcc vs fcc/hex) ! details: Argon & Moffat, Acta Metallurgica, Vol. 29, pg 293 to 299, 1981 - prm%omega = config%getFloat('omega', defaultVal = 1000.0_pReal) & + prm%omega = pl%get_asFloat('omega', defaultVal = 1000.0_pReal) & * merge(12.0_pReal,8.0_pReal,any(lattice_structure(p) == [lattice_FCC_ID,lattice_HEX_ID])) ! expand: family => system @@ -231,17 +248,17 @@ module subroutine plastic_dislotwin_init prm%B = math_expand(prm%B, N_sl) ! sanity checks - if ( prm%D0 <= 0.0_pReal) extmsg = trim(extmsg)//' D0' - if ( prm%Qsd <= 0.0_pReal) extmsg = trim(extmsg)//' Qsd' + if ( prm%D0 <= 0.0_pReal) extmsg = trim(extmsg)//' D_0' + if ( prm%Qsd <= 0.0_pReal) extmsg = trim(extmsg)//' Q_cl' if (any(rho_mob_0 < 0.0_pReal)) extmsg = trim(extmsg)//' rho_mob_0' if (any(rho_dip_0 < 0.0_pReal)) extmsg = trim(extmsg)//' rho_dip_0' - if (any(prm%v0 < 0.0_pReal)) extmsg = trim(extmsg)//' v0' + if (any(prm%v0 < 0.0_pReal)) extmsg = trim(extmsg)//' v_0' if (any(prm%b_sl <= 0.0_pReal)) extmsg = trim(extmsg)//' b_sl' - if (any(prm%Delta_F <= 0.0_pReal)) extmsg = trim(extmsg)//' Delta_F' - if (any(prm%CLambdaSlip <= 0.0_pReal)) extmsg = trim(extmsg)//' CLambdaSlip' + if (any(prm%Delta_F <= 0.0_pReal)) extmsg = trim(extmsg)//' Q_s' + if (any(prm%CLambdaSlip <= 0.0_pReal)) extmsg = trim(extmsg)//' i_sl' if (any(prm%B < 0.0_pReal)) extmsg = trim(extmsg)//' B' - if (any(prm%p<=0.0_pReal .or. prm%p>1.0_pReal)) extmsg = trim(extmsg)//' p' - if (any(prm%q< 1.0_pReal .or. prm%q>2.0_pReal)) extmsg = trim(extmsg)//' q' + if (any(prm%p<=0.0_pReal .or. prm%p>1.0_pReal)) extmsg = trim(extmsg)//' p_sl' + if (any(prm%q< 1.0_pReal .or. prm%q>2.0_pReal)) extmsg = trim(extmsg)//' q_sl' else slipActive rho_mob_0 = emptyRealArray; rho_dip_0 = emptyRealArray allocate(prm%b_sl,prm%Delta_F,prm%v0,prm%CLambdaSlip,prm%p,prm%q,prm%B,source=emptyRealArray) @@ -250,31 +267,31 @@ module subroutine plastic_dislotwin_init !-------------------------------------------------------------------------------------------------- ! twin related parameters - N_tw = config%getInts('ntwin', defaultVal=emptyIntArray) + N_tw = pl%get_asInts('N_tw', defaultVal=emptyIntArray) prm%sum_N_tw = sum(abs(N_tw)) twinActive: if (prm%sum_N_tw > 0) then - prm%P_tw = lattice_SchmidMatrix_twin(N_tw,config%getString('lattice_structure'),& - config%getFloat('c/a',defaultVal=0.0_pReal)) + prm%P_tw = lattice_SchmidMatrix_twin(N_tw,phase%get_asString('lattice'),& + phase%get_asFloat('c/a',defaultVal=0.0_pReal)) prm%h_tw_tw = lattice_interaction_TwinByTwin(N_tw,& - config%getFloats('interaction_twintwin'), & - config%getString('lattice_structure')) + pl%get_asFloats('h_tw_tw'), & + phase%get_asString('lattice')) - prm%b_tw = config%getFloats('twinburgers', requiredSize=size(N_tw)) - prm%t_tw = config%getFloats('twinsize', requiredSize=size(N_tw)) - prm%r = config%getFloats('r_twin', requiredSize=size(N_tw)) + prm%b_tw = pl%get_asFloats('b_tw', requiredSize=size(N_tw)) + prm%t_tw = pl%get_asFloats('t_tw', requiredSize=size(N_tw)) + prm%r = pl%get_asFloats('p_tw', requiredSize=size(N_tw)) - prm%xc_twin = config%getFloat('xc_twin') - prm%L_tw = config%getFloat('l0_twin') - prm%i_tw = config%getFloat('cmfptwin') + prm%xc_twin = pl%get_asFloat('x_c_tw') + prm%L_tw = pl%get_asFloat('L_tw') + prm%i_tw = pl%get_asFloat('i_tw') - prm%gamma_char= lattice_characteristicShear_Twin(N_tw,config%getString('lattice_structure'),& - config%getFloat('c/a',defaultVal=0.0_pReal)) + prm%gamma_char= lattice_characteristicShear_Twin(N_tw,phase%get_asString('lattice'),& + phase%get_asFloat('c/a',defaultVal=0.0_pReal)) - prm%C66_tw = lattice_C66_twin(N_tw,prm%C66,config%getString('lattice_structure'),& - config%getFloat('c/a',defaultVal=0.0_pReal)) + prm%C66_tw = lattice_C66_twin(N_tw,prm%C66,phase%get_asString('lattice'),& + phase%get_asFloat('c/a',defaultVal=0.0_pReal)) if (.not. prm%fccTwinTransNucleation) then - prm%dot_N_0_tw = config%getFloats('ndot0_twin') + prm%dot_N_0_tw = pl%get_asFloats('dot_N_0_tw') prm%dot_N_0_tw = math_expand(prm%dot_N_0_tw,N_tw) endif @@ -284,12 +301,12 @@ module subroutine plastic_dislotwin_init prm%r = math_expand(prm%r,N_tw) ! sanity checks - if ( prm%xc_twin < 0.0_pReal) extmsg = trim(extmsg)//' xc_twin' + if ( prm%xc_twin < 0.0_pReal) extmsg = trim(extmsg)//' x_c_twin' if ( prm%L_tw < 0.0_pReal) extmsg = trim(extmsg)//' L_tw' if ( prm%i_tw < 0.0_pReal) extmsg = trim(extmsg)//' i_tw' if (any(prm%b_tw < 0.0_pReal)) extmsg = trim(extmsg)//' b_tw' if (any(prm%t_tw < 0.0_pReal)) extmsg = trim(extmsg)//' t_tw' - if (any(prm%r < 0.0_pReal)) extmsg = trim(extmsg)//' r' + if (any(prm%r < 0.0_pReal)) extmsg = trim(extmsg)//' p_tw' if (.not. prm%fccTwinTransNucleation) then if (any(prm%dot_N_0_tw < 0.0_pReal)) extmsg = trim(extmsg)//' dot_N_0_tw' endif @@ -300,46 +317,46 @@ module subroutine plastic_dislotwin_init !-------------------------------------------------------------------------------------------------- ! transformation related parameters - N_tr = config%getInts('ntrans', defaultVal=emptyIntArray) + N_tr = pl%get_asInts('N_tr', defaultVal=emptyIntArray) prm%sum_N_tr = sum(abs(N_tr)) transActive: if (prm%sum_N_tr > 0) then - prm%b_tr = config%getFloats('transburgers') + prm%b_tr = pl%get_asFloats('b_tr') prm%b_tr = math_expand(prm%b_tr,N_tr) - prm%h = config%getFloat('transstackheight', defaultVal=0.0_pReal) ! ToDo: How to handle that??? - prm%i_tr = config%getFloat('cmfptrans', defaultVal=0.0_pReal) ! ToDo: How to handle that??? - prm%gamma_fcc_hex = config%getFloat('deltag') - prm%xc_trans = config%getFloat('xc_trans', defaultVal=0.0_pReal) ! ToDo: How to handle that??? - prm%L_tr = config%getFloat('l0_trans') + prm%h = pl%get_asFloat('h', defaultVal=0.0_pReal) ! ToDo: How to handle that??? + prm%i_tr = pl%get_asFloat('i_tr', defaultVal=0.0_pReal) ! ToDo: How to handle that??? + prm%gamma_fcc_hex = pl%get_asFloat('delta_G') + prm%xc_trans = pl%get_asFloat('x_c_tr', defaultVal=0.0_pReal) ! ToDo: How to handle that??? + prm%L_tr = pl%get_asFloat('L_tr') - prm%h_tr_tr = lattice_interaction_TransByTrans(N_tr,config%getFloats('interaction_transtrans'), & - config%getString('lattice_structure')) + prm%h_tr_tr = lattice_interaction_TransByTrans(N_tr,pl%get_asFloats('h_tr_tr'), & + phase%get_asString('lattice')) - prm%C66_tr = lattice_C66_trans(N_tr,prm%C66,config%getString('trans_lattice_structure'), & + prm%C66_tr = lattice_C66_trans(N_tr,prm%C66,pl%get_asString('trans_lattice_structure'), & 0.0_pReal, & - config%getFloat('a_bcc', defaultVal=0.0_pReal), & - config%getFloat('a_fcc', defaultVal=0.0_pReal)) + pl%get_asFloat('a_bcc', defaultVal=0.0_pReal), & + pl%get_asFloat('a_fcc', defaultVal=0.0_pReal)) - prm%P_tr = lattice_SchmidMatrix_trans(N_tr,config%getString('trans_lattice_structure'), & + prm%P_tr = lattice_SchmidMatrix_trans(N_tr,pl%get_asString('trans_lattice_structure'), & 0.0_pReal, & - config%getFloat('a_bcc', defaultVal=0.0_pReal), & - config%getFloat('a_fcc', defaultVal=0.0_pReal)) + pl%get_asFloat('a_bcc', defaultVal=0.0_pReal), & + pl%get_asFloat('a_fcc', defaultVal=0.0_pReal)) if (lattice_structure(p) /= lattice_FCC_ID) then - prm%dot_N_0_tr = config%getFloats('ndot0_trans') + prm%dot_N_0_tr = pl%get_asFloats('dot_N_0_tr') prm%dot_N_0_tr = math_expand(prm%dot_N_0_tr,N_tr) endif - prm%t_tr = config%getFloats('lamellarsize') + prm%t_tr = pl%get_asFloats('t_tr') prm%t_tr = math_expand(prm%t_tr,N_tr) - prm%s = config%getFloats('s_trans',defaultVal=[0.0_pReal]) + prm%s = pl%get_asFloats('p_tr',defaultVal=[0.0_pReal]) prm%s = math_expand(prm%s,N_tr) ! sanity checks - if ( prm%xc_trans < 0.0_pReal) extmsg = trim(extmsg)//' xc_trans' + if ( prm%xc_trans < 0.0_pReal) extmsg = trim(extmsg)//' x_c_trans' if ( prm%L_tr < 0.0_pReal) extmsg = trim(extmsg)//' L_tr' if ( prm%i_tr < 0.0_pReal) extmsg = trim(extmsg)//' i_tr' if (any(prm%t_tr < 0.0_pReal)) extmsg = trim(extmsg)//' t_tr' - if (any(prm%s < 0.0_pReal)) extmsg = trim(extmsg)//' s' + if (any(prm%s < 0.0_pReal)) extmsg = trim(extmsg)//' p_tr' if (lattice_structure(p) /= lattice_FCC_ID) then if (any(prm%dot_N_0_tr < 0.0_pReal)) extmsg = trim(extmsg)//' dot_N_0_tr' endif @@ -350,42 +367,42 @@ module subroutine plastic_dislotwin_init !-------------------------------------------------------------------------------------------------- ! shearband related parameters - prm%sbVelocity = config%getFloat('shearbandvelocity',defaultVal=0.0_pReal) + prm%sbVelocity = pl%get_asFloat('v_sb',defaultVal=0.0_pReal) if (prm%sbVelocity > 0.0_pReal) then - prm%sbResistance = config%getFloat('shearbandresistance') - prm%E_sb = config%getFloat('qedgepersbsystem') - prm%p_sb = config%getFloat('p_shearband') - prm%q_sb = config%getFloat('q_shearband') + prm%sbResistance = pl%get_asFloat('xi_sb') + prm%E_sb = pl%get_asFloat('Q_sb') + prm%p_sb = pl%get_asFloat('p_sb') + prm%q_sb = pl%get_asFloat('q_sb') ! sanity checks - if (prm%sbResistance < 0.0_pReal) extmsg = trim(extmsg)//' shearbandresistance' - if (prm%E_sb < 0.0_pReal) extmsg = trim(extmsg)//' qedgepersbsystem' - if (prm%p_sb <= 0.0_pReal) extmsg = trim(extmsg)//' p_shearband' - if (prm%q_sb <= 0.0_pReal) extmsg = trim(extmsg)//' q_shearband' + if (prm%sbResistance < 0.0_pReal) extmsg = trim(extmsg)//' xi_sb' + if (prm%E_sb < 0.0_pReal) extmsg = trim(extmsg)//' Q_sb' + if (prm%p_sb <= 0.0_pReal) extmsg = trim(extmsg)//' p_sb' + if (prm%q_sb <= 0.0_pReal) extmsg = trim(extmsg)//' q_sb' endif !-------------------------------------------------------------------------------------------------- ! parameters required for several mechanisms and their interactions if(prm%sum_N_sl + prm%sum_N_tw + prm%sum_N_tw > 0) & - prm%D = config%getFloat('grainsize') + prm%D = pl%get_asFloat('D') twinOrSlipActive: if (prm%sum_N_tw + prm%sum_N_tr > 0) then - prm%SFE_0K = config%getFloat('sfe_0k') - prm%dSFE_dT = config%getFloat('dsfe_dt') - prm%V_cs = config%getFloat('vcrossslip') + prm%SFE_0K = pl%get_asFloat('Gamma_sf_0K') + prm%dSFE_dT = pl%get_asFloat('dGamma_sf_dT') + prm%V_cs = pl%get_asFloat('V_cs') endif twinOrSlipActive slipAndTwinActive: if (prm%sum_N_sl * prm%sum_N_tw > 0) then prm%h_sl_tw = lattice_interaction_SlipByTwin(N_sl,N_tw,& - config%getFloats('interaction_sliptwin'), & - config%getString('lattice_structure')) + pl%get_asFloats('h_sl_tw'), & + phase%get_asString('lattice')) if (prm%fccTwinTransNucleation .and. size(N_tw) /= 1) extmsg = trim(extmsg)//' interaction_sliptwin' endif slipAndTwinActive slipAndTransActive: if (prm%sum_N_sl * prm%sum_N_tr > 0) then prm%h_sl_tr = lattice_interaction_SlipByTrans(N_sl,N_tr,& - config%getFloats('interaction_sliptrans'), & - config%getString('lattice_structure')) + pl%get_asFloats('h_sl_tr'), & + phase%get_asString('lattice')) if (prm%fccTwinTransNucleation .and. size(N_tr) /= 1) extmsg = trim(extmsg)//' interaction_sliptrans' endif slipAndTransActive @@ -397,7 +414,8 @@ module subroutine plastic_dislotwin_init + size(['f_tr']) * prm%sum_N_tr sizeState = sizeDotState - call material_allocateState(plasticState(p),NipcMyPhase,sizeState,sizeDotState,0) + + call constitutive_allocateState(plasticState(p),NipcMyPhase,sizeState,sizeDotState,0) !-------------------------------------------------------------------------------------------------- ! locally defined state aliases and initialization of state0 and atol @@ -406,7 +424,7 @@ module subroutine plastic_dislotwin_init stt%rho_mob=>plasticState(p)%state(startIndex:endIndex,:) stt%rho_mob= spread(rho_mob_0,2,NipcMyPhase) dot%rho_mob=>plasticState(p)%dotState(startIndex:endIndex,:) - plasticState(p)%atol(startIndex:endIndex) = config%getFloat('atol_rho',defaultVal=1.0_pReal) + plasticState(p)%atol(startIndex:endIndex) = pl%get_asFloat('atol_rho',defaultVal=1.0_pReal) if (any(plasticState(p)%atol(startIndex:endIndex) < 0.0_pReal)) extmsg = trim(extmsg)//' atol_rho' startIndex = endIndex + 1 @@ -414,7 +432,7 @@ module subroutine plastic_dislotwin_init stt%rho_dip=>plasticState(p)%state(startIndex:endIndex,:) stt%rho_dip= spread(rho_dip_0,2,NipcMyPhase) dot%rho_dip=>plasticState(p)%dotState(startIndex:endIndex,:) - plasticState(p)%atol(startIndex:endIndex) = config%getFloat('atol_rho',defaultVal=1.0_pReal) + plasticState(p)%atol(startIndex:endIndex) = pl%get_asFloat('atol_rho',defaultVal=1.0_pReal) startIndex = endIndex + 1 endIndex = endIndex + prm%sum_N_sl @@ -428,14 +446,14 @@ module subroutine plastic_dislotwin_init endIndex = endIndex + prm%sum_N_tw stt%f_tw=>plasticState(p)%state(startIndex:endIndex,:) dot%f_tw=>plasticState(p)%dotState(startIndex:endIndex,:) - plasticState(p)%atol(startIndex:endIndex) = config%getFloat('f_twin',defaultVal=1.0e-7_pReal) + plasticState(p)%atol(startIndex:endIndex) = pl%get_asFloat('f_twin',defaultVal=1.0e-7_pReal) if (any(plasticState(p)%atol(startIndex:endIndex) < 0.0_pReal)) extmsg = trim(extmsg)//' f_twin' startIndex = endIndex + 1 endIndex = endIndex + prm%sum_N_tr stt%f_tr=>plasticState(p)%state(startIndex:endIndex,:) dot%f_tr=>plasticState(p)%dotState(startIndex:endIndex,:) - plasticState(p)%atol(startIndex:endIndex) = config%getFloat('f_trans',defaultVal=1.0e-6_pReal) + plasticState(p)%atol(startIndex:endIndex) = pl%get_asFloat('f_trans',defaultVal=1.0e-6_pReal) if (any(plasticState(p)%atol(startIndex:endIndex) < 0.0_pReal)) extmsg = trim(extmsg)//' f_trans' allocate(dst%Lambda_sl (prm%sum_N_sl,NipcMyPhase),source=0.0_pReal) @@ -457,11 +475,11 @@ module subroutine plastic_dislotwin_init !-------------------------------------------------------------------------------------------------- ! exit if any parameter is out of range - if (extmsg /= '') call IO_error(211,ext_msg=trim(extmsg)//'('//PLASTICITY_DISLOTWIN_LABEL//')') + if (extmsg /= '') call IO_error(211,ext_msg=trim(extmsg)//'(dislotwin)') enddo -end subroutine plastic_dislotwin_init +end function plastic_dislotwin_init !-------------------------------------------------------------------------------------------------- @@ -824,33 +842,33 @@ module subroutine plastic_dislotwin_results(instance,group) select case(trim(prm%output(o))) case('rho_mob') - if(prm%sum_N_sl>0) call results_writeDataset(group,stt%rho_mob,'rho_mob',& + if(prm%sum_N_sl>0) call results_writeDataset(group,stt%rho_mob,trim(prm%output(o)), & 'mobile dislocation density','1/m²') case('rho_dip') - if(prm%sum_N_sl>0) call results_writeDataset(group,stt%rho_dip,'rho_dip',& + if(prm%sum_N_sl>0) call results_writeDataset(group,stt%rho_dip,trim(prm%output(o)), & 'dislocation dipole density','1/m²') case('gamma_sl') - if(prm%sum_N_sl>0) call results_writeDataset(group,stt%gamma_sl,'gamma_sl',& + if(prm%sum_N_sl>0) call results_writeDataset(group,stt%gamma_sl,trim(prm%output(o)), & 'plastic shear','1') - case('lambda_sl') - if(prm%sum_N_sl>0) call results_writeDataset(group,dst%Lambda_sl,'Lambda_sl',& + case('Lambda_sl') + if(prm%sum_N_sl>0) call results_writeDataset(group,dst%Lambda_sl,trim(prm%output(o)), & 'mean free path for slip','m') case('tau_pass') - if(prm%sum_N_sl>0) call results_writeDataset(group,dst%tau_pass,'tau_pass',& + if(prm%sum_N_sl>0) call results_writeDataset(group,dst%tau_pass,trim(prm%output(o)), & 'passing stress for slip','Pa') case('f_tw') - if(prm%sum_N_tw>0) call results_writeDataset(group,stt%f_tw,'f_tw',& + if(prm%sum_N_tw>0) call results_writeDataset(group,stt%f_tw,trim(prm%output(o)), & 'twinned volume fraction','m³/m³') - case('lambda_tw') - if(prm%sum_N_tw>0) call results_writeDataset(group,dst%Lambda_tw,'Lambda_tw',& + case('Lambda_tw') + if(prm%sum_N_tw>0) call results_writeDataset(group,dst%Lambda_tw,trim(prm%output(o)), & 'mean free path for twinning','m') case('tau_hat_tw') - if(prm%sum_N_tw>0) call results_writeDataset(group,dst%tau_hat_tw,'tau_hat_tw',& + if(prm%sum_N_tw>0) call results_writeDataset(group,dst%tau_hat_tw,trim(prm%output(o)), & 'threshold stress for twinning','Pa') case('f_tr') - if(prm%sum_N_tr>0) call results_writeDataset(group,stt%f_tr,'f_tr',& + if(prm%sum_N_tr>0) call results_writeDataset(group,stt%f_tr,trim(prm%output(o)), & 'martensite volume fraction','m³/m³') end select diff --git a/src/constitutive_plastic_isotropic.f90 b/src/constitutive_plastic_isotropic.f90 index 3484b6f64..adb87c0b1 100644 --- a/src/constitutive_plastic_isotropic.f90 +++ b/src/constitutive_plastic_isotropic.f90 @@ -49,58 +49,78 @@ contains !> @brief Perform module initialization. !> @details reads in material parameters, allocates arrays, and does sanity checks !-------------------------------------------------------------------------------------------------- -module subroutine plastic_isotropic_init +module function plastic_isotropic_init() result(myPlasticity) + logical, dimension(:), allocatable :: myPlasticity integer :: & Ninstance, & p, & + i, & NipcMyPhase, & sizeState, sizeDotState real(pReal) :: & xi_0 !< initial critical stress character(len=pStringLen) :: & extmsg = '' + class(tNode), pointer :: & + phases, & + phase, & + pl - write(6,'(/,a)') ' <<<+- plastic_'//PLASTICITY_ISOTROPIC_LABEL//' init -+>>>' + write(6,'(/,a)') ' <<<+- plastic_isotropic init -+>>>' write(6,'(/,a)') ' Maiti and Eisenlohr, Scripta Materialia 145:37–40, 2018' write(6,'(a)') ' https://doi.org/10.1016/j.scriptamat.2017.09.047' - Ninstance = count(phase_plasticity == PLASTICITY_ISOTROPIC_ID) + + myPlasticity = plastic_active('isotropic') + + Ninstance = count(myPlasticity) write(6,'(a16,1x,i5,/)') '# instances:',Ninstance; flush(6) + if(Ninstance == 0) return allocate(param(Ninstance)) allocate(state(Ninstance)) allocate(dotState(Ninstance)) - do p = 1, size(phase_plasticity) - if (phase_plasticity(p) /= PLASTICITY_ISOTROPIC_ID) cycle - associate(prm => param(phase_plasticityInstance(p)), & - dot => dotState(phase_plasticityInstance(p)), & - stt => state(phase_plasticityInstance(p)), & - config => config_phase(p)) + phases => material_root%get('phase') + i = 0 + do p = 1, phases%length + phase => phases%get(p) - prm%output = config%getStrings('(output)',defaultVal=emptyStringArray) + if(.not. myPlasticity(p)) cycle + i = i + 1 + associate(prm => param(i), & + dot => dotState(i), & + stt => state(i)) + pl => phase%get('plasticity') + + +#if defined (__GFORTRAN__) + prm%output = output_asStrings(pl) +#else + prm%output = pl%get_asStrings('output',defaultVal=emptyStringArray) +#endif #ifdef DEBUG if (p==material_phaseAt(debugConstitutive%grain,debugConstitutive%element)) & prm%of_debug = material_phasememberAt(debugConstitutive%grain,debugConstitutive%ip,debugConstitutive%element) #endif - xi_0 = config%getFloat('tau0') - prm%xi_inf = config%getFloat('tausat') - prm%dot_gamma_0 = config%getFloat('gdot0') - prm%n = config%getFloat('n') - prm%h0 = config%getFloat('h0') - prm%M = config%getFloat('m') - prm%h_ln = config%getFloat('h0_slopelnrate', defaultVal=0.0_pReal) - prm%c_1 = config%getFloat('tausat_sinhfita',defaultVal=0.0_pReal) - prm%c_4 = config%getFloat('tausat_sinhfitb',defaultVal=0.0_pReal) - prm%c_3 = config%getFloat('tausat_sinhfitc',defaultVal=0.0_pReal) - prm%c_2 = config%getFloat('tausat_sinhfitd',defaultVal=0.0_pReal) - prm%a = config%getFloat('a') + xi_0 = pl%get_asFloat('xi_0') + prm%xi_inf = pl%get_asFloat('xi_inf') + prm%dot_gamma_0 = pl%get_asFloat('dot_gamma_0') + prm%n = pl%get_asFloat('n') + prm%h0 = pl%get_asFloat('h_0') + prm%M = pl%get_asFloat('M') + prm%h_ln = pl%get_asFloat('h_ln', defaultVal=0.0_pReal) + prm%c_1 = pl%get_asFloat('c_1', defaultVal=0.0_pReal) + prm%c_4 = pl%get_asFloat('c_4', defaultVal=0.0_pReal) + prm%c_3 = pl%get_asFloat('c_3', defaultVal=0.0_pReal) + prm%c_2 = pl%get_asFloat('c_2', defaultVal=0.0_pReal) + prm%a = pl%get_asFloat('a') - prm%dilatation = config%keyExists('/dilatation/') + prm%dilatation = pl%get_AsBool('dilatation',defaultVal = .false.) !-------------------------------------------------------------------------------------------------- ! sanity checks @@ -113,22 +133,22 @@ module subroutine plastic_isotropic_init !-------------------------------------------------------------------------------------------------- ! allocate state arrays NipcMyPhase = count(material_phaseAt == p) * discretization_nIP - sizeDotState = size(['xi ','accumulated_shear']) + sizeDotState = size(['xi ','gamma']) sizeState = sizeDotState - call material_allocateState(plasticState(p),NipcMyPhase,sizeState,sizeDotState,0) + call constitutive_allocateState(plasticState(p),NipcMyPhase,sizeState,sizeDotState,0) !-------------------------------------------------------------------------------------------------- ! state aliases and initialization stt%xi => plasticState(p)%state (1,:) stt%xi = xi_0 dot%xi => plasticState(p)%dotState(1,:) - plasticState(p)%atol(1) = config%getFloat('atol_xi',defaultVal=1.0_pReal) + plasticState(p)%atol(1) = pl%get_asFloat('atol_xi',defaultVal=1.0_pReal) if (plasticState(p)%atol(1) < 0.0_pReal) extmsg = trim(extmsg)//' atol_xi' stt%gamma => plasticState(p)%state (2,:) dot%gamma => plasticState(p)%dotState(2,:) - plasticState(p)%atol(2) = config%getFloat('atol_gamma',defaultVal=1.0e-6_pReal) + plasticState(p)%atol(2) = pl%get_asFloat('atol_gamma',defaultVal=1.0e-6_pReal) if (plasticState(p)%atol(2) < 0.0_pReal) extmsg = trim(extmsg)//' atol_gamma' ! global alias plasticState(p)%slipRate => plasticState(p)%dotState(2:2,:) @@ -139,11 +159,11 @@ module subroutine plastic_isotropic_init !-------------------------------------------------------------------------------------------------- ! exit if any parameter is out of range - if (extmsg /= '') call IO_error(211,ext_msg=trim(extmsg)//'('//PLASTICITY_ISOTROPIC_LABEL//')') + if (extmsg /= '') call IO_error(211,ext_msg=trim(extmsg)//'(isotropic)') enddo -end subroutine plastic_isotropic_init +end function plastic_isotropic_init !-------------------------------------------------------------------------------------------------- @@ -319,8 +339,9 @@ module subroutine plastic_isotropic_results(instance,group) associate(prm => param(instance), stt => state(instance)) outputsLoop: do o = 1,size(prm%output) select case(trim(prm%output(o))) - case ('flowstress') ! ToDo: should be 'xi' - call results_writeDataset(group,stt%xi,'xi','resistance against plastic flow','Pa') + case ('xi') + call results_writeDataset(group,stt%xi,trim(prm%output(o)), & + 'resistance against plastic flow','Pa') end select enddo outputsLoop end associate diff --git a/src/constitutive_plastic_kinehardening.f90 b/src/constitutive_plastic_kinehardening.f90 index 163b5794a..ffbfb6a13 100644 --- a/src/constitutive_plastic_kinehardening.f90 +++ b/src/constitutive_plastic_kinehardening.f90 @@ -58,11 +58,12 @@ contains !> @brief Perform module initialization. !> @details reads in material parameters, allocates arrays, and does sanity checks !-------------------------------------------------------------------------------------------------- -module subroutine plastic_kinehardening_init +module function plastic_kinehardening_init() result(myPlasticity) + logical, dimension(:), allocatable :: myPlasticity integer :: & Ninstance, & - p, o, & + p, i, o, & NipcMyPhase, & sizeState, sizeDeltaState, sizeDotState, & startIndex, endIndex @@ -73,26 +74,42 @@ module subroutine plastic_kinehardening_init a !< non-Schmid coefficients character(len=pStringLen) :: & extmsg = '' + class(tNode), pointer :: & + phases, & + phase, & + pl - write(6,'(/,a)') ' <<<+- plastic_'//PLASTICITY_KINEHARDENING_LABEL//' init -+>>>' + write(6,'(/,a)') ' <<<+- plastic_kinehardening init -+>>>' - Ninstance = count(phase_plasticity == PLASTICITY_KINEHARDENING_ID) + myPlasticity = plastic_active('kinehardening') + + Ninstance = count(myPlasticity) write(6,'(a16,1x,i5,/)') '# instances:',Ninstance; flush(6) + if(Ninstance == 0) return allocate(param(Ninstance)) allocate(state(Ninstance)) allocate(dotState(Ninstance)) allocate(deltaState(Ninstance)) - do p = 1, size(phase_plasticityInstance) - if (phase_plasticity(p) /= PLASTICITY_KINEHARDENING_ID) cycle - associate(prm => param(phase_plasticityInstance(p)), & - dot => dotState(phase_plasticityInstance(p)), & - dlt => deltaState(phase_plasticityInstance(p)), & - stt => state(phase_plasticityInstance(p)),& - config => config_phase(p)) + phases => material_root%get('phase') + i = 0 + do p = 1, phases%length + phase => phases%get(p) - prm%output = config%getStrings('(output)',defaultVal=emptyStringArray) + if(.not. myPlasticity(p)) cycle + i = i + 1 + associate(prm => param(i), & + dot => dotState(i), & + dlt => deltaState(i), & + stt => state(i)) + pl => phase%get('plasticity') + +#if defined (__GFORTRAN__) + prm%output = output_asStrings(pl) +#else + prm%output = pl%get_asStrings('output',defaultVal=emptyStringArray) +#endif #ifdef DEBUG if (p==material_phaseAt(debugConstitutive%grain,debugConstitutive%element)) then @@ -102,14 +119,14 @@ module subroutine plastic_kinehardening_init !-------------------------------------------------------------------------------------------------- ! slip related parameters - N_sl = config%getInts('nslip',defaultVal=emptyIntArray) + N_sl = pl%get_asInts('N_sl',defaultVal=emptyIntArray) prm%sum_N_sl = sum(abs(N_sl)) slipActive: if (prm%sum_N_sl > 0) then - prm%P = lattice_SchmidMatrix_slip(N_sl,config%getString('lattice_structure'),& - config%getFloat('c/a',defaultVal=0.0_pReal)) + prm%P = lattice_SchmidMatrix_slip(N_sl,phase%get_asString('lattice'),& + phase%get_asFloat('c/a',defaultVal=0.0_pReal)) - if(trim(config%getString('lattice_structure')) == 'bcc') then - a = config%getFloats('nonschmid_coefficients',defaultVal = emptyRealArray) + if(trim(phase%get_asString('lattice')) == 'bcc') then + a = pl%get_asFloats('nonSchmid_coefficients',defaultVal = emptyRealArray) if(size(a) > 0) prm%nonSchmidActive = .true. prm%nonSchmid_pos = lattice_nonSchmidMatrix(N_sl,a,+1) prm%nonSchmid_neg = lattice_nonSchmidMatrix(N_sl,a,-1) @@ -118,19 +135,19 @@ module subroutine plastic_kinehardening_init prm%nonSchmid_neg = prm%P endif prm%interaction_SlipSlip = lattice_interaction_SlipBySlip(N_sl, & - config%getFloats('interaction_slipslip'), & - config%getString('lattice_structure')) + pl%get_asFloats('h_sl_sl'), & + phase%get_asString('lattice')) - xi_0 = config%getFloats('crss0', requiredSize=size(N_sl)) - prm%tau1 = config%getFloats('tau1', requiredSize=size(N_sl)) - prm%tau1_b = config%getFloats('tau1_b', requiredSize=size(N_sl)) - prm%theta0 = config%getFloats('theta0', requiredSize=size(N_sl)) - prm%theta1 = config%getFloats('theta1', requiredSize=size(N_sl)) - prm%theta0_b = config%getFloats('theta0_b', requiredSize=size(N_sl)) - prm%theta1_b = config%getFloats('theta1_b', requiredSize=size(N_sl)) + xi_0 = pl%get_asFloats('xi_0', requiredSize=size(N_sl)) + prm%tau1 = pl%get_asFloats('xi_inf_f', requiredSize=size(N_sl)) + prm%tau1_b = pl%get_asFloats('xi_inf_b', requiredSize=size(N_sl)) + prm%theta0 = pl%get_asFloats('h_0_f', requiredSize=size(N_sl)) + prm%theta1 = pl%get_asFloats('h_inf_f', requiredSize=size(N_sl)) + prm%theta0_b = pl%get_asFloats('h_0_b', requiredSize=size(N_sl)) + prm%theta1_b = pl%get_asFloats('h_inf_b', requiredSize=size(N_sl)) - prm%gdot0 = config%getFloat('gdot0') - prm%n = config%getFloat('n_slip') + prm%gdot0 = pl%get_asFloat('dot_gamma_0') + prm%n = pl%get_asFloat('n') ! expand: family => system xi_0 = math_expand(xi_0, N_sl) @@ -143,11 +160,11 @@ module subroutine plastic_kinehardening_init !-------------------------------------------------------------------------------------------------- ! sanity checks - if ( prm%gdot0 <= 0.0_pReal) extmsg = trim(extmsg)//' gdot0' - if ( prm%n <= 0.0_pReal) extmsg = trim(extmsg)//' n_slip' - if (any(xi_0 <= 0.0_pReal)) extmsg = trim(extmsg)//' crss0' - if (any(prm%tau1 <= 0.0_pReal)) extmsg = trim(extmsg)//' tau1' - if (any(prm%tau1_b <= 0.0_pReal)) extmsg = trim(extmsg)//' tau1_b' + if ( prm%gdot0 <= 0.0_pReal) extmsg = trim(extmsg)//' dot_gamma_0' + if ( prm%n <= 0.0_pReal) extmsg = trim(extmsg)//' n' + if (any(xi_0 <= 0.0_pReal)) extmsg = trim(extmsg)//' xi_0' + if (any(prm%tau1 <= 0.0_pReal)) extmsg = trim(extmsg)//' xi_inf_f' + if (any(prm%tau1_b <= 0.0_pReal)) extmsg = trim(extmsg)//' xi_inf_b' !ToDo: Any sensible checks for theta? else slipActive @@ -159,11 +176,11 @@ module subroutine plastic_kinehardening_init !-------------------------------------------------------------------------------------------------- ! allocate state arrays NipcMyPhase = count(material_phaseAt == p) * discretization_nIP - sizeDotState = size(['crss ','crss_back', 'accshear ']) * prm%sum_N_sl - sizeDeltaState = size(['sense ', 'chi0 ', 'gamma0' ]) * prm%sum_N_sl + sizeDotState = size(['crss ','crss_back', 'accshear ']) * prm%sum_N_sl!ToDo: adjust names, ask Philip + sizeDeltaState = size(['sense ', 'chi0 ', 'gamma0' ]) * prm%sum_N_sl !ToDo: adjust names sizeState = sizeDotState + sizeDeltaState - call material_allocateState(plasticState(p),NipcMyPhase,sizeState,sizeDotState,sizeDeltaState) + call constitutive_allocateState(plasticState(p),NipcMyPhase,sizeState,sizeDotState,sizeDeltaState) !-------------------------------------------------------------------------------------------------- ! state aliases and initialization @@ -172,20 +189,20 @@ module subroutine plastic_kinehardening_init stt%crss => plasticState(p)%state (startIndex:endIndex,:) stt%crss = spread(xi_0, 2, NipcMyPhase) dot%crss => plasticState(p)%dotState(startIndex:endIndex,:) - plasticState(p)%atol(startIndex:endIndex) = config%getFloat('atol_xi',defaultVal=1.0_pReal) + plasticState(p)%atol(startIndex:endIndex) = pl%get_asFloat('atol_xi',defaultVal=1.0_pReal) if(any(plasticState(p)%atol(startIndex:endIndex) < 0.0_pReal)) extmsg = trim(extmsg)//' atol_xi' startIndex = endIndex + 1 endIndex = endIndex + prm%sum_N_sl stt%crss_back => plasticState(p)%state (startIndex:endIndex,:) dot%crss_back => plasticState(p)%dotState(startIndex:endIndex,:) - plasticState(p)%atol(startIndex:endIndex) = config%getFloat('atol_xi',defaultVal=1.0_pReal) + plasticState(p)%atol(startIndex:endIndex) = pl%get_asFloat('atol_xi',defaultVal=1.0_pReal) startIndex = endIndex + 1 endIndex = endIndex + prm%sum_N_sl stt%accshear => plasticState(p)%state (startIndex:endIndex,:) dot%accshear => plasticState(p)%dotState(startIndex:endIndex,:) - plasticState(p)%atol(startIndex:endIndex) = config%getFloat('atol_gamma',defaultVal=1.0e-6_pReal) + plasticState(p)%atol(startIndex:endIndex) = pl%get_asFloat('atol_gamma',defaultVal=1.0e-6_pReal) if(any(plasticState(p)%atol(startIndex:endIndex) < 0.0_pReal)) extmsg = trim(extmsg)//' atol_gamma' ! global alias plasticState(p)%slipRate => plasticState(p)%dotState(startIndex:endIndex,:) @@ -212,12 +229,12 @@ module subroutine plastic_kinehardening_init !-------------------------------------------------------------------------------------------------- ! exit if any parameter is out of range - if (extmsg /= '') call IO_error(211,ext_msg=trim(extmsg)//'('//PLASTICITY_KINEHARDENING_LABEL//')') + if (extmsg /= '') call IO_error(211,ext_msg=trim(extmsg)//'(kinehardening)') enddo -end subroutine plastic_kinehardening_init +end function plastic_kinehardening_init !-------------------------------------------------------------------------------------------------- @@ -364,23 +381,23 @@ module subroutine plastic_kinehardening_results(instance,group) associate(prm => param(instance), stt => state(instance)) outputsLoop: do o = 1,size(prm%output) select case(trim(prm%output(o))) - case('resistance') - if(prm%sum_N_sl>0) call results_writeDataset(group,stt%crss,'xi_sl', & + case('xi') + if(prm%sum_N_sl>0) call results_writeDataset(group,stt%crss,trim(prm%output(o)), & 'resistance against plastic slip','Pa') - case('backstress') ! ToDo: should be 'tau_back' - if(prm%sum_N_sl>0) call results_writeDataset(group,stt%crss_back,'tau_back', & + case('tau_b') + if(prm%sum_N_sl>0) call results_writeDataset(group,stt%crss_back,trim(prm%output(o)), & 'back stress against plastic slip','Pa') - case ('sense') - if(prm%sum_N_sl>0) call results_writeDataset(group,stt%sense,'sense_of_shear', & + case ('sgn(gamma)') + if(prm%sum_N_sl>0) call results_writeDataset(group,stt%sense,trim(prm%output(o)), & ! ToDo: could be int 'tbd','1') - case ('chi0') - if(prm%sum_N_sl>0) call results_writeDataset(group,stt%chi0,'chi0', & + case ('chi_0') + if(prm%sum_N_sl>0) call results_writeDataset(group,stt%chi0,trim(prm%output(o)), & 'tbd','Pa') - case ('gamma0') - if(prm%sum_N_sl>0) call results_writeDataset(group,stt%gamma0,'gamma0', & + case ('gamma_0') + if(prm%sum_N_sl>0) call results_writeDataset(group,stt%gamma0,trim(prm%output(o)), & 'tbd','1') - case ('accumulatedshear') - if(prm%sum_N_sl>0) call results_writeDataset(group,stt%accshear,'gamma_sl', & + case ('gamma') + if(prm%sum_N_sl>0) call results_writeDataset(group,stt%accshear,trim(prm%output(o)), & 'plastic shear','1') end select enddo outputsLoop diff --git a/src/constitutive_plastic_none.f90 b/src/constitutive_plastic_none.f90 index 4e6033499..283dac75b 100644 --- a/src/constitutive_plastic_none.f90 +++ b/src/constitutive_plastic_none.f90 @@ -12,26 +12,40 @@ contains !> @brief module initialization !> @details reads in material parameters, allocates arrays, and does sanity checks !-------------------------------------------------------------------------------------------------- -module subroutine plastic_none_init +module function plastic_none_init() result(myPlasticity) + logical, dimension(:), allocatable :: myPlasticity integer :: & Ninstance, & p, & NipcMyPhase + class(tNode), pointer :: & + phases, & + phase, & + pl - write(6,'(/,a)') ' <<<+- plastic_'//PLASTICITY_NONE_LABEL//' init -+>>>' - - Ninstance = count(phase_plasticity == PLASTICITY_NONE_ID) - write(6,'(a16,1x,i5,/)') '# instances:',Ninstance; flush(6) - - do p = 1, size(phase_plasticity) - if (phase_plasticity(p) /= PLASTICITY_NONE_ID) cycle - - NipcMyPhase = count(material_phaseAt == p) * discretization_nIP - call material_allocateState(plasticState(p),NipcMyPhase,0,0,0) + write(6,'(/,a)') ' <<<+- plastic_none init -+>>>' + phases => material_root%get('phase') + allocate(myPlasticity(phases%length), source = .false. ) + do p = 1, phases%length + phase => phases%get(p) + pl => phase%get('plasticity') + if(pl%get_asString('type') == 'none') myPlasticity(p) = .true. enddo -end subroutine plastic_none_init + Ninstance = count(myPlasticity) + write(6,'(a16,1x,i5,/)') '# instances:',Ninstance; flush(6) + if(Ninstance == 0) return + + do p = 1, phases%length + phase => phases%get(p) + if(.not. myPlasticity(p)) cycle + NipcMyPhase = count(material_phaseAt == p) * discretization_nIP + call constitutive_allocateState(plasticState(p),NipcMyPhase,0,0,0) + enddo + +end function plastic_none_init + end submodule plastic_none diff --git a/src/constitutive_plastic_nonlocal.f90 b/src/constitutive_plastic_nonlocal.f90 index 4971b48f5..f16dbbf1a 100644 --- a/src/constitutive_plastic_nonlocal.f90 +++ b/src/constitutive_plastic_nonlocal.f90 @@ -163,11 +163,12 @@ contains !> @brief module initialization !> @details reads in material parameters, allocates arrays, and does sanity checks !-------------------------------------------------------------------------------------------------- -module subroutine plastic_nonlocal_init +module function plastic_nonlocal_init() result(myPlasticity) + logical, dimension(:), allocatable :: myPlasticity integer :: & Ninstance, & - p, & + p, i, & NipcMyPhase, & sizeState, sizeDotState, sizeDependentState, sizeDeltaState, & s1, s2, & @@ -178,8 +179,12 @@ module subroutine plastic_nonlocal_init extmsg = '' type(tInitialParameters) :: & ini - - write(6,'(/,a)') ' <<<+- constitutive_'//PLASTICITY_NONLOCAL_LABEL//' init -+>>>' + class(tNode), pointer :: & + phases, & + phase, & + pl + + write(6,'(/,a)') ' <<<+- plastic_nonlocal init -+>>>' write(6,'(/,a)') ' Reuber et al., Acta Materialia 71:333–348, 2014' write(6,'(a)') ' https://doi.org/10.1016/j.actamat.2014.03.012' @@ -187,8 +192,15 @@ module subroutine plastic_nonlocal_init write(6,'(/,a)') ' Kords, Dissertation RWTH Aachen, 2014' write(6,'(a)') ' http://publications.rwth-aachen.de/record/229993' - Ninstance = count(phase_plasticity == PLASTICITY_NONLOCAL_ID) + myPlasticity = plastic_active('nonlocal') + + Ninstance = count(myPlasticity) write(6,'(a16,1x,i5,/)') '# instances:',Ninstance; flush(6) + if(Ninstance == 0) then + call geometry_plastic_nonlocal_disable + return + endif + allocate(param(Ninstance)) allocate(state(Ninstance)) @@ -197,33 +209,43 @@ module subroutine plastic_nonlocal_init allocate(deltaState(Ninstance)) allocate(microstructure(Ninstance)) - do p=1, size(config_phase) - if (phase_plasticity(p) /= PLASTICITY_NONLOCAL_ID) cycle + phases => material_root%get('phase') + i = 0 + do p = 1, phases%length + phase => phases%get(p) - associate(prm => param(phase_plasticityInstance(p)), & - dot => dotState(phase_plasticityInstance(p)), & - stt => state(phase_plasticityInstance(p)), & - st0 => state0(phase_plasticityInstance(p)), & - del => deltaState(phase_plasticityInstance(p)), & - dst => microstructure(phase_plasticityInstance(p)), & - config => config_phase(p)) + if(.not. myPlasticity(p)) cycle + i = i + 1 + associate(prm => param(i), & + dot => dotState(i), & + stt => state(i), & + st0 => state0(i), & + del => deltaState(i), & + dst => microstructure(i)) + pl => phase%get('plasticity') - prm%output = config%getStrings('(output)',defaultVal=emptyStringArray) + phase_localPlasticity(p) = .not. pl%contains('nonlocal') - prm%atol_rho = config%getFloat('atol_rho',defaultVal=1.0e4_pReal) +#if defined (__GFORTRAN__) + prm%output = output_asStrings(pl) +#else + prm%output = pl%get_asStrings('output',defaultVal=emptyStringArray) +#endif + + prm%atol_rho = pl%get_asFloat('atol_rho',defaultVal=1.0e4_pReal) ! This data is read in already in lattice prm%mu = lattice_mu(p) prm%nu = lattice_nu(p) - ini%N_sl = config%getInts('nslip',defaultVal=emptyIntArray) + ini%N_sl = pl%get_asInts('N_sl',defaultVal=emptyIntArray) prm%sum_N_sl = sum(abs(ini%N_sl)) slipActive: if (prm%sum_N_sl > 0) then - prm%Schmid = lattice_SchmidMatrix_slip(ini%N_sl,config%getString('lattice_structure'),& - config%getFloat('c/a',defaultVal=0.0_pReal)) + prm%Schmid = lattice_SchmidMatrix_slip(ini%N_sl,phase%get_asString('lattice'),& + phase%get_asFloat('c/a',defaultVal=0.0_pReal)) - if(trim(config%getString('lattice_structure')) == 'bcc') then - a = config%getFloats('nonschmid_coefficients',defaultVal = emptyRealArray) + if(trim(phase%get_asString('lattice')) == 'bcc') then + a = pl%get_asFloats('nonSchmid_coefficients',defaultVal = emptyRealArray) if(size(a) > 0) prm%nonSchmidActive = .true. prm%nonSchmid_pos = lattice_nonSchmidMatrix(ini%N_sl,a,+1) prm%nonSchmid_neg = lattice_nonSchmidMatrix(ini%N_sl,a,-1) @@ -233,20 +255,20 @@ module subroutine plastic_nonlocal_init endif prm%interactionSlipSlip = lattice_interaction_SlipBySlip(ini%N_sl, & - config%getFloats('interaction_slipslip'), & - config%getString('lattice_structure')) + pl%get_asFloats('h_sl_sl'), & + phase%get_asString('lattice')) - prm%forestProjection_edge = lattice_forestProjection_edge (ini%N_sl,config%getString('lattice_structure'),& - config%getFloat('c/a',defaultVal=0.0_pReal)) - prm%forestProjection_screw = lattice_forestProjection_screw(ini%N_sl,config%getString('lattice_structure'),& - config%getFloat('c/a',defaultVal=0.0_pReal)) + prm%forestProjection_edge = lattice_forestProjection_edge (ini%N_sl,phase%get_asString('lattice'),& + phase%get_asFloat('c/a',defaultVal=0.0_pReal)) + prm%forestProjection_screw = lattice_forestProjection_screw(ini%N_sl,phase%get_asString('lattice'),& + phase%get_asFloat('c/a',defaultVal=0.0_pReal)) - prm%slip_direction = lattice_slip_direction (ini%N_sl,config%getString('lattice_structure'),& - config%getFloat('c/a',defaultVal=0.0_pReal)) - prm%slip_transverse = lattice_slip_transverse(ini%N_sl,config%getString('lattice_structure'),& - config%getFloat('c/a',defaultVal=0.0_pReal)) - prm%slip_normal = lattice_slip_normal (ini%N_sl,config%getString('lattice_structure'),& - config%getFloat('c/a',defaultVal=0.0_pReal)) + prm%slip_direction = lattice_slip_direction (ini%N_sl,phase%get_asString('lattice'),& + phase%get_asFloat('c/a',defaultVal=0.0_pReal)) + prm%slip_transverse = lattice_slip_transverse(ini%N_sl,phase%get_asString('lattice'),& + phase%get_asFloat('c/a',defaultVal=0.0_pReal)) + prm%slip_normal = lattice_slip_normal (ini%N_sl,phase%get_asString('lattice'),& + phase%get_asFloat('c/a',defaultVal=0.0_pReal)) ! collinear systems (only for octahedral slip systems in fcc) allocate(prm%colinearSystem(prm%sum_N_sl), source = -1) @@ -258,113 +280,113 @@ module subroutine plastic_nonlocal_init enddo enddo - ini%rhoSglEdgePos0 = config%getFloats('rhosgledgepos0', requiredSize=size(ini%N_sl)) - ini%rhoSglEdgeNeg0 = config%getFloats('rhosgledgeneg0', requiredSize=size(ini%N_sl)) - ini%rhoSglScrewPos0 = config%getFloats('rhosglscrewpos0', requiredSize=size(ini%N_sl)) - ini%rhoSglScrewNeg0 = config%getFloats('rhosglscrewneg0', requiredSize=size(ini%N_sl)) - ini%rhoDipEdge0 = config%getFloats('rhodipedge0', requiredSize=size(ini%N_sl)) - ini%rhoDipScrew0 = config%getFloats('rhodipscrew0', requiredSize=size(ini%N_sl)) + ini%rhoSglEdgePos0 = pl%get_asFloats('rho_u_ed_pos_0', requiredSize=size(ini%N_sl)) + ini%rhoSglEdgeNeg0 = pl%get_asFloats('rho_u_ed_neg_0', requiredSize=size(ini%N_sl)) + ini%rhoSglScrewPos0 = pl%get_asFloats('rho_u_sc_pos_0', requiredSize=size(ini%N_sl)) + ini%rhoSglScrewNeg0 = pl%get_asFloats('rho_u_sc_neg_0', requiredSize=size(ini%N_sl)) + ini%rhoDipEdge0 = pl%get_asFloats('rho_d_ed_0', requiredSize=size(ini%N_sl)) + ini%rhoDipScrew0 = pl%get_asFloats('rho_d_sc_0', requiredSize=size(ini%N_sl)) - prm%lambda0 = config%getFloats('lambda0', requiredSize=size(ini%N_sl)) - prm%burgers = config%getFloats('burgers', requiredSize=size(ini%N_sl)) + prm%lambda0 = pl%get_asFloats('i_sl', requiredSize=size(ini%N_sl)) + prm%burgers = pl%get_asFloats('b_sl', requiredSize=size(ini%N_sl)) prm%lambda0 = math_expand(prm%lambda0,ini%N_sl) prm%burgers = math_expand(prm%burgers,ini%N_sl) - prm%minDipoleHeight_edge = config%getFloats('minimumdipoleheightedge', requiredSize=size(ini%N_sl)) - prm%minDipoleHeight_screw = config%getFloats('minimumdipoleheightscrew', requiredSize=size(ini%N_sl)) + prm%minDipoleHeight_edge = pl%get_asFloats('d_ed', requiredSize=size(ini%N_sl)) + prm%minDipoleHeight_screw = pl%get_asFloats('d_sc', requiredSize=size(ini%N_sl)) prm%minDipoleHeight_edge = math_expand(prm%minDipoleHeight_edge, ini%N_sl) prm%minDipoleHeight_screw = math_expand(prm%minDipoleHeight_screw,ini%N_sl) allocate(prm%minDipoleHeight(prm%sum_N_sl,2)) prm%minDipoleHeight(:,1) = prm%minDipoleHeight_edge prm%minDipoleHeight(:,2) = prm%minDipoleHeight_screw - prm%peierlsstress_edge = config%getFloats('peierlsstressedge', requiredSize=size(ini%N_sl)) - prm%peierlsstress_screw = config%getFloats('peierlsstressscrew', requiredSize=size(ini%N_sl)) + prm%peierlsstress_edge = pl%get_asFloats('tau_peierls_ed', requiredSize=size(ini%N_sl)) + prm%peierlsstress_screw = pl%get_asFloats('tau_peierls_sc', requiredSize=size(ini%N_sl)) prm%peierlsstress_edge = math_expand(prm%peierlsstress_edge, ini%N_sl) prm%peierlsstress_screw = math_expand(prm%peierlsstress_screw,ini%N_sl) allocate(prm%peierlsstress(prm%sum_N_sl,2)) prm%peierlsstress(:,1) = prm%peierlsstress_edge prm%peierlsstress(:,2) = prm%peierlsstress_screw - prm%significantRho = config%getFloat('significantrho') - prm%significantN = config%getFloat('significantn', 0.0_pReal) - prm%CFLfactor = config%getFloat('cflfactor',defaultVal=2.0_pReal) + prm%significantRho = pl%get_asFloat('rho_significant') + prm%significantN = pl%get_asFloat('rho_num_significant', 0.0_pReal) + prm%CFLfactor = pl%get_asFloat('f_c',defaultVal=2.0_pReal) - prm%atomicVolume = config%getFloat('atomicvolume') - prm%Dsd0 = config%getFloat('selfdiffusionprefactor') !,'dsd0' - prm%selfDiffusionEnergy = config%getFloat('selfdiffusionenergy') !,'qsd' - prm%linetensionEffect = config%getFloat('linetension') - prm%edgeJogFactor = config%getFloat('edgejog')!,'edgejogs' - prm%doublekinkwidth = config%getFloat('doublekinkwidth') - prm%solidSolutionEnergy = config%getFloat('solidsolutionenergy') - prm%solidSolutionSize = config%getFloat('solidsolutionsize') - prm%solidSolutionConcentration = config%getFloat('solidsolutionconcentration') + prm%atomicVolume = pl%get_asFloat('V_at') + prm%Dsd0 = pl%get_asFloat('D_0') !,'dsd0' + prm%selfDiffusionEnergy = pl%get_asFloat('Q_cl') !,'qsd' + prm%linetensionEffect = pl%get_asFloat('f_F') + prm%edgeJogFactor = pl%get_asFloat('f_ed') !,'edgejogs' + prm%doublekinkwidth = pl%get_asFloat('w') + prm%solidSolutionEnergy = pl%get_asFloat('Q_sol') + prm%solidSolutionSize = pl%get_asFloat('f_sol') + prm%solidSolutionConcentration = pl%get_asFloat('c_sol') - prm%p = config%getFloat('p') - prm%q = config%getFloat('q') - prm%viscosity = config%getFloat('viscosity') - prm%fattack = config%getFloat('attackfrequency') + prm%p = pl%get_asFloat('p_sl') + prm%q = pl%get_asFloat('q_sl') + prm%viscosity = pl%get_asFloat('eta') + prm%fattack = pl%get_asFloat('nu_a') ! ToDo: discuss logic - ini%rhoSglScatter = config%getFloat('rhosglscatter') - ini%rhoSglRandom = config%getFloat('rhosglrandom',0.0_pReal) - if (config%keyExists('/rhosglrandom/')) & - ini%rhoSglRandomBinning = config%getFloat('rhosglrandombinning',0.0_pReal) !ToDo: useful default? + ini%rhoSglScatter = pl%get_asFloat('sigma_rho_u') + ini%rhoSglRandom = pl%get_asFloat('random_rho_u',defaultVal= 0.0_pReal) + if (pl%contains('random_rho_u')) & + ini%rhoSglRandomBinning = pl%get_asFloat('random_rho_u_binning',defaultVal=0.0_pReal) !ToDo: useful default? ! if (rhoSglRandom(instance) < 0.0_pReal) & ! if (rhoSglRandomBinning(instance) <= 0.0_pReal) & - prm%surfaceTransmissivity = config%getFloat('surfacetransmissivity',defaultVal=1.0_pReal) - prm%grainboundaryTransmissivity = config%getFloat('grainboundarytransmissivity',defaultVal=-1.0_pReal) - prm%fEdgeMultiplication = config%getFloat('edgemultiplication') - prm%shortRangeStressCorrection = config%keyExists('/shortrangestresscorrection/') + prm%surfaceTransmissivity = pl%get_asFloat('chi_surface',defaultVal=1.0_pReal) + prm%grainboundaryTransmissivity = pl%get_asFloat('chi_GB', defaultVal=-1.0_pReal) + prm%fEdgeMultiplication = pl%get_asFloat('f_ed_mult') + prm%shortRangeStressCorrection = pl%get_asBool('short_range_stress_correction', defaultVal = .false.) !-------------------------------------------------------------------------------------------------- ! sanity checks - if (any(prm%burgers < 0.0_pReal)) extmsg = trim(extmsg)//' burgers' - if (any(prm%lambda0 <= 0.0_pReal)) extmsg = trim(extmsg)//' lambda0' + if (any(prm%burgers < 0.0_pReal)) extmsg = trim(extmsg)//' b_sl' + if (any(prm%lambda0 <= 0.0_pReal)) extmsg = trim(extmsg)//' i_sl' - if (any(ini%rhoSglEdgePos0 < 0.0_pReal)) extmsg = trim(extmsg)//' rhoSglEdgePos0' - if (any(ini%rhoSglEdgeNeg0 < 0.0_pReal)) extmsg = trim(extmsg)//' rhoSglEdgeNeg0' - if (any(ini%rhoSglScrewPos0 < 0.0_pReal)) extmsg = trim(extmsg)//' rhoSglScrewPos0' - if (any(ini%rhoSglScrewNeg0 < 0.0_pReal)) extmsg = trim(extmsg)//' rhoSglScrewNeg0' - if (any(ini%rhoDipEdge0 < 0.0_pReal)) extmsg = trim(extmsg)//' rhoDipEdge0' - if (any(ini%rhoDipScrew0 < 0.0_pReal)) extmsg = trim(extmsg)//' rhoDipScrew0' + if (any(ini%rhoSglEdgePos0 < 0.0_pReal)) extmsg = trim(extmsg)//' rho_u_ed_pos_0' + if (any(ini%rhoSglEdgeNeg0 < 0.0_pReal)) extmsg = trim(extmsg)//' rho_u_ed_neg_0' + if (any(ini%rhoSglScrewPos0 < 0.0_pReal)) extmsg = trim(extmsg)//' rho_u_sc_pos_0' + if (any(ini%rhoSglScrewNeg0 < 0.0_pReal)) extmsg = trim(extmsg)//' rho_u_sc_neg_0' + if (any(ini%rhoDipEdge0 < 0.0_pReal)) extmsg = trim(extmsg)//' rho_d_ed_0' + if (any(ini%rhoDipScrew0 < 0.0_pReal)) extmsg = trim(extmsg)//' rho_d_sc_0' - if (any(prm%peierlsstress < 0.0_pReal)) extmsg = trim(extmsg)//' peierlsstress' - if (any(prm%minDipoleHeight < 0.0_pReal)) extmsg = trim(extmsg)//' minDipoleHeight' + if (any(prm%peierlsstress < 0.0_pReal)) extmsg = trim(extmsg)//' tau_peierls' + if (any(prm%minDipoleHeight < 0.0_pReal)) extmsg = trim(extmsg)//' d_ed or d_sc' - if (prm%viscosity <= 0.0_pReal) extmsg = trim(extmsg)//' viscosity' - if (prm%selfDiffusionEnergy <= 0.0_pReal) extmsg = trim(extmsg)//' selfDiffusionEnergy' - if (prm%fattack <= 0.0_pReal) extmsg = trim(extmsg)//' fattack' - if (prm%doublekinkwidth <= 0.0_pReal) extmsg = trim(extmsg)//' doublekinkwidth' - if (prm%Dsd0 < 0.0_pReal) extmsg = trim(extmsg)//' Dsd0' - if (prm%atomicVolume <= 0.0_pReal) extmsg = trim(extmsg)//' atomicVolume' ! ToDo: in disloUCLA, the atomic volume is given as a factor + if (prm%viscosity <= 0.0_pReal) extmsg = trim(extmsg)//' eta' + if (prm%selfDiffusionEnergy <= 0.0_pReal) extmsg = trim(extmsg)//' Q_cl' + if (prm%fattack <= 0.0_pReal) extmsg = trim(extmsg)//' nu_a' + if (prm%doublekinkwidth <= 0.0_pReal) extmsg = trim(extmsg)//' w' + if (prm%Dsd0 < 0.0_pReal) extmsg = trim(extmsg)//' D_0' + if (prm%atomicVolume <= 0.0_pReal) extmsg = trim(extmsg)//' V_at' ! ToDo: in disloTungsten, the atomic volume is given as a factor - if (prm%significantN < 0.0_pReal) extmsg = trim(extmsg)//' significantN' - if (prm%significantrho < 0.0_pReal) extmsg = trim(extmsg)//' significantrho' + if (prm%significantN < 0.0_pReal) extmsg = trim(extmsg)//' rho_num_significant' + if (prm%significantrho < 0.0_pReal) extmsg = trim(extmsg)//' rho_significant' if (prm%atol_rho < 0.0_pReal) extmsg = trim(extmsg)//' atol_rho' - if (prm%CFLfactor < 0.0_pReal) extmsg = trim(extmsg)//' CFLfactor' + if (prm%CFLfactor < 0.0_pReal) extmsg = trim(extmsg)//' f_c' - if (prm%p <= 0.0_pReal .or. prm%p > 1.0_pReal) extmsg = trim(extmsg)//' p' - if (prm%q < 1.0_pReal .or. prm%q > 2.0_pReal) extmsg = trim(extmsg)//' q' + if (prm%p <= 0.0_pReal .or. prm%p > 1.0_pReal) extmsg = trim(extmsg)//' p_sl' + if (prm%q < 1.0_pReal .or. prm%q > 2.0_pReal) extmsg = trim(extmsg)//' q_sl' if (prm%linetensionEffect < 0.0_pReal .or. prm%linetensionEffect > 1.0_pReal) & - extmsg = trim(extmsg)//' linetensionEffect' + extmsg = trim(extmsg)//' f_F' if (prm%edgeJogFactor < 0.0_pReal .or. prm%edgeJogFactor > 1.0_pReal) & - extmsg = trim(extmsg)//' edgeJogFactor' + extmsg = trim(extmsg)//' f_ed' - if (prm%solidSolutionEnergy <= 0.0_pReal) extmsg = trim(extmsg)//' solidSolutionEnergy' - if (prm%solidSolutionSize <= 0.0_pReal) extmsg = trim(extmsg)//' solidSolutionSize' - if (prm%solidSolutionConcentration <= 0.0_pReal) extmsg = trim(extmsg)//' solidSolutionConcentration' + if (prm%solidSolutionEnergy <= 0.0_pReal) extmsg = trim(extmsg)//' Q_sol' + if (prm%solidSolutionSize <= 0.0_pReal) extmsg = trim(extmsg)//' f_sol' + if (prm%solidSolutionConcentration <= 0.0_pReal) extmsg = trim(extmsg)//' c_sol' - if (prm%grainboundaryTransmissivity > 1.0_pReal) extmsg = trim(extmsg)//' grainboundaryTransmissivity' + if (prm%grainboundaryTransmissivity > 1.0_pReal) extmsg = trim(extmsg)//' chi_GB' if (prm%surfaceTransmissivity < 0.0_pReal .or. prm%surfaceTransmissivity > 1.0_pReal) & - extmsg = trim(extmsg)//' surfaceTransmissivity' + extmsg = trim(extmsg)//' chi_surface' if (prm%fEdgeMultiplication < 0.0_pReal .or. prm%fEdgeMultiplication > 1.0_pReal) & - extmsg = trim(extmsg)//' fEdgeMultiplication' + extmsg = trim(extmsg)//' f_ed_mult' endif slipActive @@ -384,14 +406,14 @@ module subroutine plastic_nonlocal_init 'maxDipoleHeightEdge ','maxDipoleHeightScrew' ]) * prm%sum_N_sl !< other dependent state variables that are not updated by microstructure sizeDeltaState = sizeDotState - call material_allocateState(plasticState(p),NipcMyPhase,sizeState,sizeDotState,sizeDeltaState) + call constitutive_allocateState(plasticState(p),NipcMyPhase,sizeState,sizeDotState,sizeDeltaState) - plasticState(p)%nonlocal = config%KeyExists('/nonlocal/') + plasticState(p)%nonlocal = pl%get_asBool('nonlocal') if(plasticState(p)%nonlocal .and. .not. allocated(IPneighborhood)) & call IO_error(212,ext_msg='IPneighborhood does not exist') - plasticState(p)%offsetDeltaState = 0 ! ToDo: state structure does not follow convention + plasticState(p)%offsetDeltaState = 0 ! ToDo: state structure does not follow convention st0%rho => plasticState(p)%state0 (0*prm%sum_N_sl+1:10*prm%sum_N_sl,:) stt%rho => plasticState(p)%state (0*prm%sum_N_sl+1:10*prm%sum_N_sl,:) @@ -458,7 +480,7 @@ module subroutine plastic_nonlocal_init stt%gamma => plasticState(p)%state (10*prm%sum_N_sl + 1:11*prm%sum_N_sl,1:NipcMyPhase) dot%gamma => plasticState(p)%dotState (10*prm%sum_N_sl + 1:11*prm%sum_N_sl,1:NipcMyPhase) del%gamma => plasticState(p)%deltaState (10*prm%sum_N_sl + 1:11*prm%sum_N_sl,1:NipcMyPhase) - plasticState(p)%atol(10*prm%sum_N_sl+1:11*prm%sum_N_sl ) = config%getFloat('atol_gamma', defaultVal = 1.0e-2_pReal) + plasticState(p)%atol(10*prm%sum_N_sl+1:11*prm%sum_N_sl ) = pl%get_asFloat('atol_gamma', defaultVal = 1.0e-2_pReal) if(any(plasticState(p)%atol(10*prm%sum_N_sl+1:11*prm%sum_N_sl) < 0.0_pReal)) & extmsg = trim(extmsg)//' atol_gamma' plasticState(p)%slipRate => plasticState(p)%dotState (10*prm%sum_N_sl + 1:11*prm%sum_N_sl,1:NipcMyPhase) @@ -474,12 +496,12 @@ module subroutine plastic_nonlocal_init allocate(dst%tau_back(prm%sum_N_sl,NipcMyPhase),source=0.0_pReal) end associate - if (NipcMyPhase > 0) call stateInit(ini,p,NipcMyPhase) + if (NipcMyPhase > 0) call stateInit(ini,p,NipcMyPhase,i) plasticState(p)%state0 = plasticState(p)%state !-------------------------------------------------------------------------------------------------- ! exit if any parameter is out of range - if (extmsg /= '') call IO_error(211,ext_msg=trim(extmsg)//'('//PLASTICITY_NONLOCAL_LABEL//')') + if (extmsg /= '') call IO_error(211,ext_msg=trim(extmsg)//'(nonlocal)') enddo @@ -491,35 +513,39 @@ module subroutine plastic_nonlocal_init allocate(iV(maxval(param%sum_N_sl),4,Ninstance), source=0) allocate(iD(maxval(param%sum_N_sl),2,Ninstance), source=0) - initializeInstances: do p = 1, size(phase_plasticity) - NipcMyPhase = count(material_phaseAt==p) * discretization_nIP - myPhase2: if (phase_plasticity(p) == PLASTICITY_NONLOCAL_ID) then - l = 0 - do t = 1,4 - do s = 1,param(phase_plasticityInstance(p))%sum_N_sl - l = l + 1 - iRhoU(s,t,phase_plasticityInstance(p)) = l - enddo - enddo - l = l + (4+2+1+1)*param(phase_plasticityInstance(p))%sum_N_sl ! immobile(4), dipole(2), shear, forest - do t = 1,4 - do s = 1,param(phase_plasticityInstance(p))%sum_N_sl - l = l + 1 - iV(s,t,phase_plasticityInstance(p)) = l - enddo - enddo - do t = 1,2 - do s = 1,param(phase_plasticityInstance(p))%sum_N_sl - l = l + 1 - iD(s,t,phase_plasticityInstance(p)) = l - enddo - enddo - if (iD(param(phase_plasticityInstance(p))%sum_N_sl,2,phase_plasticityInstance(p)) /= plasticState(p)%sizeState) & - call IO_error(0, ext_msg = 'state indices not properly set ('//PLASTICITY_NONLOCAL_LABEL//')') - endif myPhase2 - enddo initializeInstances + i = 0 + do p = 1, phases%length + phase => phases%get(p) -end subroutine plastic_nonlocal_init + if(.not. myPlasticity(p)) cycle + i = i + 1 + + NipcMyPhase = count(material_phaseAt==p) * discretization_nIP + l = 0 + do t = 1,4 + do s = 1,param(i)%sum_N_sl + l = l + 1 + iRhoU(s,t,i) = l + enddo + enddo + l = l + (4+2+1+1)*param(i)%sum_N_sl ! immobile(4), dipole(2), shear, forest + do t = 1,4 + do s = 1,param(i)%sum_N_sl + l = l + 1 + iV(s,t,i) = l + enddo + enddo + do t = 1,2 + do s = 1,param(i)%sum_N_sl + l = l + 1 + iD(s,t,i) = l + enddo + enddo + if (iD(param(i)%sum_N_sl,2,i) /= plasticState(p)%sizeState) & + call IO_error(0, ext_msg = 'state indices not properly set (nonlocal)') + enddo + +end function plastic_nonlocal_init !-------------------------------------------------------------------------------------------------- @@ -1447,7 +1473,8 @@ module subroutine plastic_nonlocal_updateCompatibility(orientation,instance,i,e) elseif (prm%grainboundaryTransmissivity >= 0.0_pReal) then !* GRAIN BOUNDARY ! !* fixed transmissivity for adjacent ips with different texture (only if explicitly given in material.config) - if (material_texture(1,i,e) /= material_texture(1,neighbor_i,neighbor_e) .and. & + if (any(dNeq(material_orientation0(1,i,e)%asQuaternion(), & + material_orientation0(1,neighbor_i,neighbor_e)%asQuaternion())) .and. & (.not. phase_localPlasticity(neighbor_phase))) & forall(s1 = 1:ns) my_compatibility(:,s1,s1,n) = sqrt(prm%grainboundaryTransmissivity) else @@ -1514,56 +1541,56 @@ module subroutine plastic_nonlocal_results(instance,group) associate(prm => param(instance),dst => microstructure(instance),stt=>state(instance)) outputsLoop: do o = 1,size(prm%output) select case(trim(prm%output(o))) - case('rho_sgl_mob_edg_pos') - if(prm%sum_N_sl>0) call results_writeDataset(group,stt%rho_sgl_mob_edg_pos, 'rho_sgl_mob_edg_pos', & + case('rho_u_ed_pos') + if(prm%sum_N_sl>0) call results_writeDataset(group,stt%rho_sgl_mob_edg_pos, trim(prm%output(o)), & 'positive mobile edge density','1/m²') - case('rho_sgl_imm_edg_pos') - if(prm%sum_N_sl>0) call results_writeDataset(group,stt%rho_sgl_imm_edg_pos, 'rho_sgl_imm_edg_pos',& + case('rho_b_ed_pos') + if(prm%sum_N_sl>0) call results_writeDataset(group,stt%rho_sgl_imm_edg_pos, trim(prm%output(o)), & 'positive immobile edge density','1/m²') - case('rho_sgl_mob_edg_neg') - if(prm%sum_N_sl>0) call results_writeDataset(group,stt%rho_sgl_mob_edg_neg, 'rho_sgl_mob_edg_neg',& + case('rho_u_ed_neg') + if(prm%sum_N_sl>0) call results_writeDataset(group,stt%rho_sgl_mob_edg_neg, trim(prm%output(o)), & 'negative mobile edge density','1/m²') - case('rho_sgl_imm_edg_neg') - if(prm%sum_N_sl>0) call results_writeDataset(group,stt%rho_sgl_imm_edg_neg, 'rho_sgl_imm_edg_neg',& + case('rho_b_ed_neg') + if(prm%sum_N_sl>0) call results_writeDataset(group,stt%rho_sgl_imm_edg_neg, trim(prm%output(o)), & 'negative immobile edge density','1/m²') - case('rho_dip_edg') - if(prm%sum_N_sl>0) call results_writeDataset(group,stt%rho_dip_edg, 'rho_dip_edg',& + case('rho_d_ed') + if(prm%sum_N_sl>0) call results_writeDataset(group,stt%rho_dip_edg, trim(prm%output(o)), & 'edge dipole density','1/m²') - case('rho_sgl_mob_scr_pos') - if(prm%sum_N_sl>0) call results_writeDataset(group,stt%rho_sgl_mob_scr_pos, 'rho_sgl_mob_scr_pos',& + case('rho_u_sc_pos') + if(prm%sum_N_sl>0) call results_writeDataset(group,stt%rho_sgl_mob_scr_pos, trim(prm%output(o)), & 'positive mobile screw density','1/m²') - case('rho_sgl_imm_scr_pos') - if(prm%sum_N_sl>0) call results_writeDataset(group,stt%rho_sgl_imm_scr_pos, 'rho_sgl_imm_scr_pos',& + case('rho_b_sc_pos') + if(prm%sum_N_sl>0) call results_writeDataset(group,stt%rho_sgl_imm_scr_pos, trim(prm%output(o)), & 'positive immobile screw density','1/m²') - case('rho_sgl_mob_scr_neg') - if(prm%sum_N_sl>0) call results_writeDataset(group,stt%rho_sgl_mob_scr_neg, 'rho_sgl_mob_scr_neg',& + case('rho_u_sc_neg') + if(prm%sum_N_sl>0) call results_writeDataset(group,stt%rho_sgl_mob_scr_neg, trim(prm%output(o)), & 'negative mobile screw density','1/m²') - case('rho_sgl_imm_scr_neg') - if(prm%sum_N_sl>0) call results_writeDataset(group,stt%rho_sgl_imm_scr_neg, 'rho_sgl_imm_scr_neg',& + case('rho_b_sc_neg') + if(prm%sum_N_sl>0) call results_writeDataset(group,stt%rho_sgl_imm_scr_neg, trim(prm%output(o)), & 'negative immobile screw density','1/m²') - case('rho_dip_scr') - if(prm%sum_N_sl>0) call results_writeDataset(group,stt%rho_dip_scr, 'rho_dip_scr',& + case('rho_d_sc') + if(prm%sum_N_sl>0) call results_writeDataset(group,stt%rho_dip_scr, trim(prm%output(o)), & 'screw dipole density','1/m²') - case('rho_forest') - if(prm%sum_N_sl>0) call results_writeDataset(group,stt%rho_forest, 'rho_forest',& + case('rho_f') + if(prm%sum_N_sl>0) call results_writeDataset(group,stt%rho_forest, trim(prm%output(o)), & 'forest density','1/m²') - case('v_edg_pos') - if(prm%sum_N_sl>0) call results_writeDataset(group,stt%v_edg_pos, 'v_edg_pos',& + case('v_ed_pos') + if(prm%sum_N_sl>0) call results_writeDataset(group,stt%v_edg_pos, trim(prm%output(o)), & 'positive edge velocity','m/s') - case('v_edg_neg') - if(prm%sum_N_sl>0) call results_writeDataset(group,stt%v_edg_neg, 'v_edg_neg',& + case('v_ed_neg') + if(prm%sum_N_sl>0) call results_writeDataset(group,stt%v_edg_neg, trim(prm%output(o)), & 'negative edge velocity','m/s') - case('v_scr_pos') - if(prm%sum_N_sl>0) call results_writeDataset(group,stt%v_scr_pos, 'v_scr_pos',& + case('v_sc_pos') + if(prm%sum_N_sl>0) call results_writeDataset(group,stt%v_scr_pos, trim(prm%output(o)), & 'positive srew velocity','m/s') - case('v_scr_neg') - if(prm%sum_N_sl>0) call results_writeDataset(group,stt%v_scr_neg, 'v_scr_neg',& + case('v_sc_neg') + if(prm%sum_N_sl>0) call results_writeDataset(group,stt%v_scr_neg, trim(prm%output(o)), & 'negative screw velocity','m/s') case('gamma') - if(prm%sum_N_sl>0) call results_writeDataset(group,stt%gamma,'gamma',& + if(prm%sum_N_sl>0) call results_writeDataset(group,stt%gamma, trim(prm%output(o)), & 'plastic shear','1') case('tau_pass') - if(prm%sum_N_sl>0) call results_writeDataset(group,dst%tau_pass,'tau_pass',& + if(prm%sum_N_sl>0) call results_writeDataset(group,dst%tau_pass, trim(prm%output(o)), & 'passing stress for slip','Pa') end select enddo outputsLoop @@ -1575,13 +1602,14 @@ end subroutine plastic_nonlocal_results !-------------------------------------------------------------------------------------------------- !> @brief populates the initial dislocation density !-------------------------------------------------------------------------------------------------- -subroutine stateInit(ini,phase,NipcMyPhase) +subroutine stateInit(ini,phase,NipcMyPhase,instance) type(tInitialParameters) :: & ini integer,intent(in) :: & phase, & - NipcMyPhase + NipcMyPhase, & + instance integer :: & e, & i, & @@ -1589,7 +1617,6 @@ subroutine stateInit(ini,phase,NipcMyPhase) from, & upto, & s, & - instance, & phasemember real(pReal), dimension(2) :: & noise, & @@ -1602,7 +1629,7 @@ subroutine stateInit(ini,phase,NipcMyPhase) real(pReal), dimension(NipcMyPhase) :: & volume - instance = phase_plasticityInstance(phase) + associate(stt => state(instance)) if (ini%rhoSglRandom > 0.0_pReal) then ! randomly distribute dislocation segments on random slip system and of random type in the volume diff --git a/src/constitutive_plastic_phenopowerlaw.f90 b/src/constitutive_plastic_phenopowerlaw.f90 index 3f6ade8d2..992949016 100644 --- a/src/constitutive_plastic_phenopowerlaw.f90 +++ b/src/constitutive_plastic_phenopowerlaw.f90 @@ -66,8 +66,9 @@ contains !> @brief Perform module initialization. !> @details reads in material parameters, allocates arrays, and does sanity checks !-------------------------------------------------------------------------------------------------- -module subroutine plastic_phenopowerlaw_init +module function plastic_phenopowerlaw_init() result(myPlasticity) + logical, dimension(:), allocatable :: myPlasticity integer :: & Ninstance, & p, i, & @@ -82,33 +83,46 @@ module subroutine plastic_phenopowerlaw_init a !< non-Schmid coefficients character(len=pStringLen) :: & extmsg = '' + class(tNode), pointer :: & + phases, & + phase, & + pl - write(6,'(/,a)') ' <<<+- plastic_'//PLASTICITY_PHENOPOWERLAW_LABEL//' init -+>>>' + write(6,'(/,a)') ' <<<+- plastic_phenopowerlaw init -+>>>' - Ninstance = count(phase_plasticity == PLASTICITY_PHENOPOWERLAW_ID) + + myPlasticity = plastic_active('phenopowerlaw') + + Ninstance = count(myPlasticity) write(6,'(a16,1x,i5,/)') '# instances:',Ninstance; flush(6) - + if(Ninstance == 0) return + allocate(param(Ninstance)) allocate(state(Ninstance)) allocate(dotState(Ninstance)) - do p = 1, size(phase_plasticity) - if (phase_plasticity(p) /= PLASTICITY_PHENOPOWERLAW_ID) cycle - associate(prm => param(phase_plasticityInstance(p)), & - dot => dotState(phase_plasticityInstance(p)), & - stt => state(phase_plasticityInstance(p)), & - config => config_phase(p)) + phases => material_root%get('phase') + i = 0 + do p = 1, phases%length + phase => phases%get(p) + + if(.not. myPlasticity(p)) cycle + i = i + 1 + associate(prm => param(i), & + dot => dotState(i), & + stt => state(i)) + pl => phase%get('plasticity') !-------------------------------------------------------------------------------------------------- ! slip related parameters - N_sl = config%getInts('nslip',defaultVal=emptyIntArray) + N_sl = pl%get_asInts('N_sl',defaultVal=emptyIntArray) prm%sum_N_sl = sum(abs(N_sl)) slipActive: if (prm%sum_N_sl > 0) then - prm%P_sl = lattice_SchmidMatrix_slip(N_sl,config%getString('lattice_structure'),& - config%getFloat('c/a',defaultVal=0.0_pReal)) + prm%P_sl = lattice_SchmidMatrix_slip(N_sl,phase%get_asString('lattice'),& + phase%get_asFloat('c/a',defaultVal=0.0_pReal)) - if(trim(config%getString('lattice_structure')) == 'bcc') then - a = config%getFloats('nonschmid_coefficients',defaultVal = emptyRealArray) + if(phase%get_asString('lattice') == 'bcc') then + a = pl%get_asFloats('nonSchmid_coefficients',defaultVal=emptyRealArray) if(size(a) > 0) prm%nonSchmidActive = .true. prm%nonSchmid_pos = lattice_nonSchmidMatrix(N_sl,a,+1) prm%nonSchmid_neg = lattice_nonSchmidMatrix(N_sl,a,-1) @@ -117,18 +131,18 @@ module subroutine plastic_phenopowerlaw_init prm%nonSchmid_neg = prm%P_sl endif prm%interaction_SlipSlip = lattice_interaction_SlipBySlip(N_sl, & - config%getFloats('interaction_slipslip'), & - config%getString('lattice_structure')) + pl%get_asFloats('h_sl_sl'), & + phase%get_asString('lattice')) - xi_slip_0 = config%getFloats('tau0_slip', requiredSize=size(N_sl)) - prm%xi_slip_sat = config%getFloats('tausat_slip', requiredSize=size(N_sl)) - prm%H_int = config%getFloats('h_int', requiredSize=size(N_sl), & + xi_slip_0 = pl%get_asFloats('xi_0_sl', requiredSize=size(N_sl)) + prm%xi_slip_sat = pl%get_asFloats('xi_inf_sl', requiredSize=size(N_sl)) + prm%H_int = pl%get_asFloats('h_int', requiredSize=size(N_sl), & defaultVal=[(0.0_pReal,i=1,size(N_sl))]) - prm%gdot0_slip = config%getFloat('gdot0_slip') - prm%n_slip = config%getFloat('n_slip') - prm%a_slip = config%getFloat('a_slip') - prm%h0_SlipSlip = config%getFloat('h0_slipslip') + prm%gdot0_slip = pl%get_asFloat('dot_gamma_0_sl') + prm%n_slip = pl%get_asFloat('n_sl') + prm%a_slip = pl%get_asFloat('a_sl') + prm%h0_SlipSlip = pl%get_asFloat('h_0_sl_sl') ! expand: family => system xi_slip_0 = math_expand(xi_slip_0, N_sl) @@ -136,11 +150,11 @@ module subroutine plastic_phenopowerlaw_init prm%H_int = math_expand(prm%H_int, N_sl) ! sanity checks - if ( prm%gdot0_slip <= 0.0_pReal) extmsg = trim(extmsg)//' gdot0_slip' - if ( prm%a_slip <= 0.0_pReal) extmsg = trim(extmsg)//' a_slip' - if ( prm%n_slip <= 0.0_pReal) extmsg = trim(extmsg)//' n_slip' - if (any(xi_slip_0 <= 0.0_pReal)) extmsg = trim(extmsg)//' xi_slip_0' - if (any(prm%xi_slip_sat <= 0.0_pReal)) extmsg = trim(extmsg)//' xi_slip_sat' + if ( prm%gdot0_slip <= 0.0_pReal) extmsg = trim(extmsg)//' dot_gamma_0_sl' + if ( prm%a_slip <= 0.0_pReal) extmsg = trim(extmsg)//' a_sl' + if ( prm%n_slip <= 0.0_pReal) extmsg = trim(extmsg)//' n_sl' + if (any(xi_slip_0 <= 0.0_pReal)) extmsg = trim(extmsg)//' xi_0_sl' + if (any(prm%xi_slip_sat <= 0.0_pReal)) extmsg = trim(extmsg)//' xi_inf_sl' else slipActive xi_slip_0 = emptyRealArray @@ -150,34 +164,34 @@ module subroutine plastic_phenopowerlaw_init !-------------------------------------------------------------------------------------------------- ! twin related parameters - N_tw = config%getInts('ntwin', defaultVal=emptyIntArray) + N_tw = pl%get_asInts('N_tw', defaultVal=emptyIntArray) prm%sum_N_tw = sum(abs(N_tw)) twinActive: if (prm%sum_N_tw > 0) then - prm%P_tw = lattice_SchmidMatrix_twin(N_tw,config%getString('lattice_structure'),& - config%getFloat('c/a',defaultVal=0.0_pReal)) + prm%P_tw = lattice_SchmidMatrix_twin(N_tw,phase%get_asString('lattice'),& + phase%get_asFloat('c/a',defaultVal=0.0_pReal)) prm%interaction_TwinTwin = lattice_interaction_TwinByTwin(N_tw,& - config%getFloats('interaction_twintwin'), & - config%getString('lattice_structure')) - prm%gamma_twin_char = lattice_characteristicShear_twin(N_tw,config%getString('lattice_structure'),& - config%getFloat('c/a',defaultVal=0.0_pReal)) + pl%get_asFloats('h_tw_tw'), & + phase%get_asString('lattice')) + prm%gamma_twin_char = lattice_characteristicShear_twin(N_tw,phase%get_asString('lattice'),& + phase%get_asFloat('c/a',defaultVal=0.0_pReal)) - xi_twin_0 = config%getFloats('tau0_twin',requiredSize=size(N_tw)) + xi_twin_0 = pl%get_asFloats('xi_0_tw',requiredSize=size(N_tw)) - prm%c_1 = config%getFloat('twin_c',defaultVal=0.0_pReal) - prm%c_2 = config%getFloat('twin_b',defaultVal=1.0_pReal) - prm%c_3 = config%getFloat('twin_e',defaultVal=0.0_pReal) - prm%c_4 = config%getFloat('twin_d',defaultVal=0.0_pReal) - prm%gdot0_twin = config%getFloat('gdot0_twin') - prm%n_twin = config%getFloat('n_twin') - prm%spr = config%getFloat('s_pr') - prm%h0_TwinTwin = config%getFloat('h0_twintwin') + prm%c_1 = pl%get_asFloat('c_1',defaultVal=0.0_pReal) + prm%c_2 = pl%get_asFloat('c_2',defaultVal=1.0_pReal) + prm%c_3 = pl%get_asFloat('c_3',defaultVal=0.0_pReal) + prm%c_4 = pl%get_asFloat('c_4',defaultVal=0.0_pReal) + prm%gdot0_twin = pl%get_asFloat('dot_gamma_0_tw') + prm%n_twin = pl%get_asFloat('n_tw') + prm%spr = pl%get_asFloat('f_sl_sat_tw') + prm%h0_TwinTwin = pl%get_asFloat('h_0_tw_tw') ! expand: family => system xi_twin_0 = math_expand(xi_twin_0,N_tw) ! sanity checks - if (prm%gdot0_twin <= 0.0_pReal) extmsg = trim(extmsg)//' gdot0_twin' - if (prm%n_twin <= 0.0_pReal) extmsg = trim(extmsg)//' n_twin' + if (prm%gdot0_twin <= 0.0_pReal) extmsg = trim(extmsg)//' dot_gamma_0_tw' + if (prm%n_twin <= 0.0_pReal) extmsg = trim(extmsg)//' n_tw' else twinActive xi_twin_0 = emptyRealArray @@ -188,13 +202,13 @@ module subroutine plastic_phenopowerlaw_init !-------------------------------------------------------------------------------------------------- ! slip-twin related parameters slipAndTwinActive: if (prm%sum_N_sl > 0 .and. prm%sum_N_tw > 0) then - prm%h0_TwinSlip = config%getFloat('h0_twinslip') + prm%h0_TwinSlip = pl%get_asFloat('h_0_tw_sl') prm%interaction_SlipTwin = lattice_interaction_SlipByTwin(N_sl,N_tw,& - config%getFloats('interaction_sliptwin'), & - config%getString('lattice_structure')) + pl%get_asFloats('h_sl_tw'), & + phase%get_asString('lattice')) prm%interaction_TwinSlip = lattice_interaction_TwinBySlip(N_tw,N_sl,& - config%getFloats('interaction_twinslip'), & - config%getString('lattice_structure')) + pl%get_asFloats('h_tw_sl'), & + phase%get_asString('lattice')) else slipAndTwinActive allocate(prm%interaction_SlipTwin(prm%sum_N_sl,prm%sum_N_tw)) ! at least one dimension is 0 allocate(prm%interaction_TwinSlip(prm%sum_N_tw,prm%sum_N_sl)) ! at least one dimension is 0 @@ -203,7 +217,12 @@ module subroutine plastic_phenopowerlaw_init !-------------------------------------------------------------------------------------------------- ! output pararameters - prm%output = config%getStrings('(output)',defaultVal=emptyStringArray) + +#if defined (__GFORTRAN__) + prm%output = output_asStrings(pl) +#else + prm%output = pl%get_asStrings('output',defaultVal=emptyStringArray) +#endif !-------------------------------------------------------------------------------------------------- ! allocate state arrays @@ -212,7 +231,8 @@ module subroutine plastic_phenopowerlaw_init + size(['xi_tw ','gamma_tw']) * prm%sum_N_tw sizeState = sizeDotState - call material_allocateState(plasticState(p),NipcMyPhase,sizeState,sizeDotState,0) + + call constitutive_allocateState(plasticState(p),NipcMyPhase,sizeState,sizeDotState,0) !-------------------------------------------------------------------------------------------------- ! state aliases and initialization @@ -221,7 +241,7 @@ module subroutine plastic_phenopowerlaw_init stt%xi_slip => plasticState(p)%state (startIndex:endIndex,:) stt%xi_slip = spread(xi_slip_0, 2, NipcMyPhase) dot%xi_slip => plasticState(p)%dotState(startIndex:endIndex,:) - plasticState(p)%atol(startIndex:endIndex) = config%getFloat('atol_xi',defaultVal=1.0_pReal) + plasticState(p)%atol(startIndex:endIndex) = pl%get_asFloat('atol_xi',defaultVal=1.0_pReal) if(any(plasticState(p)%atol(startIndex:endIndex) < 0.0_pReal)) extmsg = trim(extmsg)//' atol_xi' startIndex = endIndex + 1 @@ -229,14 +249,14 @@ module subroutine plastic_phenopowerlaw_init stt%xi_twin => plasticState(p)%state (startIndex:endIndex,:) stt%xi_twin = spread(xi_twin_0, 2, NipcMyPhase) dot%xi_twin => plasticState(p)%dotState(startIndex:endIndex,:) - plasticState(p)%atol(startIndex:endIndex) = config%getFloat('atol_xi',defaultVal=1.0_pReal) + plasticState(p)%atol(startIndex:endIndex) = pl%get_asFloat('atol_xi',defaultVal=1.0_pReal) if(any(plasticState(p)%atol(startIndex:endIndex) < 0.0_pReal)) extmsg = trim(extmsg)//' atol_xi' startIndex = endIndex + 1 endIndex = endIndex + prm%sum_N_sl stt%gamma_slip => plasticState(p)%state (startIndex:endIndex,:) dot%gamma_slip => plasticState(p)%dotState(startIndex:endIndex,:) - plasticState(p)%atol(startIndex:endIndex) = config%getFloat('atol_gamma',defaultVal=1.0e-6_pReal) + plasticState(p)%atol(startIndex:endIndex) = pl%get_asFloat('atol_gamma',defaultVal=1.0e-6_pReal) if(any(plasticState(p)%atol(startIndex:endIndex) < 0.0_pReal)) extmsg = trim(extmsg)//' atol_gamma' ! global alias plasticState(p)%slipRate => plasticState(p)%dotState(startIndex:endIndex,:) @@ -245,7 +265,7 @@ module subroutine plastic_phenopowerlaw_init endIndex = endIndex + prm%sum_N_tw stt%gamma_twin => plasticState(p)%state (startIndex:endIndex,:) dot%gamma_twin => plasticState(p)%dotState(startIndex:endIndex,:) - plasticState(p)%atol(startIndex:endIndex) = config%getFloat('atol_gamma',defaultVal=1.0e-6_pReal) + plasticState(p)%atol(startIndex:endIndex) = pl%get_asFloat('atol_gamma',defaultVal=1.0e-6_pReal) if(any(plasticState(p)%atol(startIndex:endIndex) < 0.0_pReal)) extmsg = trim(extmsg)//' atol_gamma' plasticState(p)%state0 = plasticState(p)%state ! ToDo: this could be done centrally @@ -254,11 +274,11 @@ module subroutine plastic_phenopowerlaw_init !-------------------------------------------------------------------------------------------------- ! exit if any parameter is out of range - if (extmsg /= '') call IO_error(211,ext_msg=trim(extmsg)//'('//PLASTICITY_PHENOPOWERLAW_LABEL//')') + if (extmsg /= '') call IO_error(211,ext_msg=trim(extmsg)//'(phenopowerlaw)') enddo -end subroutine plastic_phenopowerlaw_init +end function plastic_phenopowerlaw_init !-------------------------------------------------------------------------------------------------- @@ -384,18 +404,18 @@ module subroutine plastic_phenopowerlaw_results(instance,group) outputsLoop: do o = 1,size(prm%output) select case(trim(prm%output(o))) - case('resistance_slip') - if(prm%sum_N_sl>0) call results_writeDataset(group,stt%xi_slip, 'xi_sl', & + case('xi_sl') + if(prm%sum_N_sl>0) call results_writeDataset(group,stt%xi_slip, trim(prm%output(o)), & 'resistance against plastic slip','Pa') - case('accumulatedshear_slip') - if(prm%sum_N_sl>0) call results_writeDataset(group,stt%gamma_slip,'gamma_sl', & + case('gamma_sl') + if(prm%sum_N_sl>0) call results_writeDataset(group,stt%gamma_slip,trim(prm%output(o)), & 'plastic shear','1') - case('resistance_twin') - if(prm%sum_N_tw>0) call results_writeDataset(group,stt%xi_twin, 'xi_tw', & + case('xi_tw') + if(prm%sum_N_tw>0) call results_writeDataset(group,stt%xi_twin, trim(prm%output(o)), & 'resistance against twinning','Pa') - case('accumulatedshear_twin') - if(prm%sum_N_tw>0) call results_writeDataset(group,stt%gamma_twin,'gamma_tw', & + case('gamma_tw') + if(prm%sum_N_tw>0) call results_writeDataset(group,stt%gamma_twin,trim(prm%output(o)), & 'twinning shear','1') end select diff --git a/src/constitutive_thermal.f90 b/src/constitutive_thermal.f90 index 96d4c03ee..3aefb99a7 100644 --- a/src/constitutive_thermal.f90 +++ b/src/constitutive_thermal.f90 @@ -5,14 +5,20 @@ submodule(constitutive) constitutive_thermal interface - module subroutine source_thermal_dissipation_init - end subroutine source_thermal_dissipation_init + module function source_thermal_dissipation_init(source_length) result(mySources) + integer, intent(in) :: source_length + logical, dimension(:,:), allocatable :: mySources + end function source_thermal_dissipation_init + + module function source_thermal_externalheat_init(source_length) result(mySources) + integer, intent(in) :: source_length + logical, dimension(:,:), allocatable :: mySources + end function source_thermal_externalheat_init - module subroutine source_thermal_externalheat_init - end subroutine source_thermal_externalheat_init - - module subroutine kinematics_thermal_expansion_init - end subroutine kinematics_thermal_expansion_init + module function kinematics_thermal_expansion_init(kinematics_length) result(myKinematics) + integer, intent(in) :: kinematics_length + logical, dimension(:,:), allocatable :: myKinematics + end function kinematics_thermal_expansion_init module subroutine source_thermal_dissipation_getRateAndItsTangent(TDot, dTDot_dT, Tstar, Lp, phase) @@ -46,12 +52,15 @@ contains module subroutine thermal_init ! initialize source mechanisms - if (any(phase_source == SOURCE_thermal_dissipation_ID)) call source_thermal_dissipation_init - if (any(phase_source == SOURCE_thermal_externalheat_ID)) call source_thermal_externalheat_init - + if(maxval(phase_Nsources) /= 0) then + where(source_thermal_dissipation_init (maxval(phase_Nsources))) phase_source = SOURCE_thermal_dissipation_ID + where(source_thermal_externalheat_init(maxval(phase_Nsources))) phase_source = SOURCE_thermal_externalheat_ID + endif + !-------------------------------------------------------------------------------------------------- !initialize kinematic mechanisms - if (any(phase_kinematics == KINEMATICS_thermal_expansion_ID)) call kinematics_thermal_expansion_init + if(maxval(phase_Nkinematics) /= 0) where(kinematics_thermal_expansion_init(maxval(phase_Nkinematics))) & + phase_kinematics = KINEMATICS_thermal_expansion_ID end subroutine thermal_init diff --git a/src/crystallite.f90 b/src/crystallite.f90 index ee825d4ea..9d2d534d7 100644 --- a/src/crystallite.f90 +++ b/src/crystallite.f90 @@ -14,7 +14,6 @@ module crystallite use HDF5_utilities use DAMASK_interface use config - use debug use rotations use math use FEsolving @@ -143,7 +142,10 @@ subroutine crystallite_init class(tNode), pointer :: & num_crystallite, & - debug_crystallite ! pointer to debug options for crystallite + debug_crystallite, & ! pointer to debug options for crystallite + phases, & + phase, & + generic_param write(6,'(/,a)') ' <<<+- crystallite init -+>>>' @@ -233,19 +235,19 @@ subroutine crystallite_init call IO_error(301,ext_msg='integrator') end select - allocate(output_constituent(size(config_phase))) - do c = 1, size(config_phase) + phases => material_root%get('phase') + + allocate(output_constituent(phases%length)) + do c = 1, phases%length + phase => phases%get(c) + generic_param => phase%get('generic',defaultVal = emptyDict) #if defined(__GFORTRAN__) - allocate(output_constituent(c)%label(1)) - output_constituent(c)%label(1)= 'GfortranBug86277' - output_constituent(c)%label = config_phase(c)%getStrings('(output)',defaultVal=output_constituent(c)%label ) - if (output_constituent(c)%label (1) == 'GfortranBug86277') output_constituent(c)%label = [character(len=pStringLen)::] + output_constituent(c)%label = output_asStrings(generic_param) #else - output_constituent(c)%label = config_phase(c)%getStrings('(output)',defaultVal=[character(len=pStringLen)::]) + output_constituent(c)%label = generic_param%get_asStrings('output',defaultVal=emptyStringArray) #endif enddo - call config_deallocate('material.config/phase') !-------------------------------------------------------------------------------------------------- ! initialize @@ -681,46 +683,46 @@ subroutine crystallite_results type(rotation), allocatable, dimension(:) :: selected_rotations character(len=pStringLen) :: group,structureLabel - do p=1,size(config_name_phase) - group = trim('current/constituent')//'/'//trim(config_name_phase(p))//'/generic' + do p=1,size(material_name_phase) + group = trim('current/constituent')//'/'//trim(material_name_phase(p))//'/generic' call results_closeGroup(results_addGroup(group)) do o = 1, size(output_constituent(p)%label) select case (output_constituent(p)%label(o)) - case('f') + case('F') selected_tensors = select_tensors(crystallite_partionedF,p) - call results_writeDataset(group,selected_tensors,'F',& + call results_writeDataset(group,selected_tensors,output_constituent(p)%label(o),& 'deformation gradient','1') - case('fe') + case('Fe') selected_tensors = select_tensors(crystallite_Fe,p) - call results_writeDataset(group,selected_tensors,'Fe',& + call results_writeDataset(group,selected_tensors,output_constituent(p)%label(o),& 'elastic deformation gradient','1') - case('fp') + case('Fp') selected_tensors = select_tensors(crystallite_Fp,p) - call results_writeDataset(group,selected_tensors,'Fp',& + call results_writeDataset(group,selected_tensors,output_constituent(p)%label(o),& 'plastic deformation gradient','1') - case('fi') + case('Fi') selected_tensors = select_tensors(crystallite_Fi,p) - call results_writeDataset(group,selected_tensors,'Fi',& + call results_writeDataset(group,selected_tensors,output_constituent(p)%label(o),& 'inelastic deformation gradient','1') - case('lp') + case('Lp') selected_tensors = select_tensors(crystallite_Lp,p) - call results_writeDataset(group,selected_tensors,'Lp',& + call results_writeDataset(group,selected_tensors,output_constituent(p)%label(o),& 'plastic velocity gradient','1/s') - case('li') + case('Li') selected_tensors = select_tensors(crystallite_Li,p) - call results_writeDataset(group,selected_tensors,'Li',& + call results_writeDataset(group,selected_tensors,output_constituent(p)%label(o),& 'inelastic velocity gradient','1/s') - case('p') + case('P') selected_tensors = select_tensors(crystallite_P,p) - call results_writeDataset(group,selected_tensors,'P',& - 'First Piola-Kirchhoff stress','Pa') - case('s') + call results_writeDataset(group,selected_tensors,output_constituent(p)%label(o),& + 'First Piola-Kirchoff stress','Pa') + case('S') selected_tensors = select_tensors(crystallite_S,p) - call results_writeDataset(group,selected_tensors,'S',& - 'Second Piola-Kirchhoff stress','Pa') - case('orientation') + call results_writeDataset(group,selected_tensors,output_constituent(p)%label(o),& + 'Second Piola-Kirchoff stress','Pa') + case('O') select case(lattice_structure(p)) case(lattice_ISO_ID) structureLabel = 'iso' @@ -736,7 +738,7 @@ subroutine crystallite_results structureLabel = 'ort' end select selected_rotations = select_rotations(crystallite_orientation,p) - call results_writeDataset(group,selected_rotations,'orientation',& + call results_writeDataset(group,selected_rotations,output_constituent(p)%label(o),& 'crystal orientation as quaternion',structureLabel) end select enddo @@ -1575,7 +1577,7 @@ subroutine crystallite_restartWrite call HDF5_write(fileHandle,crystallite_S, 'S') groupHandle = HDF5_addGroup(fileHandle,'constituent') - do i = 1,size(phase_plasticity) + do i = 1,size(material_name_phase) write(datasetName,'(i0,a)') i,'_omega_plastic' call HDF5_write(groupHandle,plasticState(i)%state,datasetName) enddo @@ -1616,7 +1618,7 @@ subroutine crystallite_restartRead call HDF5_read(fileHandle,crystallite_S0, 'S') groupHandle = HDF5_openGroup(fileHandle,'constituent') - do i = 1,size(phase_plasticity) + do i = 1,size(material_name_phase) write(datasetName,'(i0,a)') i,'_omega_plastic' call HDF5_read(groupHandle,plasticState(i)%state0,datasetName) enddo diff --git a/src/damage_local.f90 b/src/damage_local.f90 index 66b50064b..296617039 100644 --- a/src/damage_local.f90 +++ b/src/damage_local.f90 @@ -7,7 +7,6 @@ module damage_local use IO use material use config - use numerics use YAML_types use constitutive use results @@ -44,9 +43,13 @@ contains subroutine damage_local_init integer :: Ninstance,NofMyHomog,h - class(tNode), pointer :: num_generic + class(tNode), pointer :: & + num_generic, & + material_homogenization, & + homog, & + homogDamage - write(6,'(/,a)') ' <<<+- damage_'//DAMAGE_local_label//' init -+>>>'; flush(6) + write(6,'(/,a)') ' <<<+- damage_local init -+>>>'; flush(6) !---------------------------------------------------------------------------------------------- ! read numerics parameter and do sanity check @@ -57,11 +60,18 @@ subroutine damage_local_init Ninstance = count(damage_type == DAMAGE_local_ID) allocate(param(Ninstance)) - do h = 1, size(config_homogenization) + material_homogenization => material_root%get('homogenization') + do h = 1, material_homogenization%length if (damage_type(h) /= DAMAGE_LOCAL_ID) cycle - associate(prm => param(damage_typeInstance(h)),config => config_homogenization(h)) + homog => material_homogenization%get(h) + homogDamage => homog%get('damage') + associate(prm => param(damage_typeInstance(h))) - prm%output = config%getStrings('(output)',defaultVal=emptyStringArray) +#if defined (__GFORTRAN__) + prm%output = output_asStrings(homogDamage) +#else + prm%output = homogDamage%get_asStrings('output',defaultVal=emptyStringArray) +#endif NofMyHomog = count(material_homogenizationAt == h) damageState(h)%sizeState = 1 @@ -152,8 +162,8 @@ subroutine damage_local_results(homog,group) associate(prm => param(damage_typeInstance(homog))) outputsLoop: do o = 1,size(prm%output) select case(prm%output(o)) - case ('damage') - call results_writeDataset(group,damage(homog)%p,'phi',& + case ('phi') + call results_writeDataset(group,damage(homog)%p,prm%output(o),& 'damage indicator','-') end select enddo outputsLoop diff --git a/src/damage_none.f90 b/src/damage_none.f90 index b8a9bd7b5..00e3e132d 100644 --- a/src/damage_none.f90 +++ b/src/damage_none.f90 @@ -18,9 +18,9 @@ subroutine damage_none_init integer :: h,NofMyHomog - write(6,'(/,a)') ' <<<+- damage_'//DAMAGE_NONE_LABEL//' init -+>>>'; flush(6) + write(6,'(/,a)') ' <<<+- damage_none init -+>>>'; flush(6) - do h = 1, size(config_homogenization) + do h = 1, material_Nhomogenization if (damage_type(h) /= DAMAGE_NONE_ID) cycle NofMyHomog = count(material_homogenizationAt == h) diff --git a/src/damage_nonlocal.f90 b/src/damage_nonlocal.f90 index 914133de7..93f8ab721 100644 --- a/src/damage_nonlocal.f90 +++ b/src/damage_nonlocal.f90 @@ -6,7 +6,6 @@ module damage_nonlocal use prec use material use config - use numerics use YAML_types use crystallite use lattice @@ -49,9 +48,12 @@ subroutine damage_nonlocal_init integer :: Ninstance,NofMyHomog,h class(tNode), pointer :: & - num_generic + num_generic, & + material_homogenization, & + homog, & + homogDamage - write(6,'(/,a)') ' <<<+- damage_'//DAMAGE_nonlocal_label//' init -+>>>'; flush(6) + write(6,'(/,a)') ' <<<+- damage_nonlocal init -+>>>'; flush(6) !------------------------------------------------------------------------------------ ! read numerics parameter @@ -61,11 +63,18 @@ subroutine damage_nonlocal_init Ninstance = count(damage_type == DAMAGE_nonlocal_ID) allocate(param(Ninstance)) - do h = 1, size(config_homogenization) + material_homogenization => material_root%get('homogenization') + do h = 1, material_homogenization%length if (damage_type(h) /= DAMAGE_NONLOCAL_ID) cycle - associate(prm => param(damage_typeInstance(h)),config => config_homogenization(h)) + homog => material_homogenization%get(h) + homogDamage => homog%get('damage') + associate(prm => param(damage_typeInstance(h))) - prm%output = config%getStrings('(output)',defaultVal=emptyStringArray) +#if defined (__GFORTRAN__) + prm%output = output_asStrings(homogDamage) +#else + prm%output = homogDamage%get_asStrings('output',defaultVal=emptyStringArray) +#endif NofMyHomog = count(material_homogenizationAt == h) damageState(h)%sizeState = 1 @@ -191,8 +200,8 @@ subroutine damage_nonlocal_results(homog,group) associate(prm => param(damage_typeInstance(homog))) outputsLoop: do o = 1,size(prm%output) select case(prm%output(o)) - case ('damage') - call results_writeDataset(group,damage(homog)%p,'phi',& + case ('phi') + call results_writeDataset(group,damage(homog)%p,prm%output(o),& 'damage indicator','-') end select enddo outputsLoop diff --git a/src/debug.f90 b/src/debug.f90 deleted file mode 100644 index c26277f12..000000000 --- a/src/debug.f90 +++ /dev/null @@ -1,50 +0,0 @@ -!-------------------------------------------------------------------------------------------------- -!> @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 Martin Diehl, Max-Planck-Institut für Eisenforschung GmbH -!> @brief Reading in and interpretating the debugging settings for the various modules -!-------------------------------------------------------------------------------------------------- -module debug - use prec - use IO - use YAML_types - use YAML_parse - - implicit none - private - - class(tNode), pointer, protected, public :: & - debug_root !< root pointer storing the debug YAML structure - - public :: debug_init - -contains - - -!-------------------------------------------------------------------------------------------------- -!> @brief reads in parameters from debug.config and allocates arrays -!-------------------------------------------------------------------------------------------------- -subroutine debug_init - - character(len=:), allocatable :: & - debug_input, & - debug_inFlow - logical :: fexist - - write(6,'(/,a)') ' <<<+- debug init -+>>>' -#ifdef DEBUG - write(6,'(a)') achar(27)//'[31m <<<+- DEBUG version -+>>>'//achar(27)//'[0m' -#endif - - debug_root => emptyDict - inquire(file='debug.yaml', exist=fexist) - fileExists: if (fexist) then - debug_input = IO_read('debug.yaml') - debug_inFlow = to_flow(debug_input) - debug_root => parse_flow(debug_inFlow) - endif fileExists - -end subroutine debug_init - -end module debug diff --git a/src/grid/DAMASK_grid.f90 b/src/grid/DAMASK_grid.f90 index 7c0f87078..0e30025d8 100644 --- a/src/grid/DAMASK_grid.f90 +++ b/src/grid/DAMASK_grid.f90 @@ -13,7 +13,6 @@ program DAMASK_grid use DAMASK_interface use IO use config - use debug use math use CPFEM2 use material diff --git a/src/grid/discretization_grid.f90 b/src/grid/discretization_grid.f90 index ce1c07fc2..6d128eb0b 100644 --- a/src/grid/discretization_grid.f90 +++ b/src/grid/discretization_grid.f90 @@ -12,8 +12,7 @@ module discretization_grid use system_routines use DAMASK_interface use IO - use debug - use numerics + use config use results use discretization use geometry_plastic_nonlocal diff --git a/src/grid/grid_damage_spectral.f90 b/src/grid/grid_damage_spectral.f90 index 65ca9b1dd..e7bbbff7f 100644 --- a/src/grid/grid_damage_spectral.f90 +++ b/src/grid/grid_damage_spectral.f90 @@ -15,7 +15,7 @@ module grid_damage_spectral use spectral_utilities use discretization_grid use damage_nonlocal - use numerics + use config use YAML_types implicit none diff --git a/src/grid/grid_mech_FEM.f90 b/src/grid/grid_mech_FEM.f90 index 43dbca00e..e8e1345ef 100644 --- a/src/grid/grid_mech_FEM.f90 +++ b/src/grid/grid_mech_FEM.f90 @@ -16,11 +16,10 @@ module grid_mech_FEM use math use spectral_utilities use FEsolving - use numerics + use config use homogenization use discretization use discretization_grid - use debug implicit none private diff --git a/src/grid/grid_mech_spectral_basic.f90 b/src/grid/grid_mech_spectral_basic.f90 index ccbeb3c42..66694e516 100644 --- a/src/grid/grid_mech_spectral_basic.f90 +++ b/src/grid/grid_mech_spectral_basic.f90 @@ -17,10 +17,8 @@ module grid_mech_spectral_basic use spectral_utilities use FEsolving use config - use numerics use homogenization use discretization_grid - use debug implicit none private diff --git a/src/grid/grid_mech_spectral_polarisation.f90 b/src/grid/grid_mech_spectral_polarisation.f90 index 347a2a832..f6d1b9ebb 100644 --- a/src/grid/grid_mech_spectral_polarisation.f90 +++ b/src/grid/grid_mech_spectral_polarisation.f90 @@ -18,10 +18,8 @@ module grid_mech_spectral_polarisation use spectral_utilities use FEsolving use config - use numerics use homogenization use discretization_grid - use debug implicit none private diff --git a/src/grid/grid_thermal_spectral.f90 b/src/grid/grid_thermal_spectral.f90 index 0b66ef3f0..58c89fdc4 100644 --- a/src/grid/grid_thermal_spectral.f90 +++ b/src/grid/grid_thermal_spectral.f90 @@ -16,7 +16,7 @@ module grid_thermal_spectral use discretization_grid use thermal_conduction use YAML_types - use numerics + use config use material implicit none diff --git a/src/grid/spectral_utilities.f90 b/src/grid/spectral_utilities.f90 index 7f2066e4b..f1daf8f08 100644 --- a/src/grid/spectral_utilities.f90 +++ b/src/grid/spectral_utilities.f90 @@ -14,8 +14,6 @@ module spectral_utilities use rotations use IO use discretization_grid - use numerics - use debug use config use discretization use homogenization diff --git a/src/homogenization.f90 b/src/homogenization.f90 index d54e1f390..b2d75d9ee 100644 --- a/src/homogenization.f90 +++ b/src/homogenization.f90 @@ -8,10 +8,8 @@ module homogenization use prec use IO use config - use debug use math use material - use numerics use constitutive use crystallite use FEsolving @@ -180,7 +178,6 @@ subroutine homogenization_init if (any(damage_type == DAMAGE_local_ID)) call damage_local_init if (any(damage_type == DAMAGE_nonlocal_ID)) call damage_nonlocal_init - call config_deallocate('material.config/homogenization') !-------------------------------------------------------------------------------------------------- ! allocate and initialize global variables @@ -607,8 +604,8 @@ subroutine homogenization_results !real(pReal), dimension(:,:,:), allocatable :: temp - do p=1,size(config_name_homogenization) - group_base = 'current/materialpoint/'//trim(config_name_homogenization(p)) + do p=1,size(material_name_homogenization) + group_base = 'current/materialpoint/'//trim(material_name_homogenization(p)) call results_closeGroup(results_addGroup(group_base)) group = trim(group_base)//'/generic' diff --git a/src/homogenization_mech_RGC.f90 b/src/homogenization_mech_RGC.f90 index 3993cd609..1d1348d69 100644 --- a/src/homogenization_mech_RGC.f90 +++ b/src/homogenization_mech_RGC.f90 @@ -87,9 +87,12 @@ module subroutine mech_RGC_init(num_homogMech) sizeState, nIntFaceTot class (tNode), pointer :: & - num_RGC ! pointer to RGC numerics data + num_RGC, & ! pointer to RGC numerics data + material_homogenization, & + homog, & + homogMech - write(6,'(/,a)') ' <<<+- homogenization_'//HOMOGENIZATION_RGC_label//' init -+>>>' + write(6,'(/,a)') ' <<<+- homogenization_mech_rgc init -+>>>' write(6,'(/,a)') ' Tjahjanto et al., International Journal of Material Forming 2(1):939–942, 2009' write(6,'(a)') ' https://doi.org/10.1007/s12289-009-0619-1' @@ -135,13 +138,16 @@ module subroutine mech_RGC_init(num_homogMech) if (num%volDiscrMod < 0.0_pReal) call IO_error(301,ext_msg='volDiscrMod_RGC') if (num%volDiscrPow <= 0.0_pReal) call IO_error(301,ext_msg='volDiscrPw_RGC') + + material_homogenization => material_root%get('homogenization') do h = 1, size(homogenization_type) if (homogenization_type(h) /= HOMOGENIZATION_RGC_ID) cycle + homog => material_homogenization%get(h) + homogMech => homog%get('mech') associate(prm => param(homogenization_typeInstance(h)), & stt => state(homogenization_typeInstance(h)), & st0 => state0(homogenization_typeInstance(h)), & - dst => dependentState(homogenization_typeInstance(h)), & - config => config_homogenization(h)) + dst => dependentState(homogenization_typeInstance(h))) #ifdef DEBUG if (h==material_homogenizationAt(debugHomog%element)) then @@ -149,17 +155,21 @@ module subroutine mech_RGC_init(num_homogMech) endif #endif - prm%output = config%getStrings('(output)',defaultVal=emptyStringArray) +#if defined (__GFORTRAN__) + prm%output = output_asStrings(homogMech) +#else + prm%output = homogMech%get_asStrings('output',defaultVal=emptyStringArray) +#endif - prm%Nconstituents = config%getInts('clustersize',requiredSize=3) + prm%Nconstituents = homogMech%get_asInts('cluster_size',requiredSize=3) if (homogenization_Ngrains(h) /= product(prm%Nconstituents)) & - call IO_error(211,ext_msg='clustersize ('//HOMOGENIZATION_RGC_label//')') + call IO_error(211,ext_msg='clustersize (mech_rgc)') - prm%xiAlpha = config%getFloat('scalingparameter') - prm%ciAlpha = config%getFloat('overproportionality') + prm%xiAlpha = homogMech%get_asFloat('xi_alpha') + prm%ciAlpha = homogMech%get_asFloat('c_alpha') - prm%dAlpha = config%getFloats('grainsize', requiredSize=3) - prm%angles = config%getFloats('clusterorientation',requiredSize=3) + prm%dAlpha = homogMech%get_asFloats('D_alpha', requiredSize=3) + prm%angles = homogMech%get_asFloats('a_g', requiredSize=3) NofMyHomog = count(material_homogenizationAt == h) nIntFaceTot = 3*( (prm%Nconstituents(1)-1)*prm%Nconstituents(2)*prm%Nconstituents(3) & @@ -946,23 +956,23 @@ module subroutine mech_RGC_results(instance,group) associate(stt => state(instance), dst => dependentState(instance), prm => param(instance)) outputsLoop: do o = 1,size(prm%output) select case(trim(prm%output(o))) - case('constitutivework') - call results_writeDataset(group,stt%work,'W',& + case('W') + call results_writeDataset(group,stt%work,trim(prm%output(o)), & 'work density','J/m³') - case('magnitudemismatch') - call results_writeDataset(group,dst%mismatch,'N',& + case('M') + call results_writeDataset(group,dst%mismatch,trim(prm%output(o)), & 'average mismatch tensor','1') - case('penaltyenergy') - call results_writeDataset(group,stt%penaltyEnergy,'R',& + case('R') + call results_writeDataset(group,stt%penaltyEnergy,trim(prm%output(o)), & 'mismatch penalty density','J/m³') - case('volumediscrepancy') - call results_writeDataset(group,dst%volumeDiscrepancy,'Delta_V',& + case('Delta_V') + call results_writeDataset(group,dst%volumeDiscrepancy,trim(prm%output(o)), & 'volume discrepancy','m³') - case('maximumrelaxrate') - call results_writeDataset(group,dst%relaxationrate_max,'max_alpha_dot',& + case('max_a_dot') + call results_writeDataset(group,dst%relaxationrate_max,trim(prm%output(o)), & 'maximum relaxation rate','m/s') - case('averagerelaxrate') - call results_writeDataset(group,dst%relaxationrate_avg,'avg_alpha_dot',& + case('avg_a_dot') + call results_writeDataset(group,dst%relaxationrate_avg,trim(prm%output(o)), & 'average relaxation rate','m/s') end select enddo outputsLoop diff --git a/src/homogenization_mech_isostrain.f90 b/src/homogenization_mech_isostrain.f90 index f85621804..91350e6b0 100644 --- a/src/homogenization_mech_isostrain.f90 +++ b/src/homogenization_mech_isostrain.f90 @@ -32,31 +32,33 @@ module subroutine mech_isostrain_init Ninstance, & h, & NofMyHomog - character(len=pStringLen) :: & - tag = '' + class(tNode), pointer :: & + material_homogenization, & + homog, & + homogMech - write(6,'(/,a)') ' <<<+- homogenization_'//HOMOGENIZATION_ISOSTRAIN_LABEL//' init -+>>>' + write(6,'(/,a)') ' <<<+- homogenization_mech_isostrain init -+>>>' Ninstance = count(homogenization_type == HOMOGENIZATION_ISOSTRAIN_ID) write(6,'(a16,1x,i5,/)') '# instances:',Ninstance; flush(6) allocate(param(Ninstance)) ! one container of parameters per instance - + + material_homogenization => material_root%get('homogenization') do h = 1, size(homogenization_type) if (homogenization_type(h) /= HOMOGENIZATION_ISOSTRAIN_ID) cycle - - associate(prm => param(homogenization_typeInstance(h)),& - config => config_homogenization(h)) + homog => material_homogenization%get(h) + homogMech => homog%get('mech') + associate(prm => param(homogenization_typeInstance(h))) - prm%Nconstituents = config_homogenization(h)%getInt('nconstituents') - tag = 'sum' - select case(trim(config%getString('mapping',defaultVal = tag))) + prm%Nconstituents = homogMech%get_asInt('N_constituents') + select case(homogMech%get_asString('mapping',defaultVal = 'sum')) case ('sum') prm%mapping = parallel_ID case ('avg') prm%mapping = average_ID case default - call IO_error(211,ext_msg=trim(tag)//' ('//HOMOGENIZATION_ISOSTRAIN_LABEL//')') + call IO_error(211,ext_msg='sum'//' (mech_isostrain)') end select NofMyHomog = count(material_homogenizationAt == h) diff --git a/src/homogenization_mech_none.f90 b/src/homogenization_mech_none.f90 index 0633f9b8c..b3886bfba 100644 --- a/src/homogenization_mech_none.f90 +++ b/src/homogenization_mech_none.f90 @@ -18,7 +18,7 @@ module subroutine mech_none_init h, & NofMyHomog - write(6,'(/,a)') ' <<<+- homogenization_'//HOMOGENIZATION_NONE_label//' init -+>>>' + write(6,'(/,a)') ' <<<+- homogenization_mech_none init -+>>>' Ninstance = count(homogenization_type == HOMOGENIZATION_NONE_ID) write(6,'(a16,1x,i5,/)') '# instances:',Ninstance; flush(6) diff --git a/src/kinematics_cleavage_opening.f90 b/src/kinematics_cleavage_opening.f90 index 2e314024c..c682fd401 100644 --- a/src/kinematics_cleavage_opening.f90 +++ b/src/kinematics_cleavage_opening.f90 @@ -10,10 +10,10 @@ submodule(constitutive:constitutive_damage) kinematics_cleavage_opening type :: tParameters !< container type for internal constitutive parameters integer :: & - sum_N_cl + sum_N_cl !< total number of cleavage planes real(pReal) :: & - sdot0, & - n + sdot0, & !< opening rate of cleavage planes + n !< damage rate sensitivity real(pReal), dimension(:), allocatable :: & critLoad real(pReal), dimension(:,:,:,:), allocatable :: & @@ -30,54 +30,73 @@ contains !> @brief module initialization !> @details reads in material parameters, allocates arrays, and does sanity checks !-------------------------------------------------------------------------------------------------- -module subroutine kinematics_cleavage_opening_init +module function kinematics_cleavage_opening_init(kinematics_length) result(myKinematics) + + integer, intent(in) :: kinematics_length + logical, dimension(:,:), allocatable :: myKinematics - integer :: Ninstance,p + integer :: Ninstance,p,k integer, dimension(:), allocatable :: N_cl !< active number of cleavage systems per family character(len=pStringLen) :: extmsg = '' + class(tNode), pointer :: & + phases, & + phase, & + pl, & + kinematics, & + kinematic_type + + write(6,'(/,a)') ' <<<+- kinematics_cleavage_opening init -+>>>' - write(6,'(/,a)') ' <<<+- kinematics_'//KINEMATICS_CLEAVAGE_OPENING_LABEL//' init -+>>>' - - Ninstance = count(phase_kinematics == KINEMATICS_CLEAVAGE_OPENING_ID) + myKinematics = kinematics_active('cleavage_opening',kinematics_length) + + Ninstance = count(myKinematics) write(6,'(a16,1x,i5,/)') '# instances:',Ninstance; flush(6) + if(Ninstance == 0) return - allocate(kinematics_cleavage_opening_instance(size(config_phase)), source=0) + phases => material_root%get('phase') allocate(param(Ninstance)) + allocate(kinematics_cleavage_opening_instance(phases%length), source=0) - do p = 1, size(config_phase) - kinematics_cleavage_opening_instance(p) = count(phase_kinematics(:,1:p) == KINEMATICS_CLEAVAGE_OPENING_ID) - if (all(phase_kinematics(:,p) /= KINEMATICS_CLEAVAGE_OPENING_ID)) cycle + do p = 1, phases%length + if(any(myKinematics(:,p))) kinematics_cleavage_opening_instance(p) = count(myKinematics(:,1:p)) + phase => phases%get(p) + pl => phase%get('plasticity') + if(count(myKinematics(:,p)) == 0) cycle + kinematics => phase%get('kinematics') + do k = 1, kinematics%length + if(myKinematics(k,p)) then + associate(prm => param(kinematics_cleavage_opening_instance(p))) + kinematic_type => kinematics%get(k) - associate(prm => param(kinematics_cleavage_opening_instance(p)), & - config => config_phase(p)) + N_cl = kinematic_type%get_asInts('N_cl') + prm%sum_N_cl = sum(abs(N_cl)) - N_cl = config%getInts('ncleavage') - prm%sum_N_cl = sum(abs(N_cl)) + prm%n = kinematic_type%get_asFloat('q') + prm%sdot0 = kinematic_type%get_asFloat('dot_o') - prm%n = config%getFloat('anisobrittle_ratesensitivity') - prm%sdot0 = config%getFloat('anisobrittle_sdot0') + prm%critLoad = kinematic_type%get_asFloats('g_crit',requiredSize=size(N_cl)) - prm%critLoad = config%getFloats('anisobrittle_criticalload',requiredSize=size(N_cl)) + prm%cleavage_systems = lattice_SchmidMatrix_cleavage(N_cl,phase%get_asString('lattice'),& + phase%get_asFloat('c/a',defaultVal=0.0_pReal)) - prm%cleavage_systems = lattice_SchmidMatrix_cleavage(N_cl,config%getString('lattice_structure'),& - config%getFloat('c/a',defaultVal=0.0_pReal)) + ! expand: family => system + prm%critLoad = math_expand(prm%critLoad,N_cl) - ! expand: family => system - prm%critLoad = math_expand(prm%critLoad,N_cl) - - ! sanity checks - if (prm%n <= 0.0_pReal) extmsg = trim(extmsg)//' anisobrittle_n' - if (prm%sdot0 <= 0.0_pReal) extmsg = trim(extmsg)//' anisobrittle_sdot0' - if (any(prm%critLoad < 0.0_pReal)) extmsg = trim(extmsg)//' anisobrittle_critLoad' + ! sanity checks + if (prm%n <= 0.0_pReal) extmsg = trim(extmsg)//' q' + if (prm%sdot0 <= 0.0_pReal) extmsg = trim(extmsg)//' dot_o' + if (any(prm%critLoad < 0.0_pReal)) extmsg = trim(extmsg)//' g_crit' !-------------------------------------------------------------------------------------------------- ! exit if any parameter is out of range - if (extmsg /= '') call IO_error(211,ext_msg=trim(extmsg)//'('//KINEMATICS_CLEAVAGE_OPENING_LABEL//')') - - end associate + if (extmsg /= '') call IO_error(211,ext_msg=trim(extmsg)//'(cleavage_opening)') + end associate + endif + enddo enddo -end subroutine kinematics_cleavage_opening_init + +end function kinematics_cleavage_opening_init !-------------------------------------------------------------------------------------------------- diff --git a/src/kinematics_slipplane_opening.f90 b/src/kinematics_slipplane_opening.f90 index b15d206d3..406e8dce5 100644 --- a/src/kinematics_slipplane_opening.f90 +++ b/src/kinematics_slipplane_opening.f90 @@ -10,10 +10,10 @@ submodule(constitutive:constitutive_damage) kinematics_slipplane_opening type :: tParameters !< container type for internal constitutive parameters integer :: & - sum_N_sl + sum_N_sl !< total number of cleavage planes real(pReal) :: & - sdot0, & - n + sdot0, & !< opening rate of cleavage planes + n !< damage rate sensitivity real(pReal), dimension(:), allocatable :: & critLoad real(pReal), dimension(:,:,:), allocatable :: & @@ -32,64 +32,85 @@ contains !> @brief module initialization !> @details reads in material parameters, allocates arrays, and does sanity checks !-------------------------------------------------------------------------------------------------- -module subroutine kinematics_slipplane_opening_init +module function kinematics_slipplane_opening_init(kinematics_length) result(myKinematics) - integer :: Ninstance,p,i + integer, intent(in) :: kinematics_length + logical, dimension(:,:), allocatable :: myKinematics + + integer :: Ninstance,p,i,k character(len=pStringLen) :: extmsg = '' integer, dimension(:), allocatable :: N_sl real(pReal), dimension(:,:), allocatable :: d,n,t + class(tNode), pointer :: & + phases, & + phase, & + pl, & + kinematics, & + kinematic_type + + write(6,'(/,a)') ' <<<+- kinematics_slipplane init -+>>>' - write(6,'(/,a)') ' <<<+- kinematics_'//KINEMATICS_SLIPPLANE_OPENING_LABEL//' init -+>>>' - - Ninstance = count(phase_kinematics == KINEMATICS_SLIPPLANE_OPENING_ID) + myKinematics = kinematics_active('slipplane_opening',kinematics_length) + + Ninstance = count(myKinematics) write(6,'(a16,1x,i5,/)') '# instances:',Ninstance; flush(6) + if(Ninstance == 0) return - allocate(kinematics_slipplane_opening_instance(size(config_phase)), source=0) + phases => material_root%get('phase') + allocate(kinematics_slipplane_opening_instance(phases%length), source=0) allocate(param(Ninstance)) - do p = 1, size(config_phase) - kinematics_slipplane_opening_instance(p) = count(phase_kinematics(:,1:p) == KINEMATICS_SLIPPLANE_OPENING_ID) - if (all(phase_kinematics(:,p) /= KINEMATICS_SLIPPLANE_OPENING_ID)) cycle - associate(prm => param(kinematics_slipplane_opening_instance(p)), & - config => config_phase(p)) + do p = 1, phases%length + if(any(myKinematics(:,p))) kinematics_slipplane_opening_instance(p) = count(myKinematics(:,1:p)) + phase => phases%get(p) + pl => phase%get('plasticity') + if(count(myKinematics(:,p)) == 0) cycle + kinematics => phase%get('kinematics') + do k = 1, kinematics%length + if(myKinematics(k,p)) then + associate(prm => param(kinematics_slipplane_opening_instance(p))) + kinematic_type => kinematics%get(k) - prm%sdot0 = config%getFloat('anisoductile_sdot0') - prm%n = config%getFloat('anisoductile_ratesensitivity') - N_sl = config%getInts('nslip') - prm%sum_N_sl = sum(abs(N_sl)) + prm%sdot0 = kinematic_type%get_asFloat('dot_o') + prm%n = kinematic_type%get_asFloat('q') + N_sl = pl%get_asInts('N_sl') + prm%sum_N_sl = sum(abs(N_sl)) - d = lattice_slip_direction (N_sl,config%getString('lattice_structure'),& - config%getFloat('c/a',defaultVal=0.0_pReal)) - t = lattice_slip_transverse(N_sl,config%getString('lattice_structure'),& - config%getFloat('c/a',defaultVal=0.0_pReal)) - n = lattice_slip_normal (N_sl,config%getString('lattice_structure'),& - config%getFloat('c/a',defaultVal=0.0_pReal)) - allocate(prm%P_d(3,3,size(d,2)),prm%P_t(3,3,size(t,2)),prm%P_n(3,3,size(n,2))) + d = lattice_slip_direction (N_sl,phase%get_asString('lattice'),& + phase%get_asFloat('c/a',defaultVal=0.0_pReal)) + t = lattice_slip_transverse(N_sl,phase%get_asString('lattice'),& + phase%get_asFloat('c/a',defaultVal=0.0_pReal)) + n = lattice_slip_normal (N_sl,phase%get_asString('lattice'),& + phase%get_asFloat('c/a',defaultVal=0.0_pReal)) + allocate(prm%P_d(3,3,size(d,2)),prm%P_t(3,3,size(t,2)),prm%P_n(3,3,size(n,2))) - do i=1, size(n,2) - prm%P_d(1:3,1:3,i) = math_outer(d(1:3,i), n(1:3,i)) - prm%P_t(1:3,1:3,i) = math_outer(t(1:3,i), n(1:3,i)) - prm%P_n(1:3,1:3,i) = math_outer(n(1:3,i), n(1:3,i)) - enddo + do i=1, size(n,2) + prm%P_d(1:3,1:3,i) = math_outer(d(1:3,i), n(1:3,i)) + prm%P_t(1:3,1:3,i) = math_outer(t(1:3,i), n(1:3,i)) + prm%P_n(1:3,1:3,i) = math_outer(n(1:3,i), n(1:3,i)) + enddo - prm%critLoad = config%getFloats('anisoductile_criticalload',requiredSize=size(N_sl)) + prm%critLoad = kinematic_type%get_asFloats('g_crit',requiredSize=size(N_sl)) - ! expand: family => system - prm%critLoad = math_expand(prm%critLoad,N_sl) + ! expand: family => system + prm%critLoad = math_expand(prm%critLoad,N_sl) - ! sanity checks - if (prm%n <= 0.0_pReal) extmsg = trim(extmsg)//' anisoDuctile_n' - if (prm%sdot0 <= 0.0_pReal) extmsg = trim(extmsg)//' anisoDuctile_sdot0' - if (any(prm%critLoad < 0.0_pReal)) extmsg = trim(extmsg)//' anisoDuctile_critLoad' + ! sanity checks + if (prm%n <= 0.0_pReal) extmsg = trim(extmsg)//' anisoDuctile_n' + if (prm%sdot0 <= 0.0_pReal) extmsg = trim(extmsg)//' anisoDuctile_sdot0' + if (any(prm%critLoad < 0.0_pReal)) extmsg = trim(extmsg)//' anisoDuctile_critLoad' !-------------------------------------------------------------------------------------------------- ! exit if any parameter is out of range - if (extmsg /= '') call IO_error(211,ext_msg=trim(extmsg)//'('//KINEMATICS_SLIPPLANE_OPENING_LABEL//')') + if (extmsg /= '') call IO_error(211,ext_msg=trim(extmsg)//'(slipplane_opening)') - end associate + end associate + endif + enddo enddo -end subroutine kinematics_slipplane_opening_init + +end function kinematics_slipplane_opening_init !-------------------------------------------------------------------------------------------------- diff --git a/src/kinematics_thermal_expansion.f90 b/src/kinematics_thermal_expansion.f90 index 8fc2dc704..3c345f148 100644 --- a/src/kinematics_thermal_expansion.f90 +++ b/src/kinematics_thermal_expansion.f90 @@ -24,43 +24,64 @@ contains !> @brief module initialization !> @details reads in material parameters, allocates arrays, and does sanity checks !-------------------------------------------------------------------------------------------------- -module subroutine kinematics_thermal_expansion_init +module function kinematics_thermal_expansion_init(kinematics_length) result(myKinematics) - integer :: Ninstance,p,i + integer, intent(in) :: kinematics_length + logical, dimension(:,:), allocatable :: myKinematics + + integer :: Ninstance,p,i,k real(pReal), dimension(:), allocatable :: temp + class(tNode), pointer :: & + phases, & + phase, & + pl, & + kinematics, & + kinematic_type + + write(6,'(/,a)') ' <<<+- kinematics_thermal_expansion init -+>>>' - write(6,'(/,a)') ' <<<+- kinematics_'//KINEMATICS_thermal_expansion_LABEL//' init -+>>>' - - Ninstance = count(phase_kinematics == KINEMATICS_thermal_expansion_ID) + myKinematics = kinematics_active('thermal_expansion',kinematics_length) + + Ninstance = count(myKinematics) write(6,'(a16,1x,i5,/)') '# instances:',Ninstance; flush(6) + if(Ninstance == 0) return - allocate(kinematics_thermal_expansion_instance(size(config_phase)), source=0) + phases => material_root%get('phase') allocate(param(Ninstance)) + allocate(kinematics_thermal_expansion_instance(phases%length), source=0) - do p = 1, size(config_phase) - kinematics_thermal_expansion_instance(p) = count(phase_kinematics(:,1:p) == KINEMATICS_thermal_expansion_ID) - if (all(phase_kinematics(:,p) /= KINEMATICS_thermal_expansion_ID)) cycle + do p = 1, phases%length + if(any(myKinematics(:,p))) kinematics_thermal_expansion_instance(p) = count(myKinematics(:,1:p)) + phase => phases%get(p) + pl => phase%get('plasticity') + 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) - associate(prm => param(kinematics_thermal_expansion_instance(p)), & - config => config_phase(p)) + prm%T_ref = kinematic_type%get_asFloat('T_ref', defaultVal=0.0_pReal) - prm%T_ref = config%getFloat('reference_temperature', defaultVal=0.0_pReal) + ! read up to three parameters (constant, linear, quadratic with T) + temp = kinematic_type%get_asFloats('A_11') + prm%expansion(1,1,1:size(temp)) = temp + temp = kinematic_type%get_asFloats('A_22',defaultVal=[(0.0_pReal, i=1,size(temp))],requiredSize=size(temp)) + prm%expansion(2,2,1:size(temp)) = temp + temp = kinematic_type%get_asFloats('A_33',defaultVal=[(0.0_pReal, i=1,size(temp))],requiredSize=size(temp)) + prm%expansion(3,3,1:size(temp)) = temp + do i=1, size(prm%expansion,3) + prm%expansion(1:3,1:3,i) = lattice_applyLatticeSymmetry33(prm%expansion(1:3,1:3,i),& + phase%get_asString('lattice')) + enddo - ! read up to three parameters (constant, linear, quadratic with T) - temp = config%getFloats('thermal_expansion11') - prm%expansion(1,1,1:size(temp)) = temp - temp = config%getFloats('thermal_expansion22',defaultVal=[(0.0_pReal, i=1,size(temp))],requiredSize=size(temp)) - prm%expansion(2,2,1:size(temp)) = temp - temp = config%getFloats('thermal_expansion33',defaultVal=[(0.0_pReal, i=1,size(temp))],requiredSize=size(temp)) - prm%expansion(3,3,1:size(temp)) = temp - do i=1, size(prm%expansion,3) - prm%expansion(1:3,1:3,i) = lattice_applyLatticeSymmetry33(prm%expansion(1:3,1:3,i),config%getString('lattice_structure')) + end associate + endif enddo - - end associate enddo -end subroutine kinematics_thermal_expansion_init + +end function kinematics_thermal_expansion_init !-------------------------------------------------------------------------------------------------- diff --git a/src/lattice.f90 b/src/lattice.f90 index 7a732d2fd..503293237 100644 --- a/src/lattice.f90 +++ b/src/lattice.f90 @@ -452,11 +452,15 @@ contains subroutine lattice_init integer :: Nphases, p,i - character(len=pStringLen) :: structure = '' - + class(tNode), pointer :: & + phases, & + phase, & + elasticity + write(6,'(/,a)') ' <<<+- lattice init -+>>>'; flush(6) - Nphases = size(config_phase) + phases => material_root%get('phase') + Nphases = phases%length allocate(lattice_structure(Nphases),source = lattice_UNDEFINED_ID) allocate(lattice_C66(6,6,Nphases), source=0.0_pReal) @@ -469,21 +473,21 @@ subroutine lattice_init lattice_mu, lattice_nu,& source=[(0.0_pReal,i=1,Nphases)]) - do p = 1, size(config_phase) + do p = 1, phases%length + phase => phases%get(p) + elasticity => phase%get('elasticity') + lattice_C66(1,1,p) = elasticity%get_asFloat('C_11') + lattice_C66(1,2,p) = elasticity%get_asFloat('C_12') - lattice_C66(1,1,p) = config_phase(p)%getFloat('c11') - lattice_C66(1,2,p) = config_phase(p)%getFloat('c12') + lattice_C66(1,3,p) = elasticity%get_asFloat('C_13',defaultVal=0.0_pReal) + lattice_C66(2,2,p) = elasticity%get_asFloat('C_22',defaultVal=0.0_pReal) + lattice_C66(2,3,p) = elasticity%get_asFloat('C_23',defaultVal=0.0_pReal) + lattice_C66(3,3,p) = elasticity%get_asFloat('C_33',defaultVal=0.0_pReal) + lattice_C66(4,4,p) = elasticity%get_asFloat('C_44',defaultVal=0.0_pReal) + lattice_C66(5,5,p) = elasticity%get_asFloat('C_55',defaultVal=0.0_pReal) + lattice_C66(6,6,p) = elasticity%get_asFloat('C_66',defaultVal=0.0_pReal) - lattice_C66(1,3,p) = config_phase(p)%getFloat('c13',defaultVal=0.0_pReal) - lattice_C66(2,2,p) = config_phase(p)%getFloat('c22',defaultVal=0.0_pReal) - lattice_C66(2,3,p) = config_phase(p)%getFloat('c23',defaultVal=0.0_pReal) - lattice_C66(3,3,p) = config_phase(p)%getFloat('c33',defaultVal=0.0_pReal) - lattice_C66(4,4,p) = config_phase(p)%getFloat('c44',defaultVal=0.0_pReal) - lattice_C66(5,5,p) = config_phase(p)%getFloat('c55',defaultVal=0.0_pReal) - lattice_C66(6,6,p) = config_phase(p)%getFloat('c66',defaultVal=0.0_pReal) - - structure = config_phase(p)%getString('lattice_structure') - select case(trim(structure)) + select case(phase%get_asString('lattice')) case('iso') lattice_structure(p) = lattice_ISO_ID case('fcc') @@ -497,10 +501,10 @@ subroutine lattice_init case('ort') lattice_structure(p) = lattice_ORT_ID case default - call IO_error(130,ext_msg='lattice_init: '//trim(structure)) + call IO_error(130,ext_msg='lattice_init: '//phase%get_asString('lattice')) end select - lattice_C66(1:6,1:6,p) = applyLatticeSymmetryC66(lattice_C66(1:6,1:6,p),structure) + 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') @@ -513,20 +517,22 @@ subroutine lattice_init ! SHOULD NOT BE PART OF LATTICE BEGIN - lattice_thermalConductivity(1,1,p) = config_phase(p)%getFloat('thermal_conductivity11',defaultVal=0.0_pReal) - lattice_thermalConductivity(2,2,p) = config_phase(p)%getFloat('thermal_conductivity22',defaultVal=0.0_pReal) - lattice_thermalConductivity(3,3,p) = config_phase(p)%getFloat('thermal_conductivity33',defaultVal=0.0_pReal) - lattice_thermalConductivity(1:3,1:3,p) = lattice_applyLatticeSymmetry33(lattice_thermalConductivity(1:3,1:3,p),structure) + lattice_thermalConductivity(1,1,p) = phase%get_asFloat('K_11',defaultVal=0.0_pReal) + lattice_thermalConductivity(2,2,p) = phase%get_asFloat('K_22',defaultVal=0.0_pReal) + lattice_thermalConductivity(3,3,p) = phase%get_asFloat('K_33',defaultVal=0.0_pReal) + lattice_thermalConductivity(1:3,1:3,p) = lattice_applyLatticeSymmetry33(lattice_thermalConductivity(1:3,1:3,p), & + phase%get_asString('lattice')) - lattice_specificHeat(p) = config_phase(p)%getFloat('specific_heat',defaultVal=0.0_pReal) - lattice_massDensity(p) = config_phase(p)%getFloat('mass_density', defaultVal=0.0_pReal) + lattice_specificHeat(p) = phase%get_asFloat('c_p',defaultVal=0.0_pReal) + lattice_massDensity(p) = phase%get_asFloat('rho', defaultVal=0.0_pReal) - lattice_DamageDiffusion(1,1,p) = config_phase(p)%getFloat('damage_diffusion11',defaultVal=0.0_pReal) - lattice_DamageDiffusion(2,2,p) = config_phase(p)%getFloat('damage_diffusion22',defaultVal=0.0_pReal) - lattice_DamageDiffusion(3,3,p) = config_phase(p)%getFloat('damage_diffusion33',defaultVal=0.0_pReal) - lattice_DamageDiffusion(1:3,1:3,p) = lattice_applyLatticeSymmetry33(lattice_DamageDiffusion(1:3,1:3,p),structure) + lattice_DamageDiffusion(1,1,p) = phase%get_asFloat('D_11',defaultVal=0.0_pReal) + lattice_DamageDiffusion(2,2,p) = phase%get_asFloat('D_22',defaultVal=0.0_pReal) + lattice_DamageDiffusion(3,3,p) = phase%get_asFloat('D_33',defaultVal=0.0_pReal) + lattice_DamageDiffusion(1:3,1:3,p) = lattice_applyLatticeSymmetry33(lattice_DamageDiffusion(1:3,1:3,p), & + phase%get_asString('lattice')) - lattice_DamageMobility(p) = config_phase(p)%getFloat('damage_mobility',defaultVal=0.0_pReal) + lattice_DamageMobility(p) = phase%get_asFloat('M',defaultVal=0.0_pReal) ! SHOULD NOT BE PART OF LATTICE END call selfTest diff --git a/src/marc/discretization_marc.f90 b/src/marc/discretization_marc.f90 index d53dccf75..e5c382fe1 100644 --- a/src/marc/discretization_marc.f90 +++ b/src/marc/discretization_marc.f90 @@ -11,8 +11,7 @@ module discretization_marc use math use DAMASK_interface use IO - use debug - use numerics + use config use FEsolving use element use discretization diff --git a/src/material.f90 b/src/material.f90 index ca2b0d49a..c89113311 100644 --- a/src/material.f90 +++ b/src/material.f90 @@ -10,52 +10,22 @@ module material use config use results use IO - use debug use rotations use discretization implicit none private - character(len=*), parameter, public :: & - ELASTICITY_hooke_label = 'hooke', & - PLASTICITY_none_label = 'none', & - PLASTICITY_isotropic_label = 'isotropic', & - PLASTICITY_phenopowerlaw_label = 'phenopowerlaw', & - PLASTICITY_kinehardening_label = 'kinehardening', & - PLASTICITY_dislotwin_label = 'dislotwin', & - PLASTICITY_disloucla_label = 'disloucla', & - PLASTICITY_nonlocal_label = 'nonlocal', & - SOURCE_thermal_dissipation_label = 'thermal_dissipation', & - SOURCE_thermal_externalheat_label = 'thermal_externalheat', & - SOURCE_damage_isoBrittle_label = 'damage_isobrittle', & - SOURCE_damage_isoDuctile_label = 'damage_isoductile', & - SOURCE_damage_anisoBrittle_label = 'damage_anisobrittle', & - SOURCE_damage_anisoDuctile_label = 'damage_anisoductile', & - KINEMATICS_thermal_expansion_label = 'thermal_expansion', & - KINEMATICS_cleavage_opening_label = 'cleavage_opening', & - KINEMATICS_slipplane_opening_label = 'slipplane_opening', & - STIFFNESS_DEGRADATION_damage_label = 'damage', & - THERMAL_isothermal_label = 'isothermal', & - THERMAL_adiabatic_label = 'adiabatic', & - THERMAL_conduction_label = 'conduction', & - DAMAGE_none_label = 'none', & - DAMAGE_local_label = 'local', & - DAMAGE_nonlocal_label = 'nonlocal', & - HOMOGENIZATION_none_label = 'none', & - HOMOGENIZATION_isostrain_label = 'isostrain', & - HOMOGENIZATION_rgc_label = 'rgc' - enum, bind(c); enumerator :: & - ELASTICITY_UNDEFINED_ID ,& - ELASTICITY_HOOKE_ID ,& - PLASTICITY_UNDEFINED_ID ,& + 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_DISLOUCLA_ID, & + PLASTICITY_DISLOTUNGSTEN_ID, & PLASTICITY_NONLOCAL_ID, & SOURCE_UNDEFINED_ID ,& SOURCE_THERMAL_DISSIPATION_ID, & @@ -82,10 +52,10 @@ module material HOMOGENIZATION_RGC_ID end enum - integer(kind(ELASTICITY_undefined_ID)), dimension(:), allocatable, public, protected :: & - phase_elasticity !< elasticity of each phase - integer(kind(PLASTICITY_undefined_ID)), dimension(:), allocatable, public, protected :: & - phase_plasticity !< plasticity of each phase + character(len=pStringLen), public, protected, allocatable, dimension(:) :: & + material_name_phase, & !< name of each phase + material_name_homogenization !< name of each homogenization + integer(kind(THERMAL_isothermal_ID)), dimension(:), allocatable, public, protected :: & thermal_type !< thermal transport model integer(kind(DAMAGE_none_ID)), dimension(:), allocatable, public, protected :: & @@ -94,23 +64,12 @@ module material homogenization_type !< type of each homogenization integer, public, protected :: & - material_Nphase, & !< number of phases material_Nhomogenization !< number of homogenizations - integer(kind(SOURCE_undefined_ID)), dimension(:,:), allocatable, public, protected :: & - 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 - integer, public, protected :: & homogenization_maxNgrains !< max number of grains in any USED homogenization integer, dimension(:), allocatable, public, protected :: & - 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_elasticityInstance, & !< instance of particular elasticity of each phase - phase_plasticityInstance, & !< instance of particular plasticity of each phase homogenization_Ngrains, & !< 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 @@ -129,33 +88,17 @@ module material integer, dimension(:,:,:), allocatable, public, protected :: & ! (constituent,elem) material_phaseMemberAt !< position of the element within its phase instance - type(tPlasticState), allocatable, dimension(:), public :: & - plasticState - type(tSourceState), allocatable, dimension(:), public :: & - sourceState type(tState), allocatable, dimension(:), public :: & homogState, & thermalState, & damageState - integer, dimension(:,:,:), allocatable, public, protected :: & - material_texture !< texture (index) of each grain,IP,element. Only used by plastic_nonlocal - type(Rotation), dimension(:,:,:), allocatable, public, protected :: & material_orientation0 !< initial orientation of each grain,IP,element - logical, dimension(:), allocatable, public, protected :: & - phase_localPlasticity !< flags phases with local constitutive law - integer, dimension(:), allocatable, private :: & microstructure_Nconstituents !< number of constituents in each microstructure - integer, dimension(:,:), allocatable, private :: & - microstructure_phase, & !< phase IDs of each microstructure - microstructure_texture !< texture IDs of each microstructure - - type(Rotation), dimension(:), allocatable, private :: & - texture_orientation !< Euler angles in material.config (possibly rotated for alignment) ! BEGIN DEPRECATED @@ -173,24 +116,28 @@ module material public :: & material_init, & - material_allocateState, & - ELASTICITY_HOOKE_ID ,& + 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_DISLOUCLA_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_ADIABATIC_ID, & @@ -211,18 +158,30 @@ subroutine material_init(restart) logical, intent(in) :: restart - integer :: i,e,m,c,h, myDebug, myPhase, myHomog, myMicro - integer, dimension(:), allocatable :: & - CounterPhase, & - CounterHomogenization + integer :: ph, myHomog class(tNode), pointer :: & - debug_material ! pointer to material debug options - + debug_material, & ! pointer to material debug options + phases, & + material_homogenization + character(len=pStringLen) :: sectionName + write(6,'(/,a)') ' <<<+- material init -+>>>'; flush(6) + phases => material_root%get('phase') + allocate(material_name_phase(phases%length)) + do ph = 1, phases%length + write(sectionName,'(i0,a)') ph,'_' + material_name_phase(ph) = trim(adjustl(sectionName))//phases%getKey(ph) !ToDO: No reason to do. Update damage tests + enddo + + material_homogenization => material_root%get('homogenization') + allocate(material_name_homogenization(material_homogenization%length)) + do myHomog = 1, material_homogenization%length + write(sectionName,'(i0,a)') myHomog,'_' + material_name_homogenization(myHomog) = trim(adjustl(sectionName))//material_homogenization%getKey(myHomog) + enddo + debug_material => debug_root%get('material',defaultVal=emptyList) - call material_parsePhase() - if (debug_material%contains('basic')) write(6,'(a)') ' Phase parsed'; flush(6) call material_parseMicrostructure() if (debug_material%contains('basic')) write(6,'(a)') ' Microstructure parsed'; flush(6) @@ -230,18 +189,8 @@ subroutine material_init(restart) call material_parseHomogenization() if (debug_material%contains('basic')) write(6,'(a)') ' Homogenization parsed'; flush(6) - call material_parseTexture() - if (debug_material%contains('basic')) write(6,'(a)') ' Texture parsed'; flush(6) - material_Nphase = size(config_phase) - material_Nhomogenization = size(config_homogenization) - - - allocate(plasticState(material_Nphase)) - allocate(sourceState (material_Nphase)) - do myPhase = 1,material_Nphase - allocate(sourceState(myPhase)%p(phase_Nsources(myPhase))) - enddo + if(homogenization_maxNgrains > size(material_phaseAt,1)) call IO_error(148) allocate(homogState (material_Nhomogenization)) allocate(thermalState (material_Nhomogenization)) @@ -255,97 +204,11 @@ subroutine material_init(restart) allocate(temperatureRate (material_Nhomogenization)) - do m = 1,size(config_microstructure) - if(minval(microstructure_phase(1:microstructure_Nconstituents(m),m)) < 1 .or. & - maxval(microstructure_phase(1:microstructure_Nconstituents(m),m)) > size(config_phase)) & - call IO_error(150,m,ext_msg='phase') - if(minval(microstructure_texture(1:microstructure_Nconstituents(m),m)) < 1 .or. & - maxval(microstructure_texture(1:microstructure_Nconstituents(m),m)) > size(config_texture)) & - call IO_error(150,m,ext_msg='texture') - if(microstructure_Nconstituents(m) < 1) & - call IO_error(151,m) - enddo - if(homogenization_maxNgrains > size(microstructure_phase,1)) call IO_error(148) - - debugOut: if (debug_material%contains('extensive')) then - write(6,'(/,a,/)') ' MATERIAL configuration' - write(6,'(a32,1x,a16,1x,a6)') 'homogenization ','type ','grains' - do h = 1,size(config_homogenization) - write(6,'(1x,a32,1x,a16,1x,i6)') config_name_homogenization(h),homogenization_type(h),homogenization_Ngrains(h) - enddo - write(6,'(/,a14,18x,1x,a11,1x,a12,1x,a13)') 'microstructure','constituents' - do m = 1,size(config_microstructure) - write(6,'(1x,a32,1x,i12)') config_name_microstructure(m), microstructure_Nconstituents(m) - if (microstructure_Nconstituents(m) > 0) then - do c = 1,microstructure_Nconstituents(m) - write(6,'(a1,1x,a32,1x,a32)') '>',config_name_phase(microstructure_phase(c,m)),& - config_name_texture(microstructure_texture(c,m)) - enddo - write(6,*) - endif - enddo - endif debugOut - - allocate(material_phaseAt(homogenization_maxNgrains,discretization_nElem), source=0) - allocate(material_texture(homogenization_maxNgrains,discretization_nIP,discretization_nElem),source=0) !this is only needed by plasticity nonlocal - allocate(material_orientation0(homogenization_maxNgrains,discretization_nIP,discretization_nElem)) - - do e = 1, discretization_nElem - do i = 1, discretization_nIP - myMicro = discretization_microstructureAt(e) - do c = 1, homogenization_Ngrains(discretization_homogenizationAt(e)) - if(microstructure_phase(c,myMicro) > 0) then - material_phaseAt(c,e) = microstructure_phase(c,myMicro) - else - call IO_error(150,ext_msg='phase') - endif - if(microstructure_texture(c,myMicro) > 0) then - material_texture(c,i,e) = microstructure_texture(c,myMicro) - material_orientation0(c,i,e) = texture_orientation(material_texture(c,i,e)) - else - call IO_error(150,ext_msg='texture') - endif - enddo - enddo - enddo - - deallocate(microstructure_phase) - deallocate(microstructure_texture) - deallocate(texture_orientation) - - - allocate(material_homogenizationAt,source=discretization_homogenizationAt) - allocate(material_homogenizationMemberAt(discretization_nIP,discretization_nElem),source=0) - - allocate(CounterHomogenization(size(config_homogenization)),source=0) - do e = 1, discretization_nElem - do i = 1, discretization_nIP - CounterHomogenization(material_homogenizationAt(e)) = & - CounterHomogenization(material_homogenizationAt(e)) + 1 - material_homogenizationMemberAt(i,e) = CounterHomogenization(material_homogenizationAt(e)) - enddo - enddo - - allocate(material_phaseMemberAt(homogenization_maxNgrains,discretization_nIP,discretization_nElem),source=0) - - allocate(CounterPhase(size(config_phase)),source=0) - do e = 1, discretization_nElem - do i = 1, discretization_nIP - do c = 1, homogenization_maxNgrains - CounterPhase(material_phaseAt(c,e)) = & - CounterPhase(material_phaseAt(c,e)) + 1 - material_phaseMemberAt(c,i,e) = CounterPhase(material_phaseAt(c,e)) - enddo - enddo - enddo - - call config_deallocate('material.config/microstructure') - call config_deallocate('material.config/texture') if (.not. restart) then call results_openJobFile - call results_mapping_constituent(material_phaseAt,material_phaseMemberAt,config_name_phase) - call results_mapping_materialpoint(material_homogenizationAt,material_homogenizationMemberAt,config_name_homogenization) + call results_mapping_constituent(material_phaseAt,material_phaseMemberAt,material_name_phase) + call results_mapping_materialpoint(material_homogenizationAt,material_homogenizationMemberAt,material_name_homogenization) call results_closeJobFile endif @@ -354,7 +217,7 @@ subroutine material_init(restart) allocate(mappingHomogenizationConst( discretization_nIP,discretization_nElem),source=1) ! hack needed to initialize field values used during constitutive initialization - do myHomog = 1,size(config_homogenization) + do myHomog = 1,material_Nhomogenization thermalMapping (myHomog)%p => mappingHomogenizationConst damageMapping (myHomog)%p => mappingHomogenizationConst allocate(temperature (myHomog)%p(1), source=thermal_initialT(myHomog)) @@ -370,82 +233,85 @@ end subroutine material_init !-------------------------------------------------------------------------------------------------- subroutine material_parseHomogenization - integer :: h - character(len=pStringLen) :: tag + class(tNode), pointer :: & + material_homogenization, & + homog, & + homogMech, & + homogThermal, & + homogDamage + integer :: h logical, dimension(:), allocatable :: homogenization_active - allocate(homogenization_type(size(config_homogenization)), source=HOMOGENIZATION_undefined_ID) - allocate(thermal_type(size(config_homogenization)), source=THERMAL_isothermal_ID) - allocate(damage_type (size(config_homogenization)), source=DAMAGE_none_ID) - allocate(homogenization_typeInstance(size(config_homogenization)), source=0) - allocate(thermal_typeInstance(size(config_homogenization)), source=0) - allocate(damage_typeInstance(size(config_homogenization)), source=0) - allocate(homogenization_Ngrains(size(config_homogenization)), source=0) - allocate(homogenization_active(size(config_homogenization)), source=.false.) !!!!!!!!!!!!!!! - allocate(thermal_initialT(size(config_homogenization)), source=300.0_pReal) - allocate(damage_initialPhi(size(config_homogenization)), source=1.0_pReal) + material_homogenization => material_root%get('homogenization') + material_Nhomogenization = material_homogenization%length - forall (h = 1:size(config_homogenization)) & - homogenization_active(h) = any(discretization_homogenizationAt == h) + allocate(homogenization_type(material_Nhomogenization), source=HOMOGENIZATION_undefined_ID) + allocate(thermal_type(material_Nhomogenization), source=THERMAL_isothermal_ID) + allocate(damage_type (material_Nhomogenization), source=DAMAGE_none_ID) + allocate(homogenization_typeInstance(material_Nhomogenization), source=0) + allocate(thermal_typeInstance(material_Nhomogenization), source=0) + allocate(damage_typeInstance(material_Nhomogenization), source=0) + allocate(homogenization_Ngrains(material_Nhomogenization), source=0) + allocate(homogenization_active(material_Nhomogenization), source=.false.) !!!!!!!!!!!!!!! + allocate(thermal_initialT(material_Nhomogenization), source=300.0_pReal) + allocate(damage_initialPhi(material_Nhomogenization), source=1.0_pReal) + forall (h = 1:material_Nhomogenization) & + homogenization_active(h) = any(discretization_homogenizationAt == h) !ToDo: SR: needed?? - do h=1, size(config_homogenization) - - tag = config_homogenization(h)%getString('mech') - select case (trim(tag)) - case(HOMOGENIZATION_NONE_label) + do h=1, material_Nhomogenization + homog => material_homogenization%get(h) + homogMech => homog%get('mech') + select case (homogMech%get_asString('type')) + case('none') homogenization_type(h) = HOMOGENIZATION_NONE_ID homogenization_Ngrains(h) = 1 - case(HOMOGENIZATION_ISOSTRAIN_label) + case('isostrain') homogenization_type(h) = HOMOGENIZATION_ISOSTRAIN_ID - homogenization_Ngrains(h) = config_homogenization(h)%getInt('nconstituents') - case(HOMOGENIZATION_RGC_label) + homogenization_Ngrains(h) = homogMech%get_asInt('N_constituents') + case('RGC') homogenization_type(h) = HOMOGENIZATION_RGC_ID - homogenization_Ngrains(h) = config_homogenization(h)%getInt('nconstituents') + homogenization_Ngrains(h) = homogMech%get_asInt('N_constituents') case default - call IO_error(500,ext_msg=trim(tag)) + call IO_error(500,ext_msg=homogMech%get_asString('type')) end select homogenization_typeInstance(h) = count(homogenization_type==homogenization_type(h)) - if (config_homogenization(h)%keyExists('thermal')) then - thermal_initialT(h) = config_homogenization(h)%getFloat('t0',defaultVal=300.0_pReal) - - tag = config_homogenization(h)%getString('thermal') - select case (trim(tag)) - case(THERMAL_isothermal_label) - thermal_type(h) = THERMAL_isothermal_ID - case(THERMAL_adiabatic_label) - thermal_type(h) = THERMAL_adiabatic_ID - case(THERMAL_conduction_label) - thermal_type(h) = THERMAL_conduction_ID - case default - call IO_error(500,ext_msg=trim(tag)) - end select + if(homog%contains('thermal')) then + homogThermal => homog%get('thermal') + thermal_initialT(h) = homogThermal%get_asFloat('T_0',defaultVal=300.0_pReal) + select case (homogThermal%get_asString('type')) + case('isothermal') + thermal_type(h) = THERMAL_isothermal_ID + case('adiabatic') + thermal_type(h) = THERMAL_adiabatic_ID + case('conduction') + thermal_type(h) = THERMAL_conduction_ID + case default + call IO_error(500,ext_msg=homogThermal%get_asString('type')) + end select endif - if (config_homogenization(h)%keyExists('damage')) then - damage_initialPhi(h) = config_homogenization(h)%getFloat('initialdamage',defaultVal=1.0_pReal) - - tag = config_homogenization(h)%getString('damage') - select case (trim(tag)) - case(DAMAGE_NONE_label) - damage_type(h) = DAMAGE_none_ID - case(DAMAGE_LOCAL_label) - damage_type(h) = DAMAGE_local_ID - case(DAMAGE_NONLOCAL_label) - damage_type(h) = DAMAGE_nonlocal_ID - case default - call IO_error(500,ext_msg=trim(tag)) - end select - + 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 + case('local') + damage_type(h) = DAMAGE_local_ID + case('nonlocal') + damage_type(h) = DAMAGE_nonlocal_ID + case default + call IO_error(500,ext_msg=homogDamage%get_asString('type')) + end select endif - enddo - do h=1, size(config_homogenization) + do h=1, material_Nhomogenization homogenization_typeInstance(h) = count(homogenization_type(1:h) == homogenization_type(h)) thermal_typeInstance(h) = count(thermal_type (1:h) == thermal_type (h)) damage_typeInstance(h) = count(damage_type (1:h) == damage_type (h)) @@ -453,6 +319,7 @@ subroutine material_parseHomogenization homogenization_maxNgrains = maxval(homogenization_Ngrains,homogenization_active) + end subroutine material_parseHomogenization @@ -461,276 +328,101 @@ end subroutine material_parseHomogenization !-------------------------------------------------------------------------------------------------- subroutine material_parseMicrostructure - character(len=pStringLen), dimension(:), allocatable :: & - strings - integer, allocatable, dimension(:) :: chunkPos - integer :: m, c, i - character(len=pStringLen) :: & - tag + class(tNode), pointer :: microstructure, & !> pointer to microstructure list + constituentsInMicrostructure, & !> pointer to a microstructure list item + constituents, & !> pointer to constituents list + constituent, & !> pointer to each constituent + phases, & + homogenization + + integer, dimension(:), allocatable :: & + CounterPhase, & + CounterHomogenization + + real(pReal), dimension(:,:), allocatable :: & - microstructure_fraction !< vol fraction of each constituent in microstructure + microstructure_fraction !< vol fraction of each constituent in microstrcuture + integer :: & - maxNconstituents !< max number of constituents in any phase + e, & + i, & + m, & + c, & + microstructure_maxNconstituents - allocate(microstructure_Nconstituents(size(config_microstructure)), source=0) + real(pReal), dimension(4) :: phase_orientation - if(any(discretization_microstructureAt > size(config_microstructure))) & - call IO_error(155,ext_msg='More microstructures in geometry than sections in material.config') + homogenization => material_root%get('homogenization') + phases => material_root%get('phase') + microstructure => material_root%get('microstructure') + allocate(microstructure_Nconstituents(microstructure%length), source = 0) + + if(any(discretization_microstructureAt > microstructure%length)) & + call IO_error(155,ext_msg='More microstructures in geometry than sections in material.yaml') - do m=1, size(config_microstructure) - microstructure_Nconstituents(m) = config_microstructure(m)%countKeys('(constituent)') + do m = 1, microstructure%length + constituentsInMicrostructure => microstructure%get(m) + constituents => constituentsInMicrostructure%get('constituents') + microstructure_Nconstituents(m) = constituents%length + enddo + + microstructure_maxNconstituents = maxval(microstructure_Nconstituents) + allocate(microstructure_fraction(microstructure_maxNconstituents,microstructure%length), source =0.0_pReal) + allocate(material_phaseAt(microstructure_maxNconstituents,discretization_nElem), source =0) + allocate(material_orientation0(microstructure_maxNconstituents,discretization_nIP,discretization_nElem)) + allocate(material_homogenizationAt(discretization_nElem)) + allocate(material_homogenizationMemberAt(discretization_nIP,discretization_nElem),source=0) + allocate(material_phaseMemberAt(microstructure_maxNconstituents,discretization_nIP,discretization_nElem),source=0) + + allocate(CounterPhase(phases%length),source=0) + allocate(CounterHomogenization(homogenization%length),source=0) + + do m = 1, microstructure%length + constituentsInMicrostructure => microstructure%get(m) + constituents => constituentsInMicrostructure%get('constituents') + do c = 1, constituents%length + constituent => constituents%get(c) + microstructure_fraction(c,m) = constituent%get_asFloat('fraction') + enddo + if (dNeq(sum(microstructure_fraction(:,m)),1.0_pReal)) call IO_error(153,ext_msg='constituent') enddo - maxNconstituents = maxval(microstructure_Nconstituents) - allocate(microstructure_phase (maxNconstituents,size(config_microstructure)),source=0) - allocate(microstructure_texture (maxNconstituents,size(config_microstructure)),source=0) - allocate(microstructure_fraction(maxNconstituents,size(config_microstructure)),source=0.0_pReal) - - allocate(strings(1)) ! Intel 16.0 Bug - do m=1, size(config_microstructure) - strings = config_microstructure(m)%getStrings('(constituent)',raw=.true.) - do c = 1, size(strings) - chunkPos = IO_stringPos(strings(c)) - - do i = 1,5,2 - tag = IO_stringValue(strings(c),chunkPos,i) - - select case (tag) - case('phase') - microstructure_phase(c,m) = IO_intValue(strings(c),chunkPos,i+1) - case('texture') - microstructure_texture(c,m) = IO_intValue(strings(c),chunkPos,i+1) - case('fraction') - microstructure_fraction(c,m) = IO_floatValue(strings(c),chunkPos,i+1) - end select - + do e = 1, discretization_nElem + do i = 1, discretization_nIP + constituentsInMicrostructure => microstructure%get(discretization_microstructureAt(e)) + constituents => constituentsInMicrostructure%get('constituents') + do c = 1, constituents%length + constituent => constituents%get(c) + material_phaseAt(c,e) = phases%getIndex(constituent%get_asString('phase')) + phase_orientation = constituent%get_asFloats('orientation') + call material_orientation0(c,i,e)%fromQuaternion(phase_orientation) + enddo + enddo + enddo + + do e = 1, discretization_nElem + do i = 1, discretization_nIP + constituentsInMicrostructure => microstructure%get(discretization_microstructureAt(e)) + material_homogenizationAt(e) = homogenization%getIndex(constituentsInMicrostructure%get_asString('homogenization')) + CounterHomogenization(material_homogenizationAt(e)) = CounterHomogenization(material_homogenizationAt(e)) + 1 + material_homogenizationMemberAt(i,e) = CounterHomogenization(material_homogenizationAt(e)) + enddo + enddo + + do e = 1, discretization_nElem + do i = 1, discretization_nIP + constituentsInMicrostructure => microstructure%get(discretization_microstructureAt(e)) + constituents => constituentsInMicrostructure%get('constituents') + do c = 1, constituents%length + CounterPhase(material_phaseAt(c,e)) = & + CounterPhase(material_phaseAt(c,e)) + 1 + material_phaseMemberAt(c,i,e) = CounterPhase(material_phaseAt(c,e)) enddo enddo - if (dNeq(sum(microstructure_fraction(:,m)),1.0_pReal)) call IO_error(153,ext_msg=config_name_microstructure(m)) enddo end subroutine material_parseMicrostructure - -!-------------------------------------------------------------------------------------------------- -!> @brief parses the phase part in the material configuration file -!-------------------------------------------------------------------------------------------------- -subroutine material_parsePhase - - integer :: sourceCtr, kinematicsCtr, stiffDegradationCtr, p - character(len=pStringLen), dimension(:), allocatable :: str - - - allocate(phase_elasticity(size(config_phase)),source=ELASTICITY_undefined_ID) - allocate(phase_plasticity(size(config_phase)),source=PLASTICITY_undefined_ID) - allocate(phase_Nsources(size(config_phase)), source=0) - allocate(phase_Nkinematics(size(config_phase)), source=0) - allocate(phase_NstiffnessDegradations(size(config_phase)),source=0) - allocate(phase_localPlasticity(size(config_phase)), source=.false.) - - do p=1, size(config_phase) - phase_Nsources(p) = config_phase(p)%countKeys('(source)') - phase_Nkinematics(p) = config_phase(p)%countKeys('(kinematics)') - phase_NstiffnessDegradations(p) = config_phase(p)%countKeys('(stiffness_degradation)') - phase_localPlasticity(p) = .not. config_phase(p)%KeyExists('/nonlocal/') - - select case (config_phase(p)%getString('elasticity')) - case (ELASTICITY_HOOKE_label) - phase_elasticity(p) = ELASTICITY_HOOKE_ID - case default - call IO_error(200,ext_msg=trim(config_phase(p)%getString('elasticity'))) - end select - - select case (config_phase(p)%getString('plasticity')) - case (PLASTICITY_NONE_label) - phase_plasticity(p) = PLASTICITY_NONE_ID - case (PLASTICITY_ISOTROPIC_label) - phase_plasticity(p) = PLASTICITY_ISOTROPIC_ID - case (PLASTICITY_PHENOPOWERLAW_label) - phase_plasticity(p) = PLASTICITY_PHENOPOWERLAW_ID - case (PLASTICITY_KINEHARDENING_label) - phase_plasticity(p) = PLASTICITY_KINEHARDENING_ID - case (PLASTICITY_DISLOTWIN_label) - phase_plasticity(p) = PLASTICITY_DISLOTWIN_ID - case (PLASTICITY_DISLOUCLA_label) - phase_plasticity(p) = PLASTICITY_DISLOUCLA_ID - case (PLASTICITY_NONLOCAL_label) - phase_plasticity(p) = PLASTICITY_NONLOCAL_ID - case default - call IO_error(201,ext_msg=trim(config_phase(p)%getString('plasticity'))) - end select - - enddo - - allocate(phase_source(maxval(phase_Nsources),size(config_phase)), source=SOURCE_undefined_ID) - allocate(phase_kinematics(maxval(phase_Nkinematics),size(config_phase)), source=KINEMATICS_undefined_ID) - allocate(phase_stiffnessDegradation(maxval(phase_NstiffnessDegradations),size(config_phase)), & - source=STIFFNESS_DEGRADATION_undefined_ID) - do p=1, size(config_phase) -#if defined(__GFORTRAN__) || defined(__PGI) - str = ['GfortranBug86277'] - str = config_phase(p)%getStrings('(source)',defaultVal=str) - if (str(1) == 'GfortranBug86277') str = [character(len=pStringLen)::] -#else - str = config_phase(p)%getStrings('(source)',defaultVal=[character(len=pStringLen)::]) -#endif - do sourceCtr = 1, size(str) - select case (trim(str(sourceCtr))) - case (SOURCE_thermal_dissipation_label) - phase_source(sourceCtr,p) = SOURCE_thermal_dissipation_ID - case (SOURCE_thermal_externalheat_label) - phase_source(sourceCtr,p) = SOURCE_thermal_externalheat_ID - case (SOURCE_damage_isoBrittle_label) - phase_source(sourceCtr,p) = SOURCE_damage_isoBrittle_ID - case (SOURCE_damage_isoDuctile_label) - phase_source(sourceCtr,p) = SOURCE_damage_isoDuctile_ID - case (SOURCE_damage_anisoBrittle_label) - phase_source(sourceCtr,p) = SOURCE_damage_anisoBrittle_ID - case (SOURCE_damage_anisoDuctile_label) - phase_source(sourceCtr,p) = SOURCE_damage_anisoDuctile_ID - end select - enddo - -#if defined(__GFORTRAN__) || defined(__PGI) - str = ['GfortranBug86277'] - str = config_phase(p)%getStrings('(kinematics)',defaultVal=str) - if (str(1) == 'GfortranBug86277') str = [character(len=pStringLen)::] -#else - str = config_phase(p)%getStrings('(kinematics)',defaultVal=[character(len=pStringLen)::]) -#endif - do kinematicsCtr = 1, size(str) - select case (trim(str(kinematicsCtr))) - case (KINEMATICS_cleavage_opening_label) - phase_kinematics(kinematicsCtr,p) = KINEMATICS_cleavage_opening_ID - case (KINEMATICS_slipplane_opening_label) - phase_kinematics(kinematicsCtr,p) = KINEMATICS_slipplane_opening_ID - case (KINEMATICS_thermal_expansion_label) - phase_kinematics(kinematicsCtr,p) = KINEMATICS_thermal_expansion_ID - end select - enddo -#if defined(__GFORTRAN__) || defined(__PGI) - str = ['GfortranBug86277'] - str = config_phase(p)%getStrings('(stiffness_degradation)',defaultVal=str) - if (str(1) == 'GfortranBug86277') str = [character(len=pStringLen)::] -#else - str = config_phase(p)%getStrings('(stiffness_degradation)',defaultVal=[character(len=pStringLen)::]) -#endif - do stiffDegradationCtr = 1, size(str) - select case (trim(str(stiffDegradationCtr))) - case (STIFFNESS_DEGRADATION_damage_label) - phase_stiffnessDegradation(stiffDegradationCtr,p) = STIFFNESS_DEGRADATION_damage_ID - end select - enddo - enddo - - allocate(phase_plasticityInstance(size(config_phase)),source=0) - allocate(phase_elasticityInstance(size(config_phase)),source=0) - - do p=1, size(config_phase) - phase_elasticityInstance(p) = count(phase_elasticity(1:p) == phase_elasticity(p)) - phase_plasticityInstance(p) = count(phase_plasticity(1:p) == phase_plasticity(p)) - enddo - -end subroutine material_parsePhase - - -!-------------------------------------------------------------------------------------------------- -!> @brief parses the texture part in the material configuration file -!-------------------------------------------------------------------------------------------------- -subroutine material_parseTexture - - integer :: j,t - character(len=pStringLen), dimension(:), allocatable :: strings ! Values for given key in material config - integer, dimension(:), allocatable :: chunkPos - real(pReal), dimension(3,3) :: transformation ! maps texture to microstructure coordinate system - real(pReal), dimension(3) :: Eulers ! Euler angles in degrees from file - type(rotation) :: transformation_ - - do t=1, size(config_texture) - if (config_texture(t)%countKeys('(gauss)') /= 1) call IO_error(147,ext_msg='count((gauss)) != 1') - if (config_texture(t)%keyExists('symmetry')) call IO_error(147,ext_msg='symmetry') - if (config_texture(t)%keyExists('(random)')) call IO_error(147,ext_msg='(random)') - if (config_texture(t)%keyExists('(fiber)')) call IO_error(147,ext_msg='(fiber)') - enddo - - allocate(texture_orientation(size(config_texture))) - - do t=1, size(config_texture) - - strings = config_texture(t)%getStrings('(gauss)',raw= .true.) - chunkPos = IO_stringPos(strings(1)) - do j = 1,5,2 - select case (IO_stringValue(strings(1),chunkPos,j)) - case('phi1') - Eulers(1) = IO_floatValue(strings(1),chunkPos,j+1) - case('phi') - Eulers(2) = IO_floatValue(strings(1),chunkPos,j+1) - case('phi2') - Eulers(3) = IO_floatValue(strings(1),chunkPos,j+1) - end select - enddo - call texture_orientation(t)%fromEulers(Eulers,degrees=.true.) - - if (config_texture(t)%keyExists('axes')) then - strings = config_texture(t)%getStrings('axes') - do j = 1, 3 ! look for "x", "y", and "z" entries - select case (strings(j)) - case('x', '+x') - transformation(j,1:3) = [ 1.0_pReal, 0.0_pReal, 0.0_pReal] ! original axis is now +x-axis - case('-x') - transformation(j,1:3) = [-1.0_pReal, 0.0_pReal, 0.0_pReal] ! original axis is now -x-axis - case('y', '+y') - transformation(j,1:3) = [ 0.0_pReal, 1.0_pReal, 0.0_pReal] ! original axis is now +y-axis - case('-y') - transformation(j,1:3) = [ 0.0_pReal,-1.0_pReal, 0.0_pReal] ! original axis is now -y-axis - case('z', '+z') - transformation(j,1:3) = [ 0.0_pReal, 0.0_pReal, 1.0_pReal] ! original axis is now +z-axis - case('-z') - transformation(j,1:3) = [ 0.0_pReal, 0.0_pReal,-1.0_pReal] ! original axis is now -z-axis - case default - call IO_error(157,t) - end select - enddo - call transformation_%fromMatrix(transformation) - texture_orientation(t) = texture_orientation(t) * transformation_ - endif - - enddo - -end subroutine material_parseTexture - - -!-------------------------------------------------------------------------------------------------- -!> @brief Allocate the components of the state structure for a given phase -!-------------------------------------------------------------------------------------------------- -subroutine material_allocateState(state, & - NipcMyPhase,sizeState,sizeDotState,sizeDeltaState) - - class(tState), intent(out) :: & - state - integer, intent(in) :: & - NipcMyPhase, & - sizeState, & - 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,NipcMyPhase), source=0.0_pReal) - allocate(state%partionedState0(sizeState,NipcMyPhase), source=0.0_pReal) - allocate(state%subState0 (sizeState,NipcMyPhase), source=0.0_pReal) - allocate(state%state (sizeState,NipcMyPhase), source=0.0_pReal) - - allocate(state%dotState (sizeDotState,NipcMyPhase), source=0.0_pReal) - - allocate(state%deltaState(sizeDeltaState,NipcMyPhase), source=0.0_pReal) - -end subroutine material_allocateState - - + end module material diff --git a/src/math.f90 b/src/math.f90 index c6e609c63..d485f2e4a 100644 --- a/src/math.f90 +++ b/src/math.f90 @@ -8,7 +8,7 @@ module math use prec use IO - use numerics + use config use YAML_types use LAPACK_interface @@ -18,8 +18,7 @@ module math ! do not make use associated entities available to other modules private :: & prec, & - IO, & - numerics + IO #endif real(pReal), parameter :: PI = acos(-1.0_pReal) !< ratio of a circle's circumference to its diameter diff --git a/src/mesh/DAMASK_mesh.f90 b/src/mesh/DAMASK_mesh.f90 index b6cb4b2d1..05339a280 100644 --- a/src/mesh/DAMASK_mesh.f90 +++ b/src/mesh/DAMASK_mesh.f90 @@ -15,7 +15,7 @@ program DAMASK_mesh use math use CPFEM2 use FEsolving - use numerics + use config use discretization_mesh use FEM_Utilities use mesh_mech_FEM diff --git a/src/mesh/FEM_utilities.f90 b/src/mesh/FEM_utilities.f90 index b66c1dfb0..b850c20e9 100644 --- a/src/mesh/FEM_utilities.f90 +++ b/src/mesh/FEM_utilities.f90 @@ -14,8 +14,7 @@ module FEM_utilities use prec use FEsolving use homogenization - use numerics - use debug + use config use math use discretization_mesh diff --git a/src/mesh/discretization_mesh.f90 b/src/mesh/discretization_mesh.f90 index 68c34be1f..7964e1220 100644 --- a/src/mesh/discretization_mesh.f90 +++ b/src/mesh/discretization_mesh.f90 @@ -14,9 +14,8 @@ module discretization_mesh use DAMASK_interface use IO - use debug + use config use discretization - use numerics use FEsolving use FEM_quadrature use YAML_types diff --git a/src/mesh/mesh_mech_FEM.f90 b/src/mesh/mesh_mech_FEM.f90 index 235039112..4d843b7a0 100644 --- a/src/mesh/mesh_mech_FEM.f90 +++ b/src/mesh/mesh_mech_FEM.f90 @@ -18,7 +18,8 @@ module mesh_mech_FEM use FEM_utilities use discretization_mesh use DAMASK_interface - use numerics + use config + use IO use FEM_quadrature use homogenization use math diff --git a/src/numerics.f90 b/src/numerics.f90 deleted file mode 100644 index 35436296c..000000000 --- a/src/numerics.f90 +++ /dev/null @@ -1,82 +0,0 @@ -!-------------------------------------------------------------------------------------------------- -!> @author Franz Roters, Max-Planck-Institut für Eisenforschung GmbH -!> @author Philip Eisenlohr, Max-Planck-Institut für Eisenforschung GmbH -!> @author Sharan Roongta, Max-Planck-Institut für Eisenforschung GmbH -!> @brief Managing of parameters related to numerics -!-------------------------------------------------------------------------------------------------- -module numerics - use prec - use IO - use YAML_types - use YAML_parse - -#ifdef PETSc -#include - use petscsys -#endif -!$ use OMP_LIB - - implicit none - private - - class(tNode), pointer, protected, public :: & - numerics_root !< root pointer storing the numerics YAML structure - integer, protected, public :: & - worldrank = 0, & !< MPI worldrank (/=0 for MPI simulations only) - worldsize = 1 !< MPI worldsize (/=1 for MPI simulations only) - integer(4), protected, public :: & - DAMASK_NumThreadsInt = 0 !< value stored in environment variable DAMASK_NUM_THREADS, set to zero if no OpenMP directive - - public :: numerics_init - -contains - - -!-------------------------------------------------------------------------------------------------- -!> @brief reads in parameters from numerics.config and sets openMP related parameters. Also does -! a sanity check -!-------------------------------------------------------------------------------------------------- -subroutine numerics_init - -!$ integer :: gotDAMASK_NUM_THREADS = 1 - integer :: ierr - character(len=:), allocatable :: & - numerics_input, & - numerics_inFlow - logical :: fexist -!$ character(len=6) DAMASK_NumThreadsString ! environment variable DAMASK_NUM_THREADS - -#ifdef PETSc - call MPI_Comm_rank(PETSC_COMM_WORLD,worldrank,ierr);CHKERRQ(ierr) - call MPI_Comm_size(PETSC_COMM_WORLD,worldsize,ierr);CHKERRQ(ierr) -#endif - write(6,'(/,a)') ' <<<+- numerics init -+>>>' - -!$ call GET_ENVIRONMENT_VARIABLE(NAME='DAMASK_NUM_THREADS',VALUE=DAMASK_NumThreadsString,STATUS=gotDAMASK_NUM_THREADS) ! get environment variable DAMASK_NUM_THREADS... -!$ if(gotDAMASK_NUM_THREADS /= 0) then ! could not get number of threads, set it to 1 -!$ call IO_warning(35,ext_msg='BEGIN:'//DAMASK_NumThreadsString//':END') -!$ DAMASK_NumThreadsInt = 1_4 -!$ else -!$ read(DAMASK_NumThreadsString,'(i6)') DAMASK_NumThreadsInt ! read as integer -!$ if (DAMASK_NumThreadsInt < 1_4) DAMASK_NumThreadsInt = 1_4 ! in case of string conversion fails, set it to one -!$ endif -!$ call omp_set_num_threads(DAMASK_NumThreadsInt) ! set number of threads for parallel execution - - numerics_root => emptyDict - inquire(file='numerics.yaml', exist=fexist) - - if (fexist) then - write(6,'(a,/)') ' using values from config file' - flush(6) - numerics_input = IO_read('numerics.yaml') - numerics_inFlow = to_flow(numerics_input) - numerics_root => parse_flow(numerics_inFlow) - endif - -!-------------------------------------------------------------------------------------------------- -! openMP parameter - !$ write(6,'(a24,1x,i8,/)') ' number of threads: ',DAMASK_NumThreadsInt - -end subroutine numerics_init - -end module numerics diff --git a/src/results.f90 b/src/results.f90 index 21173c512..45c6263e4 100644 --- a/src/results.f90 +++ b/src/results.f90 @@ -7,7 +7,7 @@ module results use DAMASK_interface use rotations - use numerics + use config use HDF5_utilities #ifdef PETSc use PETSC diff --git a/src/rotations.f90 b/src/rotations.f90 index 85f901f5d..fc523e813 100644 --- a/src/rotations.f90 +++ b/src/rotations.f90 @@ -56,7 +56,7 @@ module rotations private type, public :: rotation - type(quaternion), private :: q + type(quaternion) :: q contains procedure, public :: asQuaternion procedure, public :: asEulers diff --git a/src/source_damage_anisoBrittle.f90 b/src/source_damage_anisoBrittle.f90 index 20cf3a914..65aedacd6 100644 --- a/src/source_damage_anisoBrittle.f90 +++ b/src/source_damage_anisoBrittle.f90 @@ -12,15 +12,15 @@ submodule (constitutive:constitutive_damage) source_damage_anisoBrittle type :: tParameters !< container type for internal constitutive parameters real(pReal) :: & - sdot_0, & - n + sdot_0, & !< opening rate of cleavage planes + n !< damage rate sensitivity real(pReal), dimension(:), allocatable :: & - critDisp, & - critLoad + critDisp, & !< critical displacement + critLoad !< critical load real(pReal), dimension(:,:,:,:), allocatable :: & cleavage_systems integer :: & - sum_N_cl + sum_N_cl !< total number of cleavage planes character(len=pStringLen), allocatable, dimension(:) :: & output end type tParameters @@ -35,72 +35,87 @@ contains !> @brief module initialization !> @details reads in material parameters, allocates arrays, and does sanity checks !-------------------------------------------------------------------------------------------------- -module subroutine source_damage_anisoBrittle_init +module function source_damage_anisoBrittle_init(source_length) result(mySources) + integer, intent(in) :: source_length + logical, dimension(:,:), allocatable :: mySources + + class(tNode), pointer :: & + phases, & + phase, & + sources, & + src integer :: Ninstance,sourceOffset,NipcMyPhase,p integer, dimension(:), allocatable :: N_cl character(len=pStringLen) :: extmsg = '' - write(6,'(/,a)') ' <<<+- source_'//SOURCE_DAMAGE_ANISOBRITTLE_LABEL//' init -+>>>' + write(6,'(/,a)') ' <<<+- source_damage_anisoBrittle init -+>>>' - Ninstance = count(phase_source == SOURCE_DAMAGE_ANISOBRITTLE_ID) + mySources = source_active('damage_anisoBrittle',source_length) + + Ninstance = count(mySources) write(6,'(a16,1x,i5,/)') '# instances:',Ninstance; flush(6) + if(Ninstance == 0) return - allocate(source_damage_anisoBrittle_offset (size(config_phase)), source=0) - allocate(source_damage_anisoBrittle_instance(size(config_phase)), source=0) + phases => material_root%get('phase') allocate(param(Ninstance)) + allocate(source_damage_anisoBrittle_offset (phases%length), source=0) + allocate(source_damage_anisoBrittle_instance(phases%length), source=0) - do p = 1, size(config_phase) - source_damage_anisoBrittle_instance(p) = count(phase_source(:,1:p) == SOURCE_DAMAGE_ANISOBRITTLE_ID) - do sourceOffset = 1, phase_Nsources(p) - if (phase_source(sourceOffset,p) == SOURCE_DAMAGE_ANISOBRITTLE_ID) then + do p = 1, phases%length + phase => phases%get(p) + if(any(mySources(:,p))) source_damage_anisoBrittle_instance(p) = count(mySources(:,1:p)) + if(count(mySources(:,p)) == 0) cycle + sources => phase%get('source') + do sourceOffset = 1, sources%length + if(mySources(sourceOffset,p)) then source_damage_anisoBrittle_offset(p) = sourceOffset - exit - endif - enddo + associate(prm => param(source_damage_anisoBrittle_instance(p))) + src => sources%get(sourceOffset) + + N_cl = src%get_asInts('N_cl',defaultVal=emptyIntArray) + prm%sum_N_cl = sum(abs(N_cl)) + + prm%n = src%get_asFloat('q') + prm%sdot_0 = src%get_asFloat('dot_o') + + prm%critDisp = src%get_asFloats('s_crit', requiredSize=size(N_cl)) + prm%critLoad = src%get_asFloats('g_crit', requiredSize=size(N_cl)) + + prm%cleavage_systems = lattice_SchmidMatrix_cleavage(N_cl,phase%get_asString('lattice'),& + phase%get_asFloat('c/a',defaultVal=0.0_pReal)) + + ! expand: family => system + prm%critDisp = math_expand(prm%critDisp,N_cl) + prm%critLoad = math_expand(prm%critLoad,N_cl) - if (all(phase_source(:,p) /= SOURCE_DAMAGE_ANISOBRITTLE_ID)) cycle - associate(prm => param(source_damage_anisoBrittle_instance(p)), & - config => config_phase(p)) +#if defined (__GFORTRAN__) + prm%output = output_asStrings(src) +#else + prm%output = src%get_asStrings('output',defaultVal=emptyStringArray) +#endif + + ! sanity checks + if (prm%n <= 0.0_pReal) extmsg = trim(extmsg)//' q' + if (prm%sdot_0 <= 0.0_pReal) extmsg = trim(extmsg)//' dot_o' + if (any(prm%critLoad < 0.0_pReal)) extmsg = trim(extmsg)//' g_crit' + if (any(prm%critDisp < 0.0_pReal)) extmsg = trim(extmsg)//' s_crit' - prm%output = config%getStrings('(output)',defaultVal=emptyStringArray) + NipcMyPhase = count(material_phaseAt==p) * discretization_nIP + call constitutive_allocateState(sourceState(p)%p(sourceOffset),NipcMyPhase,1,1,0) + sourceState(p)%p(sourceOffset)%atol = src%get_asFloat('anisobrittle_atol',defaultVal=1.0e-3_pReal) + if(any(sourceState(p)%p(sourceOffset)%atol < 0.0_pReal)) extmsg = trim(extmsg)//' anisobrittle_atol' - N_cl = config%getInts('ncleavage',defaultVal=emptyIntArray) - prm%sum_N_cl = sum(abs(N_cl)) - - prm%n = config%getFloat('anisobrittle_ratesensitivity') - prm%sdot_0 = config%getFloat('anisobrittle_sdot0') - - prm%critDisp = config%getFloats('anisobrittle_criticaldisplacement',requiredSize=size(N_cl)) - prm%critLoad = config%getFloats('anisobrittle_criticalload', requiredSize=size(N_cl)) - - prm%cleavage_systems = lattice_SchmidMatrix_cleavage(N_cl,config%getString('lattice_structure'),& - config%getFloat('c/a',defaultVal=0.0_pReal)) - - ! expand: family => system - prm%critDisp = math_expand(prm%critDisp,N_cl) - prm%critLoad = math_expand(prm%critLoad,N_cl) - - ! sanity checks - if (prm%n <= 0.0_pReal) extmsg = trim(extmsg)//' anisobrittle_n' - if (prm%sdot_0 <= 0.0_pReal) extmsg = trim(extmsg)//' anisobrittle_sdot0' - if (any(prm%critLoad < 0.0_pReal)) extmsg = trim(extmsg)//' anisobrittle_critLoad' - if (any(prm%critDisp < 0.0_pReal)) extmsg = trim(extmsg)//' anisobrittle_critDisp' - - NipcMyPhase = count(material_phaseAt==p) * discretization_nIP - call material_allocateState(sourceState(p)%p(sourceOffset),NipcMyPhase,1,1,0) - sourceState(p)%p(sourceOffset)%atol = config%getFloat('anisobrittle_atol',defaultVal=1.0e-3_pReal) - if(any(sourceState(p)%p(sourceOffset)%atol < 0.0_pReal)) extmsg = trim(extmsg)//' anisobrittle_atol' - - end associate + end associate !-------------------------------------------------------------------------------------------------- ! exit if any parameter is out of range - if (extmsg /= '') call IO_error(211,ext_msg=trim(extmsg)//'('//SOURCE_DAMAGE_ANISOBRITTLE_LABEL//')') + if (extmsg /= '') call IO_error(211,ext_msg=trim(extmsg)//'(damage_anisoBrittle)') + endif + enddo + enddo -enddo - -end subroutine source_damage_anisoBrittle_init +end function source_damage_anisoBrittle_init !-------------------------------------------------------------------------------------------------- @@ -193,8 +208,8 @@ module subroutine source_damage_anisoBrittle_results(phase,group) stt => sourceState(phase)%p(source_damage_anisoBrittle_offset(phase))%state) outputsLoop: do o = 1,size(prm%output) select case(trim(prm%output(o))) - case ('anisobrittle_drivingforce') - call results_writeDataset(group,stt,'tbd','driving force','tbd') + case ('f_phi') + call results_writeDataset(group,stt,trim(prm%output(o)),'driving force','J/m³') end select enddo outputsLoop end associate diff --git a/src/source_damage_anisoDuctile.f90 b/src/source_damage_anisoDuctile.f90 index 3722f8b1c..26b653c3d 100644 --- a/src/source_damage_anisoDuctile.f90 +++ b/src/source_damage_anisoDuctile.f90 @@ -10,16 +10,16 @@ submodule(constitutive:constitutive_damage) source_damage_anisoDuctile source_damage_anisoDuctile_offset, & !< which source is my current damage mechanism? source_damage_anisoDuctile_instance !< instance of damage source mechanism - type :: tParameters !< container type for internal constitutive parameters + type :: tParameters !< container type for internal constitutive parameters real(pReal) :: & - n + n !< damage rate sensitivity real(pReal), dimension(:), allocatable :: & - critPlasticStrain + critPlasticStrain !< critical plastic strain per slip system character(len=pStringLen), allocatable, dimension(:) :: & output end type tParameters - type(tParameters), dimension(:), allocatable :: param !< containers of constitutive parameters (len Ninstance) + type(tParameters), dimension(:), allocatable :: param !< containers of constitutive parameters (len Ninstance) contains @@ -28,61 +28,80 @@ contains !> @brief module initialization !> @details reads in material parameters, allocates arrays, and does sanity checks !-------------------------------------------------------------------------------------------------- -module subroutine source_damage_anisoDuctile_init +module function source_damage_anisoDuctile_init(source_length) result(mySources) + integer, intent(in) :: source_length + logical, dimension(:,:), allocatable :: mySources + + class(tNode), pointer :: & + phases, & + phase, & + pl, & + sources, & + src integer :: Ninstance,sourceOffset,NipcMyPhase,p integer, dimension(:), allocatable :: N_sl character(len=pStringLen) :: extmsg = '' - write(6,'(/,a)') ' <<<+- source_'//SOURCE_DAMAGE_ANISODUCTILE_LABEL//' init -+>>>' + write(6,'(/,a)') ' <<<+- source_damage_anisoDuctile init -+>>>' - Ninstance = count(phase_source == SOURCE_DAMAGE_ANISODUCTILE_ID) + mySources = source_active('damage_anisoDuctile',source_length) + + Ninstance = count(mySources) write(6,'(a16,1x,i5,/)') '# instances:',Ninstance; flush(6) - allocate(source_damage_anisoDuctile_offset (size(config_phase)), source=0) - allocate(source_damage_anisoDuctile_instance(size(config_phase)), source=0) + if(Ninstance == 0) return + + phases => material_root%get('phase') allocate(param(Ninstance)) + allocate(source_damage_anisoDuctile_offset (phases%length), source=0) + allocate(source_damage_anisoDuctile_instance(phases%length), source=0) - do p = 1, size(config_phase) - source_damage_anisoDuctile_instance(p) = count(phase_source(:,1:p) == SOURCE_DAMAGE_ANISODUCTILE_ID) - do sourceOffset = 1, phase_Nsources(p) - if (phase_source(sourceOffset,p) == SOURCE_DAMAGE_ANISODUCTILE_ID) then + do p = 1, phases%length + phase => phases%get(p) + if(any(mySources(:,p))) source_damage_anisoDuctile_instance(p) = count(mySources(:,1:p)) + if(count(mySources(:,p)) == 0) cycle + sources => phase%get('source') + pl => phase%get('plasticity') + do sourceOffset = 1, sources%length + if(mySources(sourceOffset,p)) then source_damage_anisoDuctile_offset(p) = sourceOffset - exit - endif - enddo + associate(prm => param(source_damage_anisoDuctile_instance(p))) + src => sources%get(sourceOffset) - if (all(phase_source(:,p) /= SOURCE_DAMAGE_ANISODUCTILE_ID)) cycle - associate(prm => param(source_damage_anisoDuctile_instance(p)), & - config => config_phase(p)) + N_sl = pl%get_asInts('N_sl',defaultVal=emptyIntArray) + prm%n = src%get_asFloat('q') + prm%critPlasticStrain = src%get_asFloats('gamma_crit',requiredSize=size(N_sl)) - prm%output = config%getStrings('(output)',defaultVal=emptyStringArray) + ! expand: family => system + prm%critPlasticStrain = math_expand(prm%critPlasticStrain,N_sl) - N_sl = config%getInts('nslip',defaultVal=emptyIntArray) - prm%n = config%getFloat('anisoductile_ratesensitivity') - prm%critPlasticStrain = config%getFloats('anisoductile_criticalplasticstrain',requiredSize=size(N_sl)) +#if defined (__GFORTRAN__) + prm%output = output_asStrings(src) +#else + prm%output = src%get_asStrings('output',defaultVal=emptyStringArray) +#endif + + ! sanity checks + if (prm%n <= 0.0_pReal) extmsg = trim(extmsg)//' q' + if (any(prm%critPlasticStrain < 0.0_pReal)) extmsg = trim(extmsg)//' gamma_crit' - ! expand: family => system - prm%critPlasticStrain = math_expand(prm%critPlasticStrain,N_sl) + NipcMyPhase=count(material_phaseAt==p) * discretization_nIP + call constitutive_allocateState(sourceState(p)%p(sourceOffset),NipcMyPhase,1,1,0) + sourceState(p)%p(sourceOffset)%atol = src%get_asFloat('anisoDuctile_atol',defaultVal=1.0e-3_pReal) + if(any(sourceState(p)%p(sourceOffset)%atol < 0.0_pReal)) extmsg = trim(extmsg)//' anisoductile_atol' - ! sanity checks - if (prm%n <= 0.0_pReal) extmsg = trim(extmsg)//' anisoductile_ratesensitivity' - if (any(prm%critPlasticStrain < 0.0_pReal)) extmsg = trim(extmsg)//' anisoductile_criticalplasticstrain' - - NipcMyPhase=count(material_phaseAt==p) * discretization_nIP - call material_allocateState(sourceState(p)%p(sourceOffset),NipcMyPhase,1,1,0) - sourceState(p)%p(sourceOffset)%atol = config%getFloat('anisoductile_atol',defaultVal=1.0e-3_pReal) - if(any(sourceState(p)%p(sourceOffset)%atol < 0.0_pReal)) extmsg = trim(extmsg)//' anisoductile_atol' - - end associate + end associate !-------------------------------------------------------------------------------------------------- ! exit if any parameter is out of range - if (extmsg /= '') call IO_error(211,ext_msg=trim(extmsg)//'('//SOURCE_DAMAGE_ANISODUCTILE_LABEL//')') + if (extmsg /= '') call IO_error(211,ext_msg=trim(extmsg)//'(damage_anisoDuctile)') + endif + enddo + enddo -enddo -end subroutine source_damage_anisoDuctile_init +end function source_damage_anisoDuctile_init !-------------------------------------------------------------------------------------------------- @@ -157,8 +176,8 @@ module subroutine source_damage_anisoDuctile_results(phase,group) stt => sourceState(phase)%p(source_damage_anisoDuctile_offset(phase))%state) outputsLoop: do o = 1,size(prm%output) select case(trim(prm%output(o))) - case ('anisoductile_drivingforce') - call results_writeDataset(group,stt,'tbd','driving force','tbd') + case ('f_phi') + call results_writeDataset(group,stt,trim(prm%output(o)),'driving force','J/m³') end select enddo outputsLoop end associate diff --git a/src/source_damage_isoBrittle.f90 b/src/source_damage_isoBrittle.f90 index 00704fe26..b1abcf14d 100644 --- a/src/source_damage_isoBrittle.f90 +++ b/src/source_damage_isoBrittle.f90 @@ -10,10 +10,10 @@ submodule(constitutive:constitutive_damage) source_damage_isoBrittle source_damage_isoBrittle_offset, & source_damage_isoBrittle_instance - type :: tParameters !< container type for internal constitutive parameters + type :: tParameters !< container type for internal constitutive parameters real(pReal) :: & - critStrainEnergy, & - N + critStrainEnergy, & !< critical elastic strain energy + N character(len=pStringLen), allocatable, dimension(:) :: & output end type tParameters @@ -27,56 +27,72 @@ contains !> @brief module initialization !> @details reads in material parameters, allocates arrays, and does sanity checks !-------------------------------------------------------------------------------------------------- -module subroutine source_damage_isoBrittle_init +module function source_damage_isoBrittle_init(source_length) result(mySources) + integer, intent(in) :: source_length + logical, dimension(:,:), allocatable :: mySources + + class(tNode), pointer :: & + phases, & + phase, & + sources, & + src integer :: Ninstance,sourceOffset,NipcMyPhase,p character(len=pStringLen) :: extmsg = '' - write(6,'(/,a)') ' <<<+- source_'//SOURCE_DAMAGE_ISOBRITTLE_LABEL//' init -+>>>' + write(6,'(/,a)') ' <<<+- source_damage_isoBrittle init -+>>>' - Ninstance = count(phase_source == SOURCE_DAMAGE_ISOBRITTLE_ID) + mySources = source_active('damage_isoBrittle',source_length) + + Ninstance = count(mySources) write(6,'(a16,1x,i5,/)') '# instances:',Ninstance; flush(6) + if(Ninstance == 0) return - allocate(source_damage_isoBrittle_offset (size(config_phase)), source=0) - allocate(source_damage_isoBrittle_instance(size(config_phase)), source=0) + phases => material_root%get('phase') allocate(param(Ninstance)) + allocate(source_damage_isoBrittle_offset (phases%length), source=0) + allocate(source_damage_isoBrittle_instance(phases%length), source=0) - do p = 1, size(config_phase) - source_damage_isoBrittle_instance(p) = count(phase_source(:,1:p) == SOURCE_DAMAGE_ISOBRITTLE_ID) - do sourceOffset = 1, phase_Nsources(p) - if (phase_source(sourceOffset,p) == SOURCE_DAMAGE_ISOBRITTLE_ID) then + do p = 1, phases%length + phase => phases%get(p) + if(any(mySources(:,p))) source_damage_isoBrittle_instance(p) = count(mySources(:,1:p)) + if(count(mySources(:,p)) == 0) cycle + sources => phase%get('source') + do sourceOffset = 1, sources%length + if(mySources(sourceOffset,p)) then source_damage_isoBrittle_offset(p) = sourceOffset - exit - endif - enddo + associate(prm => param(source_damage_isoBrittle_instance(p))) + src => sources%get(sourceOffset) - if (all(phase_source(:,p) /= SOURCE_DAMAGE_ISOBRITTLE_ID)) cycle - associate(prm => param(source_damage_isoBrittle_instance(p)), & - config => config_phase(p)) + prm%N = src%get_asFloat('m') + prm%critStrainEnergy = src%get_asFloat('W_crit') - prm%output = config%getStrings('(output)',defaultVal=emptyStringArray) +#if defined (__GFORTRAN__) + prm%output = output_asStrings(src) +#else + prm%output = src%get_asStrings('output',defaultVal=emptyStringArray) +#endif + + ! sanity checks + if (prm%N <= 0.0_pReal) extmsg = trim(extmsg)//' m' + if (prm%critStrainEnergy <= 0.0_pReal) extmsg = trim(extmsg)//' W_crit' - prm%N = config%getFloat('isobrittle_n') - prm%critStrainEnergy = config%getFloat('isobrittle_criticalstrainenergy') + NipcMyPhase = count(material_phaseAt==p) * discretization_nIP + call constitutive_allocateState(sourceState(p)%p(sourceOffset),NipcMyPhase,1,1,1) + sourceState(p)%p(sourceOffset)%atol = src%get_asFloat('isoBrittle_atol',defaultVal=1.0e-3_pReal) + if(any(sourceState(p)%p(sourceOffset)%atol < 0.0_pReal)) extmsg = trim(extmsg)//' isobrittle_atol' - ! sanity checks - if (prm%N <= 0.0_pReal) extmsg = trim(extmsg)//' isobrittle_n' - if (prm%critStrainEnergy <= 0.0_pReal) extmsg = trim(extmsg)//' isobrittle_criticalstrainenergy' - - NipcMyPhase = count(material_phaseAt==p) * discretization_nIP - call material_allocateState(sourceState(p)%p(sourceOffset),NipcMyPhase,1,1,1) - sourceState(p)%p(sourceOffset)%atol = config%getFloat('isobrittle_atol',defaultVal=1.0e-3_pReal) - if(any(sourceState(p)%p(sourceOffset)%atol < 0.0_pReal)) extmsg = trim(extmsg)//' isobrittle_atol' - - end associate + end associate !-------------------------------------------------------------------------------------------------- ! exit if any parameter is out of range - if (extmsg /= '') call IO_error(211,ext_msg=trim(extmsg)//'('//SOURCE_DAMAGE_ISOBRITTLE_LABEL//')') + if (extmsg /= '') call IO_error(211,ext_msg=trim(extmsg)//'(damage_isoBrittle)') + endif + enddo + enddo -enddo -end subroutine source_damage_isoBrittle_init +end function source_damage_isoBrittle_init !-------------------------------------------------------------------------------------------------- @@ -168,8 +184,8 @@ module subroutine source_damage_isoBrittle_results(phase,group) stt => sourceState(phase)%p(source_damage_isoBrittle_offset(phase))%state) outputsLoop: do o = 1,size(prm%output) select case(trim(prm%output(o))) - case ('isobrittle_drivingforce') - call results_writeDataset(group,stt,'tbd','driving force','tbd') + case ('f_phi') + call results_writeDataset(group,stt,trim(prm%output(o)),'driving force','J/m³') end select enddo outputsLoop end associate diff --git a/src/source_damage_isoDuctile.f90 b/src/source_damage_isoDuctile.f90 index 517332316..dc102f539 100644 --- a/src/source_damage_isoDuctile.f90 +++ b/src/source_damage_isoDuctile.f90 @@ -10,15 +10,15 @@ submodule (constitutive:constitutive_damage) source_damage_isoDuctile source_damage_isoDuctile_offset, & !< which source is my current damage mechanism? source_damage_isoDuctile_instance !< instance of damage source mechanism - type:: tParameters !< container type for internal constitutive parameters + type:: tParameters !< container type for internal constitutive parameters real(pReal) :: & - critPlasticStrain, & + critPlasticStrain, & !< critical plastic strain N character(len=pStringLen), allocatable, dimension(:) :: & output end type tParameters - type(tParameters), dimension(:), allocatable :: param !< containers of constitutive parameters (len Ninstance) + type(tParameters), dimension(:), allocatable :: param !< containers of constitutive parameters (len Ninstance) contains @@ -28,56 +28,72 @@ contains !> @brief module initialization !> @details reads in material parameters, allocates arrays, and does sanity checks !-------------------------------------------------------------------------------------------------- -module subroutine source_damage_isoDuctile_init +module function source_damage_isoDuctile_init(source_length) result(mySources) + integer, intent(in) :: source_length + logical, dimension(:,:), allocatable :: mySources + + class(tNode), pointer :: & + phases, & + phase, & + sources, & + src integer :: Ninstance,sourceOffset,NipcMyPhase,p character(len=pStringLen) :: extmsg = '' - write(6,'(/,a)') ' <<<+- source_'//SOURCE_DAMAGE_ISODUCTILE_LABEL//' init -+>>>' + write(6,'(/,a)') ' <<<+- source_damage_isoDuctile init -+>>>' - Ninstance = count(phase_source == SOURCE_DAMAGE_ISODUCTILE_ID) + mySources = source_active('damage_isoDuctile',source_length) + + Ninstance = count(mySources) write(6,'(a16,1x,i5,/)') '# instances:',Ninstance; flush(6) + if(Ninstance == 0) return - allocate(source_damage_isoDuctile_offset (size(config_phase)), source=0) - allocate(source_damage_isoDuctile_instance(size(config_phase)), source=0) + phases => material_root%get('phase') allocate(param(Ninstance)) + allocate(source_damage_isoDuctile_offset (phases%length), source=0) + allocate(source_damage_isoDuctile_instance(phases%length), source=0) - do p = 1, size(config_phase) - source_damage_isoDuctile_instance(p) = count(phase_source(:,1:p) == SOURCE_DAMAGE_ISODUCTILE_ID) - do sourceOffset = 1, phase_Nsources(p) - if (phase_source(sourceOffset,p) == SOURCE_DAMAGE_ISODUCTILE_ID) then + do p = 1, phases%length + phase => phases%get(p) + if(count(mySources(:,p)) == 0) cycle + if(any(mySources(:,p))) source_damage_isoDuctile_instance(p) = count(mySources(:,1:p)) + sources => phase%get('source') + do sourceOffset = 1, sources%length + if(mySources(sourceOffset,p)) then source_damage_isoDuctile_offset(p) = sourceOffset - exit - endif - enddo + associate(prm => param(source_damage_isoDuctile_instance(p))) + src => sources%get(sourceOffset) - if (all(phase_source(:,p) /= SOURCE_DAMAGE_ISODUCTILE_ID)) cycle - associate(prm => param(source_damage_isoDuctile_instance(p)), & - config => config_phase(p)) + prm%N = src%get_asFloat('q') + prm%critPlasticStrain = src%get_asFloat('gamma_crit') - prm%output = config%getStrings('(output)',defaultVal=emptyStringArray) +#if defined (__GFORTRAN__) + prm%output = output_asStrings(src) +#else + prm%output = src%get_asStrings('output',defaultVal=emptyStringArray) +#endif + + ! sanity checks + if (prm%N <= 0.0_pReal) extmsg = trim(extmsg)//' q' + if (prm%critPlasticStrain <= 0.0_pReal) extmsg = trim(extmsg)//' gamma_crit' - prm%N = config%getFloat('isoductile_ratesensitivity') - prm%critPlasticStrain = config%getFloat('isoductile_criticalplasticstrain') + NipcMyPhase=count(material_phaseAt==p) * discretization_nIP + call constitutive_allocateState(sourceState(p)%p(sourceOffset),NipcMyPhase,1,1,0) + sourceState(p)%p(sourceOffset)%atol = src%get_asFloat('isoDuctile_atol',defaultVal=1.0e-3_pReal) + if(any(sourceState(p)%p(sourceOffset)%atol < 0.0_pReal)) extmsg = trim(extmsg)//' isoductile_atol' - ! sanity checks - if (prm%N <= 0.0_pReal) extmsg = trim(extmsg)//' isoductile_ratesensitivity' - if (prm%critPlasticStrain <= 0.0_pReal) extmsg = trim(extmsg)//' isoductile_criticalplasticstrain' - - NipcMyPhase=count(material_phaseAt==p) * discretization_nIP - call material_allocateState(sourceState(p)%p(sourceOffset),NipcMyPhase,1,1,0) - sourceState(p)%p(sourceOffset)%atol = config%getFloat('isoductile_atol',defaultVal=1.0e-3_pReal) - if(any(sourceState(p)%p(sourceOffset)%atol < 0.0_pReal)) extmsg = trim(extmsg)//' isoductile_atol' - - end associate + end associate !-------------------------------------------------------------------------------------------------- ! exit if any parameter is out of range - if (extmsg /= '') call IO_error(211,ext_msg=trim(extmsg)//'('//SOURCE_DAMAGE_ISODUCTILE_LABEL//')') + if (extmsg /= '') call IO_error(211,ext_msg=trim(extmsg)//'(damage_isoDuctile)') + endif + enddo + enddo -enddo -end subroutine source_damage_isoDuctile_init +end function source_damage_isoDuctile_init !-------------------------------------------------------------------------------------------------- @@ -152,8 +168,8 @@ module subroutine source_damage_isoDuctile_results(phase,group) stt => sourceState(phase)%p(source_damage_isoDuctile_offset(phase))%state) outputsLoop: do o = 1,size(prm%output) select case(trim(prm%output(o))) - case ('isoductile_drivingforce') - call results_writeDataset(group,stt,'tbd','driving force','tbd') + case ('f_phi') + call results_writeDataset(group,stt,trim(prm%output(o)),'driving force','J/m³') end select enddo outputsLoop end associate diff --git a/src/source_thermal_dissipation.f90 b/src/source_thermal_dissipation.f90 index 58a0c6b3c..d75e7f654 100644 --- a/src/source_thermal_dissipation.f90 +++ b/src/source_thermal_dissipation.f90 @@ -12,7 +12,7 @@ submodule(constitutive:constitutive_thermal) source_thermal_dissipation type :: tParameters !< container type for internal constitutive parameters real(pReal) :: & - kappa + kappa !< TAYLOR-QUINNEY factor end type tParameters type(tParameters), dimension(:), allocatable :: param !< containers of constitutive parameters (len Ninstance) @@ -25,41 +25,53 @@ contains !> @brief module initialization !> @details reads in material parameters, allocates arrays, and does sanity checks !-------------------------------------------------------------------------------------------------- -module subroutine source_thermal_dissipation_init +module function source_thermal_dissipation_init(source_length) result(mySources) + integer, intent(in) :: source_length + logical, dimension(:,:), allocatable :: mySources + + class(tNode), pointer :: & + phases, & + phase, & + sources, & + src integer :: Ninstance,sourceOffset,NipcMyPhase,p - write(6,'(/,a)') ' <<<+- source_'//SOURCE_thermal_dissipation_label//' init -+>>>' + write(6,'(/,a)') ' <<<+- source_thermal_dissipation init -+>>>' - Ninstance = count(phase_source == SOURCE_THERMAL_DISSIPATION_ID) + mySources = source_active('thermal_dissipation',source_length) + + Ninstance = count(mySources) write(6,'(a16,1x,i5,/)') '# instances:',Ninstance; flush(6) + if(Ninstance == 0) return - allocate(source_thermal_dissipation_offset (size(config_phase)), source=0) - allocate(source_thermal_dissipation_instance(size(config_phase)), source=0) + phases => material_root%get('phase') allocate(param(Ninstance)) + allocate(source_thermal_dissipation_offset (phases%length), source=0) + allocate(source_thermal_dissipation_instance(phases%length), source=0) - do p = 1, size(config_phase) - source_thermal_dissipation_instance(p) = count(phase_source(:,1:p) == SOURCE_THERMAL_DISSIPATION_ID) - do sourceOffset = 1, phase_Nsources(p) - if (phase_source(sourceOffset,p) == SOURCE_THERMAL_DISSIPATION_ID) then + do p = 1, phases%length + phase => phases%get(p) + if(count(mySources(:,p)) == 0) cycle + if(any(mySources(:,p))) source_thermal_dissipation_instance(p) = count(mySources(:,1:p)) + sources => phase%get('source') + do sourceOffset = 1, sources%length + if(mySources(sourceOffset,p)) then source_thermal_dissipation_offset(p) = sourceOffset - exit + associate(prm => param(source_thermal_dissipation_instance(p))) + + src => sources%get(sourceOffset) + prm%kappa = src%get_asFloat('kappa') + NipcMyPhase = count(material_phaseAt==p) * discretization_nIP + call constitutive_allocateState(sourceState(p)%p(sourceOffset),NipcMyPhase,0,0,0) + + end associate endif enddo - - if (all(phase_source(:,p) /= SOURCE_THERMAL_DISSIPATION_ID)) cycle - associate(prm => param(source_thermal_dissipation_instance(p)), & - config => config_phase(p)) - - prm%kappa = config%getFloat('dissipation_coldworkcoeff') - - NipcMyPhase = count(material_phaseAt==p) * discretization_nIP - call material_allocateState(sourceState(p)%p(sourceOffset),NipcMyPhase,0,0,0) - - end associate enddo -end subroutine source_thermal_dissipation_init + +end function source_thermal_dissipation_init !-------------------------------------------------------------------------------------------------- diff --git a/src/source_thermal_externalheat.f90 b/src/source_thermal_externalheat.f90 index 8ffc7a4fb..45ed2086f 100644 --- a/src/source_thermal_externalheat.f90 +++ b/src/source_thermal_externalheat.f90 @@ -11,9 +11,9 @@ submodule(constitutive:constitutive_thermal) source_thermal_externalheat source_thermal_externalheat_offset, & !< which source is my current thermal dissipation mechanism? source_thermal_externalheat_instance !< instance of thermal dissipation source mechanism - type :: tParameters !< container type for internal constitutive parameters + type :: tParameters !< container type for internal constitutive parameters real(pReal), dimension(:), allocatable :: & - time, & + time, & heat_rate integer :: & nIntervals @@ -29,44 +29,56 @@ contains !> @brief module initialization !> @details reads in material parameters, allocates arrays, and does sanity checks !-------------------------------------------------------------------------------------------------- -module subroutine source_thermal_externalheat_init +module function source_thermal_externalheat_init(source_length) result(mySources) + integer, intent(in) :: source_length + logical, dimension(:,:), allocatable :: mySources + + class(tNode), pointer :: & + phases, & + phase, & + sources, & + src integer :: Ninstance,sourceOffset,NipcMyPhase,p - write(6,'(/,a)') ' <<<+- source_'//SOURCE_thermal_externalheat_label//' init -+>>>' + write(6,'(/,a)') ' <<<+- source_thermal_externalHeat init -+>>>' - Ninstance = count(phase_source == SOURCE_thermal_externalheat_ID) + mySources = source_active('thermal_externalheat',source_length) + + Ninstance = count(mySources) write(6,'(a16,1x,i5,/)') '# instances:',Ninstance; flush(6) + if(Ninstance == 0) return - allocate(source_thermal_externalheat_offset (size(config_phase)), source=0) - allocate(source_thermal_externalheat_instance(size(config_phase)), source=0) + phases => material_root%get('phase') allocate(param(Ninstance)) + allocate(source_thermal_externalheat_offset (phases%length), source=0) + allocate(source_thermal_externalheat_instance(phases%length), source=0) - do p = 1, size(config_phase) - source_thermal_externalheat_instance(p) = count(phase_source(:,1:p) == SOURCE_thermal_externalheat_ID) - do sourceOffset = 1, phase_Nsources(p) - if (phase_source(sourceOffset,p) == SOURCE_thermal_externalheat_ID) then + do p = 1, phases%length + phase => phases%get(p) + if(any(mySources(:,p))) source_thermal_externalheat_instance(p) = count(mySources(:,1:p)) + if(count(mySources(:,p)) == 0) cycle + sources => phase%get('source') + do sourceOffset = 1, sources%length + if(mySources(sourceOffset,p)) then source_thermal_externalheat_offset(p) = sourceOffset - exit + associate(prm => param(source_thermal_externalheat_instance(p))) + src => sources%get(sourceOffset) + + prm%time = src%get_asFloats('t_n') + prm%nIntervals = size(prm%time) - 1 + + prm%heat_rate = src%get_asFloats('f_T',requiredSize = size(prm%time)) + + NipcMyPhase = count(material_phaseAt==p) * discretization_nIP + call constitutive_allocateState(sourceState(p)%p(sourceOffset),NipcMyPhase,1,1,0) + end associate + endif enddo - - if (all(phase_source(:,p) /= SOURCE_thermal_externalheat_ID)) cycle - associate(prm => param(source_thermal_externalheat_instance(p)), & - config => config_phase(p)) - - prm%time = config%getFloats('externalheat_time') - prm%nIntervals = size(prm%time) - 1 - - prm%heat_rate = config%getFloats('externalheat_rate',requiredSize = size(prm%time)) - - NipcMyPhase = count(material_phaseAt==p) * discretization_nIP - call material_allocateState(sourceState(p)%p(sourceOffset),NipcMyPhase,1,1,0) - - end associate enddo -end subroutine source_thermal_externalheat_init +end function source_thermal_externalheat_init !-------------------------------------------------------------------------------------------------- diff --git a/src/thermal_adiabatic.f90 b/src/thermal_adiabatic.f90 index c52f0a3d0..bd4a5f12c 100644 --- a/src/thermal_adiabatic.f90 +++ b/src/thermal_adiabatic.f90 @@ -5,10 +5,10 @@ module thermal_adiabatic use prec use config - use numerics use material use results use constitutive + use YAML_types use crystallite use lattice @@ -40,20 +40,32 @@ contains !-------------------------------------------------------------------------------------------------- subroutine thermal_adiabatic_init - integer :: maxNinstance,h,NofMyHomog - - write(6,'(/,a)') ' <<<+- thermal_'//THERMAL_ADIABATIC_label//' init -+>>>'; flush(6) + integer :: maxNinstance,h,NofMyHomog + class(tNode), pointer :: & + material_homogenization, & + homog, & + homogThermal + + write(6,'(/,a)') ' <<<+- thermal_adiabatic init -+>>>'; flush(6) maxNinstance = count(thermal_type == THERMAL_adiabatic_ID) if (maxNinstance == 0) return allocate(param(maxNinstance)) - do h = 1, size(thermal_type) + material_homogenization => material_root%get('homogenization') + do h = 1, material_Nhomogenization if (thermal_type(h) /= THERMAL_adiabatic_ID) cycle - associate(prm => param(thermal_typeInstance(h)),config => config_homogenization(h)) - - prm%output = config%getStrings('(output)',defaultVal=emptyStringArray) + 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 NofMyHomog=count(material_homogenizationAt==h) thermalState(h)%sizeState = 1 @@ -205,7 +217,7 @@ subroutine thermal_adiabatic_results(homog,group) associate(prm => param(damage_typeInstance(homog))) outputsLoop: do o = 1,size(prm%output) select case(trim(prm%output(o))) - case('temperature') ! ToDo: should be 'T' + case('T') call results_writeDataset(group,temperature(homog)%p,'T',& 'temperature','K') end select diff --git a/src/thermal_conduction.f90 b/src/thermal_conduction.f90 index 60766710d..9075c6d64 100644 --- a/src/thermal_conduction.f90 +++ b/src/thermal_conduction.f90 @@ -10,6 +10,7 @@ module thermal_conduction use results use crystallite use constitutive + use YAML_types implicit none private @@ -41,17 +42,28 @@ contains subroutine thermal_conduction_init integer :: Ninstance,NofMyHomog,h - - write(6,'(/,a)') ' <<<+- thermal_'//THERMAL_CONDUCTION_label//' init -+>>>'; flush(6) + class(tNode), pointer :: & + material_homogenization, & + homog, & + homogThermal + + write(6,'(/,a)') ' <<<+- thermal_conduction init -+>>>'; flush(6) Ninstance = count(thermal_type == THERMAL_conduction_ID) allocate(param(Ninstance)) - do h = 1, size(config_homogenization) + material_homogenization => material_root%get('homogenization') + do h = 1, material_Nhomogenization if (thermal_type(h) /= THERMAL_conduction_ID) cycle - associate(prm => param(thermal_typeInstance(h)),config => config_homogenization(h)) + homog => material_homogenization%get(h) + homogThermal => homog%get('thermal') + associate(prm => param(thermal_typeInstance(h))) - prm%output = config%getStrings('(output)',defaultVal=emptyStringArray) +#if defined (__GFORTRAN__) + prm%output = output_asStrings(homogThermal) +#else + prm%output = homogThermal%get_asStrings('output',defaultVal=emptyStringArray) +#endif NofMyHomog=count(material_homogenizationAt==h) thermalState(h)%sizeState = 0 @@ -213,7 +225,7 @@ subroutine thermal_conduction_results(homog,group) associate(prm => param(damage_typeInstance(homog))) outputsLoop: do o = 1,size(prm%output) select case(trim(prm%output(o))) - case('temperature') ! ToDo: should be 'T' + case('T') call results_writeDataset(group,temperature(homog)%p,'T',& 'temperature','K') end select diff --git a/src/thermal_isothermal.f90 b/src/thermal_isothermal.f90 index ceb714740..38aa99136 100644 --- a/src/thermal_isothermal.f90 +++ b/src/thermal_isothermal.f90 @@ -18,9 +18,9 @@ subroutine thermal_isothermal_init integer :: h,NofMyHomog - write(6,'(/,a)') ' <<<+- thermal_'//THERMAL_isothermal_label//' init -+>>>'; flush(6) + write(6,'(/,a)') ' <<<+- thermal_isothermal init -+>>>'; flush(6) - do h = 1, size(config_homogenization) + do h = 1, material_Nhomogenization if (thermal_type(h) /= THERMAL_isothermal_ID) cycle NofMyHomog = count(material_homogenizationAt == h) From 0c3a81e1667339b813562ed514f4442465632f2d Mon Sep 17 00:00:00 2001 From: Test User Date: Thu, 20 Aug 2020 19:08:12 +0200 Subject: [PATCH 43/73] [skip ci] updated version information after successful test of v2.0.3-2998-ga691e410 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index b7a86ed59..39f3e7155 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v2.0.3-2995-gd00974b5 +v2.0.3-2998-ga691e410 From bd78bf9d1d709797e47d3d4221c4db2a48556c44 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Fri, 21 Aug 2020 22:20:41 +0200 Subject: [PATCH 44/73] preparing first 3.0 series alpha release --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 39f3e7155..6e46bbb25 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v2.0.3-2998-ga691e410 +v3.0.0-alpha From 499ce01748b533f17a3dd109f7549356fadc6ae9 Mon Sep 17 00:00:00 2001 From: Philip Eisenlohr Date: Sat, 22 Aug 2020 13:55:18 -0400 Subject: [PATCH 45/73] added Geom.copy() method --- python/damask/_geom.py | 12 ++++++++- python/tests/test_Geom.py | 54 +++++++++++++++++++-------------------- 2 files changed, 37 insertions(+), 29 deletions(-) diff --git a/python/damask/_geom.py b/python/damask/_geom.py index 3fec15fdd..b0e917a59 100644 --- a/python/damask/_geom.py +++ b/python/damask/_geom.py @@ -1,4 +1,5 @@ import sys +import copy from io import StringIO import multiprocessing from functools import partial @@ -52,6 +53,16 @@ class Geom: ]) + def __copy__(self): + """Copy geometry.""" + return copy.deepcopy(self) + + + def copy(self): + """Copy geometry.""" + return self.__copy__() + + def update(self,microstructure=None,size=None,origin=None,rescale=False): """ Update microstructure and size. @@ -774,4 +785,3 @@ class Geom: #ToDo: self.add_comments('geom.py:vicinity_offset v{}'.format(version) return self.update(microstructure) - diff --git a/python/tests/test_Geom.py b/python/tests/test_Geom.py index 4061c3ecf..4fb1ae00a 100644 --- a/python/tests/test_Geom.py +++ b/python/tests/test_Geom.py @@ -1,5 +1,3 @@ -import copy - import pytest import numpy as np @@ -31,7 +29,7 @@ def reference_dir(reference_dir_base): class TestGeom: def test_update(self,default): - modified = copy.deepcopy(default) + modified = default.copy() modified.update( default.get_microstructure(), default.get_size(), @@ -89,12 +87,12 @@ class TestGeom: default.update(default.microstructure[1:,1:,1:],origin=np.ones(4)) def test_invalid_microstructure_size(self,default): - microstructure=np.ones((3,3)) + microstructure = np.ones((3,3)) with pytest.raises(ValueError): default.update(microstructure) def test_invalid_microstructure_type(self,default): - microstructure=np.random.randint(1,300,(3,4,5))==1 + microstructure = np.random.randint(1,300,(3,4,5))==1 with pytest.raises(TypeError): default.update(microstructure) @@ -110,7 +108,7 @@ class TestGeom: ] ) def test_mirror(self,default,update,reference_dir,directions,reflect): - modified = copy.deepcopy(default) + modified = default.copy() modified.mirror(directions,reflect) tag = f'directions={"-".join(directions)}_reflect={reflect}' reference = reference_dir/f'mirror_{tag}.geom' @@ -119,7 +117,7 @@ class TestGeom: @pytest.mark.parametrize('stencil',[1,2,3,4]) def test_clean(self,default,update,reference_dir,stencil): - modified = copy.deepcopy(default) + modified = default.copy() modified.clean(stencil) tag = f'stencil={stencil}' reference = reference_dir/f'clean_{tag}.geom' @@ -136,7 +134,7 @@ class TestGeom: ] ) def test_scale(self,default,update,reference_dir,grid): - modified = copy.deepcopy(default) + modified = default.copy() modified.scale(grid) tag = f'grid={util.srepr(grid,"-")}' reference = reference_dir/f'scale_{tag}.geom' @@ -144,7 +142,7 @@ class TestGeom: assert geom_equal(modified,Geom.from_file(reference)) def test_renumber(self,default): - modified = copy.deepcopy(default) + modified = default.copy() microstructure = modified.get_microstructure() for m in np.unique(microstructure): microstructure[microstructure==m] = microstructure.max() + np.random.randint(1,30) @@ -154,10 +152,10 @@ class TestGeom: assert geom_equal(modified,default) def test_substitute(self,default): - modified = copy.deepcopy(default) + modified = default.copy() microstructure = modified.get_microstructure() offset = np.random.randint(1,500) - microstructure+=offset + microstructure += offset modified.update(microstructure) assert not geom_equal(modified,default) modified.substitute(np.arange(default.microstructure.max())+1+offset, @@ -167,7 +165,7 @@ class TestGeom: @pytest.mark.parametrize('axis_angle',[np.array([1,0,0,86.7]), np.array([0,1,0,90.4]), np.array([0,0,1,90]), np.array([1,0,0,175]),np.array([0,-1,0,178]),np.array([0,0,1,180])]) def test_rotate360(self,default,axis_angle): - modified = copy.deepcopy(default) + 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(modified,default) @@ -175,7 +173,7 @@ class TestGeom: @pytest.mark.parametrize('Eulers',[[32.0,68.0,21.0], [0.0,32.0,240.0]]) def test_rotate(self,default,update,reference_dir,Eulers): - modified = copy.deepcopy(default) + modified = default.copy() modified.rotate(Rotation.from_Eulers(Eulers,degrees=True)) tag = f'Eulers={util.srepr(Eulers,"-")}' reference = reference_dir/f'rotate_{tag}.geom' @@ -184,25 +182,25 @@ class TestGeom: def test_canvas(self,default): grid_add = np.random.randint(0,30,(3)) - modified = copy.deepcopy(default) + modified = default.copy() modified.canvas(modified.grid + grid_add) e = default.grid assert np.all(modified.microstructure[:e[0],:e[1],:e[2]] == default.microstructure) - @pytest.mark.parametrize('center1,center2',[(np.random.random(3)*.5,np.random.random(3)), + @pytest.mark.parametrize('center1,center2',[(np.random.random(3)*.5,np.random.random(3)), (np.random.randint(4,8,(3)),np.random.randint(9,12,(3)))]) - @pytest.mark.parametrize('diameter',[np.random.random(3)*.5, - np.random.randint(4,10,(3))]) - def test_add_primitive(self,diameter,center1,center2): - """Same volume fraction for periodic microstructures and different center.""" - 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) - G_2 = Geom(np.ones(g,'i'),s,o) - G_1.add_primitive(diameter,center1,1) - G_2.add_primitive(diameter,center2,1) - assert np.count_nonzero(G_1.microstructure!=2) == np.count_nonzero(G_2.microstructure!=2) + @pytest.mark.parametrize('diameter',[np.random.random(3)*.5, + np.random.randint(4,10,(3))]) + def test_add_primitive(self,diameter,center1,center2): + """Same volume fraction for periodic microstructures and different center.""" + 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) + G_2 = Geom(np.ones(g,'i'),s,o) + G_1.add_primitive(diameter,center1,1) + G_2.add_primitive(diameter,center2,1) + assert np.count_nonzero(G_1.microstructure!=2) == np.count_nonzero(G_2.microstructure!=2) @pytest.mark.parametrize('trigger',[[1],[]]) def test_vicinity_offset(self,trigger): @@ -213,7 +211,7 @@ class TestGeom: m = np.ones(g,'i') x = (g*np.random.permutation(np.array([.5,1,1]))).astype('i') m[slice(0,x[0]),slice(0,x[1]),slice(0,x[2])] = 2 - m2 = copy.deepcopy(m) + m2 = m.copy() for i in [0,1,2]: m2[(np.roll(m,+vicinity,i)-m)!=0] += offset m2[(np.roll(m,-vicinity,i)-m)!=0] += offset From 70d1b0b987c906c2bd8424a03eaad3d49c32ced1 Mon Sep 17 00:00:00 2001 From: Test User Date: Sat, 22 Aug 2020 22:31:05 +0200 Subject: [PATCH 46/73] [skip ci] updated version information after successful test of v3.0.0-alpha-1-g499ce017 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 6e46bbb25..c744aa5d0 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v3.0.0-alpha +v3.0.0-alpha-1-g499ce017 From 2b09a7d31d1918265b4432b6946d994cbaf8e5a4 Mon Sep 17 00:00:00 2001 From: Philip Eisenlohr Date: Sat, 22 Aug 2020 21:33:38 -0400 Subject: [PATCH 47/73] fixed Geom.canvas bug, added Geom.from_vtk, added mode,selection options to Geom.clean --- python/damask/_geom.py | 64 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 52 insertions(+), 12 deletions(-) diff --git a/python/damask/_geom.py b/python/damask/_geom.py index b0e917a59..0f1c35e42 100644 --- a/python/damask/_geom.py +++ b/python/damask/_geom.py @@ -175,7 +175,7 @@ class Geom: if len(self.microstructure.shape) != 3: raise ValueError(f'Invalid microstructure shape {microstructure.shape}') elif self.microstructure.dtype not in np.sctypes['float'] + np.sctypes['int']: - raise TypeError(f'Invalid microstructue data type {microstructure.dtype}') + raise TypeError(f'Invalid microstructure data type {microstructure.dtype}') def set_size(self,size): @@ -345,6 +345,34 @@ class Geom: return Geom(microstructure.reshape(grid,order='F'),size,origin,homogenization,comments) + @staticmethod + def from_vtk(fname): + """ + Read a geom from a VTK file. + + Parameters + ---------- + fname : str or file handle + Geometry file to read. + + """ + g = VTK.from_file(fname).geom + N_cells = g.GetNumberOfCells() + microstructure = np.zeros(N_cells) + grid = np.array(g.GetDimensions())-1 + bbox = np.array(g.GetBounds()).reshape(3,2).T + size = bbox[1] - bbox[0] + + celldata = g.GetCellData() + for a in range(celldata.GetNumberOfArrays()): + if celldata.GetArrayName(a) == 'microstructure': + array = celldata.GetArray(a) + for c in range(N_cells): + microstructure[c] = array.GetValue(c) + + return Geom(microstructure.reshape(grid,order='F'),size,bbox[0]) + + @staticmethod def _find_closest_seed(seeds, weights, point): return np.argmin(np.sum((np.broadcast_to(point,(len(seeds),3))-seeds)**2,axis=1) - weights) @@ -621,7 +649,7 @@ class Geom: ) - def clean(self,stencil=3): + def clean(self,stencil=3,mode='nearest',selection=None): """ Smooth microstructure by selecting most frequent index within given stencil at each location. @@ -629,17 +657,28 @@ class Geom: ---------- stencil : int, optional Size of smoothing stencil. + mode : string, optional + The mode parameter determines how the input array is extended beyond its boundaries. + Default is 'nearest'. See scipy.ndimage.generic_filter for all options. + selection : list, optional + Field values that can be altered. Defaults to all. """ - def mostFrequent(arr): - unique, inverse = np.unique(arr, return_inverse=True) - return unique[np.argmax(np.bincount(inverse))] + def mostFrequent(arr,selection=None): + me = arr[arr.size//2] + if selection is None or me in selection: + unique, inverse = np.unique(arr, return_inverse=True) + return unique[np.argmax(np.bincount(inverse))] + else: + return me #ToDo: self.add_comments('geom.py:clean v{}'.format(version) return self.update(ndimage.filters.generic_filter( self.microstructure, mostFrequent, - size=(stencil,)*3 + size=(stencil if selection is None else stencil//2*2+1,)*3, + mode=mode, + extra_keywords=dict(selection=selection), ).astype(self.microstructure.dtype) ) @@ -708,14 +747,15 @@ class Geom: dtype = float if int(fill) != fill or self.microstructure.dtype==np.float else int canvas = np.full(self.grid if grid is None else grid, - fill if fill is not None else np.nanmax(self.microstructure)+1,dtype) + np.nanmax(self.microstructure)+1 if fill is None else fill, + dtype) - l = np.clip( offset, 0,np.minimum(self.grid +offset,grid)) # noqa - r = np.clip( offset+self.grid,0,np.minimum(self.grid*2+offset,grid)) - L = np.clip(-offset, 0,np.minimum(grid -offset,self.grid)) - R = np.clip(-offset+grid, 0,np.minimum(grid*2 -offset,self.grid)) + LL = np.clip( offset, 0,np.minimum(self.grid, grid+offset)) # noqa + 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)) - canvas[l[0]:r[0],l[1]:r[1],l[2]:r[2]] = self.microstructure[L[0]:R[0],L[1]:R[1],L[2]:R[2]] + canvas[ll[0]:ur[0],ll[1]:ur[1],ll[2]:ur[2]] = self.microstructure[LL[0]:UR[0],LL[1]:UR[1],LL[2]:UR[2]] #ToDo: self.add_comments('geom.py:canvas v{}'.format(version) return self.update(canvas,origin=self.origin+offset*self.size/self.grid,rescale=True) From a1f1b91c7f346131fdeac9db8403d930731f427c Mon Sep 17 00:00:00 2001 From: Test User Date: Sun, 23 Aug 2020 06:06:38 +0200 Subject: [PATCH 48/73] [skip ci] updated version information after successful test of v3.0.0-alpha-3-g2b09a7d3 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index c744aa5d0..a8dd6cb0f 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v3.0.0-alpha-1-g499ce017 +v3.0.0-alpha-3-g2b09a7d3 From b731b1e7684a6bdfb873b31a04a91d7499bd0081 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 23 Aug 2020 08:49:49 +0200 Subject: [PATCH 49/73] Geom.to_vtk improvements - should be integer - should have a test --- python/damask/_geom.py | 2 +- python/tests/test_Geom.py | 11 ++++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/python/damask/_geom.py b/python/damask/_geom.py index 0f1c35e42..de0b04c79 100644 --- a/python/damask/_geom.py +++ b/python/damask/_geom.py @@ -358,7 +358,7 @@ class Geom: """ g = VTK.from_file(fname).geom N_cells = g.GetNumberOfCells() - microstructure = np.zeros(N_cells) + microstructure = np.zeros(N_cells,'i') grid = np.array(g.GetDimensions())-1 bbox = np.array(g.GetBounds()).reshape(3,2).T size = bbox[1] - bbox[0] diff --git a/python/tests/test_Geom.py b/python/tests/test_Geom.py index 4fb1ae00a..60a4f4fef 100644 --- a/python/tests/test_Geom.py +++ b/python/tests/test_Geom.py @@ -1,3 +1,6 @@ +import os +import time + import pytest import numpy as np @@ -65,8 +68,14 @@ class TestGeom: new = Geom.from_file(f) assert geom_equal(new,default) - def test_export_vtk(self,default,tmpdir): + def test_read_write_vtk(self,default,tmpdir): default.to_vtk(str(tmpdir.join('default'))) + for _ in range(3): + if os.path.exists(tmpdir.join('default.vtr')): break + time.sleep(1) + new = Geom.from_vtk(str(tmpdir.join('default.vtr'))) + assert geom_equal(new,default) + @pytest.mark.parametrize('pack',[True,False]) def test_pack(self,default,tmpdir,pack): From 5fb2d30ee4a9adc539ce071cbe2defe74fab5e11 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 23 Aug 2020 09:02:17 +0200 Subject: [PATCH 50/73] fast and for arbitrary type --- python/damask/_geom.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/python/damask/_geom.py b/python/damask/_geom.py index de0b04c79..382ae4d32 100644 --- a/python/damask/_geom.py +++ b/python/damask/_geom.py @@ -6,6 +6,7 @@ from functools import partial import numpy as np from scipy import ndimage,spatial +from vtk.util.numpy_support import vtk_to_numpy as vtk_to_np from . import environment from . import Rotation @@ -357,8 +358,6 @@ class Geom: """ g = VTK.from_file(fname).geom - N_cells = g.GetNumberOfCells() - microstructure = np.zeros(N_cells,'i') grid = np.array(g.GetDimensions())-1 bbox = np.array(g.GetBounds()).reshape(3,2).T size = bbox[1] - bbox[0] @@ -366,9 +365,7 @@ class Geom: celldata = g.GetCellData() for a in range(celldata.GetNumberOfArrays()): if celldata.GetArrayName(a) == 'microstructure': - array = celldata.GetArray(a) - for c in range(N_cells): - microstructure[c] = array.GetValue(c) + microstructure = vtk_to_np(celldata.GetArray(a)) return Geom(microstructure.reshape(grid,order='F'),size,bbox[0]) From 975db01f31613d16ae16f4b68912a1c08127f037 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 23 Aug 2020 09:17:08 +0200 Subject: [PATCH 51/73] microstructure -> materialpoint at least for new functionality --- python/damask/_geom.py | 22 ++++++++++++---------- python/tests/test_Geom.py | 37 ++++++++++++++++++++++++------------- 2 files changed, 36 insertions(+), 23 deletions(-) diff --git a/python/damask/_geom.py b/python/damask/_geom.py index 382ae4d32..30aebe254 100644 --- a/python/damask/_geom.py +++ b/python/damask/_geom.py @@ -46,11 +46,11 @@ class Geom: def __repr__(self): """Basic information on geometry definition.""" return util.srepr([ - f'grid a b c: {util.srepr(self.get_grid ()," x ")}', - f'size x y z: {util.srepr(self.get_size ()," x ")}', - f'origin x y z: {util.srepr(self.get_origin()," ")}', - f'# microstructures: {self.N_microstructure}', - f'max microstructure: {np.nanmax(self.microstructure)}', + f'grid a b c: {util.srepr(self.get_grid ()," x ")}', + f'size x y z: {util.srepr(self.get_size ()," x ")}', + f'origin x y z: {util.srepr(self.get_origin()," ")}', + f'# materialpoints: {self.N_microstructure}', + f'max materialpoint: {np.nanmax(self.microstructure)}', ]) @@ -364,10 +364,12 @@ class Geom: celldata = g.GetCellData() for a in range(celldata.GetNumberOfArrays()): - if celldata.GetArrayName(a) == 'microstructure': - microstructure = vtk_to_np(celldata.GetArray(a)) + if celldata.GetArrayName(a) == 'materialpoint': + materialpoint = vtk_to_np(celldata.GetArray(a)) + return Geom(materialpoint.reshape(grid,order='F'),size,bbox[0]) + + raise ValueError(f'"materialpoint" array not found in {fname}') - return Geom(microstructure.reshape(grid,order='F'),size,bbox[0]) @staticmethod @@ -522,7 +524,7 @@ class Geom: """ v = VTK.from_rectilinearGrid(self.grid,self.size,self.origin) - v.add(self.microstructure.flatten(order='F'),'microstructure') + v.add(self.microstructure.flatten(order='F'),'materialpoint') if fname: v.write(fname) @@ -747,7 +749,7 @@ class Geom: np.nanmax(self.microstructure)+1 if fill is None else fill, dtype) - LL = np.clip( offset, 0,np.minimum(self.grid, grid+offset)) # noqa + 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)) diff --git a/python/tests/test_Geom.py b/python/tests/test_Geom.py index 60a4f4fef..d037a2a65 100644 --- a/python/tests/test_Geom.py +++ b/python/tests/test_Geom.py @@ -4,6 +4,7 @@ import time import pytest import numpy as np +from damask import VTK from damask import Geom from damask import Rotation from damask import util @@ -50,37 +51,47 @@ class TestGeom: def test_write_read_str(self,default,tmpdir): - default.to_file(str(tmpdir.join('default.geom'))) - new = Geom.from_file(str(tmpdir.join('default.geom'))) + default.to_file(str(tmpdir/'default.geom')) + new = Geom.from_file(str(tmpdir/'default.geom')) assert geom_equal(new,default) def test_write_read_file(self,default,tmpdir): - with open(tmpdir.join('default.geom'),'w') as f: + with open(tmpdir/'default.geom','w') as f: default.to_file(f) - with open(tmpdir.join('default.geom')) as f: + with open(tmpdir/'default.geom') as f: new = Geom.from_file(f) assert geom_equal(new,default) def test_write_show(self,default,tmpdir): - with open(tmpdir.join('str.geom'),'w') as f: + with open(tmpdir/'str.geom','w') as f: f.write(default.show()) - with open(tmpdir.join('str.geom')) as f: + with open(tmpdir/'str.geom') as f: new = Geom.from_file(f) assert geom_equal(new,default) def test_read_write_vtk(self,default,tmpdir): - default.to_vtk(str(tmpdir.join('default'))) - for _ in range(3): - if os.path.exists(tmpdir.join('default.vtr')): break - time.sleep(1) - new = Geom.from_vtk(str(tmpdir.join('default.vtr'))) + default.to_vtk(tmpdir/'default') + for _ in range(10): + time.sleep(.2) + if os.path.exists(tmpdir/'default.vtr'): break + + new = Geom.from_vtk(tmpdir/'default.vtr') assert geom_equal(new,default) + def test_invalid_vtk(self,tmpdir): + v = VTK.from_rectilinearGrid(np.random.randint(5,10,3)*2,np.random.random(3) + 1.0) + v.write(tmpdir/'no_materialpoint.vtr') + for _ in range(10): + time.sleep(.2) + if os.path.exists(tmpdir/'no_materialpoint.vtr'): break + with pytest.raises(ValueError): + Geom.from_vtk(tmpdir/'no_materialpoint.vtr') + @pytest.mark.parametrize('pack',[True,False]) def test_pack(self,default,tmpdir,pack): - default.to_file(tmpdir.join('default.geom'),pack=pack) - new = Geom.from_file(tmpdir.join('default.geom')) + default.to_file(tmpdir/'default.geom',pack=pack) + new = Geom.from_file(tmpdir/'default.geom') assert geom_equal(new,default) def test_invalid_combination(self,default): From 64e7582e8e621e2bc50c1bf68c661436de40a206 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 23 Aug 2020 10:02:22 +0200 Subject: [PATCH 52/73] consistent interface to ndimage filters Boolean 'periodic' sets mode to 'wrap' or 'nearest' --- python/damask/_geom.py | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/python/damask/_geom.py b/python/damask/_geom.py index 30aebe254..2f7f18066 100644 --- a/python/damask/_geom.py +++ b/python/damask/_geom.py @@ -621,11 +621,10 @@ class Geom: if 'x' in directions: ms = np.concatenate([ms,ms[limits[0]:limits[1]:-1,:,:]],0) - #ToDo: self.add_comments('geom.py:mirror v{}'.format(version) return self.update(ms,rescale=True) - def scale(self,grid): + def scale(self,grid,periodic=True): """ Scale microstructure to new grid. @@ -633,22 +632,23 @@ class Geom: ---------- grid : numpy.ndarray of shape (3) Number of grid points in x,y,z direction. + periodic : Boolean, optional + Assume geometry to be periodic. Defaults to True. """ - #ToDo: self.add_comments('geom.py:scale v{}'.format(version) return self.update( ndimage.interpolation.zoom( self.microstructure, grid/self.get_grid(), output=self.microstructure.dtype, order=0, - mode='nearest', + mode=('wrap' if periodic else 'nearest'), prefilter=False ) ) - def clean(self,stencil=3,mode='nearest',selection=None): + def clean(self,stencil=3,selection=None,periodic=True): """ Smooth microstructure by selecting most frequent index within given stencil at each location. @@ -656,11 +656,10 @@ class Geom: ---------- stencil : int, optional Size of smoothing stencil. - mode : string, optional - The mode parameter determines how the input array is extended beyond its boundaries. - Default is 'nearest'. See scipy.ndimage.generic_filter for all options. selection : list, optional Field values that can be altered. Defaults to all. + periodic : Boolean, optional + Assume geometry to be periodic. Defaults to True. """ def mostFrequent(arr,selection=None): @@ -671,12 +670,11 @@ class Geom: else: return me - #ToDo: self.add_comments('geom.py:clean v{}'.format(version) return self.update(ndimage.filters.generic_filter( self.microstructure, mostFrequent, size=(stencil if selection is None else stencil//2*2+1,)*3, - mode=mode, + mode=('wrap' if periodic else 'nearest'), extra_keywords=dict(selection=selection), ).astype(self.microstructure.dtype) ) @@ -688,7 +686,6 @@ class Geom: for i, oldID in enumerate(np.unique(self.microstructure)): renumbered = np.where(self.microstructure == oldID, i+1, renumbered) - #ToDo: self.add_comments('geom.py:renumber v{}'.format(version) return self.update(renumbered) @@ -723,7 +720,6 @@ class Geom: origin = self.origin-(np.asarray(microstructure_in.shape)-self.grid)*.5 * self.size/self.grid - #ToDo: self.add_comments('geom.py:rotate v{}'.format(version) return self.update(microstructure_in,origin=origin,rescale=True) @@ -756,7 +752,6 @@ class Geom: canvas[ll[0]:ur[0],ll[1]:ur[1],ll[2]:ur[2]] = self.microstructure[LL[0]:UR[0],LL[1]:UR[1],LL[2]:UR[2]] - #ToDo: self.add_comments('geom.py:canvas v{}'.format(version) return self.update(canvas,origin=self.origin+offset*self.size/self.grid,rescale=True) @@ -776,7 +771,6 @@ class Geom: for from_ms,to_ms in zip(from_microstructure,to_microstructure): substituted[self.microstructure==from_ms] = to_ms - #ToDo: self.add_comments('geom.py:substitute v{}'.format(version) return self.update(substituted) @@ -822,5 +816,4 @@ class Geom: extra_keywords={'trigger':trigger}) microstructure = np.ma.MaskedArray(self.microstructure + offset_, np.logical_not(mask)) - #ToDo: self.add_comments('geom.py:vicinity_offset v{}'.format(version) return self.update(microstructure) From 07af7b2f988fb548ad6d134337aecc51984a9f48 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 23 Aug 2020 10:46:15 +0200 Subject: [PATCH 53/73] geom is written to vtr exlcusively, not to general vtk base tests on vtr --- python/damask/_geom.py | 20 +++++++------ python/tests/reference/Geom/clean.vtr | 25 ++++++++++++++++ .../tests/reference/Geom/clean_2_1_False.vtr | 25 ++++++++++++++++ .../tests/reference/Geom/clean_2_1_True.vtr | 25 ++++++++++++++++ .../reference/Geom/clean_2_None_False.vtr | 25 ++++++++++++++++ .../reference/Geom/clean_2_None_True.vtr | 25 ++++++++++++++++ .../tests/reference/Geom/clean_3_1_False.vtr | 25 ++++++++++++++++ .../tests/reference/Geom/clean_3_1_True.vtr | 25 ++++++++++++++++ .../reference/Geom/clean_3_None_False.vtr | 25 ++++++++++++++++ .../reference/Geom/clean_3_None_True.vtr | 25 ++++++++++++++++ .../tests/reference/Geom/clean_4_1_False.vtr | 25 ++++++++++++++++ .../tests/reference/Geom/clean_4_1_True.vtr | 25 ++++++++++++++++ .../reference/Geom/clean_4_None_False.vtr | 25 ++++++++++++++++ .../reference/Geom/clean_4_None_True.vtr | 25 ++++++++++++++++ .../tests/reference/Geom/clean_stencil=1.geom | 25 ---------------- .../tests/reference/Geom/clean_stencil=2.geom | 25 ---------------- .../tests/reference/Geom/clean_stencil=3.geom | 25 ---------------- .../tests/reference/Geom/clean_stencil=4.geom | 25 ---------------- python/tests/test_Geom.py | 30 +++++++++++-------- 19 files changed, 354 insertions(+), 121 deletions(-) create mode 100644 python/tests/reference/Geom/clean.vtr create mode 100644 python/tests/reference/Geom/clean_2_1_False.vtr create mode 100644 python/tests/reference/Geom/clean_2_1_True.vtr create mode 100644 python/tests/reference/Geom/clean_2_None_False.vtr create mode 100644 python/tests/reference/Geom/clean_2_None_True.vtr create mode 100644 python/tests/reference/Geom/clean_3_1_False.vtr create mode 100644 python/tests/reference/Geom/clean_3_1_True.vtr create mode 100644 python/tests/reference/Geom/clean_3_None_False.vtr create mode 100644 python/tests/reference/Geom/clean_3_None_True.vtr create mode 100644 python/tests/reference/Geom/clean_4_1_False.vtr create mode 100644 python/tests/reference/Geom/clean_4_1_True.vtr create mode 100644 python/tests/reference/Geom/clean_4_None_False.vtr create mode 100644 python/tests/reference/Geom/clean_4_None_True.vtr delete mode 100644 python/tests/reference/Geom/clean_stencil=1.geom delete mode 100644 python/tests/reference/Geom/clean_stencil=2.geom delete mode 100644 python/tests/reference/Geom/clean_stencil=3.geom delete mode 100644 python/tests/reference/Geom/clean_stencil=4.geom diff --git a/python/damask/_geom.py b/python/damask/_geom.py index 2f7f18066..722df2524 100644 --- a/python/damask/_geom.py +++ b/python/damask/_geom.py @@ -347,17 +347,18 @@ class Geom: @staticmethod - def from_vtk(fname): + def from_vtr(fname): """ - Read a geom from a VTK file. + Read a VTK rectilinear grid. Parameters ---------- - fname : str or file handle + fname : str or or pathlib.Path Geometry file to read. + Valid extension is .vtr, it will be appended if not given. """ - g = VTK.from_file(fname).geom + g = VTK.from_file(fname if str(fname).endswith('.vtr') else str(fname)+'.vtr').geom grid = np.array(g.GetDimensions())-1 bbox = np.array(g.GetBounds()).reshape(3,2).T size = bbox[1] - bbox[0] @@ -513,21 +514,22 @@ class Geom: f.write(f'{reps} of {former}\n') - def to_vtk(self,fname=None): + def to_vtr(self,fname=None): """ - Generates vtk file. + Generates vtk rectilinear grid. Parameters ---------- fname : str, optional - Vtk file to write. If no file is given, a string is returned. + Filename to write. If no file is given, a string is returned. + Valid extension is .vtr, it will be appended if not given. """ v = VTK.from_rectilinearGrid(self.grid,self.size,self.origin) v.add(self.microstructure.flatten(order='F'),'materialpoint') if fname: - v.write(fname) + v.write(fname if str(fname).endswith('.vtr') else str(fname)+'.vtr') else: sys.stdout.write(v.__repr__()) @@ -642,7 +644,7 @@ class Geom: grid/self.get_grid(), output=self.microstructure.dtype, order=0, - mode=('wrap' if periodic else 'nearest'), + mode=('wrap' if periodic else 'nearest'), prefilter=False ) ) diff --git a/python/tests/reference/Geom/clean.vtr b/python/tests/reference/Geom/clean.vtr new file mode 100644 index 000000000..c76ce3988 --- /dev/null +++ b/python/tests/reference/Geom/clean.vtr @@ -0,0 +1,25 @@ + + + + + + + + + AQAAAACAAAAALQAANQAAAA==eF7t1CECACAMxLBj/380fhYwIyK2spWkmnWgt6b3AF65/avfegAAAAAAAAAAAMy0AfYtC2k= + + + + + AQAAAACAAACoAAAAVQAAAA==eF5jYICAWTNBYKU9hN5pb2IMAoeh/JP2EFUXoOKX7dPTQOAaVP6m/dkzIHAHqu4BVPwhVP1jqPwTqL5nUHUvoOpeQtW9hqp7A1X3Dqrugz0ASSZF3Q== + + + AQAAAACAAACYAAAAVgAAAA==eF5jYIAAmeOFQLTGHkLvsQ8Fg6NQ/hn7IjDjIlT8qr1F32MgugGVv2MPMeUBVN1D+8cQBVD1T+3BymSeQ/W9sF8FBq+g+t/Yg4Ut3kHN+WAPAAVdQE4= + + + AQAAAACAAABIAAAAIgAAAA==eF5jYEAGB+wh9AUofQNKP4DST6D0Cyj9Bkp/sAcAAU8I6Q== + + + + + diff --git a/python/tests/reference/Geom/clean_2_1_False.vtr b/python/tests/reference/Geom/clean_2_1_False.vtr new file mode 100644 index 000000000..c76ce3988 --- /dev/null +++ b/python/tests/reference/Geom/clean_2_1_False.vtr @@ -0,0 +1,25 @@ + + + + + + + + + AQAAAACAAAAALQAANQAAAA==eF7t1CECACAMxLBj/380fhYwIyK2spWkmnWgt6b3AF65/avfegAAAAAAAAAAAMy0AfYtC2k= + + + + + AQAAAACAAACoAAAAVQAAAA==eF5jYICAWTNBYKU9hN5pb2IMAoeh/JP2EFUXoOKX7dPTQOAaVP6m/dkzIHAHqu4BVPwhVP1jqPwTqL5nUHUvoOpeQtW9hqp7A1X3Dqrugz0ASSZF3Q== + + + AQAAAACAAACYAAAAVgAAAA==eF5jYIAAmeOFQLTGHkLvsQ8Fg6NQ/hn7IjDjIlT8qr1F32MgugGVv2MPMeUBVN1D+8cQBVD1T+3BymSeQ/W9sF8FBq+g+t/Yg4Ut3kHN+WAPAAVdQE4= + + + AQAAAACAAABIAAAAIgAAAA==eF5jYEAGB+wh9AUofQNKP4DST6D0Cyj9Bkp/sAcAAU8I6Q== + + + + + diff --git a/python/tests/reference/Geom/clean_2_1_True.vtr b/python/tests/reference/Geom/clean_2_1_True.vtr new file mode 100644 index 000000000..c76ce3988 --- /dev/null +++ b/python/tests/reference/Geom/clean_2_1_True.vtr @@ -0,0 +1,25 @@ + + + + + + + + + AQAAAACAAAAALQAANQAAAA==eF7t1CECACAMxLBj/380fhYwIyK2spWkmnWgt6b3AF65/avfegAAAAAAAAAAAMy0AfYtC2k= + + + + + AQAAAACAAACoAAAAVQAAAA==eF5jYICAWTNBYKU9hN5pb2IMAoeh/JP2EFUXoOKX7dPTQOAaVP6m/dkzIHAHqu4BVPwhVP1jqPwTqL5nUHUvoOpeQtW9hqp7A1X3Dqrugz0ASSZF3Q== + + + AQAAAACAAACYAAAAVgAAAA==eF5jYIAAmeOFQLTGHkLvsQ8Fg6NQ/hn7IjDjIlT8qr1F32MgugGVv2MPMeUBVN1D+8cQBVD1T+3BymSeQ/W9sF8FBq+g+t/Yg4Ut3kHN+WAPAAVdQE4= + + + AQAAAACAAABIAAAAIgAAAA==eF5jYEAGB+wh9AUofQNKP4DST6D0Cyj9Bkp/sAcAAU8I6Q== + + + + + diff --git a/python/tests/reference/Geom/clean_2_None_False.vtr b/python/tests/reference/Geom/clean_2_None_False.vtr new file mode 100644 index 000000000..c76ce3988 --- /dev/null +++ b/python/tests/reference/Geom/clean_2_None_False.vtr @@ -0,0 +1,25 @@ + + + + + + + + + AQAAAACAAAAALQAANQAAAA==eF7t1CECACAMxLBj/380fhYwIyK2spWkmnWgt6b3AF65/avfegAAAAAAAAAAAMy0AfYtC2k= + + + + + AQAAAACAAACoAAAAVQAAAA==eF5jYICAWTNBYKU9hN5pb2IMAoeh/JP2EFUXoOKX7dPTQOAaVP6m/dkzIHAHqu4BVPwhVP1jqPwTqL5nUHUvoOpeQtW9hqp7A1X3Dqrugz0ASSZF3Q== + + + AQAAAACAAACYAAAAVgAAAA==eF5jYIAAmeOFQLTGHkLvsQ8Fg6NQ/hn7IjDjIlT8qr1F32MgugGVv2MPMeUBVN1D+8cQBVD1T+3BymSeQ/W9sF8FBq+g+t/Yg4Ut3kHN+WAPAAVdQE4= + + + AQAAAACAAABIAAAAIgAAAA==eF5jYEAGB+wh9AUofQNKP4DST6D0Cyj9Bkp/sAcAAU8I6Q== + + + + + diff --git a/python/tests/reference/Geom/clean_2_None_True.vtr b/python/tests/reference/Geom/clean_2_None_True.vtr new file mode 100644 index 000000000..fe04087d2 --- /dev/null +++ b/python/tests/reference/Geom/clean_2_None_True.vtr @@ -0,0 +1,25 @@ + + + + + + + + + AQAAAACAAAAALQAAMQAAAA==eF7tzCEOADAMxLDr/v/o8pLSaTMwi1JJCoAvnGHrN7f/AAAAAAAAAAAAeE8DQvkLTQ== + + + + + AQAAAACAAACoAAAAVQAAAA==eF5jYICAWTNBYKU9hN5pb2IMAoeh/JP2EFUXoOKX7dPTQOAaVP6m/dkzIHAHqu4BVPwhVP1jqPwTqL5nUHUvoOpeQtW9hqp7A1X3Dqrugz0ASSZF3Q== + + + AQAAAACAAACYAAAAVgAAAA==eF5jYIAAmeOFQLTGHkLvsQ8Fg6NQ/hn7IjDjIlT8qr1F32MgugGVv2MPMeUBVN1D+8cQBVD1T+3BymSeQ/W9sF8FBq+g+t/Yg4Ut3kHN+WAPAAVdQE4= + + + AQAAAACAAABIAAAAIgAAAA==eF5jYEAGB+wh9AUofQNKP4DST6D0Cyj9Bkp/sAcAAU8I6Q== + + + + + diff --git a/python/tests/reference/Geom/clean_3_1_False.vtr b/python/tests/reference/Geom/clean_3_1_False.vtr new file mode 100644 index 000000000..c76ce3988 --- /dev/null +++ b/python/tests/reference/Geom/clean_3_1_False.vtr @@ -0,0 +1,25 @@ + + + + + + + + + AQAAAACAAAAALQAANQAAAA==eF7t1CECACAMxLBj/380fhYwIyK2spWkmnWgt6b3AF65/avfegAAAAAAAAAAAMy0AfYtC2k= + + + + + AQAAAACAAACoAAAAVQAAAA==eF5jYICAWTNBYKU9hN5pb2IMAoeh/JP2EFUXoOKX7dPTQOAaVP6m/dkzIHAHqu4BVPwhVP1jqPwTqL5nUHUvoOpeQtW9hqp7A1X3Dqrugz0ASSZF3Q== + + + AQAAAACAAACYAAAAVgAAAA==eF5jYIAAmeOFQLTGHkLvsQ8Fg6NQ/hn7IjDjIlT8qr1F32MgugGVv2MPMeUBVN1D+8cQBVD1T+3BymSeQ/W9sF8FBq+g+t/Yg4Ut3kHN+WAPAAVdQE4= + + + AQAAAACAAABIAAAAIgAAAA==eF5jYEAGB+wh9AUofQNKP4DST6D0Cyj9Bkp/sAcAAU8I6Q== + + + + + diff --git a/python/tests/reference/Geom/clean_3_1_True.vtr b/python/tests/reference/Geom/clean_3_1_True.vtr new file mode 100644 index 000000000..c76ce3988 --- /dev/null +++ b/python/tests/reference/Geom/clean_3_1_True.vtr @@ -0,0 +1,25 @@ + + + + + + + + + AQAAAACAAAAALQAANQAAAA==eF7t1CECACAMxLBj/380fhYwIyK2spWkmnWgt6b3AF65/avfegAAAAAAAAAAAMy0AfYtC2k= + + + + + AQAAAACAAACoAAAAVQAAAA==eF5jYICAWTNBYKU9hN5pb2IMAoeh/JP2EFUXoOKX7dPTQOAaVP6m/dkzIHAHqu4BVPwhVP1jqPwTqL5nUHUvoOpeQtW9hqp7A1X3Dqrugz0ASSZF3Q== + + + AQAAAACAAACYAAAAVgAAAA==eF5jYIAAmeOFQLTGHkLvsQ8Fg6NQ/hn7IjDjIlT8qr1F32MgugGVv2MPMeUBVN1D+8cQBVD1T+3BymSeQ/W9sF8FBq+g+t/Yg4Ut3kHN+WAPAAVdQE4= + + + AQAAAACAAABIAAAAIgAAAA==eF5jYEAGB+wh9AUofQNKP4DST6D0Cyj9Bkp/sAcAAU8I6Q== + + + + + diff --git a/python/tests/reference/Geom/clean_3_None_False.vtr b/python/tests/reference/Geom/clean_3_None_False.vtr new file mode 100644 index 000000000..c2ad86f43 --- /dev/null +++ b/python/tests/reference/Geom/clean_3_None_False.vtr @@ -0,0 +1,25 @@ + + + + + + + + + AQAAAACAAAAALQAAOgAAAA==eF7t1CEOACAMBMHS/z8aXwNJSagYMe6y8jIislgNtTW9d9oD/PL6r6b3AAAAAAAAAAAA4MYGlRYLYA== + + + + + AQAAAACAAACoAAAAVQAAAA==eF5jYICAWTNBYKU9hN5pb2IMAoeh/JP2EFUXoOKX7dPTQOAaVP6m/dkzIHAHqu4BVPwhVP1jqPwTqL5nUHUvoOpeQtW9hqp7A1X3Dqrugz0ASSZF3Q== + + + AQAAAACAAACYAAAAVgAAAA==eF5jYIAAmeOFQLTGHkLvsQ8Fg6NQ/hn7IjDjIlT8qr1F32MgugGVv2MPMeUBVN1D+8cQBVD1T+3BymSeQ/W9sF8FBq+g+t/Yg4Ut3kHN+WAPAAVdQE4= + + + AQAAAACAAABIAAAAIgAAAA==eF5jYEAGB+wh9AUofQNKP4DST6D0Cyj9Bkp/sAcAAU8I6Q== + + + + + diff --git a/python/tests/reference/Geom/clean_3_None_True.vtr b/python/tests/reference/Geom/clean_3_None_True.vtr new file mode 100644 index 000000000..b4d19ebcf --- /dev/null +++ b/python/tests/reference/Geom/clean_3_None_True.vtr @@ -0,0 +1,25 @@ + + + + + + + + + AQAAAACAAAAALQAANwAAAA==eF7t1KERADAMA7Gk+w9dWpYCswiI+R66q6rDzmPa/kj3ALZK/2m6BwAAAAAAAAAAAJMLZrELTQ== + + + + + AQAAAACAAACoAAAAVQAAAA==eF5jYICAWTNBYKU9hN5pb2IMAoeh/JP2EFUXoOKX7dPTQOAaVP6m/dkzIHAHqu4BVPwhVP1jqPwTqL5nUHUvoOpeQtW9hqp7A1X3Dqrugz0ASSZF3Q== + + + AQAAAACAAACYAAAAVgAAAA==eF5jYIAAmeOFQLTGHkLvsQ8Fg6NQ/hn7IjDjIlT8qr1F32MgugGVv2MPMeUBVN1D+8cQBVD1T+3BymSeQ/W9sF8FBq+g+t/Yg4Ut3kHN+WAPAAVdQE4= + + + AQAAAACAAABIAAAAIgAAAA==eF5jYEAGB+wh9AUofQNKP4DST6D0Cyj9Bkp/sAcAAU8I6Q== + + + + + diff --git a/python/tests/reference/Geom/clean_4_1_False.vtr b/python/tests/reference/Geom/clean_4_1_False.vtr new file mode 100644 index 000000000..c76ce3988 --- /dev/null +++ b/python/tests/reference/Geom/clean_4_1_False.vtr @@ -0,0 +1,25 @@ + + + + + + + + + AQAAAACAAAAALQAANQAAAA==eF7t1CECACAMxLBj/380fhYwIyK2spWkmnWgt6b3AF65/avfegAAAAAAAAAAAMy0AfYtC2k= + + + + + AQAAAACAAACoAAAAVQAAAA==eF5jYICAWTNBYKU9hN5pb2IMAoeh/JP2EFUXoOKX7dPTQOAaVP6m/dkzIHAHqu4BVPwhVP1jqPwTqL5nUHUvoOpeQtW9hqp7A1X3Dqrugz0ASSZF3Q== + + + AQAAAACAAACYAAAAVgAAAA==eF5jYIAAmeOFQLTGHkLvsQ8Fg6NQ/hn7IjDjIlT8qr1F32MgugGVv2MPMeUBVN1D+8cQBVD1T+3BymSeQ/W9sF8FBq+g+t/Yg4Ut3kHN+WAPAAVdQE4= + + + AQAAAACAAABIAAAAIgAAAA==eF5jYEAGB+wh9AUofQNKP4DST6D0Cyj9Bkp/sAcAAU8I6Q== + + + + + diff --git a/python/tests/reference/Geom/clean_4_1_True.vtr b/python/tests/reference/Geom/clean_4_1_True.vtr new file mode 100644 index 000000000..c76ce3988 --- /dev/null +++ b/python/tests/reference/Geom/clean_4_1_True.vtr @@ -0,0 +1,25 @@ + + + + + + + + + AQAAAACAAAAALQAANQAAAA==eF7t1CECACAMxLBj/380fhYwIyK2spWkmnWgt6b3AF65/avfegAAAAAAAAAAAMy0AfYtC2k= + + + + + AQAAAACAAACoAAAAVQAAAA==eF5jYICAWTNBYKU9hN5pb2IMAoeh/JP2EFUXoOKX7dPTQOAaVP6m/dkzIHAHqu4BVPwhVP1jqPwTqL5nUHUvoOpeQtW9hqp7A1X3Dqrugz0ASSZF3Q== + + + AQAAAACAAACYAAAAVgAAAA==eF5jYIAAmeOFQLTGHkLvsQ8Fg6NQ/hn7IjDjIlT8qr1F32MgugGVv2MPMeUBVN1D+8cQBVD1T+3BymSeQ/W9sF8FBq+g+t/Yg4Ut3kHN+WAPAAVdQE4= + + + AQAAAACAAABIAAAAIgAAAA==eF5jYEAGB+wh9AUofQNKP4DST6D0Cyj9Bkp/sAcAAU8I6Q== + + + + + diff --git a/python/tests/reference/Geom/clean_4_None_False.vtr b/python/tests/reference/Geom/clean_4_None_False.vtr new file mode 100644 index 000000000..811d7dc8f --- /dev/null +++ b/python/tests/reference/Geom/clean_4_None_False.vtr @@ -0,0 +1,25 @@ + + + + + + + + + AQAAAACAAAAALQAAOQAAAA==eF7t1CESACAMA8HS/z8aX4OgCGDFuszJZERkMTbU1us9gFO6/+q23moPAAAAAAAAAADAnybPzQto + + + + + AQAAAACAAACoAAAAVQAAAA==eF5jYICAWTNBYKU9hN5pb2IMAoeh/JP2EFUXoOKX7dPTQOAaVP6m/dkzIHAHqu4BVPwhVP1jqPwTqL5nUHUvoOpeQtW9hqp7A1X3Dqrugz0ASSZF3Q== + + + AQAAAACAAACYAAAAVgAAAA==eF5jYIAAmeOFQLTGHkLvsQ8Fg6NQ/hn7IjDjIlT8qr1F32MgugGVv2MPMeUBVN1D+8cQBVD1T+3BymSeQ/W9sF8FBq+g+t/Yg4Ut3kHN+WAPAAVdQE4= + + + AQAAAACAAABIAAAAIgAAAA==eF5jYEAGB+wh9AUofQNKP4DST6D0Cyj9Bkp/sAcAAU8I6Q== + + + + + diff --git a/python/tests/reference/Geom/clean_4_None_True.vtr b/python/tests/reference/Geom/clean_4_None_True.vtr new file mode 100644 index 000000000..88a8643d9 --- /dev/null +++ b/python/tests/reference/Geom/clean_4_None_True.vtr @@ -0,0 +1,25 @@ + + + + + + + + + AQAAAACAAAAALQAAJAAAAA==eF7twwEJAAAMBKH7/qWXY6DgqqmqqqqqqqqqqqqqPnhyUwtB + + + + + AQAAAACAAACoAAAAVQAAAA==eF5jYICAWTNBYKU9hN5pb2IMAoeh/JP2EFUXoOKX7dPTQOAaVP6m/dkzIHAHqu4BVPwhVP1jqPwTqL5nUHUvoOpeQtW9hqp7A1X3Dqrugz0ASSZF3Q== + + + AQAAAACAAACYAAAAVgAAAA==eF5jYIAAmeOFQLTGHkLvsQ8Fg6NQ/hn7IjDjIlT8qr1F32MgugGVv2MPMeUBVN1D+8cQBVD1T+3BymSeQ/W9sF8FBq+g+t/Yg4Ut3kHN+WAPAAVdQE4= + + + AQAAAACAAABIAAAAIgAAAA==eF5jYEAGB+wh9AUofQNKP4DST6D0Cyj9Bkp/sAcAAU8I6Q== + + + + + diff --git a/python/tests/reference/Geom/clean_stencil=1.geom b/python/tests/reference/Geom/clean_stencil=1.geom deleted file mode 100644 index 3e6f6fe9c..000000000 --- a/python/tests/reference/Geom/clean_stencil=1.geom +++ /dev/null @@ -1,25 +0,0 @@ -4 header -grid a 8 b 5 c 4 -size x 8e-06 y 5e-06 z 4e-06 -origin x 0.0 y 0.0 z 0.0 -homogenization 1 - 1 1 1 1 1 1 1 1 - 1 1 1 1 1 1 1 1 - 1 1 1 1 1 1 1 1 - 1 1 1 1 1 1 1 1 - 1 1 1 1 1 1 1 1 - 2 3 4 5 6 7 8 9 -10 11 12 13 14 15 16 17 -18 19 20 21 22 23 24 25 -26 27 28 29 30 31 32 33 -34 35 36 37 38 39 40 41 - 2 2 2 2 2 2 2 2 - 2 2 2 2 2 2 2 2 - 2 2 2 2 2 2 2 2 - 2 2 2 2 2 2 2 2 - 2 2 2 2 2 2 2 2 - 1 2 3 4 5 6 7 8 - 9 10 11 12 13 14 15 16 -17 18 19 20 21 22 23 24 -25 26 27 28 29 30 31 32 -33 34 35 36 37 38 39 40 diff --git a/python/tests/reference/Geom/clean_stencil=2.geom b/python/tests/reference/Geom/clean_stencil=2.geom deleted file mode 100644 index 14c1fa5e2..000000000 --- a/python/tests/reference/Geom/clean_stencil=2.geom +++ /dev/null @@ -1,25 +0,0 @@ -4 header -grid a 8 b 5 c 4 -size x 8e-06 y 5e-06 z 4e-06 -origin x 0.0 y 0.0 z 0.0 -homogenization 1 -1 1 1 1 1 1 1 1 -1 1 1 1 1 1 1 1 -1 1 1 1 1 1 1 1 -1 1 1 1 1 1 1 1 -1 1 1 1 1 1 1 1 -1 1 1 1 1 1 1 1 -1 1 1 1 1 1 1 1 -1 1 1 1 1 1 1 1 -1 1 1 1 1 1 1 1 -1 1 1 1 1 1 1 1 -2 2 2 2 2 2 2 2 -2 2 2 2 2 2 2 2 -2 2 2 2 2 2 2 2 -2 2 2 2 2 2 2 2 -2 2 2 2 2 2 2 2 -1 2 2 2 2 2 2 2 -2 2 2 2 2 2 2 2 -2 2 2 2 2 2 2 2 -2 2 2 2 2 2 2 2 -2 2 2 2 2 2 2 2 diff --git a/python/tests/reference/Geom/clean_stencil=3.geom b/python/tests/reference/Geom/clean_stencil=3.geom deleted file mode 100644 index 3aea8ffa5..000000000 --- a/python/tests/reference/Geom/clean_stencil=3.geom +++ /dev/null @@ -1,25 +0,0 @@ -4 header -grid a 8 b 5 c 4 -size x 8e-06 y 5e-06 z 4e-06 -origin x 0.0 y 0.0 z 0.0 -homogenization 1 -1 1 1 1 1 1 1 1 -1 1 1 1 1 1 1 1 -1 1 1 1 1 1 1 1 -1 1 1 1 1 1 1 1 -1 1 1 1 1 1 1 1 -2 2 1 1 1 1 1 1 -2 2 1 1 1 1 1 1 -1 1 1 1 1 1 1 1 -1 1 1 1 1 1 1 1 -1 1 1 1 1 1 1 1 -2 2 2 2 2 2 2 2 -2 2 2 2 2 2 2 2 -2 2 2 2 2 2 2 2 -2 2 2 2 2 2 2 2 -2 2 2 2 2 2 2 2 -2 2 2 2 2 2 2 2 -2 2 2 2 2 2 2 2 -2 2 2 2 2 2 2 2 -2 2 2 2 2 2 2 2 -2 2 2 2 2 2 2 2 diff --git a/python/tests/reference/Geom/clean_stencil=4.geom b/python/tests/reference/Geom/clean_stencil=4.geom deleted file mode 100644 index 595e04b23..000000000 --- a/python/tests/reference/Geom/clean_stencil=4.geom +++ /dev/null @@ -1,25 +0,0 @@ -4 header -grid a 8 b 5 c 4 -size x 8e-06 y 5e-06 z 4e-06 -origin x 0.0 y 0.0 z 0.0 -homogenization 1 -1 1 1 1 1 1 1 1 -1 1 1 1 1 1 1 1 -1 1 1 1 1 1 1 1 -1 1 1 1 1 1 1 1 -1 1 1 1 1 1 1 1 -1 1 1 1 1 1 1 1 -1 1 1 1 1 1 1 1 -1 1 1 1 1 1 1 1 -1 1 1 1 1 1 1 1 -1 1 1 1 1 1 1 1 -2 2 2 2 1 1 1 1 -2 2 2 2 1 1 1 1 -2 2 2 2 1 1 1 1 -1 1 1 1 1 1 1 1 -1 1 1 1 1 1 1 1 -2 2 2 2 2 2 2 2 -2 2 2 2 2 2 2 2 -2 2 2 2 2 2 2 2 -2 2 2 2 2 2 2 2 -2 2 2 2 2 2 2 2 diff --git a/python/tests/test_Geom.py b/python/tests/test_Geom.py index d037a2a65..0ac633152 100644 --- a/python/tests/test_Geom.py +++ b/python/tests/test_Geom.py @@ -69,23 +69,23 @@ class TestGeom: new = Geom.from_file(f) assert geom_equal(new,default) - def test_read_write_vtk(self,default,tmpdir): - default.to_vtk(tmpdir/'default') + def test_read_write_vtr(self,default,tmpdir): + default.to_vtr(tmpdir/'default') for _ in range(10): time.sleep(.2) if os.path.exists(tmpdir/'default.vtr'): break - new = Geom.from_vtk(tmpdir/'default.vtr') + new = Geom.from_vtr(tmpdir/'default.vtr') assert geom_equal(new,default) - def test_invalid_vtk(self,tmpdir): + def test_invalid_vtr(self,tmpdir): v = VTK.from_rectilinearGrid(np.random.randint(5,10,3)*2,np.random.random(3) + 1.0) v.write(tmpdir/'no_materialpoint.vtr') for _ in range(10): time.sleep(.2) if os.path.exists(tmpdir/'no_materialpoint.vtr'): break with pytest.raises(ValueError): - Geom.from_vtk(tmpdir/'no_materialpoint.vtr') + Geom.from_vtr(tmpdir/'no_materialpoint.vtr') @pytest.mark.parametrize('pack',[True,False]) @@ -136,13 +136,19 @@ class TestGeom: assert geom_equal(modified,Geom.from_file(reference)) @pytest.mark.parametrize('stencil',[1,2,3,4]) - def test_clean(self,default,update,reference_dir,stencil): - modified = default.copy() - modified.clean(stencil) - tag = f'stencil={stencil}' - reference = reference_dir/f'clean_{tag}.geom' - if update: modified.to_file(reference) - assert geom_equal(modified,Geom.from_file(reference)) + @pytest.mark.parametrize('selection',[None,1]) + @pytest.mark.parametrize('periodic',[True,False]) + def test_clean(self,update,reference_dir,stencil,selection,periodic): + current = Geom.from_vtr((reference_dir/'clean').with_suffix('.vtr')) + current.clean(stencil,None if selection is None else [selection],periodic) + reference = reference_dir/f'clean_{stencil}_{selection}_{periodic}' + altered = stencil !=1 and selection is not None + if update and stencil !=1: + current.to_vtr(reference) + for _ in range(10): + time.sleep(.2) + if os.path.exists(reference.with_suffix('.vtr')): break + assert geom_equal(current,Geom.from_vtr(reference if stencil !=1 else reference_dir/'clean')) @pytest.mark.parametrize('grid',[ (10,11,10), From 6f79573140f9a3b601cc94e17e13576c68baab76 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 23 Aug 2020 11:05:56 +0200 Subject: [PATCH 54/73] more test coverage --- python/damask/_geom.py | 4 +-- .../tests/reference/Geom/clean_2_2_False.vtr | 25 +++++++++++++++++++ .../tests/reference/Geom/clean_2_2_True.vtr | 25 +++++++++++++++++++ .../tests/reference/Geom/clean_3_2_False.vtr | 25 +++++++++++++++++++ .../tests/reference/Geom/clean_3_2_True.vtr | 25 +++++++++++++++++++ .../tests/reference/Geom/clean_4_2_False.vtr | 25 +++++++++++++++++++ .../tests/reference/Geom/clean_4_2_True.vtr | 25 +++++++++++++++++++ python/tests/test_Geom.py | 8 ++++-- 8 files changed, 157 insertions(+), 5 deletions(-) create mode 100644 python/tests/reference/Geom/clean_2_2_False.vtr create mode 100644 python/tests/reference/Geom/clean_2_2_True.vtr create mode 100644 python/tests/reference/Geom/clean_3_2_False.vtr create mode 100644 python/tests/reference/Geom/clean_3_2_True.vtr create mode 100644 python/tests/reference/Geom/clean_4_2_False.vtr create mode 100644 python/tests/reference/Geom/clean_4_2_True.vtr diff --git a/python/damask/_geom.py b/python/damask/_geom.py index 722df2524..c8963b616 100644 --- a/python/damask/_geom.py +++ b/python/damask/_geom.py @@ -608,9 +608,7 @@ class Geom: """ valid = {'x','y','z'} - if not all(isinstance(d, str) for d in directions): - raise TypeError('Directions are not of type str.') - elif not set(directions).issubset(valid): + if not set(directions).issubset(valid): raise ValueError(f'Invalid direction {set(directions).difference(valid)} specified.') limits = [None,None] if reflect else [-2,0] diff --git a/python/tests/reference/Geom/clean_2_2_False.vtr b/python/tests/reference/Geom/clean_2_2_False.vtr new file mode 100644 index 000000000..c2ad86f43 --- /dev/null +++ b/python/tests/reference/Geom/clean_2_2_False.vtr @@ -0,0 +1,25 @@ + + + + + + + + + AQAAAACAAAAALQAAOgAAAA==eF7t1CEOACAMBMHS/z8aXwNJSagYMe6y8jIislgNtTW9d9oD/PL6r6b3AAAAAAAAAAAA4MYGlRYLYA== + + + + + AQAAAACAAACoAAAAVQAAAA==eF5jYICAWTNBYKU9hN5pb2IMAoeh/JP2EFUXoOKX7dPTQOAaVP6m/dkzIHAHqu4BVPwhVP1jqPwTqL5nUHUvoOpeQtW9hqp7A1X3Dqrugz0ASSZF3Q== + + + AQAAAACAAACYAAAAVgAAAA==eF5jYIAAmeOFQLTGHkLvsQ8Fg6NQ/hn7IjDjIlT8qr1F32MgugGVv2MPMeUBVN1D+8cQBVD1T+3BymSeQ/W9sF8FBq+g+t/Yg4Ut3kHN+WAPAAVdQE4= + + + AQAAAACAAABIAAAAIgAAAA==eF5jYEAGB+wh9AUofQNKP4DST6D0Cyj9Bkp/sAcAAU8I6Q== + + + + + diff --git a/python/tests/reference/Geom/clean_2_2_True.vtr b/python/tests/reference/Geom/clean_2_2_True.vtr new file mode 100644 index 000000000..b4d19ebcf --- /dev/null +++ b/python/tests/reference/Geom/clean_2_2_True.vtr @@ -0,0 +1,25 @@ + + + + + + + + + AQAAAACAAAAALQAANwAAAA==eF7t1KERADAMA7Gk+w9dWpYCswiI+R66q6rDzmPa/kj3ALZK/2m6BwAAAAAAAAAAAJMLZrELTQ== + + + + + AQAAAACAAACoAAAAVQAAAA==eF5jYICAWTNBYKU9hN5pb2IMAoeh/JP2EFUXoOKX7dPTQOAaVP6m/dkzIHAHqu4BVPwhVP1jqPwTqL5nUHUvoOpeQtW9hqp7A1X3Dqrugz0ASSZF3Q== + + + AQAAAACAAACYAAAAVgAAAA==eF5jYIAAmeOFQLTGHkLvsQ8Fg6NQ/hn7IjDjIlT8qr1F32MgugGVv2MPMeUBVN1D+8cQBVD1T+3BymSeQ/W9sF8FBq+g+t/Yg4Ut3kHN+WAPAAVdQE4= + + + AQAAAACAAABIAAAAIgAAAA==eF5jYEAGB+wh9AUofQNKP4DST6D0Cyj9Bkp/sAcAAU8I6Q== + + + + + diff --git a/python/tests/reference/Geom/clean_3_2_False.vtr b/python/tests/reference/Geom/clean_3_2_False.vtr new file mode 100644 index 000000000..c2ad86f43 --- /dev/null +++ b/python/tests/reference/Geom/clean_3_2_False.vtr @@ -0,0 +1,25 @@ + + + + + + + + + AQAAAACAAAAALQAAOgAAAA==eF7t1CEOACAMBMHS/z8aXwNJSagYMe6y8jIislgNtTW9d9oD/PL6r6b3AAAAAAAAAAAA4MYGlRYLYA== + + + + + AQAAAACAAACoAAAAVQAAAA==eF5jYICAWTNBYKU9hN5pb2IMAoeh/JP2EFUXoOKX7dPTQOAaVP6m/dkzIHAHqu4BVPwhVP1jqPwTqL5nUHUvoOpeQtW9hqp7A1X3Dqrugz0ASSZF3Q== + + + AQAAAACAAACYAAAAVgAAAA==eF5jYIAAmeOFQLTGHkLvsQ8Fg6NQ/hn7IjDjIlT8qr1F32MgugGVv2MPMeUBVN1D+8cQBVD1T+3BymSeQ/W9sF8FBq+g+t/Yg4Ut3kHN+WAPAAVdQE4= + + + AQAAAACAAABIAAAAIgAAAA==eF5jYEAGB+wh9AUofQNKP4DST6D0Cyj9Bkp/sAcAAU8I6Q== + + + + + diff --git a/python/tests/reference/Geom/clean_3_2_True.vtr b/python/tests/reference/Geom/clean_3_2_True.vtr new file mode 100644 index 000000000..b4d19ebcf --- /dev/null +++ b/python/tests/reference/Geom/clean_3_2_True.vtr @@ -0,0 +1,25 @@ + + + + + + + + + AQAAAACAAAAALQAANwAAAA==eF7t1KERADAMA7Gk+w9dWpYCswiI+R66q6rDzmPa/kj3ALZK/2m6BwAAAAAAAAAAAJMLZrELTQ== + + + + + AQAAAACAAACoAAAAVQAAAA==eF5jYICAWTNBYKU9hN5pb2IMAoeh/JP2EFUXoOKX7dPTQOAaVP6m/dkzIHAHqu4BVPwhVP1jqPwTqL5nUHUvoOpeQtW9hqp7A1X3Dqrugz0ASSZF3Q== + + + AQAAAACAAACYAAAAVgAAAA==eF5jYIAAmeOFQLTGHkLvsQ8Fg6NQ/hn7IjDjIlT8qr1F32MgugGVv2MPMeUBVN1D+8cQBVD1T+3BymSeQ/W9sF8FBq+g+t/Yg4Ut3kHN+WAPAAVdQE4= + + + AQAAAACAAABIAAAAIgAAAA==eF5jYEAGB+wh9AUofQNKP4DST6D0Cyj9Bkp/sAcAAU8I6Q== + + + + + diff --git a/python/tests/reference/Geom/clean_4_2_False.vtr b/python/tests/reference/Geom/clean_4_2_False.vtr new file mode 100644 index 000000000..7665bdde2 --- /dev/null +++ b/python/tests/reference/Geom/clean_4_2_False.vtr @@ -0,0 +1,25 @@ + + + + + + + + + AQAAAACAAAAALQAANQAAAA==eF7t1CEOACAMBMGj/380Fk+TQjJi7MqtJHVYlypv9wB+0f2+7h4AAAAAAAAAAABM2HWwC1M= + + + + + AQAAAACAAACoAAAAVQAAAA==eF5jYICAWTNBYKU9hN5pb2IMAoeh/JP2EFUXoOKX7dPTQOAaVP6m/dkzIHAHqu4BVPwhVP1jqPwTqL5nUHUvoOpeQtW9hqp7A1X3Dqrugz0ASSZF3Q== + + + AQAAAACAAACYAAAAVgAAAA==eF5jYIAAmeOFQLTGHkLvsQ8Fg6NQ/hn7IjDjIlT8qr1F32MgugGVv2MPMeUBVN1D+8cQBVD1T+3BymSeQ/W9sF8FBq+g+t/Yg4Ut3kHN+WAPAAVdQE4= + + + AQAAAACAAABIAAAAIgAAAA==eF5jYEAGB+wh9AUofQNKP4DST6D0Cyj9Bkp/sAcAAU8I6Q== + + + + + diff --git a/python/tests/reference/Geom/clean_4_2_True.vtr b/python/tests/reference/Geom/clean_4_2_True.vtr new file mode 100644 index 000000000..88a8643d9 --- /dev/null +++ b/python/tests/reference/Geom/clean_4_2_True.vtr @@ -0,0 +1,25 @@ + + + + + + + + + AQAAAACAAAAALQAAJAAAAA==eF7twwEJAAAMBKH7/qWXY6DgqqmqqqqqqqqqqqqqPnhyUwtB + + + + + AQAAAACAAACoAAAAVQAAAA==eF5jYICAWTNBYKU9hN5pb2IMAoeh/JP2EFUXoOKX7dPTQOAaVP6m/dkzIHAHqu4BVPwhVP1jqPwTqL5nUHUvoOpeQtW9hqp7A1X3Dqrugz0ASSZF3Q== + + + AQAAAACAAACYAAAAVgAAAA==eF5jYIAAmeOFQLTGHkLvsQ8Fg6NQ/hn7IjDjIlT8qr1F32MgugGVv2MPMeUBVN1D+8cQBVD1T+3BymSeQ/W9sF8FBq+g+t/Yg4Ut3kHN+WAPAAVdQE4= + + + AQAAAACAAABIAAAAIgAAAA==eF5jYEAGB+wh9AUofQNKP4DST6D0Cyj9Bkp/sAcAAU8I6Q== + + + + + diff --git a/python/tests/test_Geom.py b/python/tests/test_Geom.py index 0ac633152..479dd43fc 100644 --- a/python/tests/test_Geom.py +++ b/python/tests/test_Geom.py @@ -135,14 +135,18 @@ class TestGeom: if update: modified.to_file(reference) assert geom_equal(modified,Geom.from_file(reference)) + @pytest.mark.parametrize('directions',[(1,2,'y'),('a','b','x'),[1]]) + def test_mirror_invalid(self,default,directions): + with pytest.raises(ValueError): + default.mirror(directions) + @pytest.mark.parametrize('stencil',[1,2,3,4]) - @pytest.mark.parametrize('selection',[None,1]) + @pytest.mark.parametrize('selection',[None,1,2]) @pytest.mark.parametrize('periodic',[True,False]) def test_clean(self,update,reference_dir,stencil,selection,periodic): current = Geom.from_vtr((reference_dir/'clean').with_suffix('.vtr')) current.clean(stencil,None if selection is None else [selection],periodic) reference = reference_dir/f'clean_{stencil}_{selection}_{periodic}' - altered = stencil !=1 and selection is not None if update and stencil !=1: current.to_vtr(reference) for _ in range(10): From d65371d42f8471ed255d2685a46a913a2100b4b8 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 23 Aug 2020 12:55:55 +0200 Subject: [PATCH 55/73] removed unused and untested functionality PEP 20: Explicit is better than implicit. --- python/damask/_geom.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/python/damask/_geom.py b/python/damask/_geom.py index c8963b616..571ae12eb 100644 --- a/python/damask/_geom.py +++ b/python/damask/_geom.py @@ -189,10 +189,7 @@ class Geom: physical size of the microstructure in meter. """ - if size is None: - grid = np.asarray(self.microstructure.shape) - self.size = grid/np.max(grid) - else: + if size is not None: if len(size) != 3 or any(np.array(size) <= 0): raise ValueError(f'Invalid size {size}') else: From a1c78b778a1bed0faf40dd8078a05a2deeb77e21 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 23 Aug 2020 23:22:53 +0200 Subject: [PATCH 56/73] WIP: track history in VTK objects --- python/damask/_vtk.py | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/python/damask/_vtk.py b/python/damask/_vtk.py index 00aa2f4e9..d12e80e32 100644 --- a/python/damask/_vtk.py +++ b/python/damask/_vtk.py @@ -232,6 +232,33 @@ class VTK: raise TypeError + def get_comments(self): + """Return the comments.""" + fielddata = self.geom.GetFieldData() + for a in range(fielddata.GetNumberOfArrays()): + if fielddata.GetArrayName(a) == 'comments': + comments = fielddata.GetAbstractArray(a) + return [comments.GetValue(i) for i in range(comments.GetNumberOfValues())] + return [] + + + def set_comments(self,comments): + """ + Add Comments. + + Parameters + ---------- + comments : str or list of str + Comments to add + + """ + s = vtk.vtkStringArray() + s.SetName('comments') + for c in [comments] if isinstance(comments,str) else comments: + s.InsertNextValue(c) + self.geom.GetFieldData().AddArray(s) + + def __repr__(self): """ASCII representation of the VTK data.""" writer = vtk.vtkDataSetWriter() @@ -240,7 +267,10 @@ class VTK: writer.SetInputData(self.geom) writer.Write() return writer.GetOutputString() - + celldata = g.GetCellData() + for a in range(celldata.GetNumberOfArrays()): + if celldata.GetArrayName(a) == 'materialpoint': + materialpoint = vtk_to_np(celldata.GetArray(a)) def show(self): """ From 9867830d684921502f734765aa7f8d0c5340fd67 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 23 Aug 2020 23:23:23 +0200 Subject: [PATCH 57/73] store history of geometry modifications --- python/damask/_geom.py | 20 +++++++++++++++----- python/damask/util.py | 8 ++++++++ 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/python/damask/_geom.py b/python/damask/_geom.py index 571ae12eb..8039a0038 100644 --- a/python/damask/_geom.py +++ b/python/damask/_geom.py @@ -1,7 +1,8 @@ import sys import copy -from io import StringIO +import inspect import multiprocessing +from io import StringIO from functools import partial import numpy as np @@ -416,8 +417,8 @@ class Geom: else: microstructure = microstructure.reshape(grid) - #ToDo: comments = 'geom.py:from_Laguerre_tessellation v{}'.format(version) - return Geom(microstructure+1,size,homogenization=1) + creator = util.edit_info('damask.Result.'+inspect.stack()[0][3]) + return Geom(microstructure+1,size,homogenization=1,comments=creator) @staticmethod @@ -441,8 +442,8 @@ class Geom: KDTree = spatial.cKDTree(seeds,boxsize=size) if periodic else spatial.cKDTree(seeds) devNull,microstructure = KDTree.query(coords) - #ToDo: comments = 'geom.py:from_Voronoi_tessellation v{}'.format(version) - return Geom(microstructure.reshape(grid)+1,size,homogenization=1) + creator = util.edit_info('damask.Result.'+inspect.stack()[0][3]) + return Geom(microstructure.reshape(grid)+1,size,homogenization=1,comments=creator) def to_file(self,fname,pack=None): @@ -588,6 +589,7 @@ class Geom: fill_ = np.full_like(self.microstructure,np.nanmax(self.microstructure)+1 if fill is None else fill) ms = np.ma.MaskedArray(fill_,np.logical_not(mask) if inverse else mask) + self.add_comments(util.edit_info('damask.Result.'+inspect.stack()[0][3])) return self.update(ms) @@ -618,6 +620,7 @@ class Geom: if 'x' in directions: ms = np.concatenate([ms,ms[limits[0]:limits[1]:-1,:,:]],0) + self.add_comments(util.edit_info('damask.Result.'+inspect.stack()[0][3])) return self.update(ms,rescale=True) @@ -633,6 +636,7 @@ class Geom: Assume geometry to be periodic. Defaults to True. """ + self.add_comments(util.edit_info('damask.Result.'+inspect.stack()[0][3])) return self.update( ndimage.interpolation.zoom( self.microstructure, @@ -667,6 +671,7 @@ class Geom: else: return me + self.add_comments(util.edit_info('damask.Result.'+inspect.stack()[0][3])) return self.update(ndimage.filters.generic_filter( self.microstructure, mostFrequent, @@ -683,6 +688,7 @@ class Geom: for i, oldID in enumerate(np.unique(self.microstructure)): renumbered = np.where(self.microstructure == oldID, i+1, renumbered) + self.add_comments(util.edit_info('damask.Result.'+inspect.stack()[0][3])) return self.update(renumbered) @@ -717,6 +723,7 @@ class Geom: origin = self.origin-(np.asarray(microstructure_in.shape)-self.grid)*.5 * self.size/self.grid + self.add_comments(util.edit_info('damask.Result.'+inspect.stack()[0][3])) return self.update(microstructure_in,origin=origin,rescale=True) @@ -749,6 +756,7 @@ class Geom: canvas[ll[0]:ur[0],ll[1]:ur[1],ll[2]:ur[2]] = self.microstructure[LL[0]:UR[0],LL[1]:UR[1],LL[2]:UR[2]] + self.add_comments(util.edit_info('damask.Result.'+inspect.stack()[0][3])) return self.update(canvas,origin=self.origin+offset*self.size/self.grid,rescale=True) @@ -768,6 +776,7 @@ class Geom: for from_ms,to_ms in zip(from_microstructure,to_microstructure): substituted[self.microstructure==from_ms] = to_ms + self.add_comments(util.edit_info('damask.Result.'+inspect.stack()[0][3])) return self.update(substituted) @@ -813,4 +822,5 @@ class Geom: extra_keywords={'trigger':trigger}) microstructure = np.ma.MaskedArray(self.microstructure + offset_, np.logical_not(mask)) + self.add_comments(util.edit_info('damask.Result.'+inspect.stack()[0][3])) return self.update(microstructure) diff --git a/python/damask/util.py b/python/damask/util.py index 733fd0010..f83fc4c62 100644 --- a/python/damask/util.py +++ b/python/damask/util.py @@ -9,6 +9,8 @@ from optparse import Option import numpy as np +import damask + # limit visibility __all__=[ 'srepr', @@ -20,6 +22,7 @@ __all__=[ 'scale_to_coprime', 'return_message', 'extendableOption', + 'edit_info' ] #################################################################################################### @@ -175,6 +178,11 @@ def scale_to_coprime(v): return m +def edit_info(who): + now = datetime.datetime.now().astimezone().strftime('%Y-%m-%d %H:%M:%S%z') + return f'{who} v{damask.version} ({now})' + + #################################################################################################### # Classes #################################################################################################### From c7cbd961a1e771bd6b925f4a3e7d5a000dd3d767 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Mon, 24 Aug 2020 00:31:38 +0200 Subject: [PATCH 58/73] more systematic monkeypatching allows comparison of reference files (log/history does not contain information about damask.version and datetime.datetime.now) --- python/tests/conftest.py | 26 ++++++++++++++++++++++---- python/tests/test_Colormap.py | 8 +++++--- 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/python/tests/conftest.py b/python/tests/conftest.py index 87aa9a363..a6f6e62ad 100644 --- a/python/tests/conftest.py +++ b/python/tests/conftest.py @@ -1,11 +1,29 @@ from pathlib import Path +import datetime + import numpy as np - import pytest +from _pytest.monkeypatch import MonkeyPatch -# Use to monkeypatch damask.version (for comparsion to reference files that contain version information) -def pytest_configure(): - pytest.dummy_version = '99.99.99-9999-pytest' +import damask + + +patched_version = '99.99.99-9999-pytest' +@pytest.fixture +def patch_damask_version(monkeysession): + """Set damask.version for reproducible tests results.""" + monkeysession.setattr(damask, 'version', patched_version) + +patched_date = datetime.datetime(2019, 11, 2, 11, 58, 0) +@pytest.fixture +def patch_datetime_now(monkeysession): + """Set datetime.datetime.now for reproducible tests results.""" + class mydatetime: + @classmethod + def now(cls): + return patched_date + + monkeysession.setattr(datetime, 'datetime', mydatetime) def pytest_addoption(parser): diff --git a/python/tests/test_Colormap.py b/python/tests/test_Colormap.py index b3309f12b..4fe0cc9fb 100644 --- a/python/tests/test_Colormap.py +++ b/python/tests/test_Colormap.py @@ -17,6 +17,10 @@ def reference_dir(reference_dir_base): class TestColormap: + @pytest.fixture(autouse=True) + def _patch_damask_version(self, patch_damask_version): + print('patched damask.version') + def test_conversion(self): specials = np.array([[0.,0.,0.], @@ -29,7 +33,6 @@ class TestColormap: [1.,1.,1.] ]) rgbs = np.vstack((specials,np.random.rand(100,3))) - pass # class not integrated for rgb in rgbs: print('rgb',rgb) @@ -150,8 +153,7 @@ class TestColormap: ('GOM','.legend'), ('Gmsh','.msh') ]) - def test_compare_reference(self,format,ext,tmpdir,reference_dir,update,monkeypatch): - monkeypatch.setattr(damask, 'version', pytest.dummy_version) + def test_compare_reference(self,format,ext,tmpdir,reference_dir,update): name = 'binary' c = Colormap.from_predefined(name) if update: From 44015082a3b4d3302964ac081a8aebba25473fab Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Mon, 24 Aug 2020 00:34:07 +0200 Subject: [PATCH 59/73] dead code (copy and paste error) --- python/damask/_vtk.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/python/damask/_vtk.py b/python/damask/_vtk.py index d12e80e32..22621ceaa 100644 --- a/python/damask/_vtk.py +++ b/python/damask/_vtk.py @@ -267,10 +267,7 @@ class VTK: writer.SetInputData(self.geom) writer.Write() return writer.GetOutputString() - celldata = g.GetCellData() - for a in range(celldata.GetNumberOfArrays()): - if celldata.GetArrayName(a) == 'materialpoint': - materialpoint = vtk_to_np(celldata.GetArray(a)) + def show(self): """ From 22da3af92eb4f2fa81d2ae0c2073c44b8bb26138 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Mon, 24 Aug 2020 00:42:58 +0200 Subject: [PATCH 60/73] cleaning (prospector complaint) --- python/tests/conftest.py | 10 +++++----- python/tests/test_Colormap.py | 2 -- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/python/tests/conftest.py b/python/tests/conftest.py index a6f6e62ad..2912373a5 100644 --- a/python/tests/conftest.py +++ b/python/tests/conftest.py @@ -3,27 +3,27 @@ import datetime import numpy as np import pytest -from _pytest.monkeypatch import MonkeyPatch import damask patched_version = '99.99.99-9999-pytest' @pytest.fixture -def patch_damask_version(monkeysession): +def patch_damask_version(monkeypatch): """Set damask.version for reproducible tests results.""" - monkeysession.setattr(damask, 'version', patched_version) + monkeypatch.setattr(damask, 'version', patched_version) + patched_date = datetime.datetime(2019, 11, 2, 11, 58, 0) @pytest.fixture -def patch_datetime_now(monkeysession): +def patch_datetime_now(monkeypatch): """Set datetime.datetime.now for reproducible tests results.""" class mydatetime: @classmethod def now(cls): return patched_date - monkeysession.setattr(datetime, 'datetime', mydatetime) + monkeypatch.setattr(datetime, 'datetime', mydatetime) def pytest_addoption(parser): diff --git a/python/tests/test_Colormap.py b/python/tests/test_Colormap.py index 4fe0cc9fb..d3f5e45c8 100644 --- a/python/tests/test_Colormap.py +++ b/python/tests/test_Colormap.py @@ -7,7 +7,6 @@ import pytest from PIL import Image from PIL import ImageChops -import damask from damask import Colormap @pytest.fixture @@ -22,7 +21,6 @@ class TestColormap: print('patched damask.version') def test_conversion(self): - specials = np.array([[0.,0.,0.], [1.,0.,0.], [0.,1.,0.], From 507a165733bc351fb9cb1d7bca052100d691199d Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Mon, 24 Aug 2020 06:40:36 +0200 Subject: [PATCH 61/73] functionality for getting data - handy for Geom class, but could be of general interest - add/set/get comments: follows same functions as for Geom class --- python/damask/_vtk.py | 58 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 55 insertions(+), 3 deletions(-) diff --git a/python/damask/_vtk.py b/python/damask/_vtk.py index 22621ceaa..52dd52754 100644 --- a/python/damask/_vtk.py +++ b/python/damask/_vtk.py @@ -6,6 +6,7 @@ import numpy as np import vtk from vtk.util.numpy_support import numpy_to_vtk as np_to_vtk from vtk.util.numpy_support import numpy_to_vtkIdTypeArray as np_to_vtkIdTypeArray +from vtk.util.numpy_support import vtk_to_numpy as vtk_to_np import damask from . import Table @@ -204,7 +205,18 @@ class VTK: # Check https://blog.kitware.com/ghost-and-blanking-visibility-changes/ for missing data # Needs support for pd.DataFrame and/or table def add(self,data,label=None): - """Add data to either cells or points.""" + """ + Add data to either cells or points. + + Parameters + ---------- + data : numpy.ndarray + Data to add. First dimension need to match either + number of cells or number of points + label : str + Data label. + + """ N_points = self.geom.GetNumberOfPoints() N_cells = self.geom.GetNumberOfCells() @@ -232,6 +244,33 @@ class VTK: raise TypeError + def get(self,label): + """ + Get either cell or point data. + + Cell data takes precedence over point data, i.e. this + function assumes that labels are unique among cell and + point data. + + Parameters + ---------- + label : str + Data label. + + """ + celldata = self.geom.GetCellData() + for a in range(celldata.GetNumberOfArrays()): + if celldata.GetArrayName(a) == label: + return vtk_to_np(celldata.GetArray(a)) + + pointdata = self.geom.GetPointData() + for a in range(celldata.GetNumberOfArrays()): + if pointdata.GetArrayName(a) == label: + return vtk_to_np(pointdata.GetArray(a)) + + raise ValueError(f'array "{label}" not found') + + def get_comments(self): """Return the comments.""" fielddata = self.geom.GetFieldData() @@ -244,12 +283,12 @@ class VTK: def set_comments(self,comments): """ - Add Comments. + Set Comments. Parameters ---------- comments : str or list of str - Comments to add + Comments. """ s = vtk.vtkStringArray() @@ -259,6 +298,19 @@ class VTK: self.geom.GetFieldData().AddArray(s) + def add_comments(self,comments): + """ + Add Comments. + + Parameters + ---------- + comments : str or list of str + Comments to add. + + """ + self.set_comments(self.get_comments + ([comments] if isinstance(comments,str) else comments)) + + def __repr__(self): """ASCII representation of the VTK data.""" writer = vtk.vtkDataSetWriter() From 0d3ef295548c53b9fa6632154b1bc3887f42d3a3 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Mon, 24 Aug 2020 06:46:22 +0200 Subject: [PATCH 62/73] more logical encapsulation - getting data out of VTK is a functionality of the VTK class. Need to discuss whether the VTK class should also provide grid and size (works only for rectilinear grid, so hiding VTK type is not possible anymore), but the current situation requires the Geom class to rely on 'internals' of the VTK class - header is specific to *.geom format, not to Geom objects. --- python/damask/_geom.py | 59 ++++++++++++++++-------------------------- 1 file changed, 23 insertions(+), 36 deletions(-) diff --git a/python/damask/_geom.py b/python/damask/_geom.py index 8039a0038..17cd49b08 100644 --- a/python/damask/_geom.py +++ b/python/damask/_geom.py @@ -7,7 +7,6 @@ from functools import partial import numpy as np from scipy import ndimage,spatial -from vtk.util.numpy_support import vtk_to_numpy as vtk_to_np from . import environment from . import Rotation @@ -271,16 +270,6 @@ class Geom: return self.comments[:] - def get_header(self): - """Return the full header (grid, size, origin, homogenization, comments).""" - header = [f'{len(self.comments)+4} header'] + self.comments - header.append('grid a {} b {} c {}'.format(*self.get_grid())) - header.append('size x {} y {} z {}'.format(*self.get_size())) - header.append('origin x {} y {} z {}'.format(*self.get_origin())) - header.append(f'homogenization {self.get_homogenization()}') - return header - - @staticmethod def from_file(fname): """ @@ -356,19 +345,12 @@ class Geom: Valid extension is .vtr, it will be appended if not given. """ - g = VTK.from_file(fname if str(fname).endswith('.vtr') else str(fname)+'.vtr').geom - grid = np.array(g.GetDimensions())-1 - bbox = np.array(g.GetBounds()).reshape(3,2).T + v = VTK.from_file(fname if str(fname).endswith('.vtr') else str(fname)+'.vtr') + grid = np.array(v.geom.GetDimensions())-1 + bbox = np.array(v.geom.GetBounds()).reshape(3,2).T size = bbox[1] - bbox[0] - celldata = g.GetCellData() - for a in range(celldata.GetNumberOfArrays()): - if celldata.GetArrayName(a) == 'materialpoint': - materialpoint = vtk_to_np(celldata.GetArray(a)) - return Geom(materialpoint.reshape(grid,order='F'),size,bbox[0]) - - raise ValueError(f'"materialpoint" array not found in {fname}') - + return Geom(v.get('materialpoint').reshape(grid,order='F'),size,bbox[0]) @staticmethod @@ -417,7 +399,7 @@ class Geom: else: microstructure = microstructure.reshape(grid) - creator = util.edit_info('damask.Result.'+inspect.stack()[0][3]) + creator = util.edit_info('damask.Geom.'+inspect.stack()[0][3]) return Geom(microstructure+1,size,homogenization=1,comments=creator) @@ -442,7 +424,7 @@ class Geom: KDTree = spatial.cKDTree(seeds,boxsize=size) if periodic else spatial.cKDTree(seeds) devNull,microstructure = KDTree.query(coords) - creator = util.edit_info('damask.Result.'+inspect.stack()[0][3]) + creator = util.edit_info('damask.Geom.'+inspect.stack()[0][3]) return Geom(microstructure.reshape(grid)+1,size,homogenization=1,comments=creator) @@ -458,8 +440,13 @@ class Geom: Compress geometry with 'x of y' and 'a to b'. """ - header = self.get_header() - grid = self.get_grid() + header = [f'{len(self.comments)+4} header'] + self.comments + header.append('grid a {} b {} c {}'.format(*self.get_grid())) + header.append('size x {} y {} z {}'.format(*self.get_size())) + header.append('origin x {} y {} z {}'.format(*self.get_origin())) + header.append(f'homogenization {self.get_homogenization()}') + + grid = self.get_grid() if pack is None: plain = grid.prod()/self.N_microstructure < 250 @@ -490,7 +477,7 @@ class Geom: reps += 1 else: if compressType is None: - f.write('\n'.join(self.get_header())+'\n') + f.write('\n'.join(header)+'\n') elif compressType == '.': f.write(f'{former}\n') elif compressType == 'to': @@ -589,7 +576,7 @@ class Geom: fill_ = np.full_like(self.microstructure,np.nanmax(self.microstructure)+1 if fill is None else fill) ms = np.ma.MaskedArray(fill_,np.logical_not(mask) if inverse else mask) - self.add_comments(util.edit_info('damask.Result.'+inspect.stack()[0][3])) + self.add_comments(util.edit_info('damask.Geom.'+inspect.stack()[0][3])) return self.update(ms) @@ -620,7 +607,7 @@ class Geom: if 'x' in directions: ms = np.concatenate([ms,ms[limits[0]:limits[1]:-1,:,:]],0) - self.add_comments(util.edit_info('damask.Result.'+inspect.stack()[0][3])) + self.add_comments(util.edit_info('damask.Geom.'+inspect.stack()[0][3])) return self.update(ms,rescale=True) @@ -636,7 +623,7 @@ class Geom: Assume geometry to be periodic. Defaults to True. """ - self.add_comments(util.edit_info('damask.Result.'+inspect.stack()[0][3])) + self.add_comments(util.edit_info('damask.Geom.'+inspect.stack()[0][3])) return self.update( ndimage.interpolation.zoom( self.microstructure, @@ -671,7 +658,7 @@ class Geom: else: return me - self.add_comments(util.edit_info('damask.Result.'+inspect.stack()[0][3])) + self.add_comments(util.edit_info('damask.Geom.'+inspect.stack()[0][3])) return self.update(ndimage.filters.generic_filter( self.microstructure, mostFrequent, @@ -688,7 +675,7 @@ class Geom: for i, oldID in enumerate(np.unique(self.microstructure)): renumbered = np.where(self.microstructure == oldID, i+1, renumbered) - self.add_comments(util.edit_info('damask.Result.'+inspect.stack()[0][3])) + self.add_comments(util.edit_info('damask.Geom.'+inspect.stack()[0][3])) return self.update(renumbered) @@ -723,7 +710,7 @@ class Geom: origin = self.origin-(np.asarray(microstructure_in.shape)-self.grid)*.5 * self.size/self.grid - self.add_comments(util.edit_info('damask.Result.'+inspect.stack()[0][3])) + self.add_comments(util.edit_info('damask.Geom.'+inspect.stack()[0][3])) return self.update(microstructure_in,origin=origin,rescale=True) @@ -756,7 +743,7 @@ class Geom: canvas[ll[0]:ur[0],ll[1]:ur[1],ll[2]:ur[2]] = self.microstructure[LL[0]:UR[0],LL[1]:UR[1],LL[2]:UR[2]] - self.add_comments(util.edit_info('damask.Result.'+inspect.stack()[0][3])) + self.add_comments(util.edit_info('damask.Geom.'+inspect.stack()[0][3])) return self.update(canvas,origin=self.origin+offset*self.size/self.grid,rescale=True) @@ -776,7 +763,7 @@ class Geom: for from_ms,to_ms in zip(from_microstructure,to_microstructure): substituted[self.microstructure==from_ms] = to_ms - self.add_comments(util.edit_info('damask.Result.'+inspect.stack()[0][3])) + self.add_comments(util.edit_info('damask.Geom.'+inspect.stack()[0][3])) return self.update(substituted) @@ -822,5 +809,5 @@ class Geom: extra_keywords={'trigger':trigger}) microstructure = np.ma.MaskedArray(self.microstructure + offset_, np.logical_not(mask)) - self.add_comments(util.edit_info('damask.Result.'+inspect.stack()[0][3])) + self.add_comments(util.edit_info('damask.Geom.'+inspect.stack()[0][3])) return self.update(microstructure) From b393da4955cefac766af183c5bd3d59182143de4 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Mon, 24 Aug 2020 07:28:10 +0200 Subject: [PATCH 63/73] relative imports ... it's all about damask.XXX --- python/tests/test_Orientation.py | 7 +++---- python/tests/test_Result.py | 7 ++++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/python/tests/test_Orientation.py b/python/tests/test_Orientation.py index 4987f1f1f..eb2ccfd56 100644 --- a/python/tests/test_Orientation.py +++ b/python/tests/test_Orientation.py @@ -4,7 +4,6 @@ from itertools import permutations import pytest import numpy as np -import damask from damask import Rotation from damask import Orientation from damask import Lattice @@ -68,7 +67,7 @@ class TestOrientation: {'label':'blue', 'RGB':[0,0,1],'direction':[1,1,1]}]) @pytest.mark.parametrize('lattice',['fcc','bcc']) def test_IPF_cubic(self,color,lattice): - cube = damask.Orientation(damask.Rotation(),lattice) + cube = Orientation(Rotation(),lattice) for direction in set(permutations(np.array(color['direction']))): assert np.allclose(cube.IPF_color(np.array(direction)),np.array(color['RGB'])) @@ -112,7 +111,7 @@ class TestOrientation: @pytest.mark.parametrize('lattice',Lattice.lattices) def test_disorientation360(self,lattice): R_1 = Orientation(Rotation(),lattice) - R_2 = Orientation(damask.Rotation.from_Eulers([360,0,0],degrees=True),lattice) + R_2 = Orientation(Rotation.from_Eulers([360,0,0],degrees=True),lattice) assert np.allclose(R_1.disorientation(R_2).as_matrix(),np.eye(3)) @pytest.mark.parametrize('lattice',Lattice.lattices) @@ -127,6 +126,6 @@ class TestOrientation: def test_from_average(self,lattice): R_1 = Orientation(Rotation.from_random(),lattice) eqs = [r for r in R_1.equivalent] - R_2 = damask.Orientation.from_average(eqs) + R_2 = Orientation.from_average(eqs) assert np.allclose(R_1.rotation.quaternion,R_2.rotation.quaternion) diff --git a/python/tests/test_Result.py b/python/tests/test_Result.py index 53bcdda9d..6000f50f9 100644 --- a/python/tests/test_Result.py +++ b/python/tests/test_Result.py @@ -8,8 +8,9 @@ import pytest import numpy as np import h5py -import damask from damask import Result +from damask import Rotation +from damask import Orientation from damask import mechanics from damask import grid_filters @@ -174,7 +175,7 @@ class TestResult: crystal_structure = default.get_crystal_structure() in_memory = np.empty((qu.shape[0],3),np.uint8) for i,q in enumerate(qu): - o = damask.Orientation(q,crystal_structure).reduced + o = Orientation(q,crystal_structure).reduced in_memory[i] = np.uint8(o.IPF_color(np.array(d))*255) in_file = default.read_dataset(loc['color']) assert np.allclose(in_memory,in_file) @@ -233,7 +234,7 @@ class TestResult: default.add_pole('orientation',pole,polar) loc = {'orientation': default.get_dataset_location('orientation'), 'pole': default.get_dataset_location('p^{}_[1 0 0)'.format(u'rφ' if polar else 'xy'))} - rot = damask.Rotation(default.read_dataset(loc['orientation']).view(np.double)) + rot = Rotation(default.read_dataset(loc['orientation']).view(np.double)) rotated_pole = rot * np.broadcast_to(pole,rot.shape+(3,)) xy = rotated_pole[:,0:2]/(1.+abs(pole[2])) in_memory = xy if not polar else \ From 9d505c851835eb648feb8c3dd32248cfb2a56a06 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Mon, 24 Aug 2020 09:55:41 +0200 Subject: [PATCH 64/73] better readable - more explicit reporting - always relative import for DAMASK --- python/damask/_colormap.py | 6 +++--- python/damask/_geom.py | 23 ++++++++++----------- python/damask/_vtk.py | 7 ++++--- python/damask/solver/_marc.py | 10 ++++----- python/damask/util.py | 10 +++++---- python/tests/conftest.py | 9 ++++++++ python/tests/reference/Colormap/binary.json | 2 +- python/tests/reference/Colormap/binary.txt | 2 +- python/tests/test_Colormap.py | 4 ++-- python/tests/test_Orientation.py | 5 +++-- 10 files changed, 45 insertions(+), 33 deletions(-) diff --git a/python/damask/_colormap.py b/python/damask/_colormap.py index ec4000018..e2b317d63 100644 --- a/python/damask/_colormap.py +++ b/python/damask/_colormap.py @@ -10,7 +10,7 @@ import matplotlib.pyplot as plt from matplotlib import cm from PIL import Image -import damask +from . import util from . import Table _eps = 216./24389. @@ -280,7 +280,7 @@ class Colormap(mpl.colors.ListedColormap): colors+=[i]+c out = [{ - 'Creator':f'damask.Colormap v{damask.version}', + 'Creator':util.version_date('Colormap'), 'ColorSpace':'RGB', 'Name':colormap.name, 'DefaultMap':True, @@ -296,7 +296,7 @@ class Colormap(mpl.colors.ListedColormap): def _export_ASCII(colormap,fhandle=None): """Write colormap to ASCII table.""" labels = {'RGBA':4} if colormap.colors.shape[1] == 4 else {'RGB': 3} - t = Table(colormap.colors,labels,f'Creator: damask.Colormap v{damask.version}') + t = Table(colormap.colors,labels,f'Creator: {util.version_date("Colormap")}') if fhandle is None: with open(colormap.name.replace(' ','_')+'.txt', 'w') as f: diff --git a/python/damask/_geom.py b/python/damask/_geom.py index 17cd49b08..6632eb5ed 100644 --- a/python/damask/_geom.py +++ b/python/damask/_geom.py @@ -1,6 +1,5 @@ import sys import copy -import inspect import multiprocessing from io import StringIO from functools import partial @@ -399,7 +398,7 @@ class Geom: else: microstructure = microstructure.reshape(grid) - creator = util.edit_info('damask.Geom.'+inspect.stack()[0][3]) + creator = util.version_date('Geom','from_Laguerre_tessellation') return Geom(microstructure+1,size,homogenization=1,comments=creator) @@ -424,7 +423,7 @@ class Geom: KDTree = spatial.cKDTree(seeds,boxsize=size) if periodic else spatial.cKDTree(seeds) devNull,microstructure = KDTree.query(coords) - creator = util.edit_info('damask.Geom.'+inspect.stack()[0][3]) + creator = util.version_date('Geom','from_Voronoi_tessellation') return Geom(microstructure.reshape(grid)+1,size,homogenization=1,comments=creator) @@ -576,7 +575,7 @@ class Geom: fill_ = np.full_like(self.microstructure,np.nanmax(self.microstructure)+1 if fill is None else fill) ms = np.ma.MaskedArray(fill_,np.logical_not(mask) if inverse else mask) - self.add_comments(util.edit_info('damask.Geom.'+inspect.stack()[0][3])) + self.add_comments(util.version_date('Geom','add_primitive')) return self.update(ms) @@ -607,7 +606,7 @@ class Geom: if 'x' in directions: ms = np.concatenate([ms,ms[limits[0]:limits[1]:-1,:,:]],0) - self.add_comments(util.edit_info('damask.Geom.'+inspect.stack()[0][3])) + self.add_comments(util.version_date('Geom','mirror')) return self.update(ms,rescale=True) @@ -623,7 +622,7 @@ class Geom: Assume geometry to be periodic. Defaults to True. """ - self.add_comments(util.edit_info('damask.Geom.'+inspect.stack()[0][3])) + self.add_comments(util.version_date('Geom','scale')) return self.update( ndimage.interpolation.zoom( self.microstructure, @@ -658,7 +657,7 @@ class Geom: else: return me - self.add_comments(util.edit_info('damask.Geom.'+inspect.stack()[0][3])) + self.add_comments(util.version_date('Geom','clean')) return self.update(ndimage.filters.generic_filter( self.microstructure, mostFrequent, @@ -675,7 +674,7 @@ class Geom: for i, oldID in enumerate(np.unique(self.microstructure)): renumbered = np.where(self.microstructure == oldID, i+1, renumbered) - self.add_comments(util.edit_info('damask.Geom.'+inspect.stack()[0][3])) + self.add_comments(util.version_date('Geom','renumber')) return self.update(renumbered) @@ -710,7 +709,7 @@ class Geom: origin = self.origin-(np.asarray(microstructure_in.shape)-self.grid)*.5 * self.size/self.grid - self.add_comments(util.edit_info('damask.Geom.'+inspect.stack()[0][3])) + self.add_comments(util.version_date('Geom','rotate')) return self.update(microstructure_in,origin=origin,rescale=True) @@ -743,7 +742,7 @@ class Geom: canvas[ll[0]:ur[0],ll[1]:ur[1],ll[2]:ur[2]] = self.microstructure[LL[0]:UR[0],LL[1]:UR[1],LL[2]:UR[2]] - self.add_comments(util.edit_info('damask.Geom.'+inspect.stack()[0][3])) + self.add_comments(util.version_date('Geom','canvas')) return self.update(canvas,origin=self.origin+offset*self.size/self.grid,rescale=True) @@ -763,7 +762,7 @@ class Geom: for from_ms,to_ms in zip(from_microstructure,to_microstructure): substituted[self.microstructure==from_ms] = to_ms - self.add_comments(util.edit_info('damask.Geom.'+inspect.stack()[0][3])) + self.add_comments(util.version_date('Geom','substitute')) return self.update(substituted) @@ -809,5 +808,5 @@ class Geom: extra_keywords={'trigger':trigger}) microstructure = np.ma.MaskedArray(self.microstructure + offset_, np.logical_not(mask)) - self.add_comments(util.edit_info('damask.Geom.'+inspect.stack()[0][3])) + self.add_comments(util.version_date('Geom','vicinity_offset')) return self.update(microstructure) diff --git a/python/damask/_vtk.py b/python/damask/_vtk.py index 52dd52754..349e158ca 100644 --- a/python/damask/_vtk.py +++ b/python/damask/_vtk.py @@ -8,7 +8,8 @@ from vtk.util.numpy_support import numpy_to_vtk as np_to_vtk from vtk.util.numpy_support import numpy_to_vtkIdTypeArray as np_to_vtkIdTypeArray from vtk.util.numpy_support import vtk_to_numpy as vtk_to_np -import damask +from . import util +from . import environment from . import Table @@ -314,7 +315,7 @@ class VTK: def __repr__(self): """ASCII representation of the VTK data.""" writer = vtk.vtkDataSetWriter() - writer.SetHeader(f'# damask.VTK v{damask.version}') + writer.SetHeader(f'# {util.version_date("VTK")}') writer.WriteToOutputStringOn() writer.SetInputData(self.geom) writer.Write() @@ -340,7 +341,7 @@ class VTK: ren.AddActor(actor) ren.SetBackground(0.2,0.2,0.2) - window.SetSize(damask.environment.screen_size[0],damask.environment.screen_size[1]) + window.SetSize(environment.screen_size[0],environment.screen_size[1]) iren = vtk.vtkRenderWindowInteractor() iren.SetRenderWindow(window) diff --git a/python/damask/solver/_marc.py b/python/damask/solver/_marc.py index 8e96f1b90..12e36f7ed 100644 --- a/python/damask/solver/_marc.py +++ b/python/damask/solver/_marc.py @@ -3,12 +3,12 @@ import shlex import string from pathlib import Path -import damask +from .. import environment class Marc: """Wrapper to run DAMASK with MSCMarc.""" - def __init__(self,version=damask.environment.options['MARC_VERSION']): + def __init__(self,version=environment.options['MARC_VERSION']): """ Create a Marc solver object. @@ -24,7 +24,7 @@ class Marc: @property def library_path(self): - path_MSC = damask.environment.options['MSC_ROOT'] + path_MSC = environment.options['MSC_ROOT'] path_lib = Path(f'{path_MSC}/mentat{self.version}/shlib/linux64') return path_lib if path_lib.is_dir() else None @@ -33,7 +33,7 @@ class Marc: @property def tools_path(self): - path_MSC = damask.environment.options['MSC_ROOT'] + path_MSC = environment.options['MSC_ROOT'] path_tools = Path(f'{path_MSC}/marc{self.version}/tools') return path_tools if path_tools.is_dir() else None @@ -49,7 +49,7 @@ class Marc: ): - usersub = damask.environment.root_dir/'src/DAMASK_marc' + usersub = environment.root_dir/'src/DAMASK_marc' usersub = usersub.parent/(usersub.name + ('.f90' if compile else '.marc')) if not usersub.is_file(): raise FileNotFoundError("DAMASK4Marc ({}) '{}' not found".format(('source' if compile else 'binary'),usersub)) diff --git a/python/damask/util.py b/python/damask/util.py index f83fc4c62..f7c40416e 100644 --- a/python/damask/util.py +++ b/python/damask/util.py @@ -9,7 +9,7 @@ from optparse import Option import numpy as np -import damask +from . import version # limit visibility __all__=[ @@ -22,7 +22,7 @@ __all__=[ 'scale_to_coprime', 'return_message', 'extendableOption', - 'edit_info' + 'version_date' ] #################################################################################################### @@ -178,9 +178,11 @@ def scale_to_coprime(v): return m -def edit_info(who): +def version_date(class_name,function_name=None): + """tbd.""" + _function_name = '' if function_name is None else f'.{function_name}' now = datetime.datetime.now().astimezone().strftime('%Y-%m-%d %H:%M:%S%z') - return f'{who} v{damask.version} ({now})' + return f'damask.{class_name}{_function_name} v{version} ({now})' #################################################################################################### diff --git a/python/tests/conftest.py b/python/tests/conftest.py index 2912373a5..51da90671 100644 --- a/python/tests/conftest.py +++ b/python/tests/conftest.py @@ -25,6 +25,15 @@ def patch_datetime_now(monkeypatch): monkeypatch.setattr(datetime, 'datetime', mydatetime) +@pytest.fixture +def version_date(monkeypatch): + """Set damask.util.version_date for reproducible tests results.""" + def version_date(class_name,function_name=None): + _function_name = '' if function_name is None else f'.{function_name}' + return f'damask.{class_name}{_function_name} v{patched_version} ({patched_date})' + + monkeypatch.setattr(damask.util, 'version_date', version_date) + def pytest_addoption(parser): parser.addoption("--update", diff --git a/python/tests/reference/Colormap/binary.json b/python/tests/reference/Colormap/binary.json index c71d3649b..b8b85f80f 100644 --- a/python/tests/reference/Colormap/binary.json +++ b/python/tests/reference/Colormap/binary.json @@ -1,6 +1,6 @@ [ { - "Creator": "damask.Colormap v99.99.99-9999-pytest", + "Creator": "damask.Colormap v99.99.99-9999-pytest (2019-11-02 11:58:00)", "ColorSpace": "RGB", "Name": "binary", "DefaultMap": true, diff --git a/python/tests/reference/Colormap/binary.txt b/python/tests/reference/Colormap/binary.txt index 976c0202a..ca1d2401f 100644 --- a/python/tests/reference/Colormap/binary.txt +++ b/python/tests/reference/Colormap/binary.txt @@ -1,4 +1,4 @@ -# Creator: damask.Colormap v99.99.99-9999-pytest +# Creator: damask.Colormap v99.99.99-9999-pytest (2019-11-02 11:58:00) 1_RGBA 2_RGBA 3_RGBA 4_RGBA 1.0 1.0 1.0 1.0 0.996078431372549 0.996078431372549 0.996078431372549 1.0 diff --git a/python/tests/test_Colormap.py b/python/tests/test_Colormap.py index d3f5e45c8..870ff9761 100644 --- a/python/tests/test_Colormap.py +++ b/python/tests/test_Colormap.py @@ -17,8 +17,8 @@ def reference_dir(reference_dir_base): class TestColormap: @pytest.fixture(autouse=True) - def _patch_damask_version(self, patch_damask_version): - print('patched damask.version') + def _version_date(self, version_date): + print('patched damask.util.version_date') def test_conversion(self): specials = np.array([[0.,0.,0.], diff --git a/python/tests/test_Orientation.py b/python/tests/test_Orientation.py index eb2ccfd56..636eeb0c4 100644 --- a/python/tests/test_Orientation.py +++ b/python/tests/test_Orientation.py @@ -4,6 +4,7 @@ from itertools import permutations import pytest import numpy as np +from damask import Table from damask import Rotation from damask import Orientation from damask import Lattice @@ -103,10 +104,10 @@ class TestOrientation: eu = np.array([o.rotation.as_Eulers(degrees=True) for o in ori.related(model)]) if update: coords = np.array([(1,i+1) for i,x in enumerate(eu)]) - table = damask.Table(eu,{'Eulers':(3,)}) + table = Table(eu,{'Eulers':(3,)}) table.add('pos',coords) table.to_ASCII(reference) - assert np.allclose(eu,damask.Table.from_ASCII(reference).get('Eulers')) + assert np.allclose(eu,Table.from_ASCII(reference).get('Eulers')) @pytest.mark.parametrize('lattice',Lattice.lattices) def test_disorientation360(self,lattice): From 279d43ccc64d79137805a9e75edc3e0d7b2259ba Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Mon, 24 Aug 2020 19:04:59 +0200 Subject: [PATCH 65/73] include version info + date in comments (Table class) --- python/damask/_table.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/python/damask/_table.py b/python/damask/_table.py index e8d35c545..b4822bea9 100644 --- a/python/damask/_table.py +++ b/python/damask/_table.py @@ -3,7 +3,6 @@ import re import pandas as pd import numpy as np -from . import version from . import util class Table: @@ -49,7 +48,9 @@ class Table: def _add_comment(self,label,shape,info): if info is not None: - self.comments.append(f'{label}{" "+str(shape) if np.prod(shape,dtype=int) > 1 else ""}: {info}') + specific = f'{label}{" "+str(shape) if np.prod(shape,dtype=int) > 1 else ""}: {info}' + general = util.version_date('Table') + self.comments.append(f'{specific} / {general}') @staticmethod @@ -135,7 +136,7 @@ class Table: content = f.readlines() - comments = [f'table.py:from_ang v{version}'] + comments = [util.version_date('Table','from_ang')] for line in content: if line.startswith('#'): comments.append(line.strip()) From 8ef473b71c029d66ac4218d129747ed69875f717 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Mon, 24 Aug 2020 19:22:53 +0200 Subject: [PATCH 66/73] new names in output - constituent -> phase - materialpoint -> homogenization this gives a one-to-one correspondence to the material.yaml definition next steps 1) adjust damask.Result python class 2) implement materialpoint output (homogeneous over the whole domain) for homogenized quantities (currently T,F,P,phi) --- src/results.f90 | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/results.f90 b/src/results.f90 index 45c6263e4..793d6bd3a 100644 --- a/src/results.f90 +++ b/src/results.f90 @@ -118,8 +118,14 @@ 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/constituent')) - call results_closeGroup(results_addGroup('current/materialpoint')) + call results_closeGroup(results_addGroup('current/phase')) + call results_closeGroup(results_addGroup('current/homogenization')) + + ! for backward compatibility + call results_setLink(trim('/inc'//trim(adjustl(incChar)))//'/phase',& + trim('/inc'//trim(adjustl(incChar)))//'/constituent') + call results_setLink(trim('/inc'//trim(adjustl(incChar)))//'/homogenization',& + trim('/inc'//trim(adjustl(incChar)))//'/materialpoint') end subroutine results_addIncrement @@ -182,7 +188,6 @@ subroutine results_setLink(path,link) end subroutine results_setLink - !-------------------------------------------------------------------------------------------------- !> @brief adds a string attribute to an object in the results file !-------------------------------------------------------------------------------------------------- From 55443a3ff5b3e17b394d2ff141478015ce535d5a Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Mon, 24 Aug 2020 22:54:09 +0200 Subject: [PATCH 67/73] reflect change of variable names in file layout version --- python/damask/_result.py | 2 +- src/results.f90 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/python/damask/_result.py b/python/damask/_result.py index bf3ee67b9..8e5bb2e8b 100644 --- a/python/damask/_result.py +++ b/python/damask/_result.py @@ -49,7 +49,7 @@ class Result: self.version_major = f.attrs['DADF5-major'] self.version_minor = f.attrs['DADF5-minor'] - if self.version_major != 0 or not 2 <= self.version_minor <= 6: + if self.version_major != 0 or not 2 <= self.version_minor <= 7: raise TypeError(f'Unsupported DADF5 version {self.version_major}.{self.version_minor}') self.structured = 'grid' in f['geometry'].attrs.keys() diff --git a/src/results.f90 b/src/results.f90 index 793d6bd3a..3999a396c 100644 --- a/src/results.f90 +++ b/src/results.f90 @@ -73,7 +73,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',6) + call results_addAttribute('DADF5_version_minor',7) call results_addAttribute('DAMASK_version',DAMASKVERSION) call get_command(commandLine) call results_addAttribute('call',trim(commandLine)) From 4fe4190ee0131cd5249959fa09ea676ccc94ca98 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Tue, 25 Aug 2020 11:02:51 +0200 Subject: [PATCH 68/73] mapping renamed now we have two mappings, 'phase' and 'homogenization'. They `unwind` the definition in 'materialpoint' in 'material.yaml'. Since we never introduced the inverse mapping, I have removed the cellResults subfolder. --- src/results.f90 | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/results.f90 b/src/results.f90 index 3999a396c..2e5b01937 100644 --- a/src/results.f90 +++ b/src/results.f90 @@ -613,8 +613,8 @@ subroutine results_mapping_constituent(phaseAt,memberAtLocal,label) ! write the components of the compound type individually call h5pset_preserve_f(plist_id, .TRUE., ierr) - loc_id = results_openGroup('/mapping/cellResults') - call h5dcreate_f(loc_id, 'constituent', dtype_id, filespace_id, dset_id, ierr) + loc_id = results_openGroup('/mapping') + call h5dcreate_f(loc_id, 'phase', dtype_id, filespace_id, dset_id, ierr) if (ierr < 0) call IO_error(1,ext_msg='results_mapping_constituent: h5dcreate_f') call h5dwrite_f(dset_id, name_id, reshape(label(pack(phaseAtMaterialpoint,.true.)),myShape), & @@ -635,6 +635,9 @@ subroutine results_mapping_constituent(phaseAt,memberAtLocal,label) call h5tclose_f(name_id, ierr) call h5tclose_f(position_id, ierr) + ! for backward compatibility + call results_setLink('/mapping/phase','/mapping/cellResults/constituent') + end subroutine results_mapping_constituent @@ -748,8 +751,8 @@ subroutine results_mapping_materialpoint(homogenizationAt,memberAtLocal,label) ! write the components of the compound type individually call h5pset_preserve_f(plist_id, .TRUE., ierr) - loc_id = results_openGroup('/mapping/cellResults') - call h5dcreate_f(loc_id, 'materialpoint', dtype_id, filespace_id, dset_id, ierr) + loc_id = results_openGroup('/mapping') + call h5dcreate_f(loc_id, 'homogenization', dtype_id, filespace_id, dset_id, ierr) if (ierr < 0) call IO_error(1,ext_msg='results_mapping_materialpoint: h5dcreate_f') call h5dwrite_f(dset_id, name_id, reshape(label(pack(homogenizationAtMaterialpoint,.true.)),myShape), & @@ -770,6 +773,9 @@ subroutine results_mapping_materialpoint(homogenizationAt,memberAtLocal,label) call h5tclose_f(name_id, ierr) call h5tclose_f(position_id, ierr) + ! for backward compatibility + call results_setLink('/mapping/homogenization','/mapping/cellResults/materialpoint') + end subroutine results_mapping_materialpoint From cbf402c1a4c47797b06033cf76b4d0588df318e1 Mon Sep 17 00:00:00 2001 From: Test User Date: Tue, 25 Aug 2020 23:06:46 +0200 Subject: [PATCH 69/73] [skip ci] updated version information after successful test of v3.0.0-alpha-22-gcdc9f078 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index a8dd6cb0f..686de838c 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v3.0.0-alpha-3-g2b09a7d3 +v3.0.0-alpha-22-gcdc9f078 From e3f310fa16da4d071149cc07158439311bae4378 Mon Sep 17 00:00:00 2001 From: Test User Date: Wed, 26 Aug 2020 15:05:04 +0200 Subject: [PATCH 70/73] [skip ci] updated version information after successful test of v3.0.0-alpha-27-g68c2908b --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 686de838c..9aba6acf5 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v3.0.0-alpha-22-gcdc9f078 +v3.0.0-alpha-27-g68c2908b From 06b524d13e267aeb88715e7d8ee7f4670f6c3c60 Mon Sep 17 00:00:00 2001 From: Philip Eisenlohr Date: Wed, 26 Aug 2020 21:39:20 +0200 Subject: [PATCH 71/73] added 'iso' as possible lattice (with no symmetry) --- python/damask/_lattice.py | 1 + 1 file changed, 1 insertion(+) diff --git a/python/damask/_lattice.py b/python/damask/_lattice.py index 9df451c69..da8f76b64 100644 --- a/python/damask/_lattice.py +++ b/python/damask/_lattice.py @@ -321,6 +321,7 @@ class Lattice: # ToDo: Make a subclass of Symmetry! """ lattices = { + 'iso': {'system':None}, 'triclinic':{'system':None}, 'bct': {'system':'tetragonal'}, 'hex': {'system':'hexagonal'}, From b9f1421c6bd9c8edd06d542e041fbd7f1f8a63dd Mon Sep 17 00:00:00 2001 From: Philip Eisenlohr Date: Wed, 26 Aug 2020 17:27:08 -0400 Subject: [PATCH 72/73] [skip ci] removed unnecessary line continuations "\" --- python/damask/_lattice.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/python/damask/_lattice.py b/python/damask/_lattice.py index da8f76b64..143fa50f1 100644 --- a/python/damask/_lattice.py +++ b/python/damask/_lattice.py @@ -164,16 +164,16 @@ class Symmetry: with np.errstate(invalid='ignore'): # using '*'/prod for 'and' if self.system == 'cubic': - return np.where(np.prod(np.sqrt(2)-1. >= rho_abs,axis=-1) * \ + return np.where(np.prod(np.sqrt(2)-1. >= rho_abs,axis=-1) * (1. >= np.sum(rho_abs,axis=-1)),True,False) elif self.system == 'hexagonal': - return np.where(np.prod(1. >= rho_abs,axis=-1) * \ - (2. >= np.sqrt(3)*rho_abs[...,0] + rho_abs[...,1]) * \ - (2. >= np.sqrt(3)*rho_abs[...,1] + rho_abs[...,0]) * \ + return np.where(np.prod(1. >= rho_abs,axis=-1) * + (2. >= np.sqrt(3)*rho_abs[...,0] + rho_abs[...,1]) * + (2. >= np.sqrt(3)*rho_abs[...,1] + rho_abs[...,0]) * (2. >= np.sqrt(3) + rho_abs[...,2]),True,False) elif self.system == 'tetragonal': - return np.where(np.prod(1. >= rho_abs[...,:2],axis=-1) * \ - (np.sqrt(2) >= rho_abs[...,0] + rho_abs[...,1]) * \ + return np.where(np.prod(1. >= rho_abs[...,:2],axis=-1) * + (np.sqrt(2) >= rho_abs[...,0] + rho_abs[...,1]) * (np.sqrt(2) >= rho_abs[...,2] + 1.),True,False) elif self.system == 'orthorhombic': return np.where(np.prod(1. >= rho_abs,axis=-1),True,False) From c5761831e23d17ac7cabed63ef646371bff951ec Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Thu, 27 Aug 2020 00:14:37 +0200 Subject: [PATCH 73/73] more meaningful message if add_xxx (Results) does not find matching datasets, inform the user about this fact instead of saying TypeError: object of type 'IMapUnorderedIterator' has no len() --- python/damask/_result.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/python/damask/_result.py b/python/damask/_result.py index 8e5bb2e8b..2ada4cd01 100644 --- a/python/damask/_result.py +++ b/python/damask/_result.py @@ -1065,6 +1065,10 @@ class Result: lock = mp.Manager().Lock() groups = self.groups_with_datasets(datasets.values()) + if len(groups) == 0: + print('No matching dataset found, no data was added.') + return + default_arg = partial(self._job,func=func,datasets=datasets,args=args,lock=lock) for result in util.show_progress(pool.imap_unordered(default_arg,groups),len(groups)):