diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 0f313bae4..e9784da71 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -102,13 +102,6 @@ processing: - master - release -################################################################################################### -preprocessing_deprecated: - stage: python - script: PreProcessing/test.py - except: - - master - - release ################################################################################################### compile_grid_Intel: diff --git a/CMakeLists.txt b/CMakeLists.txt index ceddd8c53..8409aadb2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required (VERSION 3.10.0) +cmake_minimum_required (VERSION 3.12.0) include (FindPkgConfig REQUIRED) if (DEFINED ENV{PETSC_DIR}) @@ -31,6 +31,7 @@ message ("\nBuilding ${CMAKE_PROJECT_NAME} ${DAMASK_VERSION}\n") add_definitions (-DPETSC) add_definitions (-DDAMASKVERSION="${DAMASK_VERSION}") +add_definitions (-DCMAKE_SYSTEM="${CMAKE_SYSTEM}") if (CMAKE_BUILD_TYPE STREQUAL "") set (CMAKE_BUILD_TYPE "RELEASE") diff --git a/DAMASK_prerequisites.sh b/DAMASK_prerequisites.sh index f0ae484e4..cff211cdb 100755 --- a/DAMASK_prerequisites.sh +++ b/DAMASK_prerequisites.sh @@ -74,7 +74,7 @@ echo PETSC_ARCH: $PETSC_ARCH echo PETSC_DIR: $PETSC_DIR echo echo $PETSC_DIR/$PETSC_ARCH/lib: -/s $PETSC_DIR/$PETSC_ARCH/lib +ls $PETSC_DIR/$PETSC_ARCH/lib echo echo $PETSC_DIR/$PETSC_ARCH/lib/petsc/conf/petscvariables: cat $PETSC_DIR/$PETSC_ARCH/lib/petsc/conf/petscvariables diff --git a/PRIVATE b/PRIVATE index 6037ed541..36ac61cae 160000 --- a/PRIVATE +++ b/PRIVATE @@ -1 +1 @@ -Subproject commit 6037ed541710fc84699ee2ca1d36a69d7fa20f0f +Subproject commit 36ac61caef1eec1ac68cadbed1a8f6f07a035f54 diff --git a/python/damask/_config.py b/python/damask/_config.py index 296ea2eee..7b2023a47 100644 --- a/python/damask/_config.py +++ b/python/damask/_config.py @@ -146,12 +146,6 @@ class Config(dict): if 'sort_keys' not in kwargs: kwargs['sort_keys'] = False - def array_representer(dumper, data): - """Convert numpy array to list of native types.""" - return dumper.represent_list([d.item() for d in data]) - - NiceDumper.add_representer(np.ndarray, array_representer) - try: fhandle.write(yaml.dump(self,Dumper=NiceDumper,**kwargs)) except TypeError: # compatibility with old pyyaml diff --git a/python/damask/_result.py b/python/damask/_result.py index 9b4abd342..141b795c2 100644 --- a/python/damask/_result.py +++ b/python/damask/_result.py @@ -567,9 +567,13 @@ class Result: formula = kwargs['formula'] for d in re.findall(r'#(.*?)#',formula): formula = formula.replace(f'#{d}#',f"kwargs['{d}']['data']") + data = eval(formula) + + if not hasattr(data,'shape') or data.shape[0] != kwargs[d]['data'].shape[0]: + raise ValueError("'{}' results in invalid shape".format(kwargs['formula'])) return { - 'data': eval(formula), + 'data': data, 'label': kwargs['label'], 'meta': { 'unit': kwargs['unit'], @@ -1258,7 +1262,7 @@ class Result: Arguments parsed to func. """ - if len(datasets) != 1 or self.N_constituents !=1: + if len(datasets) != 1 or self.N_constituents != 1: raise NotImplementedError at_cell_ph,in_data_ph,at_cell_ho,in_data_ho = self._mappings() diff --git a/python/damask/mechanics.py b/python/damask/mechanics.py index c8519abad..0e160523b 100644 --- a/python/damask/mechanics.py +++ b/python/damask/mechanics.py @@ -257,18 +257,18 @@ def _polar_decomposition(T,requested): u, _, vh = _np.linalg.svd(T) R = _np.einsum('...ij,...jk',u,vh) - output = [] + output = () if 'R' in requested: - output.append(R) + output+=(R,) if 'V' in requested: - output.append(_np.einsum('...ij,...kj',T,R)) + output+=(_np.einsum('...ij,...kj',T,R),) if 'U' in requested: - output.append(_np.einsum('...ji,...jk',R,T)) + output+=(_np.einsum('...ji,...jk',R,T),) if len(output) == 0: raise ValueError('output needs to be out of V, R, U') - return tuple(output) + return output def _equivalent_Mises(T_sym,s): diff --git a/python/setup.py b/python/setup.py index ff22c1640..c8026ce17 100644 --- a/python/setup.py +++ b/python/setup.py @@ -23,7 +23,7 @@ setuptools.setup( 'h5py>=2.9', # requires numpy 'vtk>=8.1', 'matplotlib>=3.0', # requires numpy, pillow - 'pyaml>=3.12' + 'pyyaml>=3.12' ], classifiers = [ 'Intended Audience :: Science/Research', diff --git a/python/tests/reference/Result/12grains6x7x8_tensionY.hdf5 b/python/tests/reference/Result/12grains6x7x8_tensionY.hdf5 index 1d914f8bb..6cfc9b4b4 100644 Binary files a/python/tests/reference/Result/12grains6x7x8_tensionY.hdf5 and b/python/tests/reference/Result/12grains6x7x8_tensionY.hdf5 differ diff --git a/python/tests/reference/Result/4grains2x4x3_compressionY.hdf5 b/python/tests/reference/Result/4grains2x4x3_compressionY.hdf5 index c3520c27e..369cab8fc 100644 Binary files a/python/tests/reference/Result/4grains2x4x3_compressionY.hdf5 and b/python/tests/reference/Result/4grains2x4x3_compressionY.hdf5 differ diff --git a/python/tests/reference/Result/6grains6x7x8_single_phase_tensionY.hdf5 b/python/tests/reference/Result/6grains6x7x8_single_phase_tensionY.hdf5 index 44410447b..bab0b0ead 100644 Binary files a/python/tests/reference/Result/6grains6x7x8_single_phase_tensionY.hdf5 and b/python/tests/reference/Result/6grains6x7x8_single_phase_tensionY.hdf5 differ diff --git a/python/tests/reference/Result/compressionY.yaml b/python/tests/reference/Result/compressionY.yaml index cfe67e692..285002c88 100644 --- a/python/tests/reference/Result/compressionY.yaml +++ b/python/tests/reference/Result/compressionY.yaml @@ -5,12 +5,12 @@ solver: loadstep: - boundary_conditions: mechanical: - dot_F: [x, 0, 0, - 0, -1.0e-3, 0, - 0, 0, x] - P: [0, x, x, - x, x, x, - x, x, 0] + dot_F: [[x, 0, 0], + [0, -1.0e-3, 0], + [0, 0, x]] + P: [[0, x, x], + [x, x, x], + [x, x, 0]] discretization: t: 5 N: 10 diff --git a/python/tests/reference/Result/export_VTK/test_vtk[0-0-0].md5 b/python/tests/reference/Result/export_VTK/test_vtk[0-0-0].md5 index 6999a9d31..a2f05f385 100644 --- a/python/tests/reference/Result/export_VTK/test_vtk[0-0-0].md5 +++ b/python/tests/reference/Result/export_VTK/test_vtk[0-0-0].md5 @@ -1 +1 @@ -d5db0be324a959f00245e42704ea2d6f \ No newline at end of file +a40baead936c79dd4f86f84ad858b9fa \ No newline at end of file diff --git a/python/tests/reference/Result/export_VTK/test_vtk[0-0-1].md5 b/python/tests/reference/Result/export_VTK/test_vtk[0-0-1].md5 index 5a716bce5..3269636ae 100644 --- a/python/tests/reference/Result/export_VTK/test_vtk[0-0-1].md5 +++ b/python/tests/reference/Result/export_VTK/test_vtk[0-0-1].md5 @@ -1 +1 @@ -fe9ddaf54ac1fb785094251d29fcdc9c \ No newline at end of file +6fb37bd65934de859dd6b6e0191e7d64 \ No newline at end of file diff --git a/python/tests/reference/Result/export_VTK/test_vtk[0-0-2].md5 b/python/tests/reference/Result/export_VTK/test_vtk[0-0-2].md5 index 74d0f4fdb..02963e9c3 100644 --- a/python/tests/reference/Result/export_VTK/test_vtk[0-0-2].md5 +++ b/python/tests/reference/Result/export_VTK/test_vtk[0-0-2].md5 @@ -1 +1 @@ -9c8ac0bb1eb4a7b9ebc3e5fd5840b0a4 \ No newline at end of file +61953c35f61f3234b98d78a912e7dc83 \ No newline at end of file diff --git a/python/tests/reference/Result/export_VTK/test_vtk[0-0-3].md5 b/python/tests/reference/Result/export_VTK/test_vtk[0-0-3].md5 new file mode 100644 index 000000000..8555f7692 --- /dev/null +++ b/python/tests/reference/Result/export_VTK/test_vtk[0-0-3].md5 @@ -0,0 +1 @@ +bb783bb80ff04dd435e814f4b82a3234 \ No newline at end of file diff --git a/python/tests/reference/Result/export_VTK/test_vtk[1-0-0].md5 b/python/tests/reference/Result/export_VTK/test_vtk[1-0-0].md5 index 71aef9af6..bc19a978c 100644 --- a/python/tests/reference/Result/export_VTK/test_vtk[1-0-0].md5 +++ b/python/tests/reference/Result/export_VTK/test_vtk[1-0-0].md5 @@ -1 +1 @@ -1b9ebd17c5257e2edba48d006f25d4e6 \ No newline at end of file +4f85d2613aa70622a2d5f49dc8bf2eb2 \ No newline at end of file diff --git a/python/tests/reference/Result/export_VTK/test_vtk[1-0-1].md5 b/python/tests/reference/Result/export_VTK/test_vtk[1-0-1].md5 index 030d7a406..4afdb0aa7 100644 --- a/python/tests/reference/Result/export_VTK/test_vtk[1-0-1].md5 +++ b/python/tests/reference/Result/export_VTK/test_vtk[1-0-1].md5 @@ -1 +1 @@ -8967bb1a6c329a072baaa83da534ae56 \ No newline at end of file +e1ca5306082fc3ab411f5ddab1a2e370 \ No newline at end of file diff --git a/python/tests/reference/Result/export_VTK/test_vtk[1-0-2].md5 b/python/tests/reference/Result/export_VTK/test_vtk[1-0-2].md5 index 78426bbca..4cc41cf7e 100644 --- a/python/tests/reference/Result/export_VTK/test_vtk[1-0-2].md5 +++ b/python/tests/reference/Result/export_VTK/test_vtk[1-0-2].md5 @@ -1 +1 @@ -752e8b6186ad2b6b1b5c781940669cb1 \ No newline at end of file +1641c3b3641e942ffc325d471bdfaf00 \ No newline at end of file diff --git a/python/tests/reference/Result/export_VTK/test_vtk[1-0-3].md5 b/python/tests/reference/Result/export_VTK/test_vtk[1-0-3].md5 new file mode 100644 index 000000000..61ad31564 --- /dev/null +++ b/python/tests/reference/Result/export_VTK/test_vtk[1-0-3].md5 @@ -0,0 +1 @@ +ba97286c5d95bf817143f7bb9cf58421 \ No newline at end of file diff --git a/python/tests/reference/Result/tensionY.yaml b/python/tests/reference/Result/tensionY.yaml index 7b1d8ca43..5db88ce89 100644 --- a/python/tests/reference/Result/tensionY.yaml +++ b/python/tests/reference/Result/tensionY.yaml @@ -5,12 +5,12 @@ solver: loadstep: - boundary_conditions: mechanical: - dot_F: [x, 0, 0, - 0, 1.0e-3, 0, - 0, 0, x] - P: [0, x, x, - x, x, x, - x, x, 0] + dot_F: [[x, 0, 0], + [0, 1.0e-3, 0], + [0, 0, x]] + P: [[0, x, x], + [x, x, x], + [x, x, 0]] discretization: t: 20 N: 40 diff --git a/python/tests/test_Crystal.py b/python/tests/test_Crystal.py index 5481003c9..8b5217f63 100644 --- a/python/tests/test_Crystal.py +++ b/python/tests/test_Crystal.py @@ -1,10 +1,20 @@ import pytest import numpy as np +import damask from damask import Crystal class TestCrystal: + @pytest.mark.parametrize('lattice,family',[('aP','cubic'),('xI','cubic')]) + def test_invalid_init(self,lattice,family): + with pytest.raises(KeyError): + Crystal(family=family,lattice=lattice) + + def test_eq(self): + family = np.random.choice(list(damask._crystal.lattice_symmetries.values())) + assert Crystal(family=family) == Crystal(family=family) + def test_double_to_lattice(self): c = Crystal(lattice='cF') with pytest.raises(KeyError): @@ -55,3 +65,4 @@ class TestCrystal: alpha=alpha,beta=beta,gamma=gamma) assert np.allclose(vector, c.to_frame(**{keyFrame:c.to_lattice(**{keyLattice:vector})})) + diff --git a/python/tests/test_Result.py b/python/tests/test_Result.py index b597a67b7..6c06e8636 100644 --- a/python/tests/test_Result.py +++ b/python/tests/test_Result.py @@ -13,6 +13,7 @@ import numpy as np from damask import Result from damask import Orientation +from damask import VTK from damask import tensor from damask import mechanics from damask import grid_filters @@ -106,7 +107,8 @@ class TestResult: in_file = default.place('|F_e|') assert np.allclose(in_memory,in_file) - @pytest.mark.parametrize('mode',['direct','function']) + @pytest.mark.parametrize('mode', + ['direct',pytest.param('function',marks=pytest.mark.xfail(sys.platform=="darwin",reason='n/a'))]) def test_add_calculation(self,default,tmp_path,mode): if mode == 'direct': @@ -123,6 +125,10 @@ class TestResult: in_file = default.place('x') assert np.allclose(in_memory,in_file) + def test_add_calculation_invalid(self,default): + default.add_calculation('np.linalg.norm(#F#,axis=0)','wrong_dim') + assert default.get('wrong_dim') is None + def test_add_stress_Cauchy(self,default): default.add_stress_Cauchy('P','F') in_memory = mechanics.stress_Cauchy(default.place('P'), default.place('F')) @@ -264,10 +270,15 @@ class TestResult: in_file = default.place('V(F)') assert np.allclose(in_memory,in_file) - def test_add_invalid(self,default): + def test_add_invalid_dataset(self,default): with pytest.raises(TypeError): default.add_calculation('#invalid#*2') + def test_add_generic_grid_invalid(self,ref_path): + result = Result(ref_path/'4grains2x4x3_compressionY.hdf5') + with pytest.raises(NotImplementedError): + result.add_curl('F') + @pytest.mark.parametrize('shape',['vector','tensor']) def test_add_curl(self,default,shape): @@ -360,25 +371,19 @@ class TestResult: b = default.coordinates0_node.reshape(tuple(default.cells+1)+(3,),order='F') assert np.allclose(a,b) - # need to wait for writing in parallel, output order might change if select more then one - @pytest.mark.parametrize('output',['F','*',['P']],ids=range(3)) + @pytest.mark.parametrize('output',['F','*',['P'],['P','F']],ids=range(4)) @pytest.mark.parametrize('fname',['12grains6x7x8_tensionY.hdf5'],ids=range(1)) @pytest.mark.parametrize('inc',[4,0],ids=range(2)) def test_vtk(self,request,tmp_path,ref_path,update,patch_execution_stamp,patch_datetime_now,output,fname,inc): result = Result(ref_path/fname).view('increments',inc) os.chdir(tmp_path) - result.export_VTK(output) + result.export_VTK(output,parallel=False) fname = fname.split('.')[0]+f'_inc{(inc if type(inc) == int else inc[0]):0>2}.vti' - last = '' - for i in range(10): - if os.path.isfile(tmp_path/fname): - with open(fname) as f: - cur = hashlib.md5(f.read().encode()).hexdigest() - if cur == last: - break - else: - last = cur - time.sleep(.5) + v = VTK.load(tmp_path/fname) + v.set_comments('n/a') + v.save(tmp_path/fname,parallel=False) + with open(fname) as f: + cur = hashlib.md5(f.read().encode()).hexdigest() if update: with open((ref_path/'export_VTK'/request.node.name).with_suffix('.md5'),'w') as f: f.write(cur) @@ -403,6 +408,11 @@ class TestResult: os.chdir(tmp_path) single_phase.export_VTK(mode=mode) + def test_vtk_invalid_mode(self,single_phase): + with pytest.raises(ValueError): + single_phase.export_VTK(mode='invalid') + + def test_XDMF_datatypes(self,tmp_path,single_phase,update,ref_path): for shape in [('scalar',()),('vector',(3,)),('tensor',(3,3)),('matrix',(12,))]: for dtype in ['f4','f8','i1','i2','i4','i8','u1','u2','u4','u8']: @@ -494,3 +504,14 @@ class TestResult: with bz2.BZ2File((ref_path/'place'/fname).with_suffix('.pbz2')) as f: ref = pickle.load(f) assert cur is None if ref is None else dict_equal(cur,ref) + + + @pytest.mark.parametrize('fname',['4grains2x4x3_compressionY.hdf5', + '6grains6x7x8_single_phase_tensionY.hdf5']) + @pytest.mark.parametrize('output',['material.yaml','*']) + @pytest.mark.parametrize('overwrite',[True,False]) + def test_export_setup(self,ref_path,tmp_path,fname,output,overwrite): + os.chdir(tmp_path) + r = Result(ref_path/fname) + r.export_setup(output,overwrite) + r.export_setup(output,overwrite) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index af0c75223..6ffa26441 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -4,7 +4,7 @@ if (CMAKE_Fortran_COMPILER_ID STREQUAL "GNU") SET_SOURCE_FILES_PROPERTIES("lattice.f90" PROPERTIES COMPILE_FLAGS "-ffree-line-length-240") endif() -file(GLOB damask-sources *.f90 *.c) +file(GLOB damask-sources CONFIGURE_DEPENDS *.f90 *.c) # probably we should have a subfolder for MSC.Marc list(FILTER damask-sources EXCLUDE REGEX ".*CPFEM.f90") @@ -14,7 +14,7 @@ list(FILTER damask-sources EXCLUDE REGEX ".*commercialFEM_fileList.*.f90") if (PROJECT_NAME STREQUAL "damask-grid") - file(GLOB grid-sources grid/*.f90) + file(GLOB grid-sources CONFIGURE_DEPENDS grid/*.f90) if (NOT CMAKE_BUILD_TYPE STREQUAL "SYNTAXONLY") add_executable(DAMASK_grid ${damask-sources} ${grid-sources}) @@ -28,7 +28,7 @@ if (PROJECT_NAME STREQUAL "damask-grid") elseif (PROJECT_NAME STREQUAL "damask-mesh") - file(GLOB mesh-sources mesh/*.f90) + file(GLOB mesh-sources CONFIGURE_DEPENDS mesh/*.f90) add_executable(DAMASK_mesh ${damask-sources} ${mesh-sources}) install (TARGETS DAMASK_mesh RUNTIME DESTINATION bin) diff --git a/src/DAMASK_interface.f90 b/src/DAMASK_interface.f90 index 7bfe93f9a..58b4e86c6 100644 --- a/src/DAMASK_interface.f90 +++ b/src/DAMASK_interface.f90 @@ -102,6 +102,7 @@ subroutine DAMASK_interface_init print'(/,a)', ' Version: '//DAMASKVERSION print'(/,a)', ' Compiled with: '//compiler_version() + print'(a)', ' Compiled on: '//CMAKE_SYSTEM print'(a)', ' Compiler options: '//compiler_options() ! https://github.com/jeffhammond/HPCInfo/blob/master/docs/Preprocessor-Macros.md diff --git a/src/prec.f90 b/src/prec.f90 index 4b70ffbfa..2e67ae76a 100644 --- a/src/prec.f90 +++ b/src/prec.f90 @@ -13,7 +13,7 @@ module prec implicit none public - ! https://software.intel.com/en-us/blogs/2017/03/27/doctor-fortran-in-it-takes-all-kinds + ! https://stevelionel.com/drfortran/2017/03/27/doctor-fortran-in-it-takes-all-kinds integer, parameter :: pReal = IEEE_selected_real_kind(15,307) !< number with 15 significant digits, up to 1e+-307 (typically 64 bit) integer, parameter :: pI32 = selected_int_kind(9) !< number with at least up to +-1e9 (typically 32 bit) integer, parameter :: pI64 = selected_int_kind(18) !< number with at least up to +-1e18 (typically 64 bit)