Merge branch 'misc-improvements' into 'development'

a number of small changes

See merge request damask/DAMASK!428
This commit is contained in:
Franz Roters 2021-08-27 16:22:53 +00:00
commit 3f9ee140fd
26 changed files with 88 additions and 61 deletions

View File

@ -102,13 +102,6 @@ processing:
- master - master
- release - release
###################################################################################################
preprocessing_deprecated:
stage: python
script: PreProcessing/test.py
except:
- master
- release
################################################################################################### ###################################################################################################
compile_grid_Intel: compile_grid_Intel:

View File

@ -1,4 +1,4 @@
cmake_minimum_required (VERSION 3.10.0) cmake_minimum_required (VERSION 3.12.0)
include (FindPkgConfig REQUIRED) include (FindPkgConfig REQUIRED)
if (DEFINED ENV{PETSC_DIR}) if (DEFINED ENV{PETSC_DIR})
@ -31,6 +31,7 @@ message ("\nBuilding ${CMAKE_PROJECT_NAME} ${DAMASK_VERSION}\n")
add_definitions (-DPETSC) add_definitions (-DPETSC)
add_definitions (-DDAMASKVERSION="${DAMASK_VERSION}") add_definitions (-DDAMASKVERSION="${DAMASK_VERSION}")
add_definitions (-DCMAKE_SYSTEM="${CMAKE_SYSTEM}")
if (CMAKE_BUILD_TYPE STREQUAL "") if (CMAKE_BUILD_TYPE STREQUAL "")
set (CMAKE_BUILD_TYPE "RELEASE") set (CMAKE_BUILD_TYPE "RELEASE")

View File

@ -74,7 +74,7 @@ echo PETSC_ARCH: $PETSC_ARCH
echo PETSC_DIR: $PETSC_DIR echo PETSC_DIR: $PETSC_DIR
echo echo
echo $PETSC_DIR/$PETSC_ARCH/lib: echo $PETSC_DIR/$PETSC_ARCH/lib:
/s $PETSC_DIR/$PETSC_ARCH/lib ls $PETSC_DIR/$PETSC_ARCH/lib
echo echo
echo $PETSC_DIR/$PETSC_ARCH/lib/petsc/conf/petscvariables: echo $PETSC_DIR/$PETSC_ARCH/lib/petsc/conf/petscvariables:
cat $PETSC_DIR/$PETSC_ARCH/lib/petsc/conf/petscvariables cat $PETSC_DIR/$PETSC_ARCH/lib/petsc/conf/petscvariables

@ -1 +1 @@
Subproject commit 6037ed541710fc84699ee2ca1d36a69d7fa20f0f Subproject commit 36ac61caef1eec1ac68cadbed1a8f6f07a035f54

View File

@ -146,12 +146,6 @@ class Config(dict):
if 'sort_keys' not in kwargs: if 'sort_keys' not in kwargs:
kwargs['sort_keys'] = False 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: try:
fhandle.write(yaml.dump(self,Dumper=NiceDumper,**kwargs)) fhandle.write(yaml.dump(self,Dumper=NiceDumper,**kwargs))
except TypeError: # compatibility with old pyyaml except TypeError: # compatibility with old pyyaml

View File

