Skip to content

Commit 68ca4b8

Browse files
committed
Merge branch 'housekeeping_2025-01-14' into 'development'
housekeeping_ 2025-01-14 See merge request damask/DAMASK!1027
2 parents 3d49333 + 1e8f32a commit 68ca4b8

11 files changed

+68
-57
lines changed

.gitlab-ci.yml

+3-7
Original file line numberDiff line numberDiff line change
@@ -81,11 +81,7 @@ pytest:
8181
- coverage report --fail-under=90 --show-missing
8282

8383
doctest:
84-
stage: python
85-
tags:
86-
- matesting2-container-runner
87-
image: git.damask-multiphysics.org:5050/damask/damask:python310_2407
88-
before_script: []
84+
extends: .python
8985
script:
9086
- export DAMASK_ROOT=$(pwd)
9187
- PYTHONPATH=${DAMASK_ROOT}/python:$PYTHONPATH
@@ -313,7 +309,7 @@ grid_performance:
313309
tags:
314310
- bare-metal
315311
before_script:
316-
- ${LOCAL_HOME}/bin/queue2 ${CI_JOB_ID} ${TOKEN} --blocking
312+
- ${LOCAL_HOME}/bin/queue ${CI_JOB_ID} ${TOKEN} --blocking
317313
- source env/DAMASK.sh
318314
- echo Job start:" $(date)"
319315
script:
@@ -355,7 +351,7 @@ update_revision:
355351
tags:
356352
- bare-metal
357353
before_script:
358-
- ${LOCAL_HOME}/bin/queue2 ${CI_JOB_ID} ${TOKEN}
354+
- ${LOCAL_HOME}/bin/queue ${CI_JOB_ID} ${TOKEN}
359355
- echo Job start:" $(date)"
360356
script:
361357
- cd $(mktemp -d)

PRIVATE