@ -567,9 +567,13 @@ class Result:
formula = kwargs['formula'] formula = kwargs['formula']
for d in re.findall(r'#(.*?)#',formula): for d in re.findall(r'#(.*?)#',formula):
formula = formula.replace(f'#{d}#',f"kwargs['{d}']['data']") 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 { return {
'data': eval(formula), 'data': data,
'label': kwargs['label'], 'label': kwargs['label'],
'meta': { 'meta': {
'unit': kwargs['unit'], 'unit': kwargs['unit'],
@ -1258,7 +1262,7 @@ class Result:
Arguments parsed to func. Arguments parsed to func.
""" """
if len(datasets) != 1 or self.N_constituents !=1: if len(datasets) != 1 or self.N_constituents != 1:
raise NotImplementedError raise NotImplementedError
at_cell_ph,in_data_ph,at_cell_ho,in_data_ho = self._mappings() at_cell_ph,in_data_ph,at_cell_ho,in_data_ho = self._mappings()

View File

@ -257,18 +257,18 @@ def _polar_decomposition(T,requested):
u, _, vh = _np.linalg.svd(T) u, _, vh = _np.linalg.svd(T)
R = _np.einsum('...ij,...jk',u,vh) R = _np.einsum('...ij,...jk',u,vh)
output = [] output = ()
if 'R' in requested: if 'R' in requested:
output.append(R) output+=(R,)
if 'V' in requested: if 'V' in requested:
output.append(_np.einsum('...ij,...kj',T,R)) output+=(_np.einsum('...ij,...kj',T,R),)
if 'U' in requested: if 'U' in requested:
output.append(_np.einsum('...ji,...jk',R,T)) output+=(_np.einsum('...ji,...jk',R,T),)
if len(output) == 0: if len(output) == 0:
raise ValueError('output needs to be out of V, R, U') raise ValueError('output needs to be out of V, R, U')
return tuple(output) return output
def _equivalent_Mises(T_sym,s): def _equivalent_Mises(T_sym,s):

View File

@ -23,7 +23,7 @@ setuptools.setup(
'h5py>=2.9', # requires numpy 'h5py>=2.9', # requires numpy
'vtk>=8.1', 'vtk>=8.1',
'matplotlib>=3.0', # requires numpy, pillow 'matplotlib>=3.0', # requires numpy, pillow
'pyaml>=3.12' 'pyyaml>=3.12'
], ],
classifiers = [ classifiers = [
'Intended Audience :: Science/Research', 'Intended Audience :: Science/Research',

View File

@ -5,12 +5,12 @@ solver:
loadstep: loadstep:
- boundary_conditions: - boundary_conditions:
mechanical: mechanical:
dot_F: [x, 0, 0, dot_F: [[x, 0, 0],
0, -1.0e-3, 0, [0, -1.0e-3, 0],
0, 0, x] [0, 0, x]]
P: [0, x, x, P: [[0, x, x],
x, x, x, [x, x, x],
x, x, 0] [x, x, 0]]
discretization: discretization:
t: 5 t: 5
N: 10 N: 10

View File

@ -1 +1 @@
d5db0be324a959f00245e42704ea2d6f a40baead936c79dd4f86f84ad858b9fa

View File

@ -1 +1 @@
fe9ddaf54ac1fb785094251d29fcdc9c 6fb37bd65934de859dd6b6e0191e7d64

View File

@ -1 +1 @@
9c8ac0bb1eb4a7b9ebc3e5fd5840b0a4 61953c35f61f3234b98d78a912e7dc83

View File

@ -0,0 +1 @@
bb783bb80ff04dd435e814f4b82a3234

View File

@ -1 +1 @@
1b9ebd17c5257e2edba48d006f25d4e6 4f85d2613aa70622a2d5f49dc8bf2eb2

View File

@ -1 +1 @@
8967bb1a6c329a072baaa83da534ae56 e1ca5306082fc3ab411f5ddab1a2e370

View File

@ -1 +1 @@
752e8b6186ad2b6b1b5c781940669cb1 1641c3b3641e942ffc325d471bdfaf00

View File

@ -0,0 +1 @@
ba97286c5d95bf817143f7bb9cf58421

View File

@ -5,12 +5,12 @@ solver:
loadstep: loadstep:
- boundary_conditions: - boundary_conditions:
mechanical: mechanical:
dot_F: [x, 0, 0, dot_F: [[x, 0, 0],
0, 1.0e-3, 0, [0, 1.0e-3, 0],
0, 0, x] [0, 0, x]]
P: [0, x, x, P: [[0, x, x],
x, x, x, [x, x, x],
x, x, 0] [x, x, 0]]
discretization: discretization:
t: 20 t: 20
N: 40 N: 40

View File

@ -1,10 +1,20 @@
import pytest import pytest
import numpy as np import numpy as np
import damask
from damask import Crystal from damask import Crystal
class TestCrystal: 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): def test_double_to_lattice(self):
c = Crystal(lattice='cF') c = Crystal(lattice='cF')
with pytest.raises(KeyError): with pytest.raises(KeyError):
@ -55,3 +65,4 @@ class TestCrystal:
alpha=alpha,beta=beta,gamma=gamma) alpha=alpha,beta=beta,gamma=gamma)
assert np.allclose(vector, assert np.allclose(vector,
c.to_frame(**{keyFrame:c.to_lattice(**{keyLattice:vector})})) c.to_frame(**{keyFrame:c.to_lattice(**{keyLattice:vector})}))

View File

@ -13,6 +13,7 @@ import numpy as np
from damask import Result from damask import Result
from damask import Orientation from damask import Orientation
from damask import VTK
from damask import tensor from damask import tensor
from damask import mechanics from damask import mechanics
from damask import grid_filters from damask import grid_filters
@ -106,7 +107,8 @@ class TestResult:
in_file = default.place('|F_e|') in_file = default.place('|F_e|')
assert np.allclose(in_memory,in_file) 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): def test_add_calculation(self,default,tmp_path,mode):
if mode == 'direct': if mode == 'direct':
@ -123,6 +125,10 @@ class TestResult:
in_file = default.place('x') in_file = default.place('x')
assert np.allclose(in_memory,in_file) 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): def test_add_stress_Cauchy(self,default):
default.add_stress_Cauchy('P','F') default.add_stress_Cauchy('P','F')
in_memory = mechanics.stress_Cauchy(default.place('P'), default.place('F')) in_memory = mechanics.stress_Cauchy(default.place('P'), default.place('F'))
@ -264,10 +270,15 @@ class TestResult:
in_file = default.place('V(F)') in_file = default.place('V(F)')
assert np.allclose(in_memory,in_file) assert np.allclose(in_memory,in_file)
def test_add_invalid(self,default): def test_add_invalid_dataset(self,default):
with pytest.raises(TypeError): with pytest.raises(TypeError):
default.add_calculation('#invalid#*2') 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']) @pytest.mark.parametrize('shape',['vector','tensor'])
def test_add_curl(self,default,shape): 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') b = default.coordinates0_node.reshape(tuple(default.cells+1)+(3,),order='F')
assert np.allclose(a,b) 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'],['P','F']],ids=range(4))
@pytest.mark.parametrize('output',['F','*',['P']],ids=range(3))
@pytest.mark.parametrize('fname',['12grains6x7x8_tensionY.hdf5'],ids=range(1)) @pytest.mark.parametrize('fname',['12grains6x7x8_tensionY.hdf5'],ids=range(1))
@pytest.mark.parametrize('inc',[4,0],ids=range(2)) @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): 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) result = Result(ref_path/fname).view('increments',inc)
os.chdir(tmp_path) 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' fname = fname.split('.')[0]+f'_inc{(inc if type(inc) == int else inc[0]):0>2}.vti'
last = '' v = VTK.load(tmp_path/fname)
for i in range(10): v.set_comments('n/a')
if os.path.isfile(tmp_path/fname): v.save(tmp_path/fname,parallel=False)
with open(fname) as f: with open(fname) as f:
cur = hashlib.md5(f.read().encode()).hexdigest() cur = hashlib.md5(f.read().encode()).hexdigest()
if cur == last:
break
else:
last = cur
time.sleep(.5)
if update: if update:
with open((ref_path/'export_VTK'/request.node.name).with_suffix('.md5'),'w') as f: with open((ref_path/'export_VTK'/request.node.name).with_suffix('.md5'),'w') as f:
f.write(cur) f.write(cur)
@ -403,6 +408,11 @@ class TestResult:
os.chdir(tmp_path) os.chdir(tmp_path)
single_phase.export_VTK(mode=mode) 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): def test_XDMF_datatypes(self,tmp_path,single_phase,update,ref_path):
for shape in [('scalar',()),('vector',(3,)),('tensor',(3,3)),('matrix',(12,))]: for shape in [('scalar',()),('vector',(3,)),('tensor',(3,3)),('matrix',(12,))]:
for dtype in ['f4','f8','i1','i2','i4','i8','u1','u2','u4','u8']: 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: with bz2.BZ2File((ref_path/'place'/fname).with_suffix('.pbz2')) as f:
ref = pickle.load(f) ref = pickle.load(f)
assert cur is None if ref is None else dict_equal(cur,ref) 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)