python/damask/_colormap.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,6 @@ def from_range(low: FloatSequence,
208208
raise ValueError(f'invalid color model "{model}"')
209209

210210
low_high = np.vstack((low,high)).astype(float)
211-
out_of_bounds = np.bool_(False)
212211

213212
if model.lower() == 'rgb':
214213
out_of_bounds = np.any(low_high<0) or np.any(low_high>1)
@@ -218,6 +217,8 @@ def from_range(low: FloatSequence,
218217
out_of_bounds = np.any(low_high<0) or np.any(low_high>[360,1,1])
219218
elif model.lower() == 'lab':
220219
out_of_bounds = np.any(low_high[:,0]<0)
220+
else:
221+
out_of_bounds = np.bool_(False)
221222

222223
if out_of_bounds:
223224
raise ValueError(f'{model.upper()} colors {low_high[0]} | {low_high[1]} are out of bounds')

python/damask/_orientation.py

+20-18
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import copy
2+
import warnings
23
from typing import Optional, Union, TypeVar, Literal, Sequence, NamedTuple # mypy 1.11, overload
34

45
import numpy as np
6+
import numpy.typing as npt
57

68
from ._typehints import FloatSequence, IntSequence, CrystalFamily, BravaisLattice, NumpyRngSeed
79
from . import Rotation
@@ -156,9 +158,8 @@ def __copy__(self: MyType,
156158
copy = __copy__
157159

158160

159-
160-
def __eq__(self,
161-
other: object) -> bool:
161+
def __eq__(self, # type: ignore[override]
162+
other: object) -> npt.NDArray[np.bool_]:
162163
"""
163164
Return self==other.
164165
@@ -177,8 +178,8 @@ def __eq__(self,
177178
self.parameters == other.parameters
178179
return np.logical_and(matching_type,super(self.__class__,self.reduced).__eq__(other.reduced))
179180

180-
def __ne__(self,
181-
other: object) -> bool:
181+
def __ne__(self, # type: ignore[override]
182+
other: object) -> npt.NDArray[np.bool_]:
182183
"""
183184
Return self!=other.
184185
@@ -190,14 +191,14 @@ def __ne__(self,
190191
Orientation to check for equality.
191192
192193
"""
193-
return np.logical_not(self==other) if isinstance(other, Orientation) else NotImplemented
194+
return np.logical_not(self==other)
194195

195196

196197
def isclose(self: MyType,
197198
other: MyType,
198199
rtol: float = 1e-5,
199200
atol: float = 1e-8,
200-
equal_nan: bool = True) -> bool:
201+
equal_nan: bool = True) -> np.ndarray:
201202
"""
202203
Report where values are approximately equal to corresponding ones of other Orientation.
203204
@@ -223,13 +224,11 @@ def isclose(self: MyType,
223224
self.parameters == other.parameters
224225
return np.logical_and(matching_type,super(self.__class__,self.reduced).isclose(other.reduced))
225226

226-
227-
228227
def allclose(self: MyType,
229228
other: MyType,
230229
rtol: float = 1e-5,
231230
atol: float = 1e-8,
232-
equal_nan: bool = True) -> bool:
231+
equal_nan: bool = True) -> np.bool_:
233232
"""
234233
Test whether all values are approximately equal to corresponding ones of other Orientation.
235234
@@ -250,7 +249,7 @@ def allclose(self: MyType,
250249
Whether all values are close between both orientations.
251250
252251
"""
253-
return bool(np.all(self.isclose(other,rtol,atol,equal_nan)))
252+
return np.all(self.isclose(other,rtol,atol,equal_nan))
254253

255254

256255
def __mul__(self: MyType,
@@ -1359,15 +1358,16 @@ def average(self: MyType,
13591358
# mypy 1.11
13601359
#@overload
13611360
#def to_SST(self, vector: FloatSequence, proper: bool = False, # noqa
1362-
# return_operators: Literal[False] = False) -> np.ndarray: ...
1361+
# return_operator: Literal[False] = False) -> np.ndarray: ...
13631362
#@overload
13641363
#def to_SST(self, vector: FloatSequence, proper: bool = False, # noqa
1365-
# return_operators: Literal[True] = True) -> Tuple[np.ndarray,np.ndarray]: ...
1364+
# return_operator: Literal[True] = True) -> Tuple[np.ndarray,np.ndarray]: ...
13661365
def to_SST(self,
13671366
vector: FloatSequence,
13681367
proper: bool = False,
1368+
return_operator: bool = False,
13691369
# return_operators: bool = False) -> Union[np.ndarray,Tuple[np.ndarray,np.ndarray]]:
1370-
return_operator: bool = False) -> Union[np.ndarray, ToSSTTuple]:
1370+
return_operators: bool = False) -> Union[np.ndarray, ToSSTTuple]:
13711371
"""
13721372
Rotate lab frame vector to ensure it falls into (improper or proper) standard stereographic triangle of crystal symmetry.
13731373
@@ -1392,6 +1392,8 @@ def to_SST(self,
13921392
Index of the symmetrically equivalent orientation that rotated vector to SST.
13931393
13941394
"""
1395+
if return_operators:
1396+
warnings.warn('"return_operators" is deprecated, use "return_operator".',DeprecationWarning,stacklevel=2)
13951397
vector_ = np.array(vector,float)
13961398
if vector_.shape[-1] != 3:
13971399
raise ValueError('input is not a field of three-dimensional vectors')
@@ -1520,13 +1522,13 @@ def IPF_color(self,
15201522
components_improper = np.around(np.einsum('...ji,...i',
15211523
np.broadcast_to(self.standard_triangle['improper'], vector_.shape+(3,)),
15221524
vector_), 12)
1523-
in_SST_ = np.all(components_proper >= 0.0,axis=-1) \
1524-
| np.all(components_improper >= 0.0,axis=-1)
1525-
components = np.where((in_SST_ & np.all(components_proper >= 0.0,axis=-1))[...,np.newaxis],
1525+
in_SST_ = np.logical_or(np.all(components_proper >= 0.0,axis=-1),
1526+
np.all(components_improper >= 0.0,axis=-1))
1527+
components = np.where((np.logical_and(in_SST_,np.all(components_proper >= 0.0,axis=-1)))[...,np.newaxis],
15261528
components_proper,components_improper)
15271529
else:
15281530
components = np.around(np.einsum('...ji,...i',
1529-
np.broadcast_to(self .standard_triangle['improper'], vector_.shape+(3,)),
1531+
np.broadcast_to(self.standard_triangle['improper'], vector_.shape+(3,)),
15301532
np.block([vector_[...,:2],np.abs(vector_[...,2:3])])), 12)
15311533

15321534
in_SST_ = np.all(components >= 0.0,axis=-1)

python/damask/_rotation.py

+9-9
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from typing import Optional, Union, Sequence, Tuple, Literal, List, TypeVar, NamedTuple
66

77
import numpy as np
8+
import numpy.typing as npt
89

910
from ._typehints import FloatSequence, IntSequence, NumpyRngSeed
1011
from . import tensor
@@ -144,8 +145,8 @@ def __getitem__(self: MyType,
144145
return self.copy(np.stack([c[i][item] for i in range(4)],axis=-1))
145146

146147

147-
def __eq__(self,
148-
other: object) -> bool:
148+
def __eq__(self, # type: ignore[override]
149+
other: object) -> npt.NDArray[np.bool_]:
149150
"""
150151
Return self==other.
151152
@@ -161,9 +162,8 @@ def __eq__(self,
161162
np.logical_or(np.all(self.quaternion == other.quaternion,axis=-1),
162163
np.all(self.quaternion == -1.*other.quaternion,axis=-1))
163164

164-
165-
def __ne__(self,
166-
other: object) -> bool:
165+
def __ne__(self, # type: ignore[override]
166+
other: object) -> npt.NDArray[np.bool_]:
167167
"""
168168
Return self!=other.
169169
@@ -175,13 +175,14 @@ def __ne__(self,
175175
Rotation to check for inequality.
176176
177177
"""
178-
return np.logical_not(self==other) if isinstance(other, Rotation) else NotImplemented
178+
return np.logical_not(self==other)
179+
179180

180181
def isclose(self: MyType,
181182
other: MyType,
182183
rtol: float = 1.e-5,
183184
atol: float = 1.e-8,
184-
equal_nan: bool = True) -> bool:
185+
equal_nan: bool = True) -> npt.NDArray[np.bool_]:
185186
"""
186187
Report where values are approximately equal to corresponding ones of other Rotation.
187188
@@ -207,12 +208,11 @@ def isclose(self: MyType,
207208
return np.logical_or(np.all(np.isclose(s, o,rtol,atol,equal_nan),axis=-1),
208209
np.all(np.isclose(s,-1.*o,rtol,atol,equal_nan),axis=-1))
209210

210-
211211
def allclose(self: MyType,
212212
other: MyType,
213213
rtol: float = 1.e-5,
214214
atol: float = 1.e-8,
215-
equal_nan: bool = True) -> Union[np.bool_, bool]:
215+
equal_nan: bool = True) -> np.bool_:
216216
"""
217217
Test whether all values are approximately equal to corresponding ones of other Rotation.
218218

python/damask/_table.py

+8-8
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ class Table:
1313

1414
def __init__(self,
1515
shapes: Mapping[str,Union[Union[int,np.integer],Tuple[Union[int,np.integer],...]]] = {},
16-
data: Optional[np.ndarray] = None,
16+
data: Optional[Union[np.ndarray,pd.DataFrame]] = None,
1717
comments: Union[None, str, Iterable[str]] = None):
1818
"""
1919
New spreadsheet.
@@ -421,7 +421,7 @@ def add_comment(label: str, shape: Tuple[int, ...],info: str) -> List[str]:
421421
if m:
422422
idx = np.ravel_multi_index(tuple(map(int,m.group(2).split(","))),
423423
self.shapes[key])
424-
iloc = dup.data.columns.get_loc(key).tolist().index(True) + idx
424+
iloc = dup.data.columns.get_loc(key).tolist().index(True) + idx # type: ignore
425425
dup.data.iloc[:,iloc] = data
426426
else:
427427
dup.data[label] = data.reshape(dup.data[label].shape)
@@ -598,15 +598,15 @@ def save(self,
598598
if self.shapes[l] == (1,):
599599
labels.append(f'{l}')
600600
elif len(self.shapes[l]) == 1:
601-
labels += [f'{i+1}_{l}' \
602-
for i in range(self.shapes[l][0])]
601+
labels += [f'{i+1}_{l}'
602+
for i in range(self.shapes[l][0])]
603603
else:
604-
labels += [f'{util.srepr(self.shapes[l],"x")}:{i+1}_{l}' \
605-
for i in range(np.prod(self.shapes[l],dtype=np.int64))] # type: ignore
604+
labels += [f'{util.srepr(self.shapes[l],"x")}:{i+1}_{l}'
605+
for i in range(np.prod(self.shapes[l],dtype=np.int64))] # type: ignore
606606

607607
with util.open_text(fname,'w') as f:
608608
f.write('\n'.join([f'# {c}' for c in self.comments] + [' '.join(labels)])+('\n' if labels else ''))
609-
try: # backward compatibility
609+
try: # backward compatibility (pandas<1.5)
610610
self.data.to_csv(f,sep=' ',na_rep='nan',index=False,header=False,lineterminator='\n')
611611
except TypeError:
612-
self.data.to_csv(f,sep=' ',na_rep='nan',index=False,header=False,line_terminator='\n')
612+
self.data.to_csv(f,sep=' ',na_rep='nan',index=False,header=False,line_terminator='\n') # type: ignore

python/damask/util.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -459,7 +459,7 @@ def hybrid_IA(dist: _FloatSequence,
459459
460460
"""
461461
N_opt_samples = max(_np.count_nonzero(dist),N) # random subsampling if too little samples requested
462-
N_inv_samples = 0
462+
N_inv_samples = _np.int_(0)
463463

464464
scale_,scale,inc_factor = (0.0,float(N_opt_samples),1.0)
465465
while (not _np.isclose(scale, scale_)) and (N_inv_samples != N_opt_samples):

python/pyproject.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ dependencies = [
3636
'pyyaml>=5.3',
3737
]
3838

39-
readme = 'Readme.md'
39+
readme = 'README.md'
4040
dynamic = ['version']
4141

4242
[project.urls]

python/tests/test_GeomGrid.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ def test_clean_reference(self,default,update,res_path,distance,selection,periodi
187187
@pytest.mark.parametrize('data_type',['array','list'])
188188
@pytest.mark.parametrize('invert',[True,False])
189189
def test_clean_invert(self,np_rng,default,data_type,invert):
190-
selection = np_rng.integers(1,20,6) if data_type is 'array' else list(np_rng.integers(1,20,6))
190+
selection = np_rng.integers(1,20,6) if data_type == 'array' else list(np_rng.integers(1,20,6))
191191
selection_inverse = np.setdiff1d(default.material,selection)
192192
assert default.clean(selection=selection,invert_selection=invert,rng_seed=0) == \
193193
default.clean(selection=selection_inverse,invert_selection=not invert,rng_seed=0)
@@ -362,7 +362,7 @@ def test_vicinity_offset(self,np_rng,selection):
362362
@pytest.mark.parametrize('data_type',['array','list'])
363363
@pytest.mark.parametrize('invert',[True,False])
364364
def test_vicinity_offset_invert(self,np_rng,random,data_type,invert):
365-
selection = np_rng.integers(1,20,6) if data_type is 'array' else list(np_rng.integers(1,20,6))
365+
selection = np_rng.integers(1,20,6) if data_type == 'array' else list(np_rng.integers(1,20,6))
366366
selection_inverse = np.setdiff1d(random.material,selection)
367367
assert random.vicinity_offset(selection=selection ,invert_selection=not invert) == \
368368
random.vicinity_offset(selection=selection_inverse,invert_selection= invert)

python/tests/test_Orientation.py

+5-4
Original file line numberDiff line numberDiff line change
@@ -427,7 +427,8 @@ def test_Schmid_twin_direction(self,c_a,mode):
427427
@pytest.mark.parametrize('lattice',['hP','cI','cF','tI'])
428428
def test_Schmid_vectorization(self,np_rng,assert_allclose,lattice):
429429
shape = np_rng.integers(1,4,np_rng.integers(1,4))
430-
O = Orientation.from_random(shape=shape,lattice=lattice,c=(1.2 if lattice == 'tI' else None),rng_seed=np_rng) # noqa
430+
O = Orientation.from_random(shape=shape,lattice=lattice,
431+
c=(1.2 if lattice == 'tI' else None),rng_seed=np_rng) # noqa
431432
for mode in ['slip']+([] if lattice == 'tI' else ['twin']):
432433
Ps = O.Schmid(N_slip='*') if mode == 'slip' else O.Schmid(N_twin='*')
433434
for i in itertools.product(*map(range,tuple(shape))):
@@ -437,11 +438,11 @@ def test_Schmid_vectorization(self,np_rng,assert_allclose,lattice):
437438
#assert_allclose(P,Ps[:,*i,:,:]) # ok for Python >= 3.13
438439

439440
@pytest.mark.parametrize('family',crystal_families)
440-
@pytest.mark.parametrize('shape',[(1),(2,3),(4,3,2)])
441+
@pytest.mark.parametrize('shape',[(1,),(2,3),(4,3,2)])
441442
def test_reduced_vectorization(self,np_rng,family,shape):
442443
o = Orientation.from_random(family=family,shape=shape,rng_seed=np_rng)
443-
for r, theO in zip(o.reduced.flatten(),o.flatten()):
444-
assert r == theO.reduced
444+
for i in itertools.product(*map(range,tuple(shape))):
445+
assert o[i].reduced == o[i]
445446

446447

447448
@pytest.mark.parametrize('family',crystal_families)

python/tests/test_Table.py

+16-5
Original file line numberDiff line numberDiff line change
@@ -49,21 +49,32 @@ def test_empty_init(self):
4949
t = t.set(label,data)
5050
assert np.allclose(t.get('scal').flatten()*3,t.get('vctr')[:,0])
5151

52-
def test_set(self,default):
52+
def test_set_tensor(self,default):
5353
d = default.set('F',np.zeros((5,3,3)),'set to zero').get('F')
5454
assert np.allclose(d,0.0) and d.shape[1:] == (3,3)
5555

56+
def test_set_scalar(self,np_rng,default):
57+
d = np_rng.random((5,9))
58+
assert np.allclose(d,
59+
default
60+
.set('nine',d,'random data')
61+
.get('nine'))
62+
63+
def test_set_overwrite(self,np_rng,default):
64+
d = np_rng.random((5,9))
65+
assert np.allclose(d,
66+
default
67+
.set('nine',np.ones((5,9)),'zeros')
68+
.set('nine',d,'random data')
69+
.get('nine'))
70+
5671
def test_set_component(self,default):
5772
d = default.set('F[0,0]',np.zeros((5)),'set to zero').get('F')
5873
assert np.allclose(d[...,0,0],0.0) and d.shape[1:] == (3,3)
5974

6075
def test_labels(self,default):
6176
assert default.labels == ['F','v','s']
6277

63-
def test_add(self,np_rng,default):
64-
d = np_rng.random((5,9))
65-
assert np.allclose(d,default.set('nine',d,'random data').get('nine'))
66-
6778
def test_isclose(self,default):
6879
assert default.isclose(default).all()
6980

0 commit comments

Comments
 (0)