View File

@ -4,7 +4,7 @@ if (CMAKE_Fortran_COMPILER_ID STREQUAL "GNU")
SET_SOURCE_FILES_PROPERTIES("lattice.f90" PROPERTIES COMPILE_FLAGS "-ffree-line-length-240") SET_SOURCE_FILES_PROPERTIES("lattice.f90" PROPERTIES COMPILE_FLAGS "-ffree-line-length-240")
endif() endif()
file(GLOB damask-sources *.f90 *.c) file(GLOB damask-sources CONFIGURE_DEPENDS *.f90 *.c)
# probably we should have a subfolder for MSC.Marc # probably we should have a subfolder for MSC.Marc
list(FILTER damask-sources EXCLUDE REGEX ".*CPFEM.f90") 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") 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") if (NOT CMAKE_BUILD_TYPE STREQUAL "SYNTAXONLY")
add_executable(DAMASK_grid ${damask-sources} ${grid-sources}) add_executable(DAMASK_grid ${damask-sources} ${grid-sources})
@ -28,7 +28,7 @@ if (PROJECT_NAME STREQUAL "damask-grid")
elseif (PROJECT_NAME STREQUAL "damask-mesh") 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}) add_executable(DAMASK_mesh ${damask-sources} ${mesh-sources})
install (TARGETS DAMASK_mesh RUNTIME DESTINATION bin) install (TARGETS DAMASK_mesh RUNTIME DESTINATION bin)

View File

@ -102,6 +102,7 @@ subroutine DAMASK_interface_init
print'(/,a)', ' Version: '//DAMASKVERSION print'(/,a)', ' Version: '//DAMASKVERSION
print'(/,a)', ' Compiled with: '//compiler_version() print'(/,a)', ' Compiled with: '//compiler_version()
print'(a)', ' Compiled on: '//CMAKE_SYSTEM
print'(a)', ' Compiler options: '//compiler_options() print'(a)', ' Compiler options: '//compiler_options()
! https://github.com/jeffhammond/HPCInfo/blob/master/docs/Preprocessor-Macros.md ! https://github.com/jeffhammond/HPCInfo/blob/master/docs/Preprocessor-Macros.md

View File

@ -13,7 +13,7 @@ module prec
implicit none implicit none
public 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 :: 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 :: 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) integer, parameter :: pI64 = selected_int_kind(18) !< number with at least up to +-1e18 (typically 64 bit